From 5cd02a6575e28bd43ff861521afb8c14f0adecf4 Mon Sep 17 00:00:00 2001 From: Emir Karabeg Date: Thu, 5 Nov 2026 17:52:04 -0800 Subject: [PATCH 1/2] improvement(platform): consolidate organization integrations --- .agents/skills/implement-platform/SKILL.md | 4 +- .../integration-tabs-header.tsx | 8 +- .../integrations/integrations.tsx | 8 +- .../components/search-modal/search-modal.tsx | 7 +- .../w/components/sidebar/sidebar.tsx | 5 +- apps/sim/lib/navigation/paths.ts | 15 + apps/sim/platform/AGENTS.md | 10 +- apps/sim/platform/README.md | 12 +- .../_components/links-page/links-frame.tsx | 1 + .../(shell)/_components/product-session.tsx | 9 +- .../session/integration-center-changes.tsx | 72 +++++ .../activity-chart/activity-chart.tsx | 4 +- .../home-composer/home-composer.module.css | 20 -- .../home-composer/home-composer.tsx | 51 +-- .../home-dashboard/home-dashboard.module.css | 12 +- .../home-dashboard/home-dashboard.tsx | 11 +- .../home-dashboard/zone-home-dashboard.tsx | 14 +- .../integration-list.module.css | 17 - .../integration-list/integration-list.tsx | 111 ------- .../integrations-page.module.css | 18 -- .../integrations-page/integrations-page.tsx | 76 +++-- .../integrations-page/integrations-route.tsx | 10 +- .../integration-center.module.css | 30 ++ .../integration-center/integration-center.tsx | 306 ++++++++++++++++++ .../integration-list.module.css | 17 - .../integration-list/integration-list.tsx | 121 ++----- .../integrations-page.module.css | 2 +- .../integrations-page/integrations-page.tsx | 4 +- .../integrations-page/integrations-route.tsx | 19 +- .../resource-details/resource-details.tsx | 51 +++ .../resource-editor/resource-editor.tsx | 191 +++++++++++ .../resource-list/resource-list.module.css | 16 + .../resource-list/resource-list.tsx | 133 ++++++++ .../sections/usage/usage-monitoring.tsx | 4 +- .../platform/checks/desktop/renderer.spec.ts | 2 +- .../checks/integration-center.spec.ts | 247 ++++++++++++++ apps/sim/platform/checks/integrations.spec.ts | 12 +- .../platform/checks/member-secrets.spec.ts | 6 + .../design-system/catalog/evidence.json | 10 +- .../design-system/catalog/variants.json | 1 + .../activity-row/activity-row.module.css | 15 +- .../components/activity-row/activity-row.tsx | 9 +- .../design-system/components/index.ts | 2 +- .../{range-picker.tsx => choice-menu.tsx} | 6 +- .../search-field/search-field.module.css | 7 + .../components/search-field/search-field.tsx | 2 +- .../platform/design-system/styles/rhythm.css | 1 + apps/sim/platform/docs/component-ownership.md | 8 +- apps/sim/platform/docs/integration-center.md | 30 ++ .../docs/organization-integrations.md | 2 +- apps/sim/platform/fixtures/index.ts | 3 + .../fixtures/integration-center-data.ts | 171 ++++++++++ .../platform/lib/integrations/center-model.ts | 49 +++ .../lib/integrations/center-navigation.ts | 70 ++++ .../lib/integrations/fixture-model.ts | 5 +- .../sim/platform/preview/control-specimen.tsx | 10 +- scripts/check-platform-design.test.ts | 14 +- scripts/check-platform-design.ts | 5 +- scripts/sync-platform-recipes.ts | 2 +- 59 files changed, 1665 insertions(+), 413 deletions(-) create mode 100644 apps/sim/platform/app/(shell)/_components/session/integration-center-changes.tsx delete mode 100644 apps/sim/platform/app/(shell)/home/_components/home-composer/home-composer.module.css delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.module.css delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.tsx delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/resource-details/resource-details.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/resource-editor/resource-editor.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx create mode 100644 apps/sim/platform/checks/integration-center.spec.ts rename apps/sim/platform/design-system/components/menu/{range-picker.tsx => choice-menu.tsx} (95%) create mode 100644 apps/sim/platform/docs/integration-center.md create mode 100644 apps/sim/platform/fixtures/integration-center-data.ts create mode 100644 apps/sim/platform/lib/integrations/center-model.ts create mode 100644 apps/sim/platform/lib/integrations/center-navigation.ts diff --git a/.agents/skills/implement-platform/SKILL.md b/.agents/skills/implement-platform/SKILL.md index ccb6593a2b8..82e3365140e 100644 --- a/.agents/skills/implement-platform/SKILL.md +++ b/.agents/skills/implement-platform/SKILL.md @@ -10,7 +10,7 @@ Start in the Sim checkout containing the requested product work. Read the [Platf 1. **Establish scope on the real route.** Identify the product entry, interaction, phase, and affected consumers. When rebuilding an existing workflow, trace the old navigation target, its access gate, and the actions reachable by that viewer. Use that evidence to decide which controls belong on the new page before consulting the broader API or provider catalog. Phase 1 owns foundations and the library. Phase 2 owns working UI and transient interaction state, with examples supplied through the server fixture flag. Phase 3 connects real data and operations. Reuse the same renderer in the browser and Sim Desktop. Read the installed Next guides for the file structure or framework behavior you are changing. For organization Settings, inventory the old sidebar in order, its viewer/deployment gates and every action reachable from each section. Map old header buttons to the row or section they act on. Verify the same destination and drilldown on the fixture and authenticated routes; keep real writes outside fixture sessions. 2. **Resolve design intent.** For Paper-backed work, use `$sim-paper-design` to locate the live Shared or Platform master and the product states that use it. Exclude Marcus. Preserve the key and theme roles. Treat artboard sizes as reference measurements. For code-first changes, follow the latest explicit product direction and inspect the rendered route. Identify any source you could not verify. Update the Paper canvas when the request includes Paper changes. -3. **Choose or change the owner.** Start with the behavior. An action, navigation row, value picker, or disclosure has an existing keyboard and pointer contract. Different interactions may share visual roles while retaining different semantics. Use the existing family and named props for a change in size, intent, icon, or content. Put unique anatomy and its CSS beside the route component. Keep page files free of styling. Only EMCN owns the appearance of its controls. Use Base UI there for complex keyboard, floating, and dismissal behavior. -4. **Trace the full change.** On a second independent feature use, promote the original implementation and migrate both callers. For consolidation, compare semantics, map every consumer to its replacement, then remove the obsolete implementation, export, variant styles, and unused registrations. For deletion, also check menus, preferences, fixture data, workbench references, and tests that existed only for the removed feature. Preserve unrelated consumers and historical Paper evidence. A new variant needs a reachable product use. Edit the source or compiler for generated foundations and recipes. +3. **Choose or change the owner.** Start with the behavior. An action, navigation row, value picker, or disclosure has an existing keyboard and pointer contract. Different interactions may share visual roles while retaining different semantics. Use the existing family and named props for a change in size, intent, icon, or content. Toolbar choices use ChoiceMenu, as Home's period does; Select/SelectField belong to forms and settings. Compare the rendered trigger, not just its variant name. Put unique anatomy and its CSS together in `_components//.tsx` and `.module.css`. Match an existing semantic rhythm, such as Home's ActivityRow, for a custom composition. Keep page files free of styling. Only EMCN owns the appearance of its controls. Use Base UI there for complex keyboard, floating, and dismissal behavior. +4. **Trace the full change.** On a second independent feature use, promote the original implementation and migrate both callers. For consolidation, compare semantics, map every consumer to its replacement, then remove the obsolete implementation, export, variant styles, and unused registrations. For deletion, also check menus, preferences, fixture data, workbench references, and tests that existed only for the removed feature. Preserve unrelated consumers and historical Paper evidence. Before adding a shared visual variant, name at least two independent real consumers. A single feature composes the existing primitives in its local owner; a label, icon, data value or responsive arrangement does not justify another variant. Keep the public API small enough to understand at the call site. Edit the source or compiler for generated foundations and recipes. 5. **Verify where people use it.** Run the design audit and applicable checks from the README. Render the changed product route with empty, full, stress, and fixture-off data as relevant. Check both themes, widths between artboards, long content, text scaling, keyboard, and pointer states. Compare shared controls in their actual consumers. Check the actual scroll edge and the open popup when space is tight. For shell, panel, or desktop work, exercise the real Electron renderer. For substantial implementations and consolidations, use an independent agent during design or implementation and for a final review of the changed owners and routes. Provide the working localhost route for visual review. 6. **Keep decisions durable.** Follow the contract’s maintenance guidance when an approved correction changes a shared rule. Record feature-specific decisions with their feature. For sustained work, keep a task checkpoint with the code revision, verified states, evidence, and outstanding work. Include the branch or PR, checkpoint path, and localhost route in a handoff. On resumption, compare the checkpoint with the current branch, working tree, and relevant live sources before acting. diff --git a/apps/sim/app/workspace/[workspaceId]/components/integration-tabs-header/integration-tabs-header.tsx b/apps/sim/app/workspace/[workspaceId]/components/integration-tabs-header/integration-tabs-header.tsx index 11774143550..f361ec4191b 100644 --- a/apps/sim/app/workspace/[workspaceId]/components/integration-tabs-header/integration-tabs-header.tsx +++ b/apps/sim/app/workspace/[workspaceId]/components/integration-tabs-header/integration-tabs-header.tsx @@ -3,6 +3,8 @@ import type { ReactNode } from 'react' import { ChipLink, cn } from '@sim/emcn' import { HEADER_ACTION_CLUSTER, PAGE_HEADER_BAR } from '@/components/page-header-bar' +import { workspaceIntegrationsPath } from '@/lib/navigation/paths' +import { useWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider' interface IntegrationTabsHeaderProps { active: 'integrations' | 'skills' @@ -17,9 +19,13 @@ export function IntegrationTabsHeader({ workspaceId, rightSlot, }: IntegrationTabsHeaderProps) { + const host = useWorkspaceHostContext() return (
- + Integrations diff --git a/apps/sim/app/workspace/[workspaceId]/integrations/integrations.tsx b/apps/sim/app/workspace/[workspaceId]/integrations/integrations.tsx index 7817b234ae4..226f2803cc8 100644 --- a/apps/sim/app/workspace/[workspaceId]/integrations/integrations.tsx +++ b/apps/sim/app/workspace/[workspaceId]/integrations/integrations.tsx @@ -12,7 +12,7 @@ import { Search, } from '@sim/emcn' import { Lock } from '@sim/emcn/icons' -import { useParams } from 'next/navigation' +import { redirect, useParams } from 'next/navigation' import { useQueryStates } from 'nuqs' import { blockTypeToIconMap, @@ -22,6 +22,7 @@ import { resolveCredentialDisplay, } from '@/lib/integrations' import { isIntegrationPermitted } from '@/lib/integrations/access' +import { workspaceIntegrationsPath } from '@/lib/navigation/paths' import { IntegrationTabsHeader } from '@/app/workspace/[workspaceId]/components/integration-tabs-header' import { IntegrationSection } from '@/app/workspace/[workspaceId]/integrations/components/integration-section' import { IntegrationTile } from '@/app/workspace/[workspaceId]/integrations/components/integrations-showcase' @@ -34,6 +35,7 @@ import { integrationsParsers, integrationsUrlKeys, } from '@/app/workspace/[workspaceId]/integrations/search-params' +import { useWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider' import { SettingsEmptyState, SettingsQueryErrorState, @@ -159,6 +161,10 @@ function ConnectedItem({ href, blockType, name, description, icon: Icon }: Conne } export function Integrations() { + const host = useWorkspaceHostContext() + const workspaceId = host.workspace.id + const destination = workspaceIntegrationsPath(workspaceId, host) + if (destination !== `/workspace/${workspaceId}/integrations`) redirect(destination) return ( diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx index a31b13f51f7..76d18074f06 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx @@ -45,11 +45,13 @@ import { useDeploymentShape } from '@/lib/core/config/deployment-shape' import { MothershipHandoffStorage } from '@/lib/core/utils/browser-storage' import { getFolderPathNames } from '@/lib/folders/tree' import { sendMothershipMessage } from '@/lib/mothership/events' +import { workspaceIntegrationsPath } from '@/lib/navigation/paths' import { captureEvent } from '@/lib/posthog/client' import { toSearchToken } from '@/lib/search/tokens' import { hasTriggerCapability } from '@/lib/workflows/triggers/utils' import { parseWorkspaceFileFolderDisplayPath } from '@/lib/workspace-files/folder-display-path' import { useInvokeGlobalCommand } from '@/app/workspace/[workspaceId]/providers/global-commands-provider' +import { useWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider' import { CommandFadedList, CommandSearch, @@ -157,6 +159,8 @@ function SearchModalContent({ const router = useRouter() const { chatEnabled } = useDeploymentShape() const workspaceId = params.workspaceId as string + const host = useWorkspaceHostContext() + const integrationsHref = workspaceIntegrationsPath(workspaceId, host) const currentWorkflowId = params.workflowId as string | undefined const inputRef = useRef(null) const listRef = useRef(null) @@ -249,7 +253,7 @@ function SearchModalContent({ id: 'integrations', name: 'Integrations', icon: Integration, - href: `/workspace/${workspaceId}/integrations`, + href: integrationsHref, hidden: permissionConfig.hideIntegrationsTab && !requestableFeatureKeys.has('hideIntegrationsTab'), @@ -318,6 +322,7 @@ function SearchModalContent({ permissionConfig.hideTablesTab, permissionConfig.hideFilesTab, permissionConfig.hideIntegrationsTab, + integrationsHref, requestableFeatureKeys, ] ) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx index 339422d1931..c89c7d5a149 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx @@ -54,6 +54,7 @@ import { buildFolderTree, getFolderPathNames } from '@/lib/folders/tree' import { DOCS_URL, SLACK_COMMUNITY_URL } from '@/lib/help-links' import { isIntegrationUsable } from '@/lib/integrations/access' import { SIM_RESOURCES_DRAG_TYPE } from '@/lib/mothership/resource-types' +import { workspaceIntegrationsPath } from '@/lib/navigation/paths' import { captureEvent } from '@/lib/posthog/client' import { LOGO_ACCEPT_ATTRIBUTE } from '@/lib/uploads/client/logo-file' import { useSidebarChrome } from '@/app/workspace/[workspaceId]/components/workspace-chrome' @@ -415,6 +416,7 @@ export const Sidebar = memo(function Sidebar({ organizationHref, desktopExecutor const { data: sessionData, isPending: sessionLoading } = useSession() const { data: profile } = useUserProfile() const hostContext = useWorkspaceHostContext() + const integrationsHref = workspaceIntegrationsPath(workspaceId, hostContext) const { workspace: routeWorkspace } = hostContext const { hosted, chatEnabled } = useDeploymentShape() const { canAdmin, canEdit, isLoading: permissionsLoading } = useUserPermissionsContext() @@ -798,7 +800,7 @@ export const Sidebar = memo(function Sidebar({ organizationHref, desktopExecutor id: 'integrations', label: 'Integrations', icon: Integration, - href: `/workspace/${workspaceId}/integrations`, + href: integrationsHref, additionalActivePaths: [`/workspace/${workspaceId}/skills`], hidden: permissionConfig.hideIntegrationsTab && @@ -812,6 +814,7 @@ export const Sidebar = memo(function Sidebar({ organizationHref, desktopExecutor canEdit, permissionsLoading, permissionConfig.hideIntegrationsTab, + integrationsHref, permissionConfig.hideCopilot, permissionConfig.hideFilesTab, requestableFeatureKeys, diff --git a/apps/sim/lib/navigation/paths.ts b/apps/sim/lib/navigation/paths.ts index 6878d4bf9f6..65e4895d3e0 100644 --- a/apps/sim/lib/navigation/paths.ts +++ b/apps/sim/lib/navigation/paths.ts @@ -59,6 +59,21 @@ export function organizationRoutes(organizationId: string) { } as const } +interface WorkspaceIntegrationContext { + hostOrganizationId: string | null + features?: { organizationSearch?: boolean } +} + +/** Organization members use the center; standalone workspaces retain their credential routes. */ +export function workspaceIntegrationsPath( + workspaceId: string, + context: WorkspaceIntegrationContext | null +) { + return context?.features?.organizationSearch && context.hostOrganizationId + ? organizationRoutes(context.hostOrganizationId).integrations + : `/workspace/${workspaceId}/integrations` +} + /** Where `sim//` resolves in this app: the address a member types, kept verbatim. */ export function simLinkPath(...segments: string[]): string { return ['/sim', ...segments.map(encodeURIComponent)].join('/') diff --git a/apps/sim/platform/AGENTS.md b/apps/sim/platform/AGENTS.md index f8e3e606465..1c1864e1273 100644 --- a/apps/sim/platform/AGENTS.md +++ b/apps/sim/platform/AGENTS.md @@ -17,18 +17,20 @@ Search existing EMCN and route owners first. For existing designs, follow Shared ## Code-first product design -The running product and the latest approved direction govern implementation. Use Paper to identify anatomy, semantic roles and interaction states. A new code-first variant must have a reachable product consumer; record Paper keys only if an actual counterpart exists. Preserve historical design evidence without constructing a fake counterpart. When an external interface is a visual reference, translate its proportions and behavior into Sim’s existing tokens and component names. +The running product and the latest approved direction govern implementation. Use Paper to identify anatomy, semantic roles and interaction states. A new shared visual variant requires at least two independent real consumers. Keep a one-feature composition local and compose existing primitives; do not add a variant for a label, icon, data value or responsive arrangement. Remove unused variants. Record Paper keys only if an actual counterpart exists. Preserve historical design evidence without constructing a fake counterpart. When an external interface is a visual reference, translate its proportions and behavior into Sim’s existing tokens and component names. -Keep routes thin. Colocate each feature component, its CSS Module and private helpers in `app/(shell)//_components//`. `(shell)/_components/` owns parts shared by its descendant routes (navigation, conversation composer, session). Generic controls live in `design-system/components//`; import the same implementation everywhere. Each CSS Module belongs to its component folder. Base UI adapters inside EMCN may share the named `*.shared.module.css` button and popup recipes. Product components compose the corresponding EMCN controls through props. The workbench may render product owners. Product code and its variant-use graph exclude workbench modules. No customer-facing development notices. Unimplemented external actions stay unavailable. +Keep routes thin. Colocate each feature component, its CSS Module and private helpers in `app/(shell)//_components//`, with `.tsx` as its entry. `(shell)/_components/` owns parts shared by its descendant routes (navigation, conversation composer, session). Generic controls live in `design-system/components//`; import the same implementation everywhere. Each CSS Module belongs to its component folder. Use a barrel for a family with several public exports, not a redundant wrapper around every file. Base UI adapters inside EMCN may share the named `*.shared.module.css` button and popup recipes. Product components compose the corresponding EMCN controls through props. Custom feature anatomy still uses the same typography, row geometry and semantic rhythm as an existing comparable surface. The workbench may render product owners. Product code and its variant-use graph exclude workbench modules. No customer-facing development notices. Unimplemented external actions stay unavailable. Use the semantic gaps in `design-system/styles/rhythm.css`. Title/detail stacks, sibling list items and adjacent actions each have a 2px role. The 8px row gap separates leading art from copy. Separate sibling rows with the list gap. Reserve lines for surface boundaries and data rules such as chart axes. Align a leading avatar or glyph with the first text line; center trailing metadata, badges and actions against the whole row. Align action ink with adjacent text by extending the hit area into the margin. Chat thinking, tool labels and prose share that text edge. Composer and message action groups use the same compact gap. Custom calendar, chart and summary rows use the same type and spacing. An icon that identifies a two-line notification aligns to the title; its trailing action group centers against the full row. Email thread counts and the notification trigger use the same centered inline label/count spacing. The notification trigger takes the compact secondary (Invite) button surface, and has no chevron. The tray applies control elevation once around its scroll viewport; stacked notices do not cast shadows on one another. An active popup stays above the tray, including at narrow widths. Labelled range pickers and inline ellipsis menus need accessible names, not redundant tooltips; keep tooltips on top-level icon actions. -Home and Chat share a centered, border-box reading column (maximum width and inline gutter). Align the resting Home greeting with the Home navigation row using the shell’s shared row origin **inside** the moving content. The unpadded viewport keeps the fade at the window edge. The web sidebar opener belongs to the shell, outside the scrolling page. It stays at the expanded toolbar’s 12px top inset as the center content scrolls, including on Home and in the drawer layout. Keep the button reachable without covering page actions. Electron keeps both controls in its native titlebar. Keep the same shell inset immediately above and below the footer. Major dashboard/sidebar sections are independently spaced at 24px. Responsive layouts can wrap, collapse or split panels; button height, padding and type stay stable. Composer draft and placeholder keep the same type role across widths and themes; browser zoom and user text scaling still apply. +Home and Chat share a centered, border-box reading column (maximum width and inline gutter). Home and Integrations use the shared page-heading inset inside the moving content. The shell separately reserves clearance for its sidebar opener or native titlebar; responsive layout does not change either page’s own heading inset. The unpadded viewport keeps the fade at the window edge. The web sidebar opener belongs to the shell, outside the scrolling page. It stays at the expanded toolbar’s 12px top inset as the center content scrolls, including on Home and in the drawer layout. Keep the button reachable without covering page actions. Electron keeps both controls in its native titlebar. Keep the same shell inset immediately above and below the footer. Major dashboard/sidebar sections are independently spaced at 24px. Responsive layouts can wrap, collapse or split panels; button height, padding and type stay stable. Composer draft and placeholder keep the same type role across widths and themes; browser zoom and user text scaling still apply. Use `ControlRow` for the sidebar, identity controls, panel tabs, recent links, wrapping workspace choices and horizontal destination links. The row owns its 30px height, 8px inset and the placement and hover of a 24px action, including a leading remove button that replaces an existing glyph. Workspace names, the Workspaces launcher and its tab title are text-only. A recent without a glyph keeps its remove action at the end. Keep the link, tab or button semantics on the rendered element, with sibling actions outside it. Whole section headers reveal their chevron on hover; identity controls need none. Ordinary buttons, icon triggers and rows share the sidebar Home radius (`--ui-control-radius`). Use `Button` / `IconButton` for actions and Base UI triggers, passing icons and labels through their slots. The composer toolbar owns its round actions. Switches and segmented controls keep their pill shape. Clicking the selected half of a two-choice segment switches to the other half. Native keyboard choice navigation still selects its destination. Use `ActivityRow` for a first-line glyph or avatar, title/detail and centered trailing metadata. Use the chart, calendar, composer or attachment owner when those parts have a different interaction. See the [component ownership map](docs/component-ownership.md) before adding another family. +Toolbar choices use `ChoiceMenu`, the same compact quiet button and menu as Home's activity period. A toolbar action uses the existing quiet compact Button or IconButton. `Select` and `SelectField` provide field chrome for forms and settings; do not place a full-width field picker in a control bar or invent a toolbar variant to disguise it. Reuse the existing owner for the interaction and compare its actual trigger with Home before accepting it. + Measure the actual scroll viewport with `ScrollArea`, or attach `useScrollEdges` directly to a native or Base UI scroll owner. Use the shared 16px mask only on edges with more content, updating after scroll, resize, input, reset or filtering. Platform and Settings navigation hide the native scrollbar and keep their edge fades, keyboard, wheel and touch scrolling. Other scroll areas keep their existing scrollbar behavior. Insets establish resting layout; they cannot substitute for an edge fade. Home widgets and notification panels use `--ui-widget-max-size` as a ceiling, not a forced height. Keep the dashboard free to scroll and let each overflowing list or schedule scroll independently. Plain tooltips preview at most three lines; retain the complete accessible text. A structured people popover owns its content and uses the dropdown’s popup padding and row insets. Form dialogs use `Modal` or `MultiStepModal`. Pass a title, content, action labels and handlers. A confirm handler that returns a promise holds the dialog open as pending, closes it on success, and keeps the draft with an inline message on failure; nothing dismisses it while pending. Returning `false` keeps it open at the dialog's next stage, and `onBack` turns the quiet footer action into a step back. The shared borderless surface positions its title at the logical start and supplies one quiet Cancel/Back. Command search and previews use the same shadow and dismissal layer. Form controls cannot construct or style a form header, footer or Cancel button. Opening a dialog or advancing its step focuses the first available field. Confirmation dialogs focus Cancel, and read-only previews focus Close. A nested dialog handles Escape one layer at a time. While a form is open, the global search shortcut leaves its draft and keyboard focus in place. Closing returns focus to the invoking control. Textareas scroll or grow within their owner and never show a manual resize handle. Recipient fields use the textarea’s height, draft typography and inset. Committed addresses use compact caption text and an always-visible neutral ×, like a panel tab. The remove button sits inside the tag beside its label; long addresses yield space to the button. Comma or Enter commits a draft, pasting a list commits its addresses, and Backspace from an empty draft removes the last tag. @@ -45,7 +47,7 @@ Use [the shared Platform time formatters](lib/time.ts) for displayed ages, clock - A page supplies data, semantic slots, supported variants and callbacks. It owns no CSS, inline styles, Tailwind classes or visual overrides, including layout around a component. A composition with its own spacing is itself a recipe with an owner. Keep the smallest readable recipe that serves the real callers. Layout belongs to the composition. Changes to a child control’s appearance belong to that control’s owner, including when a parent selector could reach it. No `className`, `style`, utility pass-through, arbitrary JSX prop spread or per-screen colors/geometry. - Repeated data takes a typed array with stable item IDs. A specimen's row count is an example; render zero, two or more than the reference count without numbered props. Preserve genuinely distinct fixed slots. -- Keep the smallest API that describes the behavior. Use semantic HTML and import unstyled Base UI primitives inside EMCN for complex behavior. EMCN owns appearance. Base UI can own keyboard navigation, typeahead, focus management, dismissal and floating placement. Use named native controls for interactive masters and typed record arrays for repeated data. A static structural recipe does not provide those behaviors. A different label, icon, item count or viewport width does not create another variant. +- Keep the smallest API that describes the behavior. Prefer data, semantic slots and callbacks over combinations of visual flags. Do not add nested variant objects or independently tunable spacing, radius and color props. Use semantic HTML and import unstyled Base UI primitives inside EMCN for complex behavior. EMCN owns appearance. Base UI can own keyboard navigation, typeahead, focus management, dismissal and floating placement. Use named native controls for interactive masters and typed record arrays for repeated data. A static structural recipe does not provide those behaviors. A different label, icon, item count or viewport width does not create another variant. - Pointer focus changes where typing, Tab and arrow keys go and adds no ring, outline, border change, shadow or background treatment. Keyboard focus is visible: `:focus-visible` may paint, as review on the running app settled. Keep the caret, validation, hover, selection, open state and the active row during list navigation distinct. Exercise Tab, Escape, focus restoration and typing in both themes. - Every value picker, including workbench fields and modal fields, uses the shared dropdown surfaces and row recipes. Use Select for choices, Combobox for search, and Menu for commands. Use Base UI's portalled positioner for root and nested popups, inside the active theme and modal layer. Submenus open on hover and by keyboard, preserve pointer travel into the child, and flip or shift within the available space. The parent and child close one level at a time with Escape. - Keep tokens and composite recipes central. The Tailwind theme maps to semantic variables. An owner module may apply structural Tailwind utilities and registered theme roles; callers only use its public API. `PlatformSurface` selects the theme for the tree. Modules in an owner can express grid/flex, intrinsic sizing, focus, wrapping and overflow. Do not bake a screenshot into a component. At the default root size, match the Paper measurements retained by the current product direction. Use scalable type and spacing, bounded widths, flexible tracks, logical insets and natural height. Breakpoints follow a change in composition, not the number of Paper examples. Fixed stroke widths, icon geometry, touch targets and aligned data lanes are deliberate. Test intermediate widths, long content and zoom. diff --git a/apps/sim/platform/README.md b/apps/sim/platform/README.md index 0c5af6cd966..787c1ddc79f 100644 --- a/apps/sim/platform/README.md +++ b/apps/sim/platform/README.md @@ -13,11 +13,11 @@ SIM_PLATFORM_FIXTURES=1 bun run --cwd apps/sim dev:platform Open [Home](http://localhost:3100/home), [Chat](http://localhost:3100/chat/weekly-review?state=full), [Settings](http://localhost:3100/settings), [Integrations](http://localhost:3100/integrations?state=full), or the separate [component workbench](http://localhost:3100/workbench). With the flag on, `?state=empty|full|stress` selects the fixture on any of them. `?theme=light|dark|system` selects the product appearance. Product navigation preserves these choices; nothing writes examples to storage. The URL cannot activate the server flag. Old catalog links with a recipe still open the workbench. -Settings uses the same organization catalog and section components in fixture and live routes. [General](http://localhost:3100/settings/general?state=full) includes Privacy and Account details; [Sources](http://localhost:3100/settings/integrations?state=full) is the administrator's Search source inventory. The personal Integrations page is separate. Settings examples are loaded only by the server's fixture flag. Their edits belong to the browser session; no account, credential, organization policy or subscription is changed by preview interactions. +Settings uses the same organization catalog and section components in fixture and live routes. [General](http://localhost:3100/settings/general?state=full) includes Privacy and Account details; [Sources](http://localhost:3100/settings/integrations?state=full) is the administrator's Search source inventory. The [integration center](docs/integration-center.md) is the member-facing management surface for Apps, Skills, MCPs and Credentials. Settings examples are loaded only by the server's fixture flag. Their edits belong to the browser session; no account, credential, organization policy or subscription is changed by preview interactions. Settings fixtures default to Enterprise at every density. The [Team subscription](http://localhost:3100/settings/billing?state=stress&plan=team) and [Free subscription](http://localhost:3100/settings/billing?state=empty&plan=free) previews apply the selected plan to Billing, Members and the available Settings sections. The [Knowledge graphs preview](http://localhost:3100/settings/knowledge-graphs?state=stress) uses the stress viewer’s platform-admin role, benchmark access and enabled superuser mode. -The product routes live under `app/(shell)/`. Their shared App Router layout owns the shell, sidebar scroll viewport, interface preferences and chat edits. Home, Chat, Settings and Integrations pages render their own bodies inside that layout. Navigating between them keeps the sidebar reading position, including when returning from Settings. The shell selects its gated fixture and appearance from the current URL. Each route owns its components and CSS Modules in a private `_components//` folder: the [Home chart](app/%28shell%29/home/_components/activity-chart/activity-chart.tsx) sits beside its styles; the [dialog](design-system/components/modal/modal.tsx) belongs to EMCN. Shared shell UI lives in `app/(shell)/_components/`. [Rhythm tokens](design-system/styles/rhythm.css) and the [ownership and interaction contract](AGENTS.md) apply throughout the product. The [Paper state inventory](docs/core-chat-states.md) enumerates the source rows in scope. The [organization integrations guide](docs/organization-integrations.md) maps the member inventory, credential actions and tool permissions to their Phase 3 operations. Workspace rows and chat panel workspace choices open the selected workspace’s Integrations tab in fixture mode. The workspace keeps the Platform sidebar header and footer and replaces its navigation with Back, Integrations, Skills, workspace resources and workflows. See [workspace UI](docs/workspace-ui.md) for routes, preview scope and verification. Wiki is deferred. +The product routes live under `app/(shell)/`. Their shared App Router layout owns the shell, sidebar scroll viewport, interface preferences and chat edits. Home, Chat, Settings and Integrations pages render their own bodies inside that layout. Navigating between them keeps the sidebar reading position, including when returning from Settings. The shell selects its gated fixture and appearance from the current URL. Each route owns its components and CSS Modules in a private `_components//` folder: the [Home chart](app/%28shell%29/home/_components/activity-chart/activity-chart.tsx) sits beside its styles; the [dialog](design-system/components/modal/modal.tsx) belongs to EMCN. Shared shell UI lives in `app/(shell)/_components/`. [Rhythm tokens](design-system/styles/rhythm.css) and the [ownership and interaction contract](AGENTS.md) apply throughout the product. The [Paper state inventory](docs/core-chat-states.md) enumerates the source rows in scope. The [organization integrations guide](docs/organization-integrations.md) maps the member inventory, credential actions and tool permissions to their data operations. The integration center lives at the organization root; Home and eligible workspace links open that same destination. Standalone workspaces and viewers without organization Search access retain their existing credential route. Skills, MCPs and new sharing/editor interactions currently use only server-gated fixtures. Paper workspace tabs and the control bar inform the center's anatomy. Wiki is deferred. ## Live data and the zone @@ -53,21 +53,19 @@ SIM_DESKTOP_ORIGIN=http://127.0.0.1:3100 SIM_DESKTOP_USER_DATA="$(mktemp -d)" bu ## Using EMCN -Select a theme once with `PlatformSurface`. Editors, menus, selections, links and dialogs own their keyboard behavior. `MetricGroup` and `DataTable` accept records of any length. Import controls and compositions from `@/platform/design-system/components`. Provide content and named states, never styles. For a structural master such as an Issue group, supply its Paper key and named slots. The key determines the allowed slot names and the compiler enforces missing slots. A nested button slot accepts the semantic button, not an image of it. The Paper catalog in the workbench resolves the actual example. +Select a theme once with `PlatformSurface`. Editors, menus, selections, links and dialogs own their keyboard behavior. `MetricGroup` and `DataTable` accept records of any length. Import controls and compositions from `@/platform/design-system/components`. Provide content and named states, never styles. Unique feature compositions live beside their route and use these controls. Paper structural recipes remain workbench specimens and do not substitute for interactive product components. ```tsx -import { ComponentRecipe } from '@/platform/design-system/catalog/component-recipe' import { Button } from '@/platform/design-system/components' - ``` Shared and Platform still own different recipes; `catalog/evidence.json` preserves that ownership and a path from the Base to a Platform product use. Registered states without a Platform use, canvas organizers and the other products are outside this library. Keep feature-specific compositions in their feature owner. Real data adapters live in `lib/data/`. Workspace lists, sidebar items, recents and attachment batches accept typed arrays with stable item IDs. Use the named components for these collection masters: a Paper specimen's item count is sample data. An empty array renders zero items, and adding items preserves their registered row/card appearance. Each scroll viewport determines fades and controls from its actual contents. Chart labels, marks, inspected values and legends come from the same series. Supply raw numeric values and their units to data tables. The column schema determines alignment and which columns remain visible as the table narrows. -The full fixture includes twenty sidebar workspaces, sixteen conversations, a twelve-message inbox and a calendar that scrolls from midnight to midnight even on empty days. Home and Chat share a reading width. The resting Home greeting aligns with the sidebar Home row. The shell uses one 12px inset above the organization and on both sides of the profile row. The Home content scrolls through its viewport edge fade. The shell keeps the collapsed sidebar button aligned with the expanded toolbar even as the page scrolls. Platform and Settings navigation scroll independently, with edge fades instead of a visible scrollbar. Calendar events use the muted surface. An event with a provider URL opens in a new tab. The attendee control opens its own people popover. Now appears when the calendar scrolls away from its resting position or another day is selected. It restores today’s schedule and centers the current time. Scrolling back to that position also hides Now. +The full fixture includes twenty sidebar workspaces, sixteen conversations, a twelve-message inbox and a calendar that scrolls from midnight to midnight even on empty days. Home and Chat share a reading width. Home and Integrations share the same heading inset; the shell reserves sidebar opener and native titlebar clearance separately. The shell uses one 12px inset above the organization and on both sides of the profile row. The Home content scrolls through its viewport edge fade. The shell keeps the collapsed sidebar button aligned with the expanded toolbar even as the page scrolls. Platform and Settings navigation scroll independently, with edge fades instead of a visible scrollbar. Calendar events use the muted surface. An event with a provider URL opens in a new tab. The attendee control opens its own people popover. Now appears when the calendar scrolls away from its resting position or another day is selected. It restores today’s schedule and centers the current time. Scrolling back to that position also hides Now. Start with the [component ownership map](docs/component-ownership.md) when choosing a primitive. Sidebar, recents and panel tabs use one row; form and command dialogs use one borderless surface. Copy confirmations and transient notifications last four seconds. The notification count uses the compact Invite button. Expanded notices share one subtle shadow around the list. A new notice pauses its expiry on hover or keyboard focus. Icon color transitions take 120ms and respect reduced motion. The [design contract](AGENTS.md) defines these rules. @@ -110,6 +108,6 @@ The Platform type check generates Next.js route types and checks the isolated pr The browser suite starts separate production servers with fixtures enabled and disabled. Supply `PLATFORM_REPORT_PATH` to save JSON, failure screenshots and traces. Next uses webpack for this nested app: the installed Turbopack also discovers the parent Sim project's proxy and instrumentation. Watch for that boundary when upgrading Next. -The static check covers ownership, styling props, evidence, tokens, variant use and dependency direction. If it flags a variant used on a real route, verify the call path and add that case to the checker. A workbench example cannot establish product usage. Use the rendered route to verify visual alignment. Compare both themes, keyboard and pointer states, actual overflow, text scaling and widths between approved artboards. Build the standalone app before running the browser suite to test the current sources. +The static check covers ownership, styling props, component folders, evidence, tokens, unused variants and dependency direction. It rejects a route CSS Module directly under `_components/`; put it with its component. If it flags a variant used on a real route, verify the call path and add that case to the checker. Review new shared visual variants against at least two independent consumers; semantic independence is a design review, not a count of repeated JSX rows. A workbench example cannot establish product usage. Use the rendered route to verify visual alignment. Compare both themes, keyboard and pointer states, actual overflow, text scaling and widths between approved artboards. Build the standalone app before running the browser suite to test the current sources. References: [Next project structure](https://nextjs.org/docs/app/getting-started/project-structure), [Next styling](https://nextjs.org/docs/app/getting-started/css), [Tailwind theme variables](https://tailwindcss.com/docs/theme), [shadcn/ui composition](https://ui.shadcn.com/docs), [Playwright assertions](https://playwright.dev/docs/test-assertions). diff --git a/apps/sim/platform/app/(shell)/_components/links-page/links-frame.tsx b/apps/sim/platform/app/(shell)/_components/links-page/links-frame.tsx index 7873b63c517..30539ecd563 100644 --- a/apps/sim/platform/app/(shell)/_components/links-page/links-frame.tsx +++ b/apps/sim/platform/app/(shell)/_components/links-page/links-frame.tsx @@ -47,6 +47,7 @@ export function LinksFrame({
- - {children} - + + + {children} + + diff --git a/apps/sim/platform/app/(shell)/_components/session/integration-center-changes.tsx b/apps/sim/platform/app/(shell)/_components/session/integration-center-changes.tsx new file mode 100644 index 00000000000..fd08b98b394 --- /dev/null +++ b/apps/sim/platform/app/(shell)/_components/session/integration-center-changes.tsx @@ -0,0 +1,72 @@ +'use client' + +import { createContext, type ReactNode, useContext, useState } from 'react' +import type { + IntegrationCenterData, + IntegrationResource, +} from '@/platform/lib/integrations/center-model' + +function useChanges(enabled: boolean) { + const [edits, setEdits] = useState>({}) + return { enabled, edits, setEdits } +} + +const Changes = createContext | null>(null) + +interface IntegrationCenterChangesProps { + enabled: boolean + children: ReactNode +} + +export function IntegrationCenterChanges({ enabled, children }: IntegrationCenterChangesProps) { + const changes = useChanges(enabled) + return {children} +} + +/** Only typed metadata survives a dialog; credentials and authentication tokens never enter it. */ +function resourceMetadata(resource: IntegrationResource): IntegrationResource { + const { id, name, description, scope, owner, people, canEdit } = resource + const identity = { id, name, description, scope, owner, people, canEdit } + switch (resource.kind) { + case 'skill': + return { ...identity, kind: 'skill', instructions: resource.instructions } + case 'mcp': + return { ...identity, kind: 'mcp', url: resource.url, auth: resource.auth } + case 'credential': + return { + ...identity, + kind: 'credential', + key: resource.key, + credentialType: resource.credentialType, + } + } +} + +export function useIntegrationCenterResources(data: IntegrationCenterData | null) { + const changes = useContext(Changes) + if (!changes) throw new Error('Integration center controls require the product layout') + const { edits, enabled, setEdits } = changes + const initial = data?.resources ?? [] + const ids = new Set(initial.map((resource) => resource.id)) + const resources = initial + .map((resource) => (resource.id in edits ? edits[resource.id] : resource)) + .filter((resource): resource is IntegrationResource => Boolean(resource)) + .concat( + Object.values(edits).filter((resource): resource is IntegrationResource => + Boolean(resource && !ids.has(resource.id)) + ) + ) + return { + resources, + save(resource: IntegrationResource) { + if (!enabled || !data) return + const existing = resources.find((entry) => entry.id === resource.id) + if (existing && !existing.canEdit) return + setEdits((current) => ({ ...current, [resource.id]: resourceMetadata(resource) })) + }, + remove(id: string) { + if (!enabled || !data || !resources.find((resource) => resource.id === id)?.canEdit) return + setEdits((current) => ({ ...current, [id]: null })) + }, + } +} diff --git a/apps/sim/platform/app/(shell)/home/_components/activity-chart/activity-chart.tsx b/apps/sim/platform/app/(shell)/home/_components/activity-chart/activity-chart.tsx index b82d6120e31..128123cdb1b 100644 --- a/apps/sim/platform/app/(shell)/home/_components/activity-chart/activity-chart.tsx +++ b/apps/sim/platform/app/(shell)/home/_components/activity-chart/activity-chart.tsx @@ -13,7 +13,7 @@ import { InlineNotice } from '@/platform/design-system/components' import { chartNumber, chartTick } from '@/platform/design-system/components/chart/chart-format' import { ChartTooltip } from '@/platform/design-system/components/chart/chart-tooltip' import { usePlotInspection } from '@/platform/design-system/components/chart/use-plot-inspection' -import { RangePicker } from '@/platform/design-system/components/menu/range-picker' +import { ChoiceMenu } from '@/platform/design-system/components/menu/choice-menu' import { useScrollEdges } from '@/platform/design-system/components/scroll-area/use-scroll-edges' import { DAY_MS, formatCalendarDate } from '@/platform/lib/time' @@ -138,7 +138,7 @@ export function HomeActivityChart({ )}
{ready && ( - void } -export function HomeComposer({ references, mode, onModeChange }: HomeComposerProps) { +export function HomeComposer({ references, mode }: HomeComposerProps) { const host = useComposerHost() const startChat = host.useStartChat() const startSearch = host.useStartSearch() const composer = host.useComposer({ draftKey: 'home', references, requestMode: 'agent' }) return ( -
-
- - - - -
- { + if (mode === 'Search' && startSearch) { + if (!draft.text) return false + startSearch(draft.text) + return undefined } - onSubmit={(draft) => { - if (mode === 'Search' && startSearch) { - if (!draft.text) return false - startSearch(draft.text) - return undefined - } - return startChat(draft) - }} - /> -
+ return startChat(draft) + }} + /> ) } diff --git a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.module.css b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.module.css index 8009ee797df..7008b5bfa29 100644 --- a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.module.css +++ b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.module.css @@ -16,7 +16,7 @@ inline-size: 100%; max-inline-size: 81rem; margin-inline: auto; - padding-block: 4rem 1.5rem; + padding-block: var(--ui-page-heading-inset, 4rem) 1.5rem; } /* The host page's canvas shows through, so the composer's row does not read as a band. */ .dashboard > [data-platform-ui] { @@ -32,11 +32,17 @@ gap: var(--ui-product-section-gap); margin-block-end: var(--ui-section-gap); } -.greeting { +.greeting, +.composerHeading { display: flex; - align-items: start; justify-content: space-between; gap: var(--ui-row-gap); +} +.composerHeading { + align-items: center; +} +.greeting { + align-items: start; margin-inline-end: calc(-1 * var(--ui-action-overhang)); } .greeting > div { diff --git a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.tsx b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.tsx index 66ee2f9481e..391cfdcd16a 100644 --- a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.tsx +++ b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/home-dashboard.tsx @@ -29,6 +29,7 @@ interface HomeDashboardProps { prompt: string /** The host's composer. It sits between surfaces: legacy chrome never renders inside one. */ composer: ReactNode + composerActions?: ReactNode hiddenWidgets: readonly HomeWidget[] onWidgetHiddenChange: (widget: HomeWidget, hidden: boolean) => void } @@ -43,6 +44,7 @@ export function HomeDashboard({ mode, prompt, composer, + composerActions, hiddenWidgets, onWidgetHiddenChange, }: HomeDashboardProps) { @@ -92,9 +94,12 @@ export function HomeDashboard({ }))} /> - - - +
+ + + + {composerActions} +
diff --git a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/zone-home-dashboard.tsx b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/zone-home-dashboard.tsx index b5c8c06389c..431f2c0cf93 100644 --- a/apps/sim/platform/app/(shell)/home/_components/home-dashboard/zone-home-dashboard.tsx +++ b/apps/sim/platform/app/(shell)/home/_components/home-dashboard/zone-home-dashboard.tsx @@ -5,6 +5,7 @@ import { useInterfacePreferences } from '@/platform/app/(shell)/_components/sess import { HomeComposer } from '@/platform/app/(shell)/home/_components/home-composer/home-composer' import { HomeDashboard } from '@/platform/app/(shell)/home/_components/home-dashboard/home-dashboard' import type { HomeActions, HomeView } from '@/platform/app/(shell)/home/_components/model' +import { SegmentedControl } from '@/platform/design-system/components' const PROMPTS: Record = { Build: 'What should we get done?', @@ -28,8 +29,17 @@ export function ZoneHomeDashboard({ view, actions }: ZoneHomeDashboardProps) { actions={actions} mode={homeMode} prompt={PROMPTS[homeMode]} - composer={ - + composer={} + composerActions={ + } hiddenWidgets={hiddenWidgets} onWidgetHiddenChange={(widget, hidden) => diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.module.css b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.module.css deleted file mode 100644 index e56d3006bd3..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.module.css +++ /dev/null @@ -1,17 +0,0 @@ -.list, -.group, -.rows { - display: grid; - grid-template-columns: minmax(0, 1fr); - min-inline-size: 0; -} -.list { - gap: var(--ui-product-section-gap); -} -.group, -.rows { - gap: var(--ui-list-gap); -} -.rows { - margin-inline: calc(-1 * var(--ui-row-inset)); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.tsx deleted file mode 100644 index 9dce3e920fc..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.tsx +++ /dev/null @@ -1,111 +0,0 @@ -'use client' - -import { useEffect, useState } from 'react' -import { useSearchParams } from 'next/navigation' -import styles from '@/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list.module.css' -import { ActivityRow, EmptyState, Icon, SearchField } from '@/platform/design-system/components' -import { - memberIntegrationHref, - memberStatus, - type OrganizationIntegration, -} from '@/platform/lib/integrations/fixture-model' -import type { MemberSecretSource } from '@/platform/lib/integrations/member-secret-source' - -interface IntegrationListProps { - integrations: readonly OrganizationIntegration[] - secrets: MemberSecretSource | null -} - -const SECTIONS = ['Your accounts', 'Available to connect', 'Managed by your organization'] as const -type Section = (typeof SECTIONS)[number] - -function sectionFor(item: OrganizationIntegration): Section { - if (item.account) return 'Your accounts' - if (item.availability === 'ready' && item.connectableMethod) return 'Available to connect' - return 'Managed by your organization' -} - -export function IntegrationList({ integrations, secrets }: IntegrationListProps) { - const params = useSearchParams() - const [query, setQuery] = useState(() => params.get('q') ?? '') - useEffect(() => { - const committed = params.get('q') ?? '' - if (committed === (new URLSearchParams(window.location.search).get('q') ?? '')) { - setQuery(committed) - } - }, [params]) - const term = query.trim().toLowerCase() - const entries = integrations.map((item) => ({ - id: item.providerId, - name: item.name, - detail: item.description, - status: item.availability === 'managed' && !item.account ? undefined : memberStatus(item), - section: sectionFor(item), - searchable: [item.name, item.description, item.account?.label].join(' ').toLowerCase(), - })) - if (secrets) { - const managed = secrets.mode === 'organization' - entries.push({ - id: 'secrets', - name: secrets.name, - detail: secrets.description, - status: undefined, - section: managed - ? 'Managed by your organization' - : secrets.names.length - ? 'Your accounts' - : 'Available to connect', - searchable: `${secrets.name} ${secrets.description}`.toLowerCase(), - }) - } - if (!entries.length) - return ( - - ) - const matches = entries.filter((entry) => entry.searchable.includes(term)) - - function updateQuery(next: string) { - const url = new URL(window.location.href) - if (next) url.searchParams.set('q', next) - else url.searchParams.delete('q') - window.history.replaceState(null, '', url) - setQuery(next) - } - return ( -
- - {matches.length === 0 && } - {SECTIONS.map((section) => { - const items = matches.filter((item) => item.section === section) - if (!items.length) return null - return ( -
-

{section}

-
    - {items.map((item) => ( - : - } - title={item.name} - detail={item.detail} - metadata={item.status} - /> - ))} -
-
- ) - })} -
- ) -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.module.css b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.module.css deleted file mode 100644 index a58b26670f5..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.module.css +++ /dev/null @@ -1,18 +0,0 @@ -.page { - display: grid; - grid-template-columns: minmax(0, 1fr); - inline-size: min(var(--ui-page-max-size), calc(100% - 2 * var(--ui-page-inline-gutter))); - margin-inline: auto; - padding-block: var(--shell-home-row-start) var(--ui-page-inset-block); - gap: var(--ui-product-section-gap); -} -.heading { - display: grid; - gap: var(--ui-stack-gap); -} -.heading p { - color: var(--ui-secondary); -} -.back { - margin-inline: calc(-1 * var(--ui-row-inset)); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx index 9e80d35811b..4aa62971810 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx @@ -1,37 +1,46 @@ 'use client' import { useSearchParams } from 'next/navigation' +import { useIntegrationCenterResources } from '@/platform/app/(shell)/_components/session/integration-center-changes' import { useOrganizationIntegrations } from '@/platform/app/(shell)/_components/session/integration-changes' import { IntegrationDetails } from '@/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details' -import { IntegrationList } from '@/platform/app/(shell)/integrations/_components/fixtures/integration-list/integration-list' -import styles from '@/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.module.css' import { MemberSecrets } from '@/platform/app/(shell)/integrations/_components/fixtures/member-secrets/member-secrets' import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading' -import { Chip } from '@/platform/design-system/components' +import { IntegrationCenter } from '@/platform/app/(shell)/integrations/_components/integration-center/integration-center' +import { + IntegrationsHeading, + IntegrationsPage as PageFrame, +} from '@/platform/app/(shell)/integrations/_components/integrations-page/integrations-page' +import type { IntegrationCenterData } from '@/platform/lib/integrations/center-model' +import { appCategory } from '@/platform/lib/integrations/center-navigation' import { type IntegrationsData, memberIntegrationHref, + memberStatus, } from '@/platform/lib/integrations/fixture-model' interface IntegrationsPageProps { data: IntegrationsData | null + center: IntegrationCenterData | null section?: string } -export function IntegrationsPage({ data, section }: IntegrationsPageProps) { +export function IntegrationsPage({ data, center, section }: IntegrationsPageProps) { const search = useSearchParams() const { integrations, save } = useOrganizationIntegrations(data) + const library = useIntegrationCenterResources(center) const item = integrations.find((entry) => entry.providerId === section) const secrets = section === 'secrets' ? data?.genericSecrets : null return ( -
+ {item || secrets ? ( <> - {item && } {secrets && ( <> @@ -42,15 +51,46 @@ export function IntegrationsPage({ data, section }: IntegrationsPageProps) { ) : ( <> -
-

Integrations

-

- Connect your accounts to the apps your organization makes available. -

-
- + + ({ + id: integration.providerId, + name: integration.name, + description: integration.description, + category: appCategory(integration.providerId), + href: memberIntegrationHref(`/integrations/${integration.providerId}`, search), + connected: Boolean(integration.account), + status: memberStatus(integration), + searchable: integration.account?.label, + people: center?.appPeople[integration.providerId], + }))} + library={ + center + ? { + data: { ...center, resources: library.resources }, + save: library.save, + remove: library.remove, + } + : undefined + } + credentials={ + data?.genericSecrets + ? [ + { + id: 'secrets', + name: data.genericSecrets.name, + description: data.genericSecrets.description, + category: 'Credentials', + scope: data.genericSecrets.mode === 'organization' ? 'shared' : 'personal', + connected: true, + href: memberIntegrationHref('/integrations/secrets', search), + }, + ] + : [] + } + /> )} -
+ ) } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx index c377e789cfb..2b68720a8b5 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx @@ -1,7 +1,7 @@ import { notFound } from 'next/navigation' import { IntegrationsPage } from '@/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page' import { readScenario } from '@/platform/design-system/navigation' -import { loadIntegrationsData } from '@/platform/fixtures' +import { loadIntegrationCenterData, loadIntegrationsData } from '@/platform/fixtures' interface IntegrationsRouteProps { section?: string @@ -10,12 +10,16 @@ interface IntegrationsRouteProps { export async function IntegrationsRoute({ section, searchParams }: IntegrationsRouteProps) { const query = await searchParams - const data = await loadIntegrationsData(readScenario(query.state), query.secrets) + const scenario = readScenario(query.state) + const [data, center] = await Promise.all([ + loadIntegrationsData(scenario, query.secrets), + loadIntegrationCenterData(scenario), + ]) if ( section && !(section === 'secrets' && data?.genericSecrets) && !data?.integrations.some((item) => item.providerId === section) ) notFound() - return + return } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css new file mode 100644 index 00000000000..1e7e5c2000b --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css @@ -0,0 +1,30 @@ +.center, +.groups { + display: grid; + min-inline-size: 0; + gap: var(--ui-product-section-gap); +} +.navigation { + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.controls { + display: flex; + align-items: center; + flex-wrap: wrap; + justify-content: space-between; + gap: var(--ui-row-gap); + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.search { + flex: 1 1 var(--container-208); + max-inline-size: var(--container-440); + min-inline-size: 0; +} +.actions { + display: flex; + flex-wrap: wrap; + max-inline-size: 100%; + flex: none; + align-items: center; + gap: var(--ui-action-gap); +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx new file mode 100644 index 00000000000..40e89449a3f --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx @@ -0,0 +1,306 @@ +'use client' + +import { useState } from 'react' +import { usePathname, useRouter, useSearchParams } from 'next/navigation' +import { useQueryStates } from 'nuqs' +import { NuqsAdapter } from 'nuqs/adapters/next/app' +import styles from '@/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css' +import { ResourceDetails } from '@/platform/app/(shell)/integrations/_components/resource-details/resource-details' +import { ResourceEditor } from '@/platform/app/(shell)/integrations/_components/resource-editor/resource-editor' +import { + AppGroup, + ResourceGroup, +} from '@/platform/app/(shell)/integrations/_components/resource-list/resource-list' +import { + ActionMenu, + Button, + ChoiceMenu, + DestinationTabs, + EmptyState, + Modal, + SearchField, +} from '@/platform/design-system/components' +import type { + AppSummary, + IntegrationCenterData, + IntegrationResource, + IntegrationTab, +} from '@/platform/lib/integrations/center-model' +import { + CENTER_TABS, + centerParams, + serializeCenter, +} from '@/platform/lib/integrations/center-navigation' + +interface ResourceLibrary { + data: IntegrationCenterData + save: (resource: IntegrationResource) => void + remove: (id: string) => void +} + +interface IntegrationCenterProps { + apps: readonly AppSummary[] + credentials?: readonly AppSummary[] + library?: ResourceLibrary + settled?: boolean +} + +const RESOURCE_KIND = { skills: 'skill', mcps: 'mcp', credentials: 'credential' } as const +const CREATE_LABEL = { + skills: 'Create skill', + mcps: 'Connect MCP', + credentials: 'Create credential', +} as const + +/** The same directory receives authorized live summaries or server-gated example data. */ +export function IntegrationCenter({ apps, credentials, library, settled }: IntegrationCenterProps) { + return ( + + + + ) +} + +function CenterContent({ + apps, + credentials = [], + library, + settled = true, +}: IntegrationCenterProps) { + const pathname = usePathname() + const router = useRouter() + const search = useSearchParams() + const [view, setView] = useQueryStates(centerParams, { history: 'replace', shallow: true }) + const [creating, setCreating] = useState(null) + const [deleting, setDeleting] = useState(null) + const tabs = library + ? CENTER_TABS + : CENTER_TABS.filter((tab) => tab.id === 'apps' || tab.id === 'credentials') + const current: IntegrationTab = tabs.some((tab) => tab.id === view.tab) ? view.tab : 'apps' + const base = `${pathname}?${search.toString()}` + const destinations = tabs.map((tab) => ({ + label: tab.label, + href: serializeCenter(base, { + tab: tab.id, + q: null, + category: null, + scope: null, + resource: null, + }), + })) + const currentHref = destinations[tabs.findIndex((tab) => tab.id === current)]?.href ?? pathname + const term = view.q.trim().toLowerCase() + const compare = (a: { name: string }, b: { name: string }) => + (view.order === 'asc' ? 1 : -1) * a.name.localeCompare(b.name) + const categories = [...new Set(apps.map((app) => app.category))].sort() + const visibleApps = apps + .filter( + (app) => + (view.category === 'all' || app.category === view.category) && + `${app.name} ${app.description} ${app.category} ${app.searchable ?? ''}` + .toLowerCase() + .includes(term) + ) + .sort(compare) + .map((app) => ({ ...app, href: serializeCenter(app.href, { ...view, resource: null }) })) + const resources = (library?.data.resources ?? []) + .filter( + (resource) => + current !== 'apps' && + resource.kind === RESOURCE_KIND[current] && + (view.scope === 'all' || resource.scope === view.scope) && + `${resource.name} ${resource.description} ${resource.owner.name}` + .toLowerCase() + .includes(term) + ) + .sort(compare) + const credentialLinks = credentials + .filter( + (item) => + (view.scope === 'all' || item.scope === view.scope) && + `${item.name} ${item.description}`.toLowerCase().includes(term) + ) + .sort(compare) + .map((app) => ({ ...app, href: serializeCenter(app.href, { ...view, resource: null }) })) + const editing = library?.data.resources.find((resource) => resource.id === view.resource) + const empty = + current === 'apps' + ? !visibleApps.length + : !resources.length && !(current === 'credentials' && credentialLinks.length) + + async function open(resource: IntegrationResource) { + await setView(view) + router.push(serializeCenter(base, { ...view, resource: resource.id }), { scroll: false }) + } + + async function navigate(href: string) { + // Flush the directory's pending URL update before it becomes a browser-history entry. + await setView(view) + router.push(href) + } + + return ( +
+
+ +
+
+
+ void setView({ q })} + /> +
+
+ {current === 'apps' ? ( + + void setView({ category: value === 'All categories' ? 'all' : value }) + } + /> + ) : ( + library && ( + + void setView({ + scope: + value === 'Shared' ? 'shared' : value === 'Personal' ? 'personal' : 'all', + }) + } + /> + ) + )} + void setView({ order: 'asc' }), + }, + { + id: 'desc', + label: 'Name Z–A', + checked: view.order === 'desc', + onSelect: () => void setView({ order: 'desc' }), + }, + ]} + /> + {current !== 'apps' && library && ( + + )} +
+
+
+ {current === 'apps' ? ( + <> + app.connected)} + onNavigate={navigate} + /> + !app.connected)} + onNavigate={navigate} + /> + + ) : ( + <> + {(['shared', 'personal'] as const).map((scope) => ( + resource.scope === scope)} + links={ + current === 'credentials' + ? credentialLinks.filter((item) => item.scope === scope) + : [] + } + order={view.order} + onNavigate={navigate} + onOpen={open} + onDelete={setDeleting} + /> + ))} + + )} + {settled && empty && ( + + )} +
+ {editing?.canEdit === false ? ( + void setView({ resource: null })} /> + ) : ( + library && + (creating || editing) && ( + { + setCreating(null) + void setView({ resource: null }) + }} + onSave={library.save} + /> + ) + )} + {deleting && library && ( + { + if (!open) setDeleting(null) + }} + onConfirm={() => { + library.remove(deleting.id) + setDeleting(null) + }} + /> + )} +
+ ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.module.css deleted file mode 100644 index e56d3006bd3..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.module.css +++ /dev/null @@ -1,17 +0,0 @@ -.list, -.group, -.rows { - display: grid; - grid-template-columns: minmax(0, 1fr); - min-inline-size: 0; -} -.list { - gap: var(--ui-product-section-gap); -} -.group, -.rows { - gap: var(--ui-list-gap); -} -.rows { - margin-inline: calc(-1 * var(--ui-row-inset)); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx index ae330d6b174..faa569ff89e 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx @@ -1,31 +1,14 @@ -import styles from '@/platform/app/(shell)/integrations/_components/integration-list/integration-list.module.css' -import { IntegrationMark } from '@/platform/app/(shell)/integrations/_components/integration-mark/integration-mark' -import { ActivityRow, EmptyState, SearchField } from '@/platform/design-system/components' -import { - type GenericSecrets, - isConnectable, - type OrganizationIntegration, +import { IntegrationCenter } from '@/platform/app/(shell)/integrations/_components/integration-center/integration-center' +import type { + GenericSecrets, + OrganizationIntegration, } from '@/platform/lib/data/integrations-types' - -const SECTIONS = [ - 'Your accounts', - 'Available to connect', - 'Managed by your organization', - 'Not available', -] as const -type Section = (typeof SECTIONS)[number] - -function sectionFor(item: OrganizationIntegration): Section { - if (item.accounts.length) return 'Your accounts' - if (isConnectable(item)) return 'Available to connect' - return item.availability === 'managed' ? 'Managed by your organization' : 'Not available' -} +import type { AppSummary } from '@/platform/lib/integrations/center-model' +import { appCategory } from '@/platform/lib/integrations/center-navigation' interface IntegrationListProps { integrations: readonly OrganizationIntegration[] secrets: GenericSecrets | null - query: string - onQueryChange: (query: string) => void integrationHref: (id: string) => string secretsHref: string /** False while a read could still add rows, so an empty list is not claimed too early. */ @@ -35,83 +18,35 @@ interface IntegrationListProps { export function IntegrationList({ integrations, secrets, - query, - onQueryChange, integrationHref, secretsHref, settled, }: IntegrationListProps) { - const term = query.trim().toLowerCase() - const entries = integrations.map((item) => ({ + const apps: AppSummary[] = integrations.map((item) => ({ id: item.id, + providerId: item.providerId, + icon: item.icon, href: integrationHref(item.id), - leading: , name: item.name, - detail: item.description, + description: item.description, + category: appCategory(item.providerId), + connected: item.accounts.length > 0 || item.availability === 'managed', status: item.status, - section: sectionFor(item), - searchable: [ - item.providerId, - item.name, - item.description, - ...item.accounts.map((account) => account.label), - ] - .join(' ') - .toLowerCase(), + searchable: [item.providerId, ...item.accounts.map((account) => account.label)].join(' '), })) - if (secrets) { - const managed = secrets.mode === 'organization' - entries.push({ - id: 'generic-secrets', - href: secretsHref, - leading: , - name: secrets.name, - detail: secrets.description, - status: managed ? 'Organization managed' : 'Personal secrets', - section: managed ? 'Managed by your organization' : 'Available to connect', - searchable: `${secrets.name} ${secrets.description}`.toLowerCase(), - }) - } - const matches = entries.filter((entry) => entry.searchable.includes(term)) - return ( -
- - {settled && - matches.length === 0 && - (term ? ( - - ) : ( - - ))} - {SECTIONS.map((section) => { - const items = matches.filter((item) => item.section === section) - if (!items.length) return null - return ( -
-

{section}

-
    - {items.map((item) => ( - - ))} -
-
- ) - })} -
- ) + const credentials: AppSummary[] = secrets + ? [ + { + id: 'generic-secrets', + href: secretsHref, + name: secrets.name, + description: secrets.description, + category: 'Credentials', + scope: secrets.mode === 'organization' ? 'shared' : 'personal', + connected: secrets.mode === 'organization', + status: secrets.mode === 'organization' ? 'Organization managed' : 'Personal secrets', + }, + ] + : [] + return } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.module.css index 2025764941a..98deef2ce15 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.module.css +++ b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.module.css @@ -3,7 +3,7 @@ grid-template-columns: minmax(0, 1fr); inline-size: min(var(--ui-page-max-size), calc(100% - 2 * var(--ui-page-inline-gutter))); margin-inline: auto; - padding-block: var(--shell-home-row-start) var(--ui-page-inset-block); + padding-block: var(--ui-page-heading-inset) var(--ui-page-inset-block); gap: var(--ui-product-section-gap); } .heading { diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.tsx index 15ad36adfaf..6b2430d48db 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-page.tsx @@ -32,7 +32,9 @@ export function IntegrationsHeading({ handoff }: IntegrationsHeadingProps) { return (

Integrations

-

Connect your accounts to the apps your organization makes available.

+

+ Connect your tools, share with your team, and bring everything into Sim. +

{handoff}
) diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-route.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-route.tsx index 208d8700597..d218a4221d2 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-route.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integrations-page/integrations-route.tsx @@ -1,6 +1,7 @@ 'use client' import type { ReactNode } from 'react' +import { useSearchParams } from 'next/navigation' import { IntegrationDetails } from '@/platform/app/(shell)/integrations/_components/integration-details/integration-details' import { IntegrationList } from '@/platform/app/(shell)/integrations/_components/integration-list/integration-list' import { @@ -19,6 +20,7 @@ import { useMemberIntegrations, } from '@/platform/lib/data/integrations' import { GENERIC_SECRETS_SEGMENT } from '@/platform/lib/data/integrations-types' +import { integrationCenterHref } from '@/platform/lib/integrations/center-navigation' const LOADING_CONNECTIONS = 'Loading your connections' const LOADING_CONNECTION = 'Loading connection' @@ -66,16 +68,21 @@ export function IntegrationsRoute({ connectionRequest, handoff, }: IntegrationsRouteProps) { + const params = useSearchParams() const { integrations, genericSecrets, inventory, policies, secrets } = useMemberIntegrations(organizationId) const actions = useIntegrationActions(organizationId) - const { search, setSearch, account, clearAccount, serialize } = useIntegrationsView() + const { search, account, clearAccount, serialize } = useIntegrationsView() const defaults = defaultIntegrationPaths(organizationId) const indexPath = basePath ?? defaults.index const pathOf = (id: string) => `${indexPath}/${encodeURIComponent(id)}` - const integrationHref = (id: string) => serialize(pathOf(id), { q: search }) - const indexHref = serialize(indexPath, { q: search }) - const memberSecretsHref = serialize(memberSecretsPath ?? defaults.memberSecrets, { q: search }) + const integrationHref = (id: string) => + serialize(integrationCenterHref(pathOf(id), params), { q: search }) + const indexHref = serialize(integrationCenterHref(indexPath, params), { q: search }) + const memberSecretsHref = serialize( + integrationCenterHref(memberSecretsPath ?? defaults.memberSecrets, params), + { q: search } + ) const inventoryStatus = inventory.error ? ( @@ -104,8 +111,6 @@ export function IntegrationsRoute({ - serialize(pathOf(integration.id), { + serialize(integrationCenterHref(pathOf(integration.id), params), { q: search, account: credentialId, }) diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-details/resource-details.tsx b/apps/sim/platform/app/(shell)/integrations/_components/resource-details/resource-details.tsx new file mode 100644 index 00000000000..42f9c4c4628 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-details/resource-details.tsx @@ -0,0 +1,51 @@ +import { ModalBody, PropertyList, TextAreaField } from '@/platform/design-system/components' +import { OverlayDialog } from '@/platform/design-system/components/modal/overlay-dialog' +import type { IntegrationResource } from '@/platform/lib/integrations/center-model' + +interface ResourceDetailsProps { + resource: IntegrationResource + onClose: () => void +} + +export function ResourceDetails({ resource, onClose }: ResourceDetailsProps) { + return ( + + + person.name).join(', '), + }, + ...(resource.kind === 'mcp' + ? [{ id: 'url', label: 'Server URL', kind: 'text' as const, value: resource.url }] + : []), + ...(resource.kind === 'credential' + ? [{ id: 'key', label: 'Key', kind: 'text' as const, value: resource.key }] + : []), + ]} + /> + {resource.kind === 'skill' && ( + + )} + + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-editor/resource-editor.tsx b/apps/sim/platform/app/(shell)/integrations/_components/resource-editor/resource-editor.tsx new file mode 100644 index 00000000000..dbcfaf311d9 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-editor/resource-editor.tsx @@ -0,0 +1,191 @@ +'use client' + +import { useState } from 'react' +import { generateId } from '@sim/utils/id' +import { + Modal, + MultiSelect, + SecretField, + SelectField, + TextAreaField, + TextField, +} from '@/platform/design-system/components' +import type { + IntegrationCenterData, + IntegrationResource, +} from '@/platform/lib/integrations/center-model' + +interface ResourceEditorProps { + kind: IntegrationResource['kind'] + resource?: IntegrationResource + data: IntegrationCenterData + onSave: (resource: IntegrationResource) => void + onClose: () => void +} + +const TITLES = { skill: 'skill', mcp: 'MCP', credential: 'credential' } as const + +export function ResourceEditor({ kind, resource, data, onSave, onClose }: ResourceEditorProps) { + const [scope, setScope] = useState(resource?.scope ?? 'personal') + const [people, setPeople] = useState( + resource?.people + .filter((person) => person.id !== resource.owner.id) + .map((person) => person.id) ?? [] + ) + const [auth, setAuth] = useState(resource?.kind === 'mcp' ? resource.auth : 'none') + + function save(values: FormData) { + if (resource?.canEdit === false) return + const read = (name: string) => String(values.get(name) ?? '').trim() + const name = read('name') + if (!name) throw new Error('Enter a name.') + const identity = { + id: resource?.id ?? generateId(), + name, + description: read('description'), + scope, + owner: resource?.owner ?? data.viewer, + people: + scope === 'shared' + ? data.people.filter( + (person) => + people.includes(person.id) || person.id === (resource?.owner.id ?? data.viewer.id) + ) + : [resource?.owner ?? data.viewer], + canEdit: true, + } + if (scope === 'shared' && !people.length) + throw new Error('Choose at least one person to share with.') + if (kind === 'skill') { + if (!read('instructions')) throw new Error('Add instructions for this skill.') + onSave({ ...identity, kind, instructions: read('instructions') }) + } else if (kind === 'mcp') { + const url = new URL(read('url')) + if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password) + throw new Error('Enter an HTTP or HTTPS server URL without credentials.') + onSave({ ...identity, kind, url: url.toString(), auth }) + } else { + if (!read('key')) throw new Error('Enter a credential key.') + onSave({ + ...identity, + kind, + key: read('key'), + credentialType: read('credentialType') === 'api-key' ? 'api-key' : 'secret', + }) + } + onClose() + } + + return ( + { + if (!open) onClose() + }} + onConfirm={save} + > + + + {kind === 'skill' && ( + + )} + {kind === 'mcp' && ( + <> + + { + if (value === 'none' || value === 'bearer' || value === 'oauth') setAuth(value) + }} + options={[ + { value: 'none', label: 'None' }, + { value: 'bearer', label: 'Bearer token' }, + { value: 'oauth', label: 'OAuth' }, + ]} + /> + {auth === 'bearer' && ( + + )} + + )} + {kind === 'credential' && ( + <> + + + + + )} + { + if (value === 'shared' || value === 'personal') setScope(value) + }} + options={[ + { value: 'personal', label: 'Personal' }, + { value: 'shared', label: 'Shared' }, + ]} + /> + {scope === 'shared' && ( + person.id !== (resource?.owner.id ?? data.viewer.id)) + .map((person) => ({ value: person.id, label: person.name }))} + value={people} + onValueChange={setPeople} + /> + )} + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css new file mode 100644 index 00000000000..0e26f24277c --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css @@ -0,0 +1,16 @@ +.group { + display: grid; + min-inline-size: 0; + gap: var(--ui-section-gap); +} +.rows { + display: grid; + gap: var(--ui-list-gap); + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.people { + display: flex; + align-items: center; + gap: var(--ui-row-gap); + color: var(--ui-secondary); +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx new file mode 100644 index 00000000000..8759ad85db5 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx @@ -0,0 +1,133 @@ +import { IntegrationMark } from '@/platform/app/(shell)/integrations/_components/integration-mark/integration-mark' +import styles from '@/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css' +import { ActionMenu, ActivityRow, AvatarGroup, Icon } from '@/platform/design-system/components' +import type { AppSummary, IntegrationResource } from '@/platform/lib/integrations/center-model' + +interface AppGroupProps { + title: string + apps: readonly AppSummary[] + onNavigate: (href: string) => void +} + +export function AppGroup({ title, apps, onNavigate }: AppGroupProps) { + if (!apps.length) return null + return ( +
+

{title}

+
    + {apps.map((app) => ( + + ))} +
+
+ ) +} + +interface AppEntryProps { + app: AppSummary + onNavigate: (href: string) => void +} + +function AppEntry({ app, onNavigate }: AppEntryProps) { + return ( + { + event.preventDefault() + onNavigate(app.href) + }} + leading={} + title={app.name} + detail={app.description} + metadata={app.status} + showChevron={!app.people?.length} + trailing={ + app.people?.length ? ( + + + {app.people.length} + + ) : undefined + } + /> + ) +} + +interface ResourceGroupProps { + title: string + resources: readonly IntegrationResource[] + links?: readonly AppSummary[] + order: 'asc' | 'desc' + onNavigate: (href: string) => void + onOpen: (resource: IntegrationResource) => void + onDelete: (resource: IntegrationResource) => void +} + +export function ResourceGroup({ + title, + resources, + links = [], + order, + onNavigate, + onOpen, + onDelete, +}: ResourceGroupProps) { + if (!resources.length && !links.length) return null + const entries = [...resources, ...links].sort( + (a, b) => (order === 'asc' ? 1 : -1) * a.name.localeCompare(b.name) + ) + return ( +
+

{title}

+
    + {entries.map((resource) => + 'kind' in resource ? ( + + } + title={resource.name} + detail={resource.description} + showChevron={false} + onOpen={() => onOpen(resource)} + trailing={ + <> + {resource.scope === 'shared' && ( + + )} + {resource.canEdit && ( + onOpen(resource) }, + { id: 'share', label: 'Manage access', onSelect: () => onOpen(resource) }, + { + id: 'delete', + label: 'Delete', + destructive: true, + separatorBefore: true, + onSelect: () => onDelete(resource), + }, + ]} + /> + )} + + } + /> + ) : ( + + ) + )} +
+
+ ) +} diff --git a/apps/sim/platform/app/(shell)/settings/_components/sections/usage/usage-monitoring.tsx b/apps/sim/platform/app/(shell)/settings/_components/sections/usage/usage-monitoring.tsx index b41cb4e6eab..e279306cee1 100644 --- a/apps/sim/platform/app/(shell)/settings/_components/sections/usage/usage-monitoring.tsx +++ b/apps/sim/platform/app/(shell)/settings/_components/sections/usage/usage-monitoring.tsx @@ -21,8 +21,8 @@ import { UsageCalendar } from '@/platform/app/(shell)/settings/_components/secti import styles from '@/platform/app/(shell)/settings/_components/sections/usage/usage-section.module.css' import { Button, + ChoiceMenu, DateRangePicker, - RangePicker, ScrollArea, SegmentedControl, } from '@/platform/design-system/components' @@ -123,7 +123,7 @@ export function UsageMonitoring({ organization }: Pick
- { + await page.goto(`${origin}/integrations?state=stress&tab=credentials`) + const main = page.getByRole('main') + const secrets = main.getByRole('link', { name: /^Generic Secrets / }) + await expect(secrets).toBeVisible() + await main.getByRole('button', { name: /^Sharing:/ }).click() + await page.getByRole('menuitemradio', { name: 'Shared', exact: true }).click() + await expect(secrets).toHaveCount(0) + await main.getByRole('button', { name: /^Sharing:/ }).click() + await page.getByRole('menuitemradio', { name: 'Personal', exact: true }).click() + await secrets.click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await expect(main.getByRole('button', { name: /^Sharing:/ })).toContainText('Personal') + await expect(secrets).toBeVisible() +}) + +test('directory filters and ordering survive app details and resource browser history', async ({ + page, +}) => { + await page.goto(`${origin}/integrations?state=full`) + const main = page.getByRole('main') + await main.getByRole('button', { name: /^App category:/ }).click() + await page.getByRole('menuitemradio', { name: 'Communication', exact: true }).click() + await main.getByRole('button', { name: 'Sort integrations', exact: true }).click() + await page.getByRole('menuitemcheckbox', { name: 'Name Z–A', exact: true }).click() + await expect( + main.getByRole('region', { name: 'Connected', exact: true }).getByRole('link').first() + ).toContainText('Google Calendar') + await main.getByRole('searchbox', { name: 'Search apps', exact: true }).fill('gmail') + await main.getByRole('link', { name: /^Gmail / }).click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await expect(main.getByRole('searchbox', { name: 'Search apps', exact: true })).toHaveValue( + 'gmail' + ) + await expect(main.getByRole('button', { name: /^App category:/ })).toContainText('Communication') + await expect(page).toHaveURL(/order=desc/) + await expect(main.getByRole('link', { name: /^Fireflies / })).toHaveCount(0) + + await main + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: 'Skills', exact: true }) + .click() + await main.getByRole('button', { name: /^Sharing:/ }).click() + await page.getByRole('menuitemradio', { name: 'Personal', exact: true }).click() + await main.getByRole('searchbox', { name: 'Search skills', exact: true }).fill('preparation') + await main.getByRole('button', { name: /^Meeting preparation / }).click() + await expect(page.getByRole('dialog', { name: 'Edit skill', exact: true })).toBeVisible() + await page.goBack() + await expect(page.getByRole('dialog')).toHaveCount(0) + await expect(main.getByRole('searchbox', { name: 'Search skills', exact: true })).toHaveValue( + 'preparation' + ) + await expect(main.getByRole('button', { name: /^Sharing:/ })).toContainText('Personal') + await expect(main.getByRole('button', { name: /^Weekly customer review / })).toHaveCount(0) +}) + +test('editing a shared skill preserves its members and survives leaving the directory', async ({ + page, +}) => { + await page.goto(`${origin}/integrations?state=full&tab=skills`) + const main = page.getByRole('main') + await main.getByRole('button', { name: /^Weekly customer review / }).click() + const editor = page.getByRole('dialog', { name: 'Edit skill', exact: true }) + await editor + .getByLabel('Description', { exact: true }) + .fill('Include renewal decisions in the weekly account review.') + await editor.getByRole('combobox', { name: /^People with access:/ }).click() + await expect(page.getByRole('option', { name: 'Emir Karabeg', exact: true })).toHaveAttribute( + 'aria-selected', + 'true' + ) + await page.getByRole('option', { name: 'Alex Chen', exact: true }).click() + await page.keyboard.press('Escape') + await editor.getByRole('button', { name: 'Save changes', exact: true }).click() + await expect(editor).toHaveCount(0) + const navigation = page.getByRole('region', { name: 'Platform navigation' }) + await navigation.getByRole('link', { name: 'Home', exact: true }).click() + await navigation.getByRole('link', { name: 'Integrations', exact: true }).click() + await main + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: 'Skills', exact: true }) + .click() + await main.getByRole('button', { name: /^Weekly customer review / }).click() + await expect(editor.getByLabel('Description', { exact: true })).toHaveValue( + 'Include renewal decisions in the weekly account review.' + ) + await editor.getByRole('combobox', { name: /^People with access:/ }).click() + for (const name of ['Emir Karabeg', 'Maya Thompson', 'Alex Chen']) { + await expect(page.getByRole('option', { name, exact: true })).toHaveAttribute( + 'aria-selected', + 'true' + ) + } +}) + +test('shared creation needs a recipient and deletion affects only the confirmed resource', async ({ + page, +}) => { + await page.goto(`${origin}/integrations?state=full&tab=skills`) + const main = page.getByRole('main') + await main.getByRole('button', { name: 'Create skill', exact: true }).click() + const editor = page.getByRole('dialog', { name: 'Create skill', exact: true }) + await editor.getByLabel('Name', { exact: true }).fill('Daily account brief') + await editor.getByLabel('Description', { exact: true }).fill('Prepare the daily handoff.') + await editor + .getByLabel('Instructions', { exact: true }) + .fill('Summarize open decisions and cite each source.') + await editor.getByRole('combobox', { name: 'Access', exact: true }).click() + await page.getByRole('option', { name: 'Shared', exact: true }).click() + await editor.getByRole('button', { name: 'Create', exact: true }).click() + await expect(editor.getByRole('alert')).toContainText('Choose at least one person') + await editor.getByRole('combobox', { name: /^People with access:/ }).click() + await page.getByRole('option', { name: 'Nina Patel', exact: true }).click() + await page.keyboard.press('Escape') + await editor.getByRole('button', { name: 'Create', exact: true }).click() + const added = main + .getByRole('region', { name: 'Shared', exact: true }) + .getByRole('button', { name: /^Daily account brief / }) + await expect(added).toBeVisible() + await main.getByRole('button', { name: 'Manage Daily account brief', exact: true }).click() + await page.getByRole('menuitem', { name: 'Delete', exact: true }).click() + const confirmation = page.getByRole('dialog', { + name: 'Delete Daily account brief?', + exact: true, + }) + await confirmation.getByRole('button', { name: 'Cancel', exact: true }).click() + await expect(added).toBeVisible() + await main.getByRole('button', { name: 'Manage Daily account brief', exact: true }).click() + await page.getByRole('menuitem', { name: 'Delete', exact: true }).click() + await confirmation.getByRole('button', { name: 'Delete', exact: true }).click() + await expect(added).toHaveCount(0) + await expect(main.getByRole('button', { name: /^Weekly customer review / })).toBeVisible() +}) + +test('MCP and credential examples retain metadata without sending writes or retaining secrets', async ({ + page, +}) => { + const writes: string[] = [] + page.on('request', (request) => { + if (!['GET', 'HEAD', 'OPTIONS'].includes(request.method())) writes.push(request.url()) + }) + await page.goto(`${origin}/integrations?state=full&tab=mcps`) + const main = page.getByRole('main') + await main.getByRole('button', { name: 'Connect MCP', exact: true }).click() + const mcp = page.getByRole('dialog', { name: 'Create MCP', exact: true }) + await mcp.getByLabel('Name', { exact: true }).fill('Test research server') + await mcp.getByLabel('Server URL', { exact: true }).fill('https://research.example.com/mcp') + await mcp.getByRole('combobox', { name: 'Authentication', exact: true }).click() + await page.getByRole('option', { name: 'Bearer token', exact: true }).click() + await mcp.getByLabel('Token', { exact: true }).fill('integration-center-test-token') + await mcp.getByRole('button', { name: 'Connect', exact: true }).click() + await main.getByRole('button', { name: /^Test research server(?: |$)/ }).click() + const editMcp = page.getByRole('dialog', { name: 'Edit MCP', exact: true }) + await expect(editMcp.getByLabel('Server URL', { exact: true })).toHaveValue( + 'https://research.example.com/mcp' + ) + await expect(editMcp.getByLabel('Token', { exact: true })).toHaveValue('') + await editMcp.getByRole('button', { name: 'Cancel', exact: true }).click() + + await main + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: 'Credentials', exact: true }) + .click() + await main.getByRole('button', { name: 'Create credential', exact: true }).click() + const credential = page.getByRole('dialog', { name: 'Create credential', exact: true }) + await credential.getByLabel('Name', { exact: true }).fill('Test research key') + await credential.getByLabel('Key', { exact: true }).fill('RESEARCH_KEY') + await credential.getByLabel('Value', { exact: true }).fill('integration-center-test-secret') + await credential.getByRole('button', { name: 'Create', exact: true }).click() + await main.getByRole('button', { name: /^Test research key(?: |$)/ }).click() + const editCredential = page.getByRole('dialog', { name: 'Edit credential', exact: true }) + await expect(editCredential.getByLabel('Key', { exact: true })).toHaveValue('RESEARCH_KEY') + await expect(editCredential.getByLabel('Replace value', { exact: true })).toHaveValue('') + await editCredential.getByRole('button', { name: 'Cancel', exact: true }).click() + const storage = await page.evaluate(() => JSON.stringify({ ...localStorage, ...sessionStorage })) + expect(storage).not.toContain('integration-center-test-token') + expect(storage).not.toContain('integration-center-test-secret') + expect(writes).toEqual([]) +}) + +test('directory controls remain reachable without overlapping at intermediate widths', async ({ + page, +}) => { + await page.goto(`${origin}/integrations?state=full`) + const main = page.getByRole('main') + for (const width of [390, 768, 1024]) { + await page.setViewportSize({ width, height: 900 }) + for (const tab of ['Apps', 'Credentials']) { + await main + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: tab, exact: true }) + .click() + const controls = [ + main.getByRole('searchbox', { + name: tab === 'Apps' ? 'Search apps' : 'Search credentials', + exact: true, + }), + main.getByRole('button', { name: tab === 'Apps' ? /^App category:/ : /^Sharing:/ }), + main.getByRole('button', { name: 'Sort integrations', exact: true }), + ...(tab === 'Credentials' + ? [main.getByRole('button', { name: 'Create credential', exact: true })] + : []), + ] + const boxes = await Promise.all( + controls.map(async (control) => { + await expect(control).toBeVisible() + const box = await control.boundingBox() + if (!box) throw new Error('A directory control has no visible bounds') + expect(box.x).toBeGreaterThanOrEqual(0) + expect(box.x + box.width).toBeLessThanOrEqual(width + 1) + return box + }) + ) + for (const [index, box] of boxes.entries()) { + for (const other of boxes.slice(index + 1)) { + const overlapWidth = + Math.min(box.x + box.width, other.x + other.width) - Math.max(box.x, other.x) + const overlapHeight = + Math.min(box.y + box.height, other.y + other.height) - Math.max(box.y, other.y) + expect(overlapWidth > 1 && overlapHeight > 1).toBe(false) + } + } + expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual( + width + ) + } + } +}) + +test('disabling fixtures exposes no resource examples or creation controls', async ({ page }) => { + for (const tab of ['skills', 'mcps', 'credentials']) { + await page.goto(`http://127.0.0.1:3180/integrations?state=full&tab=${tab}`) + const main = page.getByRole('main') + await expect( + main.getByRole('button', { name: /^(Create skill|Connect MCP|Create credential)$/ }) + ).toHaveCount(0) + await expect(main.getByRole('button', { name: /^Weekly customer review / })).toHaveCount(0) + await expect(main.getByRole('button', { name: /^Customer knowledge / })).toHaveCount(0) + await expect(main.getByRole('button', { name: /^Research API / })).toHaveCount(0) + } +}) diff --git a/apps/sim/platform/checks/integrations.spec.ts b/apps/sim/platform/checks/integrations.spec.ts index 01bfadc49a8..e1fa1be9d97 100644 --- a/apps/sim/platform/checks/integrations.spec.ts +++ b/apps/sim/platform/checks/integrations.spec.ts @@ -7,7 +7,7 @@ test('an approved app can connect and disconnect a sample account during the sam }) => { await page.goto(`${origin}/integrations?state=full`) const list = page.getByRole('main') - await list.getByRole('searchbox', { name: 'Search integrations' }).fill('Linear issues') + await list.getByRole('searchbox', { name: 'Search apps' }).fill('Linear issues') await list.getByRole('link', { name: /^Linear / }).click() const guide = list.getByRole('link', { name: 'Docs (opens in a new tab)', exact: true }) await expect(guide).toHaveAttribute('href', 'https://docs.sim.ai/search/linear') @@ -31,9 +31,7 @@ test('an approved app can connect and disconnect a sample account during the sam await expect(title).toBeFocused() await list.getByRole('link', { name: 'Integrations', exact: true }).click() await expect( - list - .getByRole('region', { name: 'Available to connect' }) - .getByRole('link', { name: /^Linear / }) + list.getByRole('region', { name: 'Explore apps' }).getByRole('link', { name: /^Linear / }) ).toBeVisible() }) @@ -69,7 +67,7 @@ test('a cleared integration search stays clear when opening a provider and retur }) => { await page.goto(`${origin}/integrations?state=full&q=Fireflies`) const main = page.getByRole('main') - const field = main.getByRole('searchbox', { name: 'Search integrations' }) + const field = main.getByRole('searchbox', { name: 'Search apps' }) await page .getByRole('region', { name: 'Platform navigation' }) .getByRole('link', { name: 'Integrations', exact: true }) @@ -102,7 +100,7 @@ test('managed, unconfigured and retained connections expose only the actions the await expect(reads).toContainText('Read available meeting summaries') await expect(main.getByRole('radio')).toHaveCount(0) await main.getByRole('link', { name: 'Integrations', exact: true }).click() - const managed = main.getByRole('region', { name: 'Managed by your organization' }) + const managed = main.getByRole('region', { name: 'Explore apps' }) for (const provider of ['GitLab', 'Slack', 'Granola', 'Zoom']) { await managed.getByRole('link', { name: new RegExp(`^${provider} `) }).click() const docs = main.getByRole('link', { name: /Docs/ }) @@ -147,7 +145,7 @@ test('the fixture flag and member inventory gate both the index and deep links', [origin, 'empty'], ]) { await page.goto(`${site}/integrations?state=${state}`) - await expect(page.getByRole('heading', { name: 'No integrations available' })).toBeVisible() + await expect(page.getByRole('heading', { name: 'No apps yet' })).toBeVisible() await page.goto(`${site}/integrations/gmail?state=${state}`) await expect(page.getByRole('heading', { name: 'Gmail', exact: true })).toHaveCount(0) await expect(page.getByText('emir@sim.ai', { exact: true })).toHaveCount(0) diff --git a/apps/sim/platform/checks/member-secrets.spec.ts b/apps/sim/platform/checks/member-secrets.spec.ts index 4d3ff98eee0..094bab85463 100644 --- a/apps/sim/platform/checks/member-secrets.spec.ts +++ b/apps/sim/platform/checks/member-secrets.spec.ts @@ -6,10 +6,15 @@ test('the member secrets destination delivers only the credential names the view page, }) => { const link = page.getByRole('main').getByRole('link', { name: /^Generic Secrets/ }) + const credentials = page + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: 'Credentials', exact: true }) await page.goto(`${origin}/integrations?state=full`) + await credentials.click() await expect(link).toHaveCount(0) await page.goto(`${origin}/integrations?state=stress`) + await credentials.click() await link.click() await expect(page.getByRole('region', { name: 'Personal secrets' })).toContainText( 'REPORTING_TOKEN' @@ -18,6 +23,7 @@ test('the member secrets destination delivers only the credential names the view const managed = await page.goto(`${origin}/integrations?state=stress&secrets=organization`) expect(await managed?.text()).not.toContain('REPORTING_TOKEN') + await credentials.click() await link.click() await expect(page).toHaveURL(/\/integrations\/secrets\?.*secrets=organization/) const main = page.getByRole('main') diff --git a/apps/sim/platform/design-system/catalog/evidence.json b/apps/sim/platform/design-system/catalog/evidence.json index ec45e36910b..ef9b4ea2520 100644 --- a/apps/sim/platform/design-system/catalog/evidence.json +++ b/apps/sim/platform/design-system/catalog/evidence.json @@ -3519,7 +3519,7 @@ "family": "RangeControl/default", "theme": "D", "scope": "shared", - "owner": "RangePicker", + "owner": "ChoiceMenu", "icon": "I080", "base": ["01M6ASMN2120W3CEDT8FXWCTQX", "p-5-0", "C6-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-17-0", "2Y9T-0"] @@ -3529,7 +3529,7 @@ "family": "RangeControl/default", "theme": "D", "scope": "platform", - "owner": "RangePicker", + "owner": "ChoiceMenu", "icon": "I080", "base": ["01M6ASMG4R446K2Z96JZRXZFX7", "p-2-0", "218-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-17-0", "2XGG-0"] @@ -3539,7 +3539,7 @@ "family": "RangeControl/default", "theme": "L", "scope": "shared", - "owner": "RangePicker", + "owner": "ChoiceMenu", "icon": "I080", "base": ["01M6ASMJ22TS7WG8Q3P5YTHWWD", "p-8-0", "TD-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-L-0", "2EIP-0"] @@ -3549,7 +3549,7 @@ "family": "RangeControl/default", "theme": "L", "scope": "platform", - "owner": "RangePicker", + "owner": "ChoiceMenu", "icon": "I080", "base": ["01M6ASMDKJ81HACJGPNYCJQVVT", "p-2-0", "1ZE-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-L-0", "1C60-0"] @@ -3559,7 +3559,7 @@ "family": "RangeControl/open", "theme": "L", "scope": "platform", - "owner": "RangePicker", + "owner": "ChoiceMenu", "icon": "I080", "base": ["01M6ASMDKJ81HACJGPNYCJQVVT", "p-2-0", "23T-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-L-0", "1DGU-0"] diff --git a/apps/sim/platform/design-system/catalog/variants.json b/apps/sim/platform/design-system/catalog/variants.json index 594521dfef5..1755c319420 100644 --- a/apps/sim/platform/design-system/catalog/variants.json +++ b/apps/sim/platform/design-system/catalog/variants.json @@ -70,6 +70,7 @@ "SearchField": { "variant": { "outlined": ["C0925", "C0926", "C0928"], + "quiet": [], "sidebar": ["C1083", "C1084", "C1086", "C1088"] } }, diff --git a/apps/sim/platform/design-system/components/activity-row/activity-row.module.css b/apps/sim/platform/design-system/components/activity-row/activity-row.module.css index 0afc80787e2..9647ad3f12d 100644 --- a/apps/sim/platform/design-system/components/activity-row/activity-row.module.css +++ b/apps/sim/platform/design-system/components/activity-row/activity-row.module.css @@ -1,12 +1,16 @@ .entry { + display: flex; + align-items: center; min-inline-size: 0; container: activity-row / inline-size; + border-radius: var(--ui-control-radius); } .row { display: flex; align-items: center; gap: var(--ui-row-gap); - inline-size: 100%; + flex: 1; + min-inline-size: 0; padding: var(--ui-row-block) var(--ui-row-inset); border-radius: var(--ui-control-radius); text-align: start; @@ -34,9 +38,16 @@ grid-row: 1 / span 2; } } -.row:hover { +.entry:hover { background: var(--ui-hover); } +.trailing { + display: inline-flex; + align-items: center; + flex: none; + gap: var(--ui-action-gap); + padding-inline-end: var(--ui-row-inset); +} .body { display: flex; align-items: start; diff --git a/apps/sim/platform/design-system/components/activity-row/activity-row.tsx b/apps/sim/platform/design-system/components/activity-row/activity-row.tsx index e09fe9c443c..580acf6ee14 100644 --- a/apps/sim/platform/design-system/components/activity-row/activity-row.tsx +++ b/apps/sim/platform/design-system/components/activity-row/activity-row.tsx @@ -1,4 +1,4 @@ -import type { ReactNode } from 'react' +import type { ComponentProps, ReactNode } from 'react' import Link from 'next/link' import { ActivityBody } from '@/platform/design-system/components/activity-row/activity-body' import styles from '@/platform/design-system/components/activity-row/activity-row.module.css' @@ -7,6 +7,7 @@ import { CountedLabel } from '@/platform/design-system/components/overflow-text/ import { OverflowText } from '@/platform/design-system/components/overflow-text/overflow-text' interface ActivityRowProps { + onNavigate?: ComponentProps['onNavigate'] leading?: ReactNode title: string count?: number @@ -14,11 +15,13 @@ interface ActivityRowProps { detailLead?: string metadata?: string showChevron?: boolean + trailing?: ReactNode } type ActivityTarget = { href: string; onOpen?: never } | { href?: never; onOpen: () => void } export function ActivityRow({ + onNavigate, leading, title, count, @@ -26,6 +29,7 @@ export function ActivityRow({ detailLead, metadata, showChevron = true, + trailing, onOpen, href, }: ActivityRowProps & ActivityTarget) { @@ -57,7 +61,7 @@ export function ActivityRow({ return (
  • {href !== undefined ? ( - + {content} ) : ( @@ -65,6 +69,7 @@ export function ActivityRow({ {content} )} + {trailing && {trailing}}
  • ) } diff --git a/apps/sim/platform/design-system/components/index.ts b/apps/sim/platform/design-system/components/index.ts index a17e03fb1b1..e5eed4f4752 100644 --- a/apps/sim/platform/design-system/components/index.ts +++ b/apps/sim/platform/design-system/components/index.ts @@ -31,7 +31,7 @@ export { MenuItem, VisibilityMenu, } from './menu/action-menu' -export { RangePicker } from './menu/range-picker' +export { ChoiceMenu } from './menu/choice-menu' export { Modal, MultiStepModal } from './modal/modal' export { ModalBody, ModalFooter, ModalHeader } from './modal/modal-parts' export { OverflowText } from './overflow-text/overflow-text' diff --git a/apps/sim/platform/design-system/components/menu/range-picker.tsx b/apps/sim/platform/design-system/components/menu/choice-menu.tsx similarity index 95% rename from apps/sim/platform/design-system/components/menu/range-picker.tsx rename to apps/sim/platform/design-system/components/menu/choice-menu.tsx index 058474cb219..eb2866ca0a2 100644 --- a/apps/sim/platform/design-system/components/menu/range-picker.tsx +++ b/apps/sim/platform/design-system/components/menu/choice-menu.tsx @@ -6,7 +6,7 @@ import { Button } from '@/platform/design-system/components/button/button' import { ActionMenuPopup, MenuItem } from '@/platform/design-system/components/menu/action-menu' import { usePopoverContainer } from '@/platform/design-system/components/menu/use-popover-container' -interface RangePickerProps { +interface ChoiceMenuProps { id?: string label: string options: readonly string[] @@ -16,7 +16,7 @@ interface RangePickerProps { onValueChange?: (value: string) => void } -export function RangePicker({ +export function ChoiceMenu({ id, label, options, @@ -24,7 +24,7 @@ export function RangePicker({ defaultValue, defaultOpen = false, onValueChange, -}: RangePickerProps) { +}: ChoiceMenuProps) { const [localValue, setLocalValue] = useState(defaultValue) const selection = controlledValue ?? localValue const value = selection !== undefined && options.includes(selection) ? selection : options[0] diff --git a/apps/sim/platform/design-system/components/search-field/search-field.module.css b/apps/sim/platform/design-system/components/search-field/search-field.module.css index 2245c502f81..39ef22a0c19 100644 --- a/apps/sim/platform/design-system/components/search-field/search-field.module.css +++ b/apps/sim/platform/design-system/components/search-field/search-field.module.css @@ -18,6 +18,13 @@ .search[data-variant="sidebar"] { border-color: var(--ui-divider); } +.search[data-variant="quiet"] { + border-color: transparent; + background: transparent; +} +.search[data-variant="quiet"]:hover { + background: var(--ui-hover); +} .menuSearch { display: flex; flex: none; diff --git a/apps/sim/platform/design-system/components/search-field/search-field.tsx b/apps/sim/platform/design-system/components/search-field/search-field.tsx index 07c3989b75e..8cd4b430cbb 100644 --- a/apps/sim/platform/design-system/components/search-field/search-field.tsx +++ b/apps/sim/platform/design-system/components/search-field/search-field.tsx @@ -12,7 +12,7 @@ interface SearchFieldProps { defaultValue?: string value?: string shortcut?: '⌘K' | '/' - variant?: 'outlined' | 'sidebar' + variant?: 'outlined' | 'sidebar' | 'quiet' onValueChange?: (query: string) => void } diff --git a/apps/sim/platform/design-system/styles/rhythm.css b/apps/sim/platform/design-system/styles/rhythm.css index fcac5e5c88c..edccfc6afaa 100644 --- a/apps/sim/platform/design-system/styles/rhythm.css +++ b/apps/sim/platform/design-system/styles/rhythm.css @@ -4,6 +4,7 @@ --ui-product-section-gap: var(--spacing-24); --ui-widget-max-size: var(--spacing-320); --ui-page-inset-block: var(--ui-product-section-gap); + --ui-page-heading-inset: var(--spacing-64); --ui-motion-color: 120ms; --ui-control-radius: var(--radius-control); --ui-stack-gap: var(--spacing-2); diff --git a/apps/sim/platform/docs/component-ownership.md b/apps/sim/platform/docs/component-ownership.md index 17bb0263b5d..1413f0b6ffe 100644 --- a/apps/sim/platform/docs/component-ownership.md +++ b/apps/sim/platform/docs/component-ownership.md @@ -7,7 +7,7 @@ Start with the interaction. A different label, icon, data source, theme or scree | Perform an action | `button/`: Button owns labeled actions and leading/trailing icons; IconButton owns icon-only actions and its few target sizes. Notification triggers reuse the compact secondary button; thread and notification counts share one label/count layout. CopyButton adds clipboard feedback to IconButton. Menu, popover and range triggers render these same buttons, with Base UI supplying behavior. | | Navigate or select a row | ControlRow renders the actual link, tab or button. Chip, IdentityButton, sidebar, recent-items, destination-tabs, tabs and workspace-list compose it. A trailing ellipsis/close or a leading remove share a sibling action target: never nest a second button inside the first. A row's read-only state goes in its `status` slot, which yields to the action where a pointer can reveal it and sits beside it on touch. Workspace choices can wrap to fit their name. | | Open a two-line activity or destination | ActivityRow owns the text stack, leading art, hit area and optional trailing content. Home email and attention, the notification inbox and the chat panel launcher supply data. A notification with independent action buttons composes the same noninteractive ActivityBody alongside its actions. Section titles and scroll bounds stay with the containing feature. | -| Choose a value or run a command | Picker owns Select, SearchableSelect (client filtering, or server search through `search`), MultiSelect, and calendar choices through DatePicker and DateRangePicker; `Calendar` stays private to it. Menu owns actions, nested menus, popovers and preset range choices. These share popup and row recipes; retain their distinct ARIA roles and keyboard behavior. CommandPalette owns multi-group search and navigation inside the shared dialog. | +| Choose a value or run a command | Picker owns Select, SearchableSelect (client filtering, or server search through `search`), MultiSelect, and calendar choices through DatePicker and DateRangePicker; `Calendar` stays private to it. Menu owns actions, nested menus and popovers. ChoiceMenu owns compact toolbar choices, including Home ranges and integration filters, with the same quiet button and radio-menu rows. Select remains the owner for form fields. These share popup and row recipes; retain their distinct ARIA roles and keyboard behavior. CommandPalette owns multi-group search and navigation inside the shared dialog. | | Edit or toggle | Field owns labeled input/textarea chrome, hints and errors, plus CopyField (read-only value with copy), SecretField (masked entry with reveal) and FileField (choose or drop; the caller reads the file). Platform globals disable manual textarea resizing. SearchField/MenuSearchField own clearable search and filtering. WorkspaceFields owns recipient parsing, editing, validation (controlled through `recipients` and `validate`), removal and logo upload. RecipientTag pairs a bounded address with an always-visible inline IconButton. The field wraps tags as a unit. ComposerInput owns draft typing, paste and submission. Switch owns a setting that applies at once, Checkbox owns a boolean in a form or grid, SegmentedControl owns mutually exclusive choices. | | Display layers and transient feedback | Modal owns title, body, multi-step progression and footer. OverlayDialog supplies the same surface to search and attachment previews. Tooltip owns bounded plain labels; a structured people panel uses its own measured content. Feedback owns clipboard success and timeout behavior. Status owns StatusTag, a read-only state on a row, InlineNotice, a persistent message in the page flow with an optional action, and FailureNotice, a failed read with its retry; a transient outcome still goes to the tray. The notification tray owns history and Undo, with one control shadow outside the scroll viewport. | | Show files, people and media | Attachments composes ControlRow with file glyph or thumbnail, an accessible preview target and an independent quiet remove action. Avatar owns image and single-initial fallbacks across profiles, email and people details. Icon owns interface paint and distinguishes branded artwork. Product callers supply media or data. | @@ -16,12 +16,12 @@ Start with the interaction. A different label, icon, data source, theme or scree Routes compose these owners. The shell owns navigation, window chrome, session state and the shared message composer. Home owns the arrangement of widgets, calendar and chart. `(shell)/_components/chat/` owns turns, tool payloads, interaction cards, panel contents and resources, which Chat and Search share; `(shell)/_components/search/` owns search results. SettingsRow takes a leading avatar or glyph. Settings owns profile, appearance, notification preferences and their section layout; each live section owns one folder under `settings/_components/sections/`, and `settings/_components/section-parts/` owns what they share: the layout, sub-view header, loading rows, saved-preference rows and the credits dialog. An editor registers with `useSettingsUnsavedGuard`; `session-state/settings-leave-guard` is the one dialog, and the one owner of link and browser-history guarding. `app/_components/shell-gate/` owns the states that replace a route or the whole shell: access denied, unavailable, error and not found. `lib/data/` owns everything real data needs: the mode, the organization surface, query and session providers, and the adapters from contract shapes to view models. Product code uses no fixture fallback. The workbench and its Paper specimens are engineering tools; gallery examples do not justify product variants. -Organization integrations, workspace integrations and workspace skills share the page frame, heading, back link and grouped list in `(shell)/_components/resource-directory`. Each directory composes EMCN SearchField, Select, ActivityRow and Icon as needed. The workspace inventory groups visible credentials, featured apps and categories. Skills has its own list and editor. Workspace examples and edits live in the fixture session. Live workspace routes hand off to the existing workspace access boundary, including provider, credential and skill details. - Member integrations use ActivityRow links, the shared Icon for provider marks, and shared segmented controls for individual tool permissions, and the same inline ConnectionPrompt as Home Email and Calendar. Its [member inventory contract](organization-integrations.md) covers personal credentials, eligible tool policies and the Phase 3 handoff. The [Platform time library](../lib/time.ts) formats raw instants, calendar days and elapsed metadata for every feature. Home owns its Build/Search metric and a single selected time window. -For a proposed addition, trace its second consumer before copying a hit area, hover, menu, timer or modal part. Promote the original when semantics match, and verify both callers with a pointer and keyboard. For different semantics, share the visual recipe and preserve the proper native element. +For a proposed addition, trace its second consumer before copying a hit area, hover, menu, timer or modal part. A new shared visual variant requires two independent product consumers; repeating a sample row or adding a workbench example does not count. Promote the original when semantics match, and verify both callers with a pointer and keyboard. For different semantics, share the visual recipe and preserve the proper native element. Keep one-feature anatomy in its route owner and choose its spacing and type from the closest existing composition. + +The [integration center](integration-center.md) lives in `integrations/_components/integration-center/` at the organization root. Its Apps, Skills, MCPs and Credentials destinations compose DestinationTabs, the shared search control and ActivityRow. The local `resource-list/` and `resource-editor/` owners interpret integration-specific content and actions. They do not own another button, menu, tab, form-field or dialog recipe. Personal and shared data use the same renderer. Eligible workspace entry points open or redirect to this organization center; they do not mount a separate Platform integration page. Standalone workspaces and viewers without organization Search access retain their existing credential route. Organization Settings uses the [navigation catalog](../lib/data/settings-navigation.ts) for sidebar order and server-gated resolution. The [section registry](../app/%28shell%29/settings/_components/section-registry.ts) lazy-loads one owner per tab. General composes Profile, Preferences, Privacy and Account, including their detail views. Section titles and action rows use EMCN SettingsSection and SettingsRow. diff --git a/apps/sim/platform/docs/integration-center.md b/apps/sim/platform/docs/integration-center.md new file mode 100644 index 00000000000..735ed4f1ead --- /dev/null +++ b/apps/sim/platform/docs/integration-center.md @@ -0,0 +1,30 @@ +# Integration center + +`/integrations` at the organization root is the member-facing management surface for Apps, Skills, MCPs and Credentials. Home and eligible organization workspace entry points navigate here rather than mounting another copy. A standalone workspace, or a viewer without the organization's Search access, retains the existing workspace credential route until an authorized replacement exists. Organization approval and source administration remain in Settings. Entering from a workspace must not silently turn a personal credential into an organization or workspace credential. + +## Product structure + +| Destination | Content | +| --- | --- | +| Apps | Connected apps first, then available apps filterable by category. Provider names and descriptions come from existing catalog metadata. Member credentials retain their provider detail routes. | +| Skills | Shared and Personal sections. A skill has a name, description and instructions, with ownership shown separately from its content. | +| MCPs | Shared and Personal sections for custom servers. Connection details belong to the server, not a fabricated provider catalog. | +| Credentials | Shared and Personal sections for named credentials and secrets. Show access in the list and ownership in the detail or editor, without exposing a secret in a list. | + +Keep the heading, description, reading column and major gaps aligned with Home. DestinationTabs and the compact control bar follow the Platform Workspaces anatomy in Paper. Search sits at the start of the control bar; destination-specific sorting, filtering and create actions sit at the end. Category and access choices use ChoiceMenu, the exact Home period owner with a compact quiet trigger. Select/SelectField belong to the editor's form fields, not this toolbar. Categories and ownership sections live in the content, not as another nested tab system. + +The route entry stays thin. `integrations/_components/integration-center/` owns the frame and destination composition. `resource-list/` and `resource-editor/` own the feature's list content and editor fields. Reuse EMCN DestinationTabs, SearchField, ActivityRow, Avatar, Button, Menu, Modal and Field owners. Base UI supplies complex behavior inside EMCN; product code supplies data and callbacks. Leading marks align with the first line, trailing people and actions center against the whole row, and lists use the same shared rhythm as Home email and notification rows. + +## Data and access + +Apps retain the existing [member inventory and credential contract](organization-integrations.md). A connected account or an organization-approved provider does not prove that its credential is shared. Usage avatars and counts require an authorized roster projection; do not derive organization usage from the viewer's personal accounts or expose another member's credential label. + +New skill, MCP, sharing and credential editor interactions are UI work. Their example records are loaded only through the server fixture flag and edited in the product session. Skills and MCPs are shown only in fixture mode until their live data adapters exist. Live Apps and Credentials render only data and actions supplied by an existing authorized operation. They must not substitute fixture records when a request is loading, denied, unavailable or failed. Sharing controls in an example are not permission enforcement, and creating a local example must not call a real credential, secret or policy mutation. + +The organization center is the canonical destination. Workspace navigation resolves the workspace host and the viewer's organization eligibility before linking or redirecting there; it never uses the session's unrelated active organization or silently changes credential scope. Preserve the existing route for viewers who cannot use the organization center, rather than trapping them behind an unavailable page. Paper references and historical documentation do not justify another Platform workspace management surface. The browser and Electron use the same renderer. + +## Verification + +Check destination navigation and browser history, search and empty results, sort/filter controls, create/edit/cancel flows, personal/shared grouping, dropdown placement and keyboard dismissal. Verify long names, multiple usage avatars, empty and stress data, narrow and intermediate widths, dark theme and real overflow fades. Fixture-off output must contain no sample people, credentials or shared resources. Existing live Apps detail and connection behavior must remain reachable. + +Run the Platform design audit, type check, build and browser checks from the [README](../README.md). The static audit enforces styling and ownership boundaries and unused variants. Review independently that every new shared visual variant has two real consumers and that custom feature anatomy uses an established layout rhythm; a numeric JSX count cannot establish those design decisions. diff --git a/apps/sim/platform/docs/organization-integrations.md b/apps/sim/platform/docs/organization-integrations.md index 0c2f5ded16a..b4e485f520a 100644 --- a/apps/sim/platform/docs/organization-integrations.md +++ b/apps/sim/platform/docs/organization-integrations.md @@ -1,6 +1,6 @@ # Member integrations -The organization sidebar opens `/integrations`. This is the signed-in member’s Search integrations inventory. Each row opens `/integrations/[providerId]` to show the provider description, personal credential, and available actions. The index groups connected accounts, apps available to connect, and sources managed by the organization. Each row uses the workspace catalog description. Search matches provider names, descriptions and the viewer’s credential label. Selecting a result preserves the current search on return. Clearing the search and immediately opening a result still opens that provider. Browser history and sidebar navigation restore the filter from their destination URL. The browser and Sim Desktop share these routes. +The organization sidebar opens the [integration center](integration-center.md) at `/integrations`. Its Apps destination retains the signed-in member’s authorized Search integrations inventory and `/integrations/[providerId]` details. A provider detail shows its catalog description, personal credential and available actions. Search matches provider names, descriptions and the viewer’s credential label. Selecting a result preserves the current search on return. Clearing the search and immediately opening a result still opens that provider. Browser history and sidebar navigation restore the filter from their destination URL. The browser and Sim Desktop share these routes. The center's additional sharing and resource examples do not expand this live authorization contract. The existing [organization route](../../app/o/%5BorganizationId%5D/integrations/page.tsx) requires member-scoped Search access. Its [member inventory](../../app/o/%5BorganizationId%5D/integrations/utils.ts) considers source approval, provider availability, effective organization configuration, and the viewer’s existing accounts. Existing credentials can remain visible after approval changes. Some configured Assistant apps can appear when the viewer is eligible. Generic Secrets appears only when enabled. Organization approval and source setup belong to the separate [Sources settings route](../../lib/sim-search/setup-navigation.ts). diff --git a/apps/sim/platform/fixtures/index.ts b/apps/sim/platform/fixtures/index.ts index ad8ffc8b2b9..012f45b083e 100644 --- a/apps/sim/platform/fixtures/index.ts +++ b/apps/sim/platform/fixtures/index.ts @@ -119,6 +119,9 @@ export const loadIntegrationsData = fixture( } } ) +export const loadIntegrationCenterData = fixture(async (scenario) => + (await import('@/platform/fixtures/integration-center-data')).integrationCenterData(scenario) +) export const loadPanelData = fixture( async (scenario) => (await import('@/platform/fixtures/panel-data')).panelScenarios[scenario] ) diff --git a/apps/sim/platform/fixtures/integration-center-data.ts b/apps/sim/platform/fixtures/integration-center-data.ts new file mode 100644 index 00000000000..18e51930941 --- /dev/null +++ b/apps/sim/platform/fixtures/integration-center-data.ts @@ -0,0 +1,171 @@ +import 'server-only' +import type { Scenario } from '@/platform/fixtures' +import type { + IntegrationCenterData, + IntegrationPerson, + IntegrationResource, +} from '@/platform/lib/integrations/center-model' + +const emir: IntegrationPerson = { id: 'emir', name: 'Emir Karabeg' } +const nina: IntegrationPerson = { id: 'nina', name: 'Nina Patel' } +const alex: IntegrationPerson = { id: 'alex', name: 'Alex Chen' } +const maya: IntegrationPerson = { id: 'maya', name: 'Maya Thompson' } +const daniel: IntegrationPerson = { id: 'daniel', name: 'Daniel Kim' } +const people = [emir, nina, alex, maya, daniel] + +const resources: IntegrationResource[] = [ + { + id: 'weekly-customer-review', + kind: 'skill', + name: 'Weekly customer review', + description: 'Turn customer conversations into a concise weekly account review.', + instructions: + 'Review the latest customer conversations. Summarize goals, decisions, open questions, and next steps. Link each finding to its source and identify an owner for each follow-up.', + scope: 'shared', + owner: nina, + people: [nina, emir, maya], + canEdit: true, + }, + { + id: 'release-notes', + kind: 'skill', + name: 'Release notes', + description: 'Draft clear, customer-facing notes from completed engineering work.', + instructions: + 'Group completed work into features, improvements, and fixes. Describe the user-visible change in plain language. Include a source link for each item and omit internal implementation details.', + scope: 'shared', + owner: alex, + people: [alex, daniel], + canEdit: false, + }, + { + id: 'meeting-preparation', + kind: 'skill', + name: 'Meeting preparation', + description: 'Gather the context, open questions, and decisions for my next meeting.', + instructions: + 'Read the meeting agenda and relevant conversations. Prepare a short brief with context, unresolved questions, and decisions needed. Finish with links to the source material.', + scope: 'personal', + owner: emir, + people: [], + canEdit: true, + }, + { + id: 'research-summary', + kind: 'skill', + name: 'Research summary', + description: 'Compare sources and extract the findings that matter for my research.', + instructions: + 'Compare the supplied sources. Distinguish evidence from assumptions, flag disagreements, and summarize practical implications. Cite the source for each substantive claim.', + scope: 'personal', + owner: emir, + people: [], + canEdit: true, + }, + { + id: 'customer-knowledge', + kind: 'mcp', + name: 'Customer knowledge', + description: 'Search the support knowledge base and customer account context.', + url: 'https://customer-knowledge.example.com/mcp', + auth: 'oauth', + scope: 'shared', + owner: nina, + people: [nina, emir, maya, daniel], + canEdit: true, + }, + { + id: 'engineering-tools', + kind: 'mcp', + name: 'Engineering tools', + description: 'Read service documentation and inspect deployment information.', + url: 'https://engineering-tools.example.com/mcp', + auth: 'bearer', + scope: 'shared', + owner: alex, + people: [alex, daniel], + canEdit: false, + }, + { + id: 'research-library', + kind: 'mcp', + name: 'Research library', + description: 'Search my saved papers, reading notes, and references.', + url: 'https://research-library.example.com/mcp', + auth: 'oauth', + scope: 'personal', + owner: emir, + people: [], + canEdit: true, + }, + { + id: 'customer-io-key', + kind: 'credential', + name: 'Customer.io', + description: 'The operations team’s key for customer messaging workflows.', + key: 'CUSTOMER_IO_API_KEY', + credentialType: 'api-key', + scope: 'shared', + owner: nina, + people: [nina, emir, maya], + canEdit: true, + }, + { + id: 'webhook-signing-secret', + kind: 'credential', + name: 'Webhook signing secret', + description: 'Verifies events received by the engineering workspace.', + key: 'WEBHOOK_SIGNING_SECRET', + credentialType: 'secret', + scope: 'shared', + owner: alex, + people: [alex, daniel], + canEdit: false, + }, + { + id: 'research-api-key', + kind: 'credential', + name: 'Research API', + description: 'My API key for research and enrichment.', + key: 'RESEARCH_API_KEY', + credentialType: 'api-key', + scope: 'personal', + owner: emir, + people: [], + canEdit: true, + }, +] + +export function integrationCenterData(scenario: Scenario): IntegrationCenterData { + if (scenario === 'empty') return { viewer: emir, people, appPeople: {}, resources: [] } + const extra = + scenario === 'stress' + ? Array.from({ length: 60 }, (_, index): IntegrationResource => { + const source = resources[index % resources.length] + if (!source) throw new Error('Integration center resources are missing') + return { + ...source, + id: `${source.id}-${index + 1}`, + name: `${source.name} for international customer operations ${index + 1}`, + description: + 'Shared context for customer onboarding, regional operations, and long-running research across the team. Includes supporting references and detailed instructions.', + } + }) + : [] + return { + viewer: emir, + people, + appPeople: { + gmail: [emir, nina, alex, maya, daniel], + google_calendar: [emir, nina, alex, maya], + google_drive: [emir, nina, alex, maya, daniel], + github: [emir, alex, daniel], + fireflies: [emir, nina, maya], + hubspot: [nina, emir], + salesforce: [nina, maya], + notion: [alex, daniel], + linear: [alex, daniel], + }, + resources: [...resources, ...extra], + } +} diff --git a/apps/sim/platform/lib/integrations/center-model.ts b/apps/sim/platform/lib/integrations/center-model.ts new file mode 100644 index 00000000000..588eda5e904 --- /dev/null +++ b/apps/sim/platform/lib/integrations/center-model.ts @@ -0,0 +1,49 @@ +export type IntegrationTab = 'apps' | 'skills' | 'mcps' | 'credentials' +type IntegrationScope = 'shared' | 'personal' + +export interface IntegrationPerson { + id: string + name: string + src?: string +} + +export interface AppSummary { + id: string + providerId?: string + icon?: ComponentType<{ className?: string }> + name: string + description: string + category: string + href: string + connected: boolean + status?: string + searchable?: string + people?: readonly IntegrationPerson[] + scope?: IntegrationScope +} + +interface ResourceIdentity { + id: string + name: string + description: string + scope: IntegrationScope + owner: IntegrationPerson + people: readonly IntegrationPerson[] + canEdit: boolean +} + +export type IntegrationResource = ResourceIdentity & + ( + | { kind: 'skill'; instructions: string } + | { kind: 'mcp'; url: string; auth: 'none' | 'bearer' | 'oauth' } + | { kind: 'credential'; key: string; credentialType: 'secret' | 'api-key' } + ) + +export interface IntegrationCenterData { + viewer: IntegrationPerson + people: IntegrationPerson[] + appPeople: Record + resources: IntegrationResource[] +} + +import type { ComponentType } from 'react' diff --git a/apps/sim/platform/lib/integrations/center-navigation.ts b/apps/sim/platform/lib/integrations/center-navigation.ts new file mode 100644 index 00000000000..ff237bb94c7 --- /dev/null +++ b/apps/sim/platform/lib/integrations/center-navigation.ts @@ -0,0 +1,70 @@ +import { createLoader, createSerializer, parseAsString, parseAsStringLiteral } from 'nuqs/server' + +export const CENTER_TABS = [ + { id: 'apps', label: 'Apps' }, + { id: 'skills', label: 'Skills' }, + { id: 'mcps', label: 'MCPs' }, + { id: 'credentials', label: 'Credentials' }, +] as const + +export const centerParams = { + tab: parseAsStringLiteral(['apps', 'skills', 'mcps', 'credentials']).withDefault('apps'), + q: parseAsString.withDefault(''), + category: parseAsString.withDefault('all'), + scope: parseAsStringLiteral(['all', 'shared', 'personal']).withDefault('all'), + order: parseAsStringLiteral(['asc', 'desc']).withDefault('asc'), + resource: parseAsString, +} + +export const serializeCenter = createSerializer(centerParams) + +/** Discovery categories describe providers, independently of their connection or sharing state. */ +export function appCategory(provider: string): string { + if ( + [ + 'gmail', + 'outlook', + 'google_calendar', + 'google-calendar', + 'slack', + 'microsoft_teams', + 'fireflies', + 'zoom', + ].includes(provider) + ) + return 'Communication' + if ( + [ + 'google_drive', + 'google-drive', + 'notion', + 'confluence', + 'coda', + 'sharepoint', + 'dropbox', + ].includes(provider) + ) + return 'Knowledge' + if (['github', 'gitlab', 'linear', 'jira'].includes(provider)) return 'Development' + if (['hubspot', 'salesforce', 'attio', 'intercom', 'zendesk'].includes(provider)) + return 'Customers' + return 'Productivity' +} + +const loadCenter = createLoader(centerParams) + +/** Keep directory filters through a provider detail or credential round trip. */ +export function integrationCenterHref( + path: string, + search: Pick, + query = search.get('q') +) { + const state = loadCenter({ + tab: search.get('tab') ?? undefined, + q: query ?? undefined, + category: search.get('category') ?? undefined, + scope: search.get('scope') ?? undefined, + order: search.get('order') ?? undefined, + }) + return serializeCenter(path, state) +} diff --git a/apps/sim/platform/lib/integrations/fixture-model.ts b/apps/sim/platform/lib/integrations/fixture-model.ts index ea6814c6dd4..f51697179e5 100644 --- a/apps/sim/platform/lib/integrations/fixture-model.ts +++ b/apps/sim/platform/lib/integrations/fixture-model.ts @@ -1,4 +1,5 @@ import { platformHref } from '@/platform/design-system/navigation' +import { integrationCenterHref } from '@/platform/lib/integrations/center-navigation' import type { MemberSecretSource } from '@/platform/lib/integrations/member-secret-source' export type AccountMethod = 'oauth' | 'mcp' | 'slack' @@ -51,9 +52,7 @@ export function memberIntegrationHref( search: Pick, query = search.get('q') ) { - const destination = platformHref(path, search) - if (!query) return destination - return `${destination}${destination.includes('?') ? '&' : '?'}${new URLSearchParams({ q: query })}` + return integrationCenterHref(platformHref(path, search), search, query) } export function memberStatus(item: OrganizationIntegration) { diff --git a/apps/sim/platform/preview/control-specimen.tsx b/apps/sim/platform/preview/control-specimen.tsx index f0ca6b4fd2f..951e8e66bf4 100644 --- a/apps/sim/platform/preview/control-specimen.tsx +++ b/apps/sim/platform/preview/control-specimen.tsx @@ -12,6 +12,7 @@ import { BrowserActionsMenu, Button, Chip, + ChoiceMenu, ComposerInput, DataTable, DestinationTabs, @@ -35,7 +36,6 @@ import { PeoplePopover, PersonRow, PropertyList, - RangePicker, RecentItems, RecipientField, RecipientTag, @@ -108,11 +108,11 @@ const views = [ function AgentFilter({ data }: { data: PreviewData | null }) { const agents = (data?.dashboard.rows ?? []).map((row) => String(row.values.agent)) - return + return } const requestFilter = ( - + ) function FeedbackFields({ notes }: { notes?: string }) { @@ -547,9 +547,9 @@ export function ControlSpecimen({ master, data, renderChild, location }: Control ) } - case 'RangePicker': + case 'ChoiceMenu': return ( - }` ) write( - 'platform/app/settings/_components/panel.tsx', - `import classes from '@/platform/app/settings/_components/panel.module.css' + 'platform/app/settings/_components/panel/panel.tsx', + `import classes from '@/platform/app/settings/_components/panel/panel.module.css' export function Panel(){return
    }` ) - write('platform/app/settings/_components/panel.module.css', '.panel{padding:0}') + write('platform/app/settings/_components/panel/panel.module.css', '.panel{padding:0}') const modal = 'platform/design-system/components/modal' write( `${modal}/modal.tsx`, @@ -103,6 +103,14 @@ it('rejects design drift across real JSX, CSS and Paper ownership boundaries', ( ) expect(audit()).toEqual({ status: 0, output: expect.stringContaining('passed') }) + const looseRecipe = 'platform/app/settings/_components/loose.module.css' + write(looseRecipe, '.loose{padding:0}') + expect(audit()).toEqual({ + status: 1, + output: expect.stringContaining(`${looseRecipe} [component-folder]`), + }) + rmSync(path.join(APP, looseRecipe)) + writeCatalog('evidence', [ evidence, { diff --git a/scripts/check-platform-design.ts b/scripts/check-platform-design.ts index 5f246d5ce34..b2fe4c5d085 100644 --- a/scripts/check-platform-design.ts +++ b/scripts/check-platform-design.ts @@ -1107,7 +1107,10 @@ function checkJs(file: string, content: string) { for (const file of sourceFiles) { if (file.startsWith(`${system}features/`)) report('feature-owner', file, 'Colocate product UI in the owning route’s _components directory') - if (/^platform\/design-system\/components\/[^/]+$/.test(file) && !file.endsWith('/index.ts')) + if ( + (/^platform\/design-system\/components\/[^/]+$/.test(file) && !file.endsWith('/index.ts')) || + (file.startsWith('platform/app/') && /\/_components\/[^/]+\.module\.css$/.test(file)) + ) report( 'component-folder', file, diff --git a/scripts/sync-platform-recipes.ts b/scripts/sync-platform-recipes.ts index 9dd4c0d2b02..3aa9ff84cde 100644 --- a/scripts/sync-platform-recipes.ts +++ b/scripts/sync-platform-recipes.ts @@ -190,7 +190,7 @@ const nativeOwners = { 'C0656', 'C0657', ], - RangePicker: ['C0845', 'C0846', 'C0847', 'C0848', 'C0854'], + ChoiceMenu: ['C0845', 'C0846', 'C0847', 'C0848', 'C0854'], SegmentedControl: ['C0967', 'C0968', 'C0969', 'C0970', 'C0979', 'C0980', 'C0981', 'C0982'], SelectionItem: ['C0955', 'C0956', 'C0957', 'C0958', 'C0963', 'C0964', 'C0965', 'C0966'], ScrollArea: ['C0922', 'C0924', 'C1082'], From a824d1072fda42bed02b67991a8c5008486cdf3a Mon Sep 17 00:00:00 2001 From: Emir Karabeg Date: Thu, 5 Nov 2026 18:54:07 -0800 Subject: [PATCH 2/2] improvement(platform): expand integration catalog and credential management --- apps/sim/platform/AGENTS.md | 4 +- apps/sim/platform/README.md | 5 +- .../session/integration-changes.tsx | 100 ++- .../connected-credential.tsx | 12 +- .../connection-access/connection-access.tsx | 5 +- .../credential-access.module.css | 14 + .../credential-access/credential-access.tsx | 201 ++++++ .../credential-connect/credential-connect.tsx | 337 +++++++++ .../_components/credential-connect/types.ts | 7 + .../credential-detail/credential-detail.tsx | 181 +++++ .../credential-list.module.css | 13 + .../credential-list/credential-list.tsx | 88 +++ .../connected-credential.module.css | 19 - .../connected-credential.tsx | 77 -- .../connection-access.module.css | 26 - .../connection-access/connection-access.tsx | 66 -- .../connection-access/scope-groups.ts | 35 - .../integration-details.tsx | 400 ++++++++--- .../integration-details/search-params.ts | 4 + .../integrations-page/integrations-page.tsx | 114 ++- .../integrations-page/integrations-route.tsx | 11 +- .../provider-heading.module.css | 20 - .../provider-heading/provider-heading.tsx | 26 - .../tool-permissions/tool-permissions.tsx | 12 +- .../integration-capabilities.module.css | 16 + .../integration-capabilities.tsx | 167 +++++ .../integration-capabilities/search-params.ts | 5 + .../integration-center.module.css | 27 +- .../integration-center/integration-center.tsx | 64 +- .../integration-controls.module.css | 21 + .../integration-controls.tsx | 16 + .../integration-details.tsx | 56 +- .../integration-list/integration-list.tsx | 5 +- .../integration-usage.module.css | 13 + .../integration-usage/integration-usage.tsx | 43 ++ .../provider-heading/provider-heading.tsx | 7 + .../resource-list/resource-list.module.css | 6 - .../resource-list/resource-list.tsx | 31 +- .../slack-bot-connection.module.css | 22 + .../slack-bot-connection.tsx | 258 +++++++ .../_components/slack-slash-commands/index.ts | 5 + .../slack-slash-commands.module.css | 15 + .../slack-slash-commands.tsx | 97 +++ apps/sim/platform/checks/conversation.spec.ts | 17 +- .../platform/checks/desktop/renderer.spec.ts | 4 + .../checks/integration-center.spec.ts | 36 +- apps/sim/platform/checks/integrations.spec.ts | 468 ++++++++++++- .../design-system/catalog/evidence.json | 6 +- .../design-system/catalog/icon-geometry.tsx | 5 +- .../components/activity-row/activity-row.tsx | 8 +- .../components/avatar/avatar.module.css | 13 - .../components/avatar/avatar.tsx | 42 +- .../icon/provider-mark-ids.generated.ts | 278 ++++++++ .../components/icon/provider-marks.ts | 10 +- .../design-system/components/index.ts | 2 +- .../components/stack/stack.module.css | 29 + .../design-system/components/stack/stack.tsx | 35 + .../platform/design-system/styles/rhythm.css | 1 + apps/sim/platform/docs/component-ownership.md | 4 +- apps/sim/platform/docs/integration-center.md | 22 +- .../docs/organization-integrations.md | 8 +- apps/sim/platform/fixtures/index.ts | 17 +- .../fixtures/integration-center-data.ts | 29 +- .../sim/platform/fixtures/integration-data.ts | 194 ++++- .../fixtures/settings-sources-data.ts | 4 +- .../platform/lib/data/integrations-model.ts | 9 +- .../platform/lib/data/integrations-types.ts | 4 +- .../lib/integrations/catalog-model.ts | 22 + .../lib/integrations/catalog.generated.ts | 6 + .../platform/lib/integrations/center-model.ts | 8 +- .../lib/integrations/center-navigation.ts | 33 - .../lib/integrations/credential-display.ts | 12 + .../lib/integrations/credential-model.ts | 58 ++ .../lib/integrations/fixture-model.ts | 33 +- .../lib/integrations/metadata.generated.ts | 205 ++++++ .../sim/platform/preview/control-specimen.tsx | 6 +- .../public/provider-marks/catalog.svg | 663 ++++++++++++++++++ bun.lock | 1 + package.json | 1 + scripts/platform-integration-connections.ts | 298 ++++++++ scripts/sync-platform-integration-metadata.ts | 113 +++ scripts/sync-platform-recipes.ts | 2 +- 82 files changed, 4617 insertions(+), 740 deletions(-) create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-connect/credential-connect.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-connect/types.ts create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-detail/credential-detail.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.tsx delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.module.css delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.tsx delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.module.css delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.tsx delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/scope-groups.ts create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params.ts delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.module.css delete mode 100644 apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/search-params.ts create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/slack-bot-connection/slack-bot-connection.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/slack-bot-connection/slack-bot-connection.tsx create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/index.ts create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.module.css create mode 100644 apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.tsx create mode 100644 apps/sim/platform/design-system/components/icon/provider-mark-ids.generated.ts create mode 100644 apps/sim/platform/design-system/components/stack/stack.module.css create mode 100644 apps/sim/platform/design-system/components/stack/stack.tsx create mode 100644 apps/sim/platform/lib/integrations/catalog-model.ts create mode 100644 apps/sim/platform/lib/integrations/catalog.generated.ts create mode 100644 apps/sim/platform/lib/integrations/credential-display.ts create mode 100644 apps/sim/platform/lib/integrations/credential-model.ts create mode 100644 apps/sim/platform/public/provider-marks/catalog.svg create mode 100644 scripts/platform-integration-connections.ts diff --git a/apps/sim/platform/AGENTS.md b/apps/sim/platform/AGENTS.md index 1c1864e1273..a544c4f0f95 100644 --- a/apps/sim/platform/AGENTS.md +++ b/apps/sim/platform/AGENTS.md @@ -27,9 +27,11 @@ Home and Chat share a centered, border-box reading column (maximum width and inl Use `ControlRow` for the sidebar, identity controls, panel tabs, recent links, wrapping workspace choices and horizontal destination links. The row owns its 30px height, 8px inset and the placement and hover of a 24px action, including a leading remove button that replaces an existing glyph. Workspace names, the Workspaces launcher and its tab title are text-only. A recent without a glyph keeps its remove action at the end. Keep the link, tab or button semantics on the rendered element, with sibling actions outside it. Whole section headers reveal their chevron on hover; identity controls need none. Ordinary buttons, icon triggers and rows share the sidebar Home radius (`--ui-control-radius`). Use `Button` / `IconButton` for actions and Base UI triggers, passing icons and labels through their slots. The composer toolbar owns its round actions. Switches and segmented controls keep their pill shape. Clicking the selected half of a two-choice segment switches to the other half. Native keyboard choice navigation still selects its destination. +Use `Stack` for compact people or integration artwork: show two items, a passive `+N` overflow count, and each item’s name on hover. Counts remain intrinsic-width and use compact notation from one thousand; never replace them with an ellipsis action. Each hovered item shifts left by the shared inset without moving its siblings. Use the shared motion duration and respect reduced motion. `AvatarGroup` supplies people to the same stack for integration usage and calendar attendees. + Use `ActivityRow` for a first-line glyph or avatar, title/detail and centered trailing metadata. Use the chart, calendar, composer or attachment owner when those parts have a different interaction. See the [component ownership map](docs/component-ownership.md) before adding another family. -Toolbar choices use `ChoiceMenu`, the same compact quiet button and menu as Home's activity period. A toolbar action uses the existing quiet compact Button or IconButton. `Select` and `SelectField` provide field chrome for forms and settings; do not place a full-width field picker in a control bar or invent a toolbar variant to disguise it. Reuse the existing owner for the interaction and compare its actual trigger with Home before accepting it. +Toolbar choices use `ChoiceMenu`, the same compact quiet button and menu as Home's activity period. A toolbar action uses the existing quiet compact Button or IconButton. Page-level actions live in the control bar beneath the title and description; an action for a particular record belongs with that record. `Select` and `SelectField` provide field chrome for forms and settings; do not place a full-width field picker in a control bar or invent a toolbar variant to disguise it. Reuse the existing owner for the interaction and compare its actual trigger with Home before accepting it. Measure the actual scroll viewport with `ScrollArea`, or attach `useScrollEdges` directly to a native or Base UI scroll owner. Use the shared 16px mask only on edges with more content, updating after scroll, resize, input, reset or filtering. Platform and Settings navigation hide the native scrollbar and keep their edge fades, keyboard, wheel and touch scrolling. Other scroll areas keep their existing scrollbar behavior. Insets establish resting layout; they cannot substitute for an edge fade. Home widgets and notification panels use `--ui-widget-max-size` as a ceiling, not a forced height. Keep the dashboard free to scroll and let each overflowing list or schedule scroll independently. Plain tooltips preview at most three lines; retain the complete accessible text. A structured people popover owns its content and uses the dropdown’s popup padding and row insets. diff --git a/apps/sim/platform/README.md b/apps/sim/platform/README.md index 787c1ddc79f..b9fce94f944 100644 --- a/apps/sim/platform/README.md +++ b/apps/sim/platform/README.md @@ -15,6 +15,8 @@ Open [Home](http://localhost:3100/home), [Chat](http://localhost:3100/chat/weekl Settings uses the same organization catalog and section components in fixture and live routes. [General](http://localhost:3100/settings/general?state=full) includes Privacy and Account details; [Sources](http://localhost:3100/settings/integrations?state=full) is the administrator's Search source inventory. The [integration center](docs/integration-center.md) is the member-facing management surface for Apps, Skills, MCPs and Credentials. Settings examples are loaded only by the server's fixture flag. Their edits belong to the browser session; no account, credential, organization policy or subscription is changed by preview interactions. +Integration fixtures cover the full workspace app catalog, multiple credentials, OAuth and provider-specific service-account forms, access management, suggested skills and templates. App-level actions use the control bar; credential rows open their own details. Family credentials share a canonical ID across apps. New enrollment and sharing remain UI-only, with secrets confined to the open form. The existing live Search adapter keeps its own authorized inventory and actions until the broader credential seam is connected. + Settings fixtures default to Enterprise at every density. The [Team subscription](http://localhost:3100/settings/billing?state=stress&plan=team) and [Free subscription](http://localhost:3100/settings/billing?state=empty&plan=free) previews apply the selected plan to Billing, Members and the available Settings sections. The [Knowledge graphs preview](http://localhost:3100/settings/knowledge-graphs?state=stress) uses the stress viewer’s platform-admin role, benchmark access and enabled superuser mode. The product routes live under `app/(shell)/`. Their shared App Router layout owns the shell, sidebar scroll viewport, interface preferences and chat edits. Home, Chat, Settings and Integrations pages render their own bodies inside that layout. Navigating between them keeps the sidebar reading position, including when returning from Settings. The shell selects its gated fixture and appearance from the current URL. Each route owns its components and CSS Modules in a private `_components//` folder: the [Home chart](app/%28shell%29/home/_components/activity-chart/activity-chart.tsx) sits beside its styles; the [dialog](design-system/components/modal/modal.tsx) belongs to EMCN. Shared shell UI lives in `app/(shell)/_components/`. [Rhythm tokens](design-system/styles/rhythm.css) and the [ownership and interaction contract](AGENTS.md) apply throughout the product. The [Paper state inventory](docs/core-chat-states.md) enumerates the source rows in scope. The [organization integrations guide](docs/organization-integrations.md) maps the member inventory, credential actions and tool permissions to their data operations. The integration center lives at the organization root; Home and eligible workspace links open that same destination. Standalone workspaces and viewers without organization Search access retain their existing credential route. Skills, MCPs and new sharing/editor interactions currently use only server-gated fixtures. Paper workspace tabs and the control bar inform the center's anatomy. Wiki is deferred. @@ -65,7 +67,7 @@ Shared and Platform still own different recipes; `catalog/evidence.json` preserv Workspace lists, sidebar items, recents and attachment batches accept typed arrays with stable item IDs. Use the named components for these collection masters: a Paper specimen's item count is sample data. An empty array renders zero items, and adding items preserves their registered row/card appearance. Each scroll viewport determines fades and controls from its actual contents. Chart labels, marks, inspected values and legends come from the same series. Supply raw numeric values and their units to data tables. The column schema determines alignment and which columns remain visible as the table narrows. -The full fixture includes twenty sidebar workspaces, sixteen conversations, a twelve-message inbox and a calendar that scrolls from midnight to midnight even on empty days. Home and Chat share a reading width. Home and Integrations share the same heading inset; the shell reserves sidebar opener and native titlebar clearance separately. The shell uses one 12px inset above the organization and on both sides of the profile row. The Home content scrolls through its viewport edge fade. The shell keeps the collapsed sidebar button aligned with the expanded toolbar even as the page scrolls. Platform and Settings navigation scroll independently, with edge fades instead of a visible scrollbar. Calendar events use the muted surface. An event with a provider URL opens in a new tab. The attendee control opens its own people popover. Now appears when the calendar scrolls away from its resting position or another day is selected. It restores today’s schedule and centers the current time. Scrolling back to that position also hides Now. +The full fixture includes twenty sidebar workspaces, sixteen conversations, a twelve-message inbox and a calendar that scrolls from midnight to midnight even on empty days. Home and Chat share a reading width. Home and Integrations share the same heading inset; the shell reserves sidebar opener and native titlebar clearance separately. The shell uses one 12px inset above the organization and on both sides of the profile row. The Home content scrolls through its viewport edge fade. The shell keeps the collapsed sidebar button aligned with the expanded toolbar even as the page scrolls. Platform and Settings navigation scroll independently, with edge fades instead of a visible scrollbar. Calendar events use the muted surface. An event with a provider URL opens in a new tab. Attendees and integration usage share Stack: two photos with names on hover and a passive +N count, compacted for large totals. Now appears when the calendar scrolls away from its resting position or another day is selected. It restores today’s schedule and centers the current time. Scrolling back to that position also hides Now. Start with the [component ownership map](docs/component-ownership.md) when choosing a primitive. Sidebar, recents and panel tabs use one row; form and command dialogs use one borderless surface. Copy confirmations and transient notifications last four seconds. The notification count uses the compact Invite button. Expanded notices share one subtle shadow around the list. A new notice pauses its expiry on hover or keyboard focus. Icon color transitions take 120ms and respect reduced motion. The [design contract](AGENTS.md) defines these rules. @@ -88,6 +90,7 @@ The [Platform design contract](AGENTS.md) is authoritative. Use the repository's - **Styles:** obtain Shared Light `get_tokens` (the token array) and `get_computed_styles` for the type masters (the node-to-style map); confirm theme file hashes match before assuming identical vocabulary. Run `bun scripts/sync-platform-foundations.ts `, or append `--check` to compare without writing. This preserves aliases and converts scalable Paper px to rem at the 16px reference scale. Roles and material composites live in `design-system/styles`. The Tailwind entry scans only component owners; product pages do not receive a styling API. - **Structure:** capture current Shared/Platform master JSX locally with node IDs for the compiler's anatomy check in `/.jsx` and reconcile the registry and recipe contracts. Run `bun scripts/sync-platform-recipes.ts ` from the repository root. Review changed keys, token aliases, CSS and nested slot geometry in the rendered workbench. Do not edit generated selectors to fix a product use. - **Assets:** retain canonical glyph geometry and brand paints. Media belongs in named slots; do not fetch private Paper artwork at runtime. Fixture content is removable from `fixtures/`. Remove its loader, preview calls and synthetic data together when real resource reads arrive. +- **Integration catalog:** run `bun scripts/sync-platform-integration-metadata.ts` after changing public provider metadata, connection definitions, skills, templates or registry icons. The generated server-only catalog supplies selected detail content; the directory receives compact summaries. `bun run check:platform-integration-metadata` detects drift. Runtime product code never imports the executable block/tool registry. ## Verification diff --git a/apps/sim/platform/app/(shell)/_components/session/integration-changes.tsx b/apps/sim/platform/app/(shell)/_components/session/integration-changes.tsx index 992909e234a..5302c061adc 100644 --- a/apps/sim/platform/app/(shell)/_components/session/integration-changes.tsx +++ b/apps/sim/platform/app/(shell)/_components/session/integration-changes.tsx @@ -1,18 +1,14 @@ 'use client' import { createContext, type ReactNode, useContext, useState } from 'react' +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' import type { IntegrationsData, OrganizationIntegration, } from '@/platform/lib/integrations/fixture-model' -type AccountEdits = Pick< - OrganizationIntegration, - 'account' | 'connectableMethod' | 'connectionCandidate' -> - function useEdits() { - return useState>({}) + return useState>({}) } const Changes = createContext | null>(null) @@ -26,25 +22,89 @@ export function IntegrationChanges({ children }: IntegrationChangesProps) { return {children} } +function metadata(credential: IntegrationCredential): IntegrationCredential { + const { + id, + appId, + providerId, + type, + displayName, + description, + accountLabel, + instanceUrl, + role, + status, + canReconnect, + scope, + members, + permissions, + } = credential + return { + id, + appId, + providerId, + type, + displayName, + description, + accountLabel, + instanceUrl, + role, + status, + canReconnect, + scope, + permissions, + members: members.map( + ({ id, userId, name, email, src, role, roleSource, explicitAdmin, status }) => ({ + id, + userId, + name, + email, + src, + role, + roleSource, + explicitAdmin, + status, + }) + ), + } +} + +/** A family credential is edited by its canonical ID across every app that displays it. */ export function useOrganizationIntegrations(data: IntegrationsData | null) { const edits = useContext(Changes) if (!edits) throw new Error('Integration controls must be inside the product layout') - const [accounts, setAccounts] = edits + const [credentials, setCredentials] = edits + const roster = new Map( + data?.integrations.flatMap((item) => + item.credentials.map((credential) => [credential.id, credential] as const) + ) + ) + for (const [id, credential] of Object.entries(credentials)) roster.set(id, credential) + const visible = [...roster.values()].filter((credential): credential is IntegrationCredential => + Boolean(credential) + ) + const integrations = (data?.integrations ?? []).map((item) => ({ + ...item, + credentials: visible.filter( + (credential) => + credential.appId === item.providerId || + item.credentialProviders.includes(credential.providerId) + ), + })) return { - integrations: (data?.integrations ?? []).map((item) => ({ - ...item, - ...accounts[item.providerId], - })), + integrations, save(item: OrganizationIntegration) { - if (!data?.integrations.some(({ providerId }) => providerId === item.providerId)) return - setAccounts((current) => ({ - ...current, - [item.providerId]: { - account: item.account, - connectableMethod: item.connectableMethod, - connectionCandidate: item.connectionCandidate, - }, - })) + const previous = integrations.find(({ providerId }) => providerId === item.providerId) + if (!data || !previous) return + setCredentials((current) => { + const next = { ...current } + const retained = new Set(item.credentials.map(({ id }) => id)) + for (const credential of previous.credentials) { + if (!retained.has(credential.id)) next[credential.id] = null + } + for (const credential of item.credentials) next[credential.id] = metadata(credential) + return next + }) }, } } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.tsx b/apps/sim/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.tsx index 470e30dbbac..4303cc2f37a 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.tsx @@ -3,7 +3,7 @@ import { useState } from 'react' import Link from 'next/link' import styles from '@/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.module.css' -import { ActionMenu, Button, Modal } from '@/platform/design-system/components' +import { ActionMenu, Modal } from '@/platform/design-system/components' import type { IntegrationAccount } from '@/platform/lib/data/integrations-types' interface CredentialRow extends IntegrationAccount { @@ -16,8 +16,6 @@ interface ConnectedCredentialProps { integrationName: string accounts: readonly CredentialRow[] pending: boolean - /** Connects a further account into a free slot, when the organization offers one. */ - addAccount?: { disabled: boolean; onSelect: () => void } onReconnect: (accountId: string) => void onDisconnect: (accountId: string) => Promise } @@ -26,7 +24,6 @@ export function ConnectedCredential({ integrationName, accounts, pending, - addAccount, onReconnect, onDisconnect, }: ConnectedCredentialProps) { @@ -75,13 +72,6 @@ export function ConnectedCredential({ />
    ))} - {addAccount && ( -
    - -
    - )} {confirming && ( & { availability: string } } export function ConnectionAccess({ integration }: ConnectionAccessProps) { diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.module.css b/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.module.css new file mode 100644 index 00000000000..2b6a834363c --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.module.css @@ -0,0 +1,14 @@ +.section { + display: grid; + min-inline-size: 0; + gap: var(--ui-section-gap); +} +.heading, +.actions { + display: flex; + align-items: center; + gap: var(--ui-action-gap); +} +.heading { + justify-content: space-between; +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.tsx b/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.tsx new file mode 100644 index 00000000000..72a3cfe56df --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-access/credential-access.tsx @@ -0,0 +1,201 @@ +'use client' + +import { useState } from 'react' +import styles from '@/platform/app/(shell)/integrations/_components/credential-access/credential-access.module.css' +import { + ActionMenu, + Avatar, + Button, + ChoiceMenu, + EmptyState, + Modal, + SearchableSelect, + SelectField, + Tooltip, +} from '@/platform/design-system/components' +import { CountedLabel } from '@/platform/design-system/components/overflow-text/counted-label' +import { SettingsRow } from '@/platform/design-system/components/settings-section/settings-section' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' +import type { + CredentialMember, + IntegrationCredential, +} from '@/platform/lib/integrations/credential-model' + +interface CredentialAccessProps { + credential: IntegrationCredential + viewer: IntegrationPerson + people: readonly IntegrationPerson[] + onChange: (credential: IntegrationCredential) => void + onLeave: () => void +} + +const ROLES = [ + { value: 'member', label: 'Member' }, + { value: 'admin', label: 'Admin' }, +] as const + +export function CredentialAccess({ + credential, + viewer, + people, + onChange, + onLeave, +}: CredentialAccessProps) { + const [adding, setAdding] = useState(false) + const [personId, setPersonId] = useState(null) + const [role, setRole] = useState('member') + const [removing, setRemoving] = useState(null) + const members = credential.members.filter((member) => member.status === 'active') + const existing = new Set(members.map((member) => member.userId)) + const available = people.filter((person) => !existing.has(person.id)) + const admins = members.filter((member) => member.explicitAdmin).length + const editable = credential.role === 'admin' + function lockReason(member: CredentialMember) { + return member.roleSource === 'workspace-admin' + ? 'Access follows workspace admin permissions.' + : member.role === 'admin' && member.explicitAdmin && admins <= 1 + ? 'Make someone else an admin before removing or changing this access.' + : undefined + } + + function update(member: CredentialMember, role: CredentialMember['role']) { + if (!editable || lockReason(member)) return + onChange({ + ...credential, + role: member.userId === viewer.id ? role : credential.role, + members: credential.members.map((entry) => + entry.id === member.id ? { ...entry, role, explicitAdmin: role === 'admin' } : entry + ), + }) + } + + return ( +
    +
    +

    + +

    + {editable && ( + + )} +
    + {members.map((member) => { + const reason = lockReason(member) + const own = member.userId === viewer.id + return ( + } + > +
    + {editable && !reason ? ( + update(member, value === 'Admin' ? 'admin' : 'member')} + /> + ) : ( + + {member.role === 'admin' ? 'Admin' : 'Member'} + + )} + {(own || editable) && ( + setRemoving(member), + }, + ]} + /> + )} +
    +
    + ) + })} + {!members.length && } + {adding && ( + { + const person = available.find((entry) => entry.id === personId) + if (!person || !editable) return false + onChange({ + ...credential, + members: [ + ...credential.members.filter((member) => member.userId !== person.id), + { + ...person, + userId: person.id, + role, + roleSource: 'explicit', + explicitAdmin: role === 'admin', + status: 'active', + }, + ], + }) + setPersonId(null) + }} + > + ({ value: person.id, label: person.name }))} + value={personId} + onValueChange={setPersonId} + placeholder='Choose a person' + /> + setRole(value === 'admin' ? 'admin' : 'member')} + /> + + )} + {removing && ( + { + if (!open) setRemoving(null) + }} + onConfirm={() => { + if (lockReason(removing)) return false + if (removing.userId === viewer.id) onLeave() + else if (editable) + onChange({ + ...credential, + members: credential.members.filter((entry) => entry.id !== removing.id), + }) + }} + /> + )} +
    + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/credential-connect.tsx b/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/credential-connect.tsx new file mode 100644 index 00000000000..9314c142d90 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/credential-connect.tsx @@ -0,0 +1,337 @@ +'use client' + +import { useState } from 'react' +import { toRecord } from '@sim/utils/object' +import Link from 'next/link' +import { ConnectionAccess } from '@/platform/app/(shell)/integrations/_components/connection-access/connection-access' +import type { CredentialDraft } from '@/platform/app/(shell)/integrations/_components/credential-connect/types' +import { SlackBotConnection } from '@/platform/app/(shell)/integrations/_components/slack-bot-connection/slack-bot-connection' +import { + Button, + CopyField, + FileField, + Modal, + SecretField, + SelectField, + TextAreaField, + TextField, +} from '@/platform/design-system/components' +import type { + CredentialConnection, + CredentialField, + IntegrationCredential, +} from '@/platform/lib/integrations/credential-model' + +interface CredentialConnectProps { + integrationName: string + connection: CredentialConnection + workspaces: readonly { id: string; name: string }[] + initial?: IntegrationCredential + onClose: () => void + onSubmit: (draft: CredentialDraft) => void +} + +interface ConnectionFieldProps { + field: CredentialField + value: string + onChange: (value: string) => void +} + +function ConnectionField({ field, value, onChange }: ConnectionFieldProps) { + if (field.options) + return ( + + ) + if (field.multiline) + return ( + + ) + if (field.secret) + return ( + + ) + return ( + + ) +} + +export function CredentialConnect(props: CredentialConnectProps) { + if (props.connection.setup === 'slack-bot') + return ( + + ) + return ( + + ) +} + +function CredentialConnectForm({ + integrationName, + connection, + workspaces, + initial, + onClose, + onSubmit, +}: CredentialConnectProps) { + const [values, setValues] = useState>(() => + Object.fromEntries( + connection.fields.map((field) => [ + field.id, + (field.id === 'domain' || field.id === 'dataverseEnvironmentUrl') && initial?.instanceUrl + ? initial.instanceUrl + : (field.defaultValue ?? ''), + ]) + ) + ) + const [workspaceId, setWorkspaceId] = useState( + initial?.scope.kind === 'workspace' ? initial.scope.id : (workspaces[0]?.id ?? '') + ) + const [displayName, setDisplayName] = useState(initial?.displayName ?? '') + const [description, setDescription] = useState(initial?.description ?? '') + const [file, setFile] = useState<{ name: string } | undefined>() + const [fileError, setFileError] = useState() + const fields = connection.fields.filter((field) => { + if ( + field.visibleWhen && + !field.visibleWhen.values.includes(values[field.visibleWhen.field] ?? '') + ) + return false + if ( + connection.setup === 'oracle-database' && + field.id === 'walletPassword' && + !values.walletContent + ) + return false + return true + }) + const disabled = + fields.some((field) => !field.optional && !values[field.id]?.trim()) || + (!connection.personalOnly && !workspaceId) || + (connection.setup === 'oauth' && !displayName.trim()) + function change(id: string, value: string) { + setValues((current) => ({ ...current, [id]: value })) + } + return ( + { + if (!open) onClose() + }} + onConfirm={() => { + let name = displayName.trim() + let accountLabel = initial?.accountLabel + if (connection.setup === 'google-json') { + let key: Record + try { + key = toRecord(JSON.parse(values.serviceAccountJson ?? '')) + } catch { + throw new Error('Enter a valid service account JSON key.') + } + if ( + key.type !== 'service_account' || + !['client_email', 'private_key', 'project_id'].every( + (field) => typeof key[field] === 'string' && key[field] + ) + ) + throw new Error( + 'The JSON key needs a service account email, private key, and project ID.' + ) + if (typeof key.client_email === 'string') { + accountLabel = key.client_email + if (!name) name = accountLabel + } + } + const host = values.domain?.trim() + let instanceUrl = initial?.instanceUrl + if (connection.personalOnly && !instanceUrl) { + let instance: URL + try { + instance = new URL(host?.includes('://') ? host : `https://${host}`) + } catch { + throw new Error('Enter a valid GitLab host.') + } + if ( + instance.protocol !== 'https:' || + instance.username || + instance.password || + instance.search || + instance.hash || + (instance.pathname !== '/' && instance.pathname !== '') + ) + throw new Error('Enter a GitLab HTTPS host without a path, query, or credentials.') + instanceUrl = instance.origin + } + if (connection.providerId === 'microsoft-dataverse' && !instanceUrl) { + let environment: URL + try { + environment = new URL(values.dataverseEnvironmentUrl) + } catch { + throw new Error('Enter a valid environment URL.') + } + if ( + environment.protocol !== 'https:' || + environment.username || + environment.password || + environment.search || + environment.hash || + (environment.pathname !== '/' && environment.pathname !== '') + ) + throw new Error('Enter an HTTPS environment URL without a path, query, or credentials.') + instanceUrl = environment.origin + } + const draft: CredentialDraft = { + displayName: name || integrationName, + description: description.trim(), + accountLabel, + workspaceId: connection.personalOnly ? undefined : workspaceId, + instanceUrl: + connection.personalOnly || connection.providerId === 'microsoft-dataverse' + ? instanceUrl + : undefined, + } + setValues({}) + onSubmit(draft) + }} + > + {!connection.personalOnly && !initial && ( + ({ value: workspace.id, label: workspace.name }))} + /> + )} + {fields.map((field) => + initial?.instanceUrl && + ((initial.type === 'personal_token' && field.id === 'domain') || + (initial.providerId === 'microsoft-dataverse' && + field.id === 'dataverseEnvironmentUrl')) ? ( + + ) : ( + change(field.id, value)} + /> + ) + )} + {connection.setup === 'google-json' && ( + { + setFile(undefined) + change('serviceAccountJson', '') + }} + onFileChange={async (file) => { + if (file.size > 2 * 1024 * 1024) { + setFileError('Choose a JSON key smaller than 2 MB.') + return + } + try { + change('serviceAccountJson', await file.text()) + setFile({ name: file.name }) + setFileError(undefined) + } catch { + setFileError('Could not read this file.') + } + }} + /> + )} + {connection.kind !== 'personal_token' && ( + <> + + + + )} + {connection.requiredScopes && connection.requiredScopes.length > 0 && ( + + )} + {connection.docsUrl && ( + + )} + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/types.ts b/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/types.ts new file mode 100644 index 00000000000..057a34cfead --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-connect/types.ts @@ -0,0 +1,7 @@ +export interface CredentialDraft { + displayName: string + description: string + accountLabel?: string + workspaceId?: string + instanceUrl?: string +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-detail/credential-detail.tsx b/apps/sim/platform/app/(shell)/integrations/_components/credential-detail/credential-detail.tsx new file mode 100644 index 00000000000..174213e9304 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-detail/credential-detail.tsx @@ -0,0 +1,181 @@ +'use client' + +import { useState } from 'react' +import { CredentialAccess } from '@/platform/app/(shell)/integrations/_components/credential-access/credential-access' +import { ToolPermissions } from '@/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions' +import { IntegrationControls } from '@/platform/app/(shell)/integrations/_components/integration-controls/integration-controls' +import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/provider-heading/provider-heading' +import { + ActionMenu, + Button, + Chip, + CopyField, + Modal, + TextAreaField, + TextField, +} from '@/platform/design-system/components' +import { + SettingsRow, + SettingsSection, +} from '@/platform/design-system/components/settings-section/settings-section' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' + +interface CredentialDetailProps { + credential: IntegrationCredential + integrationName: string + viewer: IntegrationPerson + people: readonly IntegrationPerson[] + onBack: () => void + onChange: (credential: IntegrationCredential) => void + onReconnect?: () => void + onDisconnect: () => void + onLeave: () => void +} + +const METHOD_LABELS = { + oauth: 'OAuth account', + service_account: 'Service account', + personal_token: 'Personal access token', + mcp: 'MCP connection', + slack: 'Slack app', +} as const + +export function CredentialDetail({ + credential, + integrationName, + viewer, + people, + onBack, + onChange, + onReconnect, + onDisconnect, + onLeave, +}: CredentialDetailProps) { + const [editing, setEditing] = useState(false) + const editable = credential.role === 'admin' && credential.scope.kind !== 'organization-managed' + return ( + <> + + + {integrationName} + + } + > + {editable && ( + + )} + + + + + {editable && ( + + )} + + + {editable && ( + + )} + + + + + {credential.instanceUrl && ( + + )} + {credential.scope.kind === 'workspace' && credential.type !== 'personal_token' && ( + + )} + {credential.permissions && ( + onChange({ ...credential, permissions })} + /> + )} + {editing && ( + { + const displayName = String(values.get('displayName') ?? '').trim() + if (!displayName) return false + onChange({ + ...credential, + displayName, + description: String(values.get('description') ?? '').trim(), + }) + }} + > + + + + )} + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.module.css b/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.module.css new file mode 100644 index 00000000000..24e84d370c6 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.module.css @@ -0,0 +1,13 @@ +.section { + display: grid; + min-inline-size: 0; + gap: var(--ui-section-gap); +} +.list { + display: grid; + gap: var(--ui-list-gap); + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.empty { + color: var(--ui-secondary); +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.tsx new file mode 100644 index 00000000000..ca6bf2a752a --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/credential-list/credential-list.tsx @@ -0,0 +1,88 @@ +import styles from '@/platform/app/(shell)/integrations/_components/credential-list/credential-list.module.css' +import { IntegrationUsage } from '@/platform/app/(shell)/integrations/_components/integration-usage/integration-usage' +import { ActionMenu, ActivityRow } from '@/platform/design-system/components' +import { CountedLabel } from '@/platform/design-system/components/overflow-text/counted-label' +import { credentialDescription } from '@/platform/lib/integrations/credential-display' +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' + +interface CredentialListProps { + integrationName: string + credentials: readonly IntegrationCredential[] + onOpen: (credential: IntegrationCredential) => void + onReconnect: (credential: IntegrationCredential) => void + onDisconnect: (credential: IntegrationCredential) => void + canReconnect: (credential: IntegrationCredential) => boolean +} + +export function CredentialList({ + integrationName, + credentials, + onOpen, + onReconnect, + onDisconnect, + canReconnect, +}: CredentialListProps) { + return ( +
    +

    + +

    + {credentials.length > 0 ? ( +
      + {credentials.map((credential) => ( + onOpen(credential)} + metadata={ + member.status === 'active')} + label='People with access' + /> + } + trailing={ + credential.role === 'admin' && credential.scope.kind !== 'organization-managed' ? ( + onOpen(credential), + }, + ...(canReconnect(credential) + ? [ + { + id: 'reconnect', + label: 'Reconnect', + onSelect: () => onReconnect(credential), + }, + ] + : []), + { + id: 'disconnect', + label: 'Disconnect', + destructive: true, + separatorBefore: true, + onSelect: () => onDisconnect(credential), + }, + ]} + /> + ) : undefined + } + /> + ))} +
    + ) : ( +

    + No connected credentials +

    + )} +
    + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.module.css b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.module.css deleted file mode 100644 index 633e876f383..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.module.css +++ /dev/null @@ -1,19 +0,0 @@ -.section { - display: grid; - gap: var(--ui-row-gap); -} -.identity { - display: grid; - min-inline-size: 0; - gap: var(--ui-stack-gap); - overflow-wrap: anywhere; -} -.row { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--ui-row-gap); -} -.muted { - color: var(--ui-secondary); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.tsx deleted file mode 100644 index f3eea20d735..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.tsx +++ /dev/null @@ -1,77 +0,0 @@ -'use client' - -import { useState } from 'react' -import styles from '@/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential.module.css' -import { ActionMenu, Modal } from '@/platform/design-system/components' -import type { IntegrationAccount } from '@/platform/lib/integrations/fixture-model' - -interface ConnectedCredentialProps { - account: IntegrationAccount - status?: string - canAuthorize: boolean - onReconnect: () => void - onDisconnect: () => void -} - -export function ConnectedCredential({ - account, - status, - canAuthorize, - onReconnect, - onDisconnect, -}: ConnectedCredentialProps) { - const [confirming, setConfirming] = useState(false) - return ( -
    -

    Connected credential

    -
    -
    -

    {account.label}

    - {status && ( -

    - {status} -

    - )} -
    - setConfirming(true), - }, - ]} - /> -
    - {confirming && ( - - )} -
    - ) -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.module.css b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.module.css deleted file mode 100644 index 84d7043bcf9..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.module.css +++ /dev/null @@ -1,26 +0,0 @@ -.section, -.heading, -.group, -.items { - display: grid; - min-inline-size: 0; -} -.section { - gap: var(--ui-section-gap); -} -.heading { - gap: var(--ui-stack-gap); -} -.group { - gap: var(--ui-row-gap); -} -.items { - gap: var(--ui-list-gap); - list-style: disc outside; - padding-inline-start: var(--spacing-16); - overflow-wrap: anywhere; -} -.items li::marker, -.heading p { - color: var(--ui-secondary); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.tsx deleted file mode 100644 index 7a07c6c3b7d..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import styles from '@/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access.module.css' -import { - SCOPE_GROUPS, - scopeGroup, -} from '@/platform/app/(shell)/integrations/_components/fixtures/connection-access/scope-groups' -import { CountedLabel } from '@/platform/design-system/components/overflow-text/counted-label' -import type { OrganizationIntegration } from '@/platform/lib/integrations/fixture-model' - -interface AccessGroupProps { - title: string - items: readonly { id: string; label: string }[] -} - -function AccessGroup({ title, items }: AccessGroupProps) { - if (!items.length) return null - return ( -
    -

    - -

    -
      - {items.map(({ id, label }) => ( -
    • - {label} -
    • - ))} -
    -
    - ) -} - -interface ConnectionAccessProps { - integration: OrganizationIntegration -} - -export function ConnectionAccess({ integration }: ConnectionAccessProps) { - const { searchReads, searchResource, requestedScopes, availability, accessDescription } = - integration - return ( - <> - {searchResource && - availability === 'ready' && - (searchReads.length > 0 || !requestedScopes?.length) && ( -
    -
    -

    Search access

    -

    {accessDescription}

    -
    - -
    - )} - {requestedScopes && requestedScopes.length > 0 && ( -
    -

    Requested permissions

    - {SCOPE_GROUPS.map((group) => ( - scopeGroup(id) === group)} - /> - ))} -
    - )} - - ) -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/scope-groups.ts b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/scope-groups.ts deleted file mode 100644 index 071c891d34d..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/connection-access/scope-groups.ts +++ /dev/null @@ -1,35 +0,0 @@ -const ACCOUNT_SCOPES = new Set([ - 'openid', - 'userinfo.email', - 'userinfo.profile', - 'read:me', - 'offline_access', - 'refresh_token', -]) - -const GOOGLE_WRITE_SCOPES = new Set([ - 'gmail.send', - 'gmail.modify', - 'gmail.labels', - 'calendar', - 'drive', - 'drive.file', - 'meetings.space.created', -]) - -export const SCOPE_GROUPS = [ - 'Account and sign-in', - 'Read and search', - 'Write and manage', - 'Provider access', -] as const - -export function scopeGroup(id: string): (typeof SCOPE_GROUPS)[number] { - const scope = id.replace(/^https:\/\/www\.googleapis\.com\/auth\//, '') - if (ACCOUNT_SCOPES.has(scope)) return 'Account and sign-in' - if (GOOGLE_WRITE_SCOPES.has(scope) || /^(write|delete|manage)(:|$)/.test(scope)) - return 'Write and manage' - if (/^(read|search)(:|$)|:(read|history)([.:]|$)|\.readonly$/.test(scope)) - return 'Read and search' - return 'Provider access' -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details.tsx index 9ad654917cb..b5500af6c1e 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details.tsx @@ -1,139 +1,319 @@ 'use client' -import { useLayoutEffect, useRef } from 'react' -import { useRouter, useSearchParams } from 'next/navigation' -import { ConnectedCredential } from '@/platform/app/(shell)/integrations/_components/fixtures/connected-credential/connected-credential' -import { ConnectionAccess } from '@/platform/app/(shell)/integrations/_components/fixtures/connection-access/connection-access' -import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading' -import { ToolPermissions } from '@/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions' -import { Chip, EmptyState } from '@/platform/design-system/components' -import { ConnectionPrompt } from '@/platform/design-system/components/connection-prompt/connection-prompt' +import { useState } from 'react' +import { generateId } from '@sim/utils/id' +import Link from 'next/link' +import { usePathname, useRouter, useSearchParams } from 'next/navigation' +import { useQueryStates } from 'nuqs' +import { ConnectionAccess } from '@/platform/app/(shell)/integrations/_components/connection-access/connection-access' +import { CredentialConnect } from '@/platform/app/(shell)/integrations/_components/credential-connect/credential-connect' +import type { CredentialDraft } from '@/platform/app/(shell)/integrations/_components/credential-connect/types' +import { CredentialDetail } from '@/platform/app/(shell)/integrations/_components/credential-detail/credential-detail' +import { CredentialList } from '@/platform/app/(shell)/integrations/_components/credential-list/credential-list' import { - memberIntegrationHref, - memberStatus, - type OrganizationIntegration, -} from '@/platform/lib/integrations/fixture-model' + credentialParams, + serializeCredential, +} from '@/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params' +import { IntegrationCapabilities } from '@/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities' +import { IntegrationControls } from '@/platform/app/(shell)/integrations/_components/integration-controls/integration-controls' +import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/provider-heading/provider-heading' +import { ActionMenu, Button, Modal } from '@/platform/design-system/components' +import type { IntegrationCatalogEntry } from '@/platform/lib/integrations/catalog-model' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' +import type { + CredentialConnection, + IntegrationCredential, +} from '@/platform/lib/integrations/credential-model' +import type { OrganizationIntegration } from '@/platform/lib/integrations/fixture-model' interface IntegrationDetailsProps { integration: OrganizationIntegration onChange: (next: OrganizationIntegration) => void + knownCredentials: readonly IntegrationCredential[] + viewer: IntegrationPerson + eligiblePeople: readonly IntegrationPerson[] + workspaces: readonly { id: string; name: string; memberIds: readonly string[] }[] + people?: readonly IntegrationPerson[] + peopleTotal?: number + catalog?: IntegrationCatalogEntry | null + addedSkills?: readonly string[] + onAddSkill?: (skill: IntegrationCatalogEntry['skills'][number]) => void } -export function IntegrationDetails({ integration, onChange }: IntegrationDetailsProps) { +export function IntegrationDetails({ + integration, + onChange, + knownCredentials, + viewer, + eligiblePeople, + workspaces, + people, + peopleTotal, + catalog, + addedSkills, + onAddSkill, +}: IntegrationDetailsProps) { + const pathname = usePathname() const router = useRouter() const search = useSearchParams() - const { account, providerId, connectableMethod, connectionCandidate } = integration - const titleRef = useRef(null) - const returnToTitle = useRef(false) - useLayoutEffect(() => { - if (returnToTitle.current) { - titleRef.current?.focus({ preventScroll: true }) - returnToTitle.current = false - } - }, [account?.id]) - const requested = search.get('account') - const staleCredential = Boolean(requested && requested !== account?.id) - const providerHref = memberIntegrationHref( - `/integrations/${encodeURIComponent(providerId)}`, - search - ) - const canConnect = !account && integration.availability === 'ready' && connectableMethod !== null - const canAuthorize = Boolean(integration.fixtureAuthorization) - const canAttach = canAuthorize && canConnect && connectionCandidate?.method === connectableMethod - const accessMessage = - integration.availability === 'managed' - ? `Managed by your organization. ${integration.accessDescription}` - : integration.accessDescription - - function connect() { - if (!canAttach || !connectionCandidate) return - returnToTitle.current = true + const [view, setView] = useQueryStates(credentialParams) + const [enrollment, setEnrollment] = useState<{ + connection: CredentialConnection + credential?: IntegrationCredential + } | null>(null) + const [disconnecting, setDisconnecting] = useState(null) + const selected = integration.credentials.find((credential) => credential.id === view.credential) + const connections = catalog?.connections ?? [] + const selectedScope = selected?.scope + const workspace = + selectedScope?.kind === 'workspace' + ? workspaces.find((entry) => entry.id === selectedScope.id) + : undefined + const allowedPeople = workspace + ? eligiblePeople.filter((person) => workspace.memberIds.includes(person.id)) + : [] + function canReconnect(credential: IntegrationCredential) { + if (credential.providerId === 'microsoft-dataverse' && !credential.instanceUrl) return false + return ( + credential.role === 'admin' && + credential.scope.kind !== 'organization-managed' && + credential.canReconnect && + connections.some( + (entry) => entry.providerId === credential.providerId && entry.kind === credential.type + ) + ) + } + async function open(credential: IntegrationCredential) { + await setView(view) + router.push( + serializeCredential(`${pathname}?${search.toString()}`, { credential: credential.id }), + { scroll: false } + ) + } + function save(credential: IntegrationCredential) { + const current = integration.credentials.find((entry) => entry.id === credential.id) + if (!current || current.role !== 'admin' || current.scope.kind === 'organization-managed') + return + if (current.displayName !== credential.displayName) assertAvailableName(credential) onChange({ ...integration, - account: connectionCandidate, - connectableMethod: null, - connectionCandidate: undefined, + credentials: integration.credentials.map((entry) => + entry.id === credential.id ? credential : entry + ), }) } - - function disconnect() { - if (!account) return - returnToTitle.current = true - const restore = integration.availability === 'ready' && account.canReconnect + function assertAvailableName(credential: IntegrationCredential) { + const scope = credential.scope + if ( + (credential.type !== 'oauth' && credential.type !== 'service_account') || + scope.kind !== 'workspace' + ) + return + if ( + knownCredentials.some( + (entry) => + entry.id !== credential.id && + entry.type === credential.type && + entry.scope.kind === 'workspace' && + entry.scope.id === scope.id && + (credential.type === 'oauth' + ? entry.displayName.trim().toLowerCase() === credential.displayName.trim().toLowerCase() + : entry.providerId === credential.providerId && + entry.displayName === credential.displayName) + ) + ) + throw new Error('A credential with this display name already exists in this workspace.') + } + function remove(credential: IntegrationCredential) { + const current = integration.credentials.find((entry) => entry.id === credential.id) + if (!current || current.role !== 'admin' || current.scope.kind === 'organization-managed') + return + commitRemoval(current) + } + function commitRemoval(credential: IntegrationCredential) { onChange({ ...integration, - account: null, - connectableMethod: restore ? account.method : null, - connectionCandidate: - restore && canAuthorize - ? { - ...account, - status: 'active', - permissions: account.permissions && { - ...account.permissions, - read: account.permissions.canAutoApprove ? 'allow' : 'ask', - write: 'ask', - tools: account.permissions.tools.map((tool) => ({ ...tool, override: null })), - }, - } - : undefined, + credentials: integration.credentials.filter((entry) => entry.id !== credential.id), }) - if (requested) router.replace(providerHref, { scroll: false }) + if (selected?.id === credential.id) void setView({ credential: null }) + } + function leave(credential: IntegrationCredential) { + const current = integration.credentials.find((entry) => entry.id === credential.id) + if (!current || current.scope.kind !== 'workspace') return + const members = current.members.filter((member) => member.status === 'active') + const member = members.find((entry) => entry.userId === viewer.id) + if ( + !member || + member.roleSource === 'workspace-admin' || + (member.explicitAdmin && members.filter((entry) => entry.explicitAdmin).length <= 1) + ) + return + commitRemoval(current) + } + function reconnect(credential: IntegrationCredential) { + if (!canReconnect(credential)) return + const connection = connections.find( + (entry) => entry.providerId === credential.providerId && entry.kind === credential.type + ) + if (connection) setEnrollment({ connection, credential }) + } + function connect(draft: CredentialDraft) { + if (!enrollment || (!enrollment.credential && !integration.canAddCredential)) return + if (enrollment.credential) { + const current = integration.credentials.find( + (entry) => entry.id === enrollment.credential?.id + ) + if (!current) return + save({ + ...current, + displayName: draft.displayName, + description: draft.description, + accountLabel: draft.accountLabel ?? current.accountLabel, + status: 'active', + }) + setEnrollment(null) + return + } + const workspace = enrollment.connection.personalOnly + ? undefined + : workspaces.find((entry) => entry.id === draft.workspaceId) + if (!enrollment.connection.personalOnly && !workspace) return + const credential: IntegrationCredential = { + id: generateId(), + appId: integration.providerId, + providerId: enrollment.connection.providerId, + type: enrollment.connection.kind, + displayName: draft.displayName, + description: draft.description, + accountLabel: draft.accountLabel, + instanceUrl: draft.instanceUrl, + role: 'admin', + status: 'active', + canReconnect: true, + scope: workspace + ? { kind: 'workspace', id: workspace.id, name: workspace.name } + : { kind: 'personal', ownerId: viewer.id }, + members: enrollment.connection.personalOnly + ? [] + : [ + { + ...viewer, + userId: viewer.id, + role: 'admin', + roleSource: 'explicit', + explicitAdmin: true, + status: 'active', + }, + ], + } + assertAvailableName(credential) + onChange({ ...integration, credentials: [...integration.credentials, credential] }) + setEnrollment(null) } - return ( <> - - {account && !staleCredential && ( - { - if (canAuthorize && account.canReconnect) - onChange({ ...integration, account: { ...account, status: 'active' } }) - }} - onDisconnect={disconnect} + {selected ? ( + void setView({ credential: null })} + onChange={save} + onReconnect={canReconnect(selected) ? () => reconnect(selected) : undefined} + onDisconnect={() => setDisconnecting(selected)} + onLeave={() => leave(selected)} /> + ) : ( + <> + + + } + > + Docs + + } + > + {integration.canAddCredential && connections.length === 1 ? ( + + ) : integration.canAddCredential && connections.length > 1 ? ( + ({ + id: connection.id, + label: connection.label, + onSelect: () => setEnrollment({ connection }), + }))} + /> + ) : null} + + void open(credential)} + onReconnect={reconnect} + canReconnect={canReconnect} + onDisconnect={setDisconnecting} + /> + + {catalog && ( + + )} + )} - {staleCredential ? ( - View integration} - /> - ) : !account ? ( - setEnrollment(null)} + onSubmit={connect} /> - ) : null} - {!staleCredential && account?.permissions && ( - - onChange({ ...integration, account: { ...account, permissions } }) - } + )} + {disconnecting && ( + { + if (!open) setDisconnecting(null) + }} + onConfirm={() => remove(disconnecting)} /> )} - {!staleCredential && } ) } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params.ts b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params.ts new file mode 100644 index 00000000000..3be955bc5ff --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params.ts @@ -0,0 +1,4 @@ +import { createSerializer, parseAsString } from 'nuqs/server' + +export const credentialParams = { credential: parseAsString.withDefault('') } +export const serializeCredential = createSerializer(credentialParams) diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx index 4aa62971810..08f793d4b4e 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page.tsx @@ -1,36 +1,71 @@ 'use client' +import { generateId } from '@sim/utils/id' import { useSearchParams } from 'next/navigation' +import { NuqsAdapter } from 'nuqs/adapters/next/app' import { useIntegrationCenterResources } from '@/platform/app/(shell)/_components/session/integration-center-changes' import { useOrganizationIntegrations } from '@/platform/app/(shell)/_components/session/integration-changes' import { IntegrationDetails } from '@/platform/app/(shell)/integrations/_components/fixtures/integration-details/integration-details' +import { serializeCredential } from '@/platform/app/(shell)/integrations/_components/fixtures/integration-details/search-params' import { MemberSecrets } from '@/platform/app/(shell)/integrations/_components/fixtures/member-secrets/member-secrets' -import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading' import { IntegrationCenter } from '@/platform/app/(shell)/integrations/_components/integration-center/integration-center' import { IntegrationsHeading, IntegrationsPage as PageFrame, } from '@/platform/app/(shell)/integrations/_components/integrations-page/integrations-page' -import type { IntegrationCenterData } from '@/platform/lib/integrations/center-model' -import { appCategory } from '@/platform/lib/integrations/center-navigation' +import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/provider-heading/provider-heading' +import type { IntegrationCatalogEntry } from '@/platform/lib/integrations/catalog-model' +import type { AppSummary, IntegrationCenterData } from '@/platform/lib/integrations/center-model' +import { credentialDescription } from '@/platform/lib/integrations/credential-display' import { type IntegrationsData, memberIntegrationHref, - memberStatus, } from '@/platform/lib/integrations/fixture-model' interface IntegrationsPageProps { data: IntegrationsData | null center: IntegrationCenterData | null section?: string + catalog?: IntegrationCatalogEntry | null } -export function IntegrationsPage({ data, center, section }: IntegrationsPageProps) { +export function IntegrationsPage({ data, center, section, catalog }: IntegrationsPageProps) { + return ( + + + + ) +} + +function IntegrationsContent({ data, center, section, catalog }: IntegrationsPageProps) { const search = useSearchParams() const { integrations, save } = useOrganizationIntegrations(data) const library = useIntegrationCenterResources(center) const item = integrations.find((entry) => entry.providerId === section) const secrets = section === 'secrets' ? data?.genericSecrets : null + const providerNames = new Map( + integrations.map((integration) => [integration.providerId, integration.name]) + ) + const credentialLinks: AppSummary[] = [ + ...new Map( + integrations.flatMap((integration) => + integration.credentials.map((credential) => [credential.id, credential] as const) + ) + ).values(), + ].map((credential) => ({ + id: credential.id, + providerId: credential.appId, + name: credential.displayName, + description: credentialDescription(credential, providerNames.get(credential.appId)), + category: 'Credentials', + connected: true, + scope: credential.scope.kind === 'personal' ? 'personal' : 'shared', + people: credential.members.filter((member) => member.status === 'active'), + href: serializeCredential( + memberIntegrationHref(`/integrations/${encodeURIComponent(credential.appId)}`, search), + { credential: credential.id } + ), + })) return ( {item || secrets ? ( <> - {item && } + {item && center && ( + entry.credentials)} + viewer={center.viewer} + eligiblePeople={center.people} + workspaces={center.workspaces} + catalog={catalog} + people={center?.appPeople[item.providerId]} + peopleTotal={center?.appUsageTotal[item.providerId]} + addedSkills={catalog?.skills + .filter((skill) => + library.resources.some( + (entry) => entry.kind === 'skill' && entry.instructions === skill.content + ) + ) + .map((skill) => skill.name)} + onAddSkill={ + center + ? (skill) => { + if ( + library.resources.some( + (entry) => entry.kind === 'skill' && entry.instructions === skill.content + ) + ) + return + library.save({ + id: generateId(), + kind: 'skill', + name: skill.name, + description: skill.description, + instructions: skill.content, + scope: 'personal', + owner: center.viewer, + people: [center.viewer], + canEdit: true, + }) + } + : undefined + } + /> + )} {secrets && ( <> @@ -57,12 +135,14 @@ export function IntegrationsPage({ data, center, section }: IntegrationsPageProp id: integration.providerId, name: integration.name, description: integration.description, - category: appCategory(integration.providerId), + category: integration.category ?? 'Other', href: memberIntegrationHref(`/integrations/${integration.providerId}`, search), - connected: Boolean(integration.account), - status: memberStatus(integration), - searchable: integration.account?.label, + connected: integration.credentials.length > 0, + searchable: integration.credentials + .map((credential) => `${credential.displayName} ${credential.accountLabel ?? ''}`) + .join(' '), people: center?.appPeople[integration.providerId], + peopleTotal: center?.appUsageTotal[integration.providerId], }))} library={ center @@ -73,21 +153,25 @@ export function IntegrationsPage({ data, center, section }: IntegrationsPageProp } : undefined } - credentials={ - data?.genericSecrets + credentials={[ + ...credentialLinks, + ...(data?.genericSecrets ? [ { id: 'secrets', name: data.genericSecrets.name, description: data.genericSecrets.description, category: 'Credentials', - scope: data.genericSecrets.mode === 'organization' ? 'shared' : 'personal', + scope: + data.genericSecrets.mode === 'organization' + ? ('shared' as const) + : ('personal' as const), connected: true, href: memberIntegrationHref('/integrations/secrets', search), }, ] - : [] - } + : []), + ]} /> )} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx index 2b68720a8b5..c60c5abb18a 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-route.tsx @@ -1,7 +1,11 @@ import { notFound } from 'next/navigation' import { IntegrationsPage } from '@/platform/app/(shell)/integrations/_components/fixtures/integrations-page/integrations-page' import { readScenario } from '@/platform/design-system/navigation' -import { loadIntegrationCenterData, loadIntegrationsData } from '@/platform/fixtures' +import { + loadIntegrationCatalogEntry, + loadIntegrationCenterData, + loadIntegrationsData, +} from '@/platform/fixtures' interface IntegrationsRouteProps { section?: string @@ -11,9 +15,10 @@ interface IntegrationsRouteProps { export async function IntegrationsRoute({ section, searchParams }: IntegrationsRouteProps) { const query = await searchParams const scenario = readScenario(query.state) - const [data, center] = await Promise.all([ + const [data, center, catalog] = await Promise.all([ loadIntegrationsData(scenario, query.secrets), loadIntegrationCenterData(scenario), + loadIntegrationCatalogEntry(scenario, section), ]) if ( section && @@ -21,5 +26,5 @@ export async function IntegrationsRoute({ section, searchParams }: IntegrationsR !data?.integrations.some((item) => item.providerId === section) ) notFound() - return + return } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.module.css b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.module.css deleted file mode 100644 index f534de998b6..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.header { - display: grid; - grid-template-columns: auto minmax(0, 1fr); - align-items: start; - gap: var(--ui-row-gap); -} -.mark { - display: grid; - place-items: center; - block-size: var(--leading-32); -} -.copy { - display: grid; - min-inline-size: 0; - overflow-wrap: anywhere; - gap: var(--ui-stack-gap); -} -.copy p { - color: var(--ui-secondary); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.tsx deleted file mode 100644 index 7356689dac9..00000000000 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type { Ref } from 'react' -import styles from '@/platform/app/(shell)/integrations/_components/fixtures/provider-heading/provider-heading.module.css' -import { Icon } from '@/platform/design-system/components' - -interface ProviderHeadingProps { - name: string - description: string - providerId?: string - titleRef?: Ref -} - -export function ProviderHeading({ name, description, providerId, titleRef }: ProviderHeadingProps) { - return ( -
    - - {providerId ? : } - -
    -

    - {name} -

    -

    {description}

    -
    -
    - ) -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions.tsx b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions.tsx index a07f01d19e8..d9366bcba88 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/fixtures/tool-permissions/tool-permissions.tsx @@ -19,17 +19,23 @@ const GROUPS = [ ] as const interface ToolPermissionsProps { - account: IntegrationAccount + account: Pick permissions: Permissions onChange: (next: Permissions) => void + readOnly?: boolean } -export function ToolPermissions({ account, permissions, onChange }: ToolPermissionsProps) { +export function ToolPermissions({ + account, + permissions, + onChange, + readOnly, +}: ToolPermissionsProps) { const [query, setQuery] = useState('') const canAllow = permissions.canAutoApprove && account.status === 'active' const choices = ACTIONS.map((option) => ({ ...option, - disabled: option.value === 'allow' && !canAllow, + disabled: readOnly || (option.value === 'allow' && !canAllow), })) const filter = query.trim().toLowerCase() const matches = permissions.tools.filter((tool) => diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.module.css new file mode 100644 index 00000000000..bdc1ad086b3 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.module.css @@ -0,0 +1,16 @@ +.section { + display: grid; + min-inline-size: 0; + gap: var(--ui-section-gap); +} +.links { + display: grid; + gap: var(--ui-list-gap); + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.bounded { + display: grid; + grid-template-columns: minmax(0, 1fr); + min-block-size: 0; + max-block-size: var(--ui-widget-max-size); +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.tsx new file mode 100644 index 00000000000..b7d1b31ff5c --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.tsx @@ -0,0 +1,167 @@ +'use client' + +import { useState } from 'react' +import { useQueryStates } from 'nuqs' +import styles from '@/platform/app/(shell)/integrations/_components/integration-capabilities/integration-capabilities.module.css' +import { catalogParams } from '@/platform/app/(shell)/integrations/_components/integration-capabilities/search-params' +import { IntegrationMark } from '@/platform/app/(shell)/integrations/_components/integration-mark/integration-mark' +import { + ActivityRow, + CopyButton, + Modal, + ModalBody, + Pagination, + ScrollArea, + Stack, + TextAreaField, +} from '@/platform/design-system/components' +import { OverlayDialog } from '@/platform/design-system/components/modal/overlay-dialog' +import { CountedLabel } from '@/platform/design-system/components/overflow-text/counted-label' +import { SettingsRow } from '@/platform/design-system/components/settings-section/settings-section' +import type { IntegrationCatalogEntry } from '@/platform/lib/integrations/catalog-model' + +type CatalogSkill = IntegrationCatalogEntry['skills'][number] +type CatalogTemplate = IntegrationCatalogEntry['templates'][number] + +interface IntegrationCapabilitiesProps { + catalog: IntegrationCatalogEntry + addedSkills?: readonly string[] + onAddSkill?: (skill: CatalogSkill) => void +} + +const TEMPLATES_PER_PAGE = 8 + +export function IntegrationCapabilities({ + catalog, + addedSkills = [], + onAddSkill, +}: IntegrationCapabilitiesProps) { + const [skill, setSkill] = useState(null) + const [template, setTemplate] = useState(null) + const [view, setView] = useQueryStates(catalogParams) + const templatePages = Math.ceil(catalog.templates.length / TEMPLATES_PER_PAGE) + const templatePage = Math.max(1, Math.min(view['templates-page'], templatePages)) + const templates = catalog.templates.slice( + (templatePage - 1) * TEMPLATES_PER_PAGE, + templatePage * TEMPLATES_PER_PAGE + ) + const installed = new Set(addedSkills) + const information = [ + { title: 'Actions', items: catalog.operations }, + { title: 'Triggers', items: catalog.triggers }, + ] + return ( + <> + {catalog.skills.length > 0 && ( +
    +

    Suggested skills

    +
      + {catalog.skills.map((entry) => ( + setSkill(entry)} + /> + ))} +
    +
    + )} + {catalog.templates.length > 0 && ( +
    +

    + +

    +
    + +
      + {templates.map((entry) => ( + ({ + id: integration.id, + label: integration.name, + content: , + }))} + /> + } + onOpen={() => setTemplate(entry)} + /> + ))} +
    +
    +
    + {templatePages > 1 && ( + void setView({ 'templates-page': page })} + /> + )} +
    + )} + {information.map(({ title, items }) => + items.length ? ( +
    +

    + +

    +
    + + {items.map((entry) => ( + + ))} + +
    +
    + ) : null + )} + {skill && + (onAddSkill ? ( + { + if (!open) setSkill(null) + }} + onConfirm={() => onAddSkill(skill)} + > + + + ) : ( + setSkill(null)} + > + + + + + ))} + {template && ( + setTemplate(null)}> + + + + + + )} + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/search-params.ts b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/search-params.ts new file mode 100644 index 00000000000..773b86cc9a1 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-capabilities/search-params.ts @@ -0,0 +1,5 @@ +import { parseAsInteger } from 'nuqs/server' + +export const catalogParams = { + 'templates-page': parseAsInteger.withDefault(1), +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css index 1e7e5c2000b..6f7892a922f 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css @@ -7,24 +7,15 @@ .navigation { margin-inline: calc(-1 * var(--ui-row-inset)); } -.controls { - display: flex; - align-items: center; - flex-wrap: wrap; - justify-content: space-between; - gap: var(--ui-row-gap); - margin-inline: calc(-1 * var(--ui-row-inset)); -} -.search { - flex: 1 1 var(--container-208); - max-inline-size: var(--container-440); +.toolbar, +.empty { + display: grid; min-inline-size: 0; + gap: var(--ui-section-gap); +} +.empty { + gap: var(--ui-stack-gap); } -.actions { - display: flex; - flex-wrap: wrap; - max-inline-size: 100%; - flex: none; - align-items: center; - gap: var(--ui-action-gap); +.empty p { + color: var(--ui-secondary); } diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx index 40e89449a3f..b3acabd9df6 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-center/integration-center.tsx @@ -3,8 +3,8 @@ import { useState } from 'react' import { usePathname, useRouter, useSearchParams } from 'next/navigation' import { useQueryStates } from 'nuqs' -import { NuqsAdapter } from 'nuqs/adapters/next/app' import styles from '@/platform/app/(shell)/integrations/_components/integration-center/integration-center.module.css' +import { IntegrationControls } from '@/platform/app/(shell)/integrations/_components/integration-controls/integration-controls' import { ResourceDetails } from '@/platform/app/(shell)/integrations/_components/resource-details/resource-details' import { ResourceEditor } from '@/platform/app/(shell)/integrations/_components/resource-editor/resource-editor' import { @@ -16,7 +16,6 @@ import { Button, ChoiceMenu, DestinationTabs, - EmptyState, Modal, SearchField, } from '@/platform/design-system/components' @@ -53,15 +52,7 @@ const CREATE_LABEL = { } as const /** The same directory receives authorized live summaries or server-gated example data. */ -export function IntegrationCenter({ apps, credentials, library, settled }: IntegrationCenterProps) { - return ( - - - - ) -} - -function CenterContent({ +export function IntegrationCenter({ apps, credentials = [], library, @@ -141,24 +132,25 @@ function CenterContent({ return (
    -
    - -
    -
    -
    - void setView({ q })} +
    +
    +
    -
    + void setView({ q })} + /> + } + > {current === 'apps' ? ( )} -
    +
    {current === 'apps' ? ( @@ -255,16 +247,18 @@ function CenterContent({ )} {settled && empty && ( - +

    + {term ? 'No results found' : `No ${current === 'mcps' ? 'MCPs' : current} yet`} +

    +

    + {term ? 'Try a different name or clear your filters.' : current === 'apps' ? 'Apps available to your organization appear here.' - : 'Your personal and shared connections appear here.' - } - /> + : 'Your personal and shared connections appear here.'} +

    +
    )} {editing?.canEdit === false ? ( diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.module.css new file mode 100644 index 00000000000..6215991cb60 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.module.css @@ -0,0 +1,21 @@ +.controls { + display: flex; + align-items: center; + flex-wrap: wrap; + justify-content: space-between; + gap: var(--ui-row-gap); + margin-inline: calc(-1 * var(--ui-row-inset)); +} +.leading { + flex: 1 1 var(--container-208); + max-inline-size: var(--container-440); + min-inline-size: 0; +} +.actions { + display: flex; + flex-wrap: wrap; + max-inline-size: 100%; + flex: none; + align-items: center; + gap: var(--ui-action-gap); +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.tsx new file mode 100644 index 00000000000..ba96283c340 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.tsx @@ -0,0 +1,16 @@ +import type { ReactNode } from 'react' +import styles from '@/platform/app/(shell)/integrations/_components/integration-controls/integration-controls.module.css' + +interface IntegrationControlsProps { + leading: ReactNode + children?: ReactNode +} + +export function IntegrationControls({ leading, children }: IntegrationControlsProps) { + return ( +
    +
    {leading}
    + {children &&
    {children}
    } +
    + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-details/integration-details.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-details/integration-details.tsx index a6da3d4c9b8..2a738ddd998 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-details/integration-details.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-details/integration-details.tsx @@ -1,16 +1,18 @@ 'use client' import { type ReactNode, useLayoutEffect, useRef } from 'react' +import Link from 'next/link' import { ConnectedCredential } from '@/platform/app/(shell)/integrations/_components/connected-credential/connected-credential' import { ConnectionAccess } from '@/platform/app/(shell)/integrations/_components/connection-access/connection-access' +import { IntegrationControls } from '@/platform/app/(shell)/integrations/_components/integration-controls/integration-controls' import { ProviderHeading } from '@/platform/app/(shell)/integrations/_components/provider-heading/provider-heading' -import { Chip, EmptyState } from '@/platform/design-system/components' -import { ConnectionPrompt } from '@/platform/design-system/components/connection-prompt/connection-prompt' +import { Button, Chip, EmptyState } from '@/platform/design-system/components' import { accountStatus, isConnectable, type OrganizationIntegration, } from '@/platform/lib/data/integrations-types' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' interface IntegrationDetailsProps { integration: OrganizationIntegration @@ -22,6 +24,8 @@ interface IntegrationDetailsProps { onReconnect: (accountId: string) => void onDisconnect: (accountId: string) => Promise renderToolPermissions: (accountId: string) => ReactNode + people?: readonly IntegrationPerson[] + peopleTotal?: number } export function IntegrationDetails({ @@ -34,6 +38,8 @@ export function IntegrationDetails({ onReconnect, onDisconnect, renderToolPermissions, + people, + peopleTotal, }: IntegrationDetailsProps) { const { accounts, availability, connectionTarget, providerId, name } = integration const titleRef = useRef(null) @@ -63,7 +69,33 @@ export function IntegrationDetails({ description={integration.description} providerId={providerId} icon={integration.icon} + people={people} + peopleTotal={peopleTotal} /> + + } + > + Docs + + } + > + {connectionTarget && ( + + )} + {stale ? ( ({ ...account, - statusLabel: accountStatus(integration, account), + statusLabel: accountStatus(integration), href: selected ? undefined : accountHref(account.id), }))} pending={pending} - addAccount={connectionTarget ? { disabled: !canConnect, onSelect: onConnect } : undefined} onReconnect={onReconnect} onDisconnect={onDisconnect} /> ) : ( - )} {selected?.hasToolPermissions && renderToolPermissions(selected.id)} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx index faa569ff89e..8c3f5d12631 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx @@ -4,7 +4,6 @@ import type { OrganizationIntegration, } from '@/platform/lib/data/integrations-types' import type { AppSummary } from '@/platform/lib/integrations/center-model' -import { appCategory } from '@/platform/lib/integrations/center-navigation' interface IntegrationListProps { integrations: readonly OrganizationIntegration[] @@ -29,9 +28,8 @@ export function IntegrationList({ href: integrationHref(item.id), name: item.name, description: item.description, - category: appCategory(item.providerId), + category: item.category, connected: item.accounts.length > 0 || item.availability === 'managed', - status: item.status, searchable: [item.providerId, ...item.accounts.map((account) => account.label)].join(' '), })) const credentials: AppSummary[] = secrets @@ -44,7 +42,6 @@ export function IntegrationList({ category: 'Credentials', scope: secrets.mode === 'organization' ? 'shared' : 'personal', connected: secrets.mode === 'organization', - status: secrets.mode === 'organization' ? 'Organization managed' : 'Personal secrets', }, ] : [] diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.module.css b/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.module.css new file mode 100644 index 00000000000..60ef8d68bd5 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.module.css @@ -0,0 +1,13 @@ +.usage, +.person { + display: inline-flex; + align-items: center; + gap: var(--ui-row-gap); +} +.usage { + flex-wrap: wrap; + color: var(--ui-secondary); +} +.person { + min-inline-size: 0; +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.tsx b/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.tsx new file mode 100644 index 00000000000..11966b15d00 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.tsx @@ -0,0 +1,43 @@ +import styles from '@/platform/app/(shell)/integrations/_components/integration-usage/integration-usage.module.css' +import { Avatar, AvatarGroup } from '@/platform/design-system/components' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' + +interface IntegrationUsageProps { + people: readonly IntegrationPerson[] + total?: number + expanded?: boolean + label?: string +} + +export function IntegrationUsage({ + people, + total = people.length, + expanded, + label = 'Used by', +}: IntegrationUsageProps) { + if (!people.length && !total) return null + if (!expanded) return + const visible = people.slice(0, 2) + const remaining = Math.max(0, total - visible.length) + return ( + + {label} + {visible.map((person, index) => ( + + {index > 0 && !remaining && and} + + + {person.name} + {index < visible.length - 1 && remaining > 0 ? ',' : ''} + + + ))} + {remaining > 0 && ( + + {visible.length ? 'and ' : ''} + {remaining.toLocaleString('en-US')} {remaining === 1 ? 'other' : 'others'} + + )} + + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/provider-heading/provider-heading.tsx b/apps/sim/platform/app/(shell)/integrations/_components/provider-heading/provider-heading.tsx index b80d1d8bbed..5686fdee3d2 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/provider-heading/provider-heading.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/provider-heading/provider-heading.tsx @@ -1,6 +1,8 @@ import type { ComponentType, Ref } from 'react' import { IntegrationMark } from '@/platform/app/(shell)/integrations/_components/integration-mark/integration-mark' +import { IntegrationUsage } from '@/platform/app/(shell)/integrations/_components/integration-usage/integration-usage' import styles from '@/platform/app/(shell)/integrations/_components/provider-heading/provider-heading.module.css' +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' interface ProviderHeadingProps { name: string @@ -8,6 +10,8 @@ interface ProviderHeadingProps { providerId?: string icon?: ComponentType<{ className?: string }> titleRef?: Ref + people?: readonly IntegrationPerson[] + peopleTotal?: number } export function ProviderHeading({ @@ -16,6 +20,8 @@ export function ProviderHeading({ providerId, icon, titleRef, + people, + peopleTotal, }: ProviderHeadingProps) { return (
    @@ -27,6 +33,7 @@ export function ProviderHeading({ {name}

    {description}

    + {people && }
    ) diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css index 0e26f24277c..917262ba9cc 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css @@ -8,9 +8,3 @@ gap: var(--ui-list-gap); margin-inline: calc(-1 * var(--ui-row-inset)); } -.people { - display: flex; - align-items: center; - gap: var(--ui-row-gap); - color: var(--ui-secondary); -} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx index 8759ad85db5..5b8e1ce20b9 100644 --- a/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx +++ b/apps/sim/platform/app/(shell)/integrations/_components/resource-list/resource-list.tsx @@ -1,6 +1,7 @@ import { IntegrationMark } from '@/platform/app/(shell)/integrations/_components/integration-mark/integration-mark' +import { IntegrationUsage } from '@/platform/app/(shell)/integrations/_components/integration-usage/integration-usage' import styles from '@/platform/app/(shell)/integrations/_components/resource-list/resource-list.module.css' -import { ActionMenu, ActivityRow, AvatarGroup, Icon } from '@/platform/design-system/components' +import { ActionMenu, ActivityRow, Icon } from '@/platform/design-system/components' import type { AppSummary, IntegrationResource } from '@/platform/lib/integrations/center-model' interface AppGroupProps { @@ -39,14 +40,13 @@ function AppEntry({ app, onNavigate }: AppEntryProps) { leading={} title={app.name} detail={app.description} - metadata={app.status} - showChevron={!app.people?.length} - trailing={ - app.people?.length ? ( - - - {app.people.length} - + metadata={ + app.people?.length || app.peopleTotal ? ( + ) : undefined } /> @@ -87,7 +87,7 @@ export function ResourceGroup({ leading={ } @@ -95,14 +95,13 @@ export function ResourceGroup({ detail={resource.description} showChevron={false} onOpen={() => onOpen(resource)} + metadata={ + resource.scope === 'shared' ? ( + + ) : undefined + } trailing={ <> - {resource.scope === 'shared' && ( - - )} {resource.canEdit && ( void + onSubmit: (draft: CredentialDraft) => void +} + +/** Collects a local connection draft; secret fields never leave this mounted dialog. */ +export function SlackBotConnection({ + workspaces, + initial, + onClose, + onSubmit, +}: SlackBotConnectionProps) { + const [displayName, setDisplayName] = useState(initial?.displayName ?? '') + const [description, setDescription] = useState(initial?.description ?? '') + const [workspaceId, setWorkspaceId] = useState( + initial?.scope.kind === 'workspace' ? initial.scope.id : (workspaces[0]?.id ?? '') + ) + const [capabilities, setCapabilities] = useState(() => + CAPABILITIES.filter(({ defaultChecked }) => defaultChecked).map(({ id }) => id) + ) + const [commands, setCommands] = useState([]) + const [botToken, setBotToken] = useState('') + const [signingSecret, setSigningSecret] = useState('') + const reconnect = Boolean(initial) + const nameError = + !reconnect && displayName && !/^[a-zA-Z0-9 ._-]+$/.test(displayName.trim()) + ? 'Use letters, numbers, spaces, periods, hyphens, or underscores.' + : undefined + const configurationInvalid = + !displayName.trim() || + Boolean(nameError) || + (!initial && !workspaces.some(({ id }) => id === workspaceId)) || + (!reconnect && Boolean(slashCommandsError(commands))) + + function close() { + setBotToken('') + setSigningSecret('') + onClose() + } + + return ( + { + if (!open) close() + }} + title={reconnect ? 'Reconnect Slack bot' : 'Connect Slack bot'} + confirmLabel={reconnect ? 'Reconnect' : 'Connect bot'} + confirmDisabled={configurationInvalid || !botToken.trim() || !signingSecret.trim()} + onConfirm={() => { + setBotToken('') + setSigningSecret('') + onSubmit({ + displayName: displayName.trim(), + description: description.trim(), + workspaceId: initial + ? initial.scope.kind === 'workspace' + ? initial.scope.id + : undefined + : workspaceId, + }) + }} + steps={[ + { + title: reconnect ? 'Reconnect Slack bot' : 'Configure Slack bot', + continueDisabled: configurationInvalid, + content: ( + <> + + + {!initial && ( + ({ value: id, label: name }))} + /> + )} + {!reconnect && ( + <> + ({ value: id, label }))} + searchLabel='Search permissions' + placeholder='No additional permissions' + /> + + + )} + + ), + }, + { + title: reconnect ? 'Open your app in Slack' : 'Set up your app in Slack', + content: ( + <> +
    + + +
    + + {!reconnect && capabilities.length > 0 && ( +
    +

    Selected permissions

    +
      + {CAPABILITIES.filter(({ id }) => capabilities.includes(id)).map( + ({ id, label, description: detail }) => ( +
    • + {label} +

      {detail}

      +
    • + ) + )} +
    +
    + )} + + ), + }, + { + title: 'Install and copy the bot token', + description: reconnect + ? 'Open OAuth & Permissions in your existing Slack app. Reinstall only if Slack requests it, then copy the Bot User OAuth Token.' + : 'In Slack, open OAuth & Permissions, choose Install to Workspace, and approve access. Copy the Bot User OAuth Token.', + continueDisabled: !botToken.trim(), + content: ( + + ), + }, + { + title: 'Copy the signing secret', + description: + 'Open Basic Information in the same Slack app. Under App Credentials, reveal and copy the Signing Secret.', + content: ( + + ), + }, + ]} + /> + ) +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/index.ts b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/index.ts new file mode 100644 index 00000000000..feef053b2b1 --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/index.ts @@ -0,0 +1,5 @@ +export { + type SlackCommandDraft, + SlackSlashCommands, + slashCommandsError, +} from './slack-slash-commands' diff --git a/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.module.css b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.module.css new file mode 100644 index 00000000000..d2c2935bc5e --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.module.css @@ -0,0 +1,15 @@ +.heading { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--ui-row-gap); +} +.commands, +.command { + display: grid; + min-inline-size: 0; + gap: var(--ui-section-gap); +} +.commands:empty { + display: none; +} diff --git a/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.tsx b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.tsx new file mode 100644 index 00000000000..ad64e8053dd --- /dev/null +++ b/apps/sim/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.tsx @@ -0,0 +1,97 @@ +import { generateId } from '@sim/utils/id' +import styles from '@/platform/app/(shell)/integrations/_components/slack-slash-commands/slack-slash-commands.module.css' +import { Button, FieldFrame, IconButton, TextField } from '@/platform/design-system/components' + +export interface SlackCommandDraft { + id: string + command: string + description: string + usageHint: string +} + +export function slashCommandsError(commands: readonly SlackCommandDraft[]): string | undefined { + if (commands.some(({ command, description }) => !command.trim() || !description.trim())) + return 'Every slash command needs a command and description.' + if ( + commands.some( + ({ command }) => + !command.trim().startsWith('/') || command.trim().length === 1 || /\s/.test(command.trim()) + ) + ) + return 'Slash commands must be one word beginning with /.' + const names = commands.map(({ command }) => command.trim()) + if (new Set(names).size !== names.length) return 'Each slash command must be unique.' + return undefined +} + +interface SlackSlashCommandsProps { + commands: readonly SlackCommandDraft[] + onChange: (commands: SlackCommandDraft[]) => void +} + +export function SlackSlashCommands({ commands, onChange }: SlackSlashCommandsProps) { + function update(id: string, field: 'command' | 'description' | 'usageHint', value: string) { + onChange(commands.map((entry) => (entry.id === id ? { ...entry, [field]: value } : entry))) + } + return ( + +
    + +
    +
    + {commands.map((entry, index) => ( +
    +
    + Command {index + 1} + onChange(commands.filter(({ id }) => id !== entry.id))} + /> +
    + update(entry.id, 'command', value)} + placeholder='/ask-sim' + maxLength={32} + required + /> + update(entry.id, 'description', value)} + placeholder='What this command does' + maxLength={2000} + required + /> + update(entry.id, 'usageHint', value)} + placeholder='question or task' + maxLength={1000} + optional + /> +
    + ))} +
    +
    + ) +} diff --git a/apps/sim/platform/checks/conversation.spec.ts b/apps/sim/platform/checks/conversation.spec.ts index 80e8989b3cd..853ad248b4c 100644 --- a/apps/sim/platform/checks/conversation.spec.ts +++ b/apps/sim/platform/checks/conversation.spec.ts @@ -78,15 +78,16 @@ test('Now restores today’s time after scrolling the calendar or viewing anothe await expect(currentTime).toBeInViewport() await schedule.getByText('Customer operations review', { exact: true }).click() await expect(page.getByRole('dialog')).toHaveCount(0) - await page.getByRole('button', { name: 'Show 2 more people' }).hover() - await expect(page.getByRole('tooltip').getByText('Nina Patel')).toBeVisible() - await expect(page.getByRole('tooltip')).toHaveCount(1) - await page.keyboard.press('Escape') + const people = calendar + .getByRole('group', { name: 'People in this meeting', exact: true }) + .first() + await expect(people.getByRole('button')).toHaveCount(0) + const overflow = people.getByLabel('2 others', { exact: true }) + await expect(overflow).toHaveText('+2') + await overflow.click() + await expect(page.getByRole('dialog')).toHaveCount(0) await expect(page.getByRole('tooltip')).toHaveCount(0) - await page - .getByRole('region', { name: 'Calendar', exact: true }) - .getByRole('img', { name: 'Nina Patel', exact: true }) - .hover() + await people.getByRole('img', { name: 'Nina Patel', exact: true }).hover() await expect(page.getByRole('tooltip', { name: 'Nina Patel', exact: true })).toBeVisible() }) diff --git a/apps/sim/platform/checks/desktop/renderer.spec.ts b/apps/sim/platform/checks/desktop/renderer.spec.ts index f3e084a4a8e..9eff9995ce7 100644 --- a/apps/sim/platform/checks/desktop/renderer.spec.ts +++ b/apps/sim/platform/checks/desktop/renderer.spec.ts @@ -27,6 +27,10 @@ test('the actual desktop renderer shares product routes, reserves native chrome const memberPage = page.getByRole('main') await memberPage.getByRole('searchbox', { name: 'Search apps' }).fill('Gmail') await memberPage.getByRole('link', { name: /^Gmail / }).click() + await memberPage + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^emir@sim.ai / }) + .click() const send = memberPage.getByRole('group', { name: 'Gmail Send permission' }) await send.getByRole('radio', { name: 'Ask' }).press('ArrowRight') const blocked = send.getByRole('radio', { name: 'Block' }) diff --git a/apps/sim/platform/checks/integration-center.spec.ts b/apps/sim/platform/checks/integration-center.spec.ts index d5a0e332e65..0c380d07e3e 100644 --- a/apps/sim/platform/checks/integration-center.spec.ts +++ b/apps/sim/platform/checks/integration-center.spec.ts @@ -26,19 +26,19 @@ test('directory filters and ordering survive app details and resource browser hi await page.goto(`${origin}/integrations?state=full`) const main = page.getByRole('main') await main.getByRole('button', { name: /^App category:/ }).click() - await page.getByRole('menuitemradio', { name: 'Communication', exact: true }).click() + await page.getByRole('menuitemradio', { name: 'Email', exact: true }).click() await main.getByRole('button', { name: 'Sort integrations', exact: true }).click() await page.getByRole('menuitemcheckbox', { name: 'Name Z–A', exact: true }).click() await expect( main.getByRole('region', { name: 'Connected', exact: true }).getByRole('link').first() - ).toContainText('Google Calendar') + ).toContainText('Gmail') await main.getByRole('searchbox', { name: 'Search apps', exact: true }).fill('gmail') await main.getByRole('link', { name: /^Gmail / }).click() await main.getByRole('link', { name: 'Integrations', exact: true }).click() await expect(main.getByRole('searchbox', { name: 'Search apps', exact: true })).toHaveValue( 'gmail' ) - await expect(main.getByRole('button', { name: /^App category:/ })).toContainText('Communication') + await expect(main.getByRole('button', { name: /^App category:/ })).toContainText('Email') await expect(page).toHaveURL(/order=desc/) await expect(main.getByRole('link', { name: /^Fireflies / })).toHaveCount(0) @@ -60,6 +60,36 @@ test('directory filters and ordering survive app details and resource browser hi await expect(main.getByRole('button', { name: /^Weekly customer review / })).toHaveCount(0) }) +test('app roster overflow stays passive while avatars explain people and the whole row opens details', async ({ + page, +}) => { + for (const [scenario, count, accessibleCount] of [ + ['full', '+13', '13 others'], + ['stress', '+1k', '1000 others'], + ]) { + await page.goto(`${origin}/integrations?state=${scenario}`) + const gmail = page.getByRole('main').getByRole('link', { name: /^Gmail / }) + const people = gmail.getByRole('group', { name: 'Used by', exact: true }) + await expect(people.getByRole('button')).toHaveCount(0) + const overflow = people.getByLabel(accessibleCount, { exact: true }) + await expect(overflow).toHaveText(count) + const nina = people.getByRole('img', { name: 'Nina Patel', exact: true }) + await expect + .poll(() => + nina + .locator('img') + .evaluate((image: HTMLImageElement) => image.complete && image.naturalWidth > 0) + ) + .toBe(true) + await nina.hover() + await expect(page.getByRole('tooltip', { name: 'Nina Patel', exact: true })).toBeVisible() + await overflow.click() + await expect(page).toHaveURL(/\/integrations\/gmail/) + await expect(page.getByRole('heading', { name: 'Gmail', exact: true })).toBeVisible() + await expect(page.getByRole('dialog')).toHaveCount(0) + } +}) + test('editing a shared skill preserves its members and survives leaving the directory', async ({ page, }) => { diff --git a/apps/sim/platform/checks/integrations.spec.ts b/apps/sim/platform/checks/integrations.spec.ts index e1fa1be9d97..cd2e8aeaf43 100644 --- a/apps/sim/platform/checks/integrations.spec.ts +++ b/apps/sim/platform/checks/integrations.spec.ts @@ -2,46 +2,448 @@ import { expect, test } from '@playwright/test' const origin = process.env.PLATFORM_E2E_ORIGIN ?? 'http://127.0.0.1:3181' -test('an approved app can connect and disconnect a sample account during the same session', async ({ +test('workspace catalog discovery opens real capabilities and preserves installed skills through navigation', async ({ + page, + context, +}) => { + await context.grantPermissions(['clipboard-read', 'clipboard-write']) + await page.goto(`${origin}/integrations?state=full`) + const main = page.getByRole('main') + await main.getByRole('searchbox', { name: 'Search apps', exact: true }).fill('1Password') + await main.getByRole('button', { name: /^App category:/ }).click() + await page.getByRole('menuitemradio', { name: 'Security', exact: true }).click() + await main.getByRole('link', { name: /^1Password / }).click() + await expect(main.getByRole('link', { name: 'Docs', exact: true })).toHaveAttribute( + 'href', + 'https://docs.sim.ai/integrations/onepassword' + ) + await expect( + main + .getByRole('region', { name: 'Actions', exact: true }) + .getByText('List Vaults', { exact: true }) + ).toBeVisible() + const suggested = main.getByRole('region', { name: 'Suggested skills', exact: true }) + await suggested.getByRole('button', { name: /^fetch-secret-for-runtime / }).click() + const skill = page.getByRole('dialog', { name: 'fetch-secret-for-runtime', exact: true }) + const instructions = await skill + .getByRole('textbox', { name: 'Instructions', exact: true }) + .inputValue() + expect(instructions.length).toBeGreaterThan(0) + await skill.getByRole('button', { name: 'Add to Skills', exact: true }).click() + await expect(skill).toHaveCount(0) + await suggested.getByRole('button', { name: /^fetch-secret-for-runtime / }).click() + await expect(skill.getByRole('button', { name: 'Added to Skills', exact: true })).toBeDisabled() + await skill.getByRole('button', { name: 'Cancel', exact: true }).click() + await main + .getByRole('region', { name: 'Templates', exact: true }) + .getByRole('button', { name: /^1Password vault audit / }) + .click() + const template = page.getByRole('dialog', { name: '1Password vault audit', exact: true }) + const prompt = await template.getByRole('textbox', { name: 'Prompt', exact: true }).inputValue() + await template.getByRole('button', { name: 'Copy prompt', exact: true }).click() + await expect.poll(() => page.evaluate(() => navigator.clipboard.readText())).toBe(prompt) + await template.getByRole('button', { name: 'Close', exact: true }).click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await expect(main.getByRole('searchbox', { name: 'Search apps', exact: true })).toHaveValue( + '1Password' + ) + await expect(main.getByRole('button', { name: /^App category:/ })).toContainText('Security') + await main + .getByRole('navigation', { name: 'Integration categories' }) + .getByRole('link', { name: 'Skills', exact: true }) + .click() + await main.getByRole('button', { name: /^fetch-secret-for-runtime / }).click() + await expect( + page + .getByRole('dialog', { name: 'Edit skill', exact: true }) + .getByRole('textbox', { name: 'Instructions', exact: true }) + ).toHaveValue(instructions) +}) + +test('adding another credential preserves existing accounts and its details survive immediate browser back', async ({ page, }) => { await page.goto(`${origin}/integrations?state=full`) const list = page.getByRole('main') - await list.getByRole('searchbox', { name: 'Search apps' }).fill('Linear issues') - await list.getByRole('link', { name: /^Linear / }).click() - const guide = list.getByRole('link', { name: 'Docs (opens in a new tab)', exact: true }) - await expect(guide).toHaveAttribute('href', 'https://docs.sim.ai/search/linear') + await list.getByRole('searchbox', { name: 'Search apps' }).fill('gmail') + await list.getByRole('link', { name: /^Gmail / }).click() + const guide = list.getByRole('link', { name: 'Docs', exact: true }) + await expect(guide).toHaveAttribute('href', 'https://docs.sim.ai/search/gmail') await expect(guide).toHaveAttribute('target', '_blank') - await list.getByRole('button', { name: 'Linear', exact: true }).click() - const title = list.getByRole('heading', { name: 'Linear', exact: true }) - await expect(title).toBeFocused() - await expect(page.getByRole('dialog')).toHaveCount(0) - await expect(list.getByRole('button', { name: 'Add account' })).toHaveCount(0) - const credential = list.getByRole('region', { name: 'Connected credential' }) - await expect(credential.getByText('emir@sim.ai', { exact: true })).toBeVisible() + const credentials = list.getByRole('region', { name: 'Connected credentials', exact: true }) + const original = credentials.getByRole('button', { name: /^emir@sim.ai / }) + await expect(original).toBeVisible() + await list.getByRole('button', { name: 'Add credential', exact: true }).click() + await page.getByRole('menuitem', { name: 'Connect with OAuth', exact: true }).click() + const connect = page.getByRole('dialog', { name: 'Connect Gmail', exact: true }) + await connect.getByRole('textbox', { name: 'Display name', exact: true }).fill('Secondary Gmail') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await expect(original).toBeVisible() + await credentials.getByRole('button', { name: /^Secondary Gmail / }).click() + await expect(list.getByRole('heading', { name: 'Secondary Gmail', exact: true })).toBeVisible() + await page.goBack() + await expect(credentials).toBeVisible() + await credentials.getByRole('button', { name: /^Secondary Gmail / }).click() + await list.getByRole('button', { name: 'Edit', exact: true }).click() + const edit = page.getByRole('dialog', { name: 'Edit credential', exact: true }) + await edit + .getByRole('textbox', { name: 'Display name', exact: true }) + .fill('Gmail account review') + await edit.getByRole('button', { name: 'Save', exact: true }).click() await list.getByRole('link', { name: 'Integrations', exact: true }).click() - await expect(list.getByRole('searchbox')).toHaveValue('Linear issues') - await list.getByRole('link', { name: /^Linear / }).click() - await credential.getByRole('button', { name: 'Manage emir@sim.ai' }).click() - await page.getByRole('menuitem', { name: 'Disconnect account' }).click() + await expect(list.getByRole('searchbox')).toHaveValue('gmail') + await list.getByRole('link', { name: /^Gmail / }).click() + await credentials + .getByRole('button', { name: 'Manage Gmail account review', exact: true }) + .click() + await page.getByRole('menuitem', { name: 'Disconnect', exact: true }).click() await page - .getByRole('dialog', { name: 'Disconnect account?' }) + .getByRole('dialog', { name: 'Disconnect Gmail account review?', exact: true }) .getByRole('button', { name: 'Disconnect', exact: true }) .click() - await expect(title).toBeFocused() - await list.getByRole('link', { name: 'Integrations', exact: true }).click() + await expect(credentials.getByRole('button', { name: /^Gmail account review / })).toHaveCount(0) + await expect(original).toBeVisible() +}) + +test('shared family credential edits and access changes propagate without removing the last explicit admin', async ({ + page, +}) => { + await page.goto(`${origin}/integrations?state=full`) + const main = page.getByRole('main') + await main.getByRole('link', { name: /^Google Sheets / }).click() + await expect( + main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^Customer operations service account / }) + ).toBeVisible() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await main.getByRole('link', { name: /^Gmail / }).click() + await expect( + main.getByRole('region', { name: 'Connected credentials', exact: true }) + ).toBeVisible() + await main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^Customer operations service account / }) + .click() + const people = main.getByRole('region', { name: 'People with access', exact: true }) + await people.getByRole('button', { name: 'Manage access for Nina Patel', exact: true }).click() + await expect(page.getByRole('menuitem', { name: 'Remove', exact: true })).toBeDisabled() + await page.keyboard.press('Escape') + await people.getByRole('button', { name: 'Manage access for Emir Karabeg', exact: true }).click() + await expect(page.getByRole('menuitem', { name: 'Leave', exact: true })).toBeDisabled() + await page.keyboard.press('Escape') + await people.getByRole('button', { name: 'Add people', exact: true }).click() + const add = page.getByRole('dialog', { name: 'Add people', exact: true }) + await add.getByRole('combobox', { name: 'Person', exact: true }).click() + await page.getByRole('option', { name: 'Maya Thompson', exact: true }).click() + await add.getByRole('button', { name: 'Add', exact: true }).click() + await expect(people.getByText('Maya Thompson', { exact: true })).toBeVisible() + await people.getByRole('button', { name: /^Role for Alex Chen:/ }).click() + await page.getByRole('menuitemradio', { name: 'Admin', exact: true }).click() + await people.getByRole('button', { name: 'Manage access for Nina Patel', exact: true }).click() + await page.getByRole('menuitem', { name: 'Remove', exact: true }).click() + await page + .getByRole('dialog', { name: 'Remove Nina Patel?', exact: true }) + .getByRole('button', { name: 'Remove', exact: true }) + .click() + await expect(people.getByText('Nina Patel', { exact: true })).toHaveCount(0) + await main.getByRole('button', { name: 'Edit', exact: true }).click() + const edit = page.getByRole('dialog', { name: 'Edit credential', exact: true }) + await edit + .getByRole('textbox', { name: 'Display name', exact: true }) + .fill('Shared Google operations') + await edit.getByRole('button', { name: 'Save', exact: true }).click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + const tabs = main.getByRole('navigation', { name: 'Integration categories' }) + await tabs.getByRole('link', { name: 'Credentials', exact: true }).click() + const sharedCredential = main.getByRole('link', { name: /^Shared Google operations / }) + await expect(sharedCredential).toHaveCount(1) + await sharedCredential.click() + await expect( + main.getByRole('heading', { name: 'Shared Google operations', exact: true }) + ).toBeVisible() + await page.goBack() + await expect( + main.getByRole('searchbox', { name: 'Search credentials', exact: true }) + ).toBeVisible() + await tabs.getByRole('link', { name: 'Apps', exact: true }).click() + await main.getByRole('link', { name: /^Google Drive / }).click() + await main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^Shared Google operations / }) + .click() + await expect(people.getByText('Maya Thompson', { exact: true })).toBeVisible() + await expect(people.getByText('Nina Patel', { exact: true })).toHaveCount(0) + await people.getByRole('button', { name: 'Manage access for Alex Chen', exact: true }).click() + await expect(page.getByRole('menuitem', { name: 'Remove', exact: true })).toBeDisabled() +}) + +test('service-account branches validate active fields and discard secrets after reconnecting', async ({ + page, +}) => { + const writes: string[] = [] + page.on('request', (request) => { + if (!['GET', 'HEAD', 'OPTIONS'].includes(request.method())) writes.push(request.url()) + }) + await page.goto(`${origin}/integrations/salesforce?state=full`) + const main = page.getByRole('main') + await expect(main.getByRole('button', { name: 'Add credential', exact: true })).toBeVisible() + await main.getByRole('button', { name: 'Add credential', exact: true }).click() + await page.getByRole('menuitem', { name: 'Add integration user app', exact: true }).click() + const connect = page.getByRole('dialog', { name: 'Connect Salesforce', exact: true }) + await connect + .getByRole('textbox', { name: 'Display name', exact: true }) + .fill('Salesforce reporting') + await connect.getByRole('textbox', { name: 'Consumer key', exact: true }).fill('test-consumer') + await connect + .getByRole('textbox', { name: 'My Domain host', exact: true }) + .fill('test.my.salesforce.com') + await expect(connect.getByRole('button', { name: 'Connect', exact: true })).toBeDisabled() + await connect.getByRole('combobox', { name: 'Authentication method', exact: true }).click() + await page.getByRole('option', { name: 'JWT bearer (private key)', exact: true }).click() + await expect(connect.getByLabel('Consumer secret', { exact: true })).toHaveCount(0) + await connect + .getByRole('textbox', { name: 'Private key', exact: true }) + .fill('not-a-real-private-key') + await expect(connect.getByRole('button', { name: 'Connect', exact: true })).toBeDisabled() + await connect + .getByRole('textbox', { name: 'Run as username', exact: true }) + .fill('reporting@example.com') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await main.getByRole('button', { name: 'Manage Salesforce reporting', exact: true }).click() + await page.getByRole('menuitem', { name: 'Reconnect', exact: true }).click() + const reconnect = page.getByRole('dialog', { + name: 'Reconnect Salesforce reporting', + exact: true, + }) + await reconnect.getByRole('combobox', { name: 'Authentication method', exact: true }).click() + await page.getByRole('option', { name: 'JWT bearer (private key)', exact: true }).click() + await expect(reconnect.getByRole('textbox', { name: 'Private key', exact: true })).toHaveValue('') + await expect(reconnect.getByRole('button', { name: 'Reconnect', exact: true })).toBeDisabled() + await reconnect.getByRole('button', { name: 'Cancel', exact: true }).click() + const storage = await page.evaluate(() => JSON.stringify({ ...localStorage, ...sessionStorage })) + expect(storage).not.toContain('not-a-real-private-key') + expect(writes).toEqual([]) +}) + +test('a Google JSON credential is validated before joining every app in its family and never prefills a key', async ({ + page, +}) => { + await page.goto(`${origin}/integrations/gmail?state=full`) + const main = page.getByRole('main') + await main.getByRole('button', { name: 'Add credential', exact: true }).click() + await page.getByRole('menuitem', { name: 'Add service account', exact: true }).click() + const connect = page.getByRole('dialog', { name: 'Connect Gmail', exact: true }) + await connect + .getByRole('textbox', { name: 'JSON key', exact: true }) + .fill('{"type":"service_account"}') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await expect(connect.getByRole('alert')).toContainText( + 'service account email, private key, and project ID' + ) + await connect.getByLabel('Or upload a JSON key', { exact: true }).setInputFiles({ + name: 'service-account.json', + mimeType: 'application/json', + buffer: Buffer.from( + JSON.stringify({ + type: 'service_account', + client_email: 'test@example.iam.gserviceaccount.com', + private_key: 'fixture-private-key', + project_id: 'fixture-project', + }) + ), + }) + await connect + .getByRole('textbox', { name: 'Display name', exact: true }) + .fill('Google reporting key') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await main.getByRole('link', { name: /^Google Drive / }).click() + const credentials = main.getByRole('region', { name: 'Connected credentials', exact: true }) + await expect(credentials.getByRole('button', { name: /^Google reporting key / })).toBeVisible() + await credentials + .getByRole('button', { name: 'Manage Google reporting key', exact: true }) + .click() + await page.getByRole('menuitem', { name: 'Reconnect', exact: true }).click() + const reconnect = page.getByRole('dialog', { + name: 'Reconnect Google reporting key', + exact: true, + }) + await expect(reconnect.getByRole('textbox', { name: 'JSON key', exact: true })).toHaveValue('') + await expect(reconnect.getByRole('button', { name: 'Reconnect', exact: true })).toBeDisabled() + await reconnect.getByRole('button', { name: 'Cancel', exact: true }).click() + await credentials + .getByRole('button', { name: 'Manage Google reporting key', exact: true }) + .click() + await page.getByRole('menuitem', { name: 'Disconnect', exact: true }).click() + await page + .getByRole('dialog', { name: 'Disconnect Google reporting key?', exact: true }) + .getByRole('button', { name: 'Disconnect', exact: true }) + .click() + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await main.getByRole('link', { name: /^Gmail / }).click() + await expect(credentials.getByRole('button', { name: /^Google reporting key / })).toHaveCount(0) + await expect(credentials.getByRole('button', { name: /^emir@sim.ai / })).toBeVisible() +}) + +test('Slack bot steps preserve configuration when going back and clear secrets on a new connection', async ({ + page, +}) => { + await page.goto(`${origin}/integrations/slack?state=full`) + const main = page.getByRole('main') + await main.getByRole('button', { name: 'Add credential', exact: true }).click() + await page.getByRole('menuitem', { name: 'Set up a custom bot', exact: true }).click() + const modal = page.getByRole('dialog') + await expect( + modal.getByRole('heading', { name: 'Configure Slack bot', exact: true }) + ).toBeVisible() + await modal.getByRole('textbox', { name: 'Bot name', exact: true }).fill('Review Bot') + await modal.getByRole('combobox', { name: /^Additional permissions:/ }).click() + await expect(page.getByRole('option', { name: '@mention', exact: true })).toHaveAttribute( + 'aria-selected', + 'true' + ) + await page.getByRole('option', { name: 'Direct message', exact: true }).click() + await page.keyboard.press('Escape') + await modal.getByRole('button', { name: 'Add command', exact: true }).click() + await modal.getByRole('textbox', { name: 'Slash command 1', exact: true }).fill('/review') + await modal + .getByRole('textbox', { name: 'Command 1 description', exact: true }) + .fill('Review an account') + await modal.getByRole('button', { name: 'Add command', exact: true }).click() + await modal.getByRole('textbox', { name: 'Slash command 2', exact: true }).fill('/review') + await modal + .getByRole('textbox', { name: 'Command 2 description', exact: true }) + .fill('Duplicate command') + await expect(modal.getByRole('button', { name: 'Continue', exact: true })).toBeDisabled() + await modal.getByRole('button', { name: 'Remove slash command 2', exact: true }).click() + await modal.getByRole('button', { name: 'Continue', exact: true }).click() + const selected = modal.getByRole('region', { name: 'Selected permissions', exact: true }) + await expect(selected.getByText('@mention', { exact: true })).toBeVisible() + await expect(selected.getByText('Direct message', { exact: true })).toHaveCount(0) + await modal.getByRole('button', { name: 'Back', exact: true }).click() + await expect(modal.getByRole('textbox', { name: 'Slash command 1', exact: true })).toHaveValue( + '/review' + ) + await modal.getByRole('button', { name: 'Continue', exact: true }).click() + await modal.getByRole('button', { name: 'Continue', exact: true }).click() + await expect(modal.getByRole('button', { name: 'Continue', exact: true })).toBeDisabled() + await modal.getByLabel('Bot token', { exact: true }).fill('xoxb-fixture-token') + await modal.getByRole('button', { name: 'Continue', exact: true }).click() + await modal.getByRole('button', { name: 'Back', exact: true }).click() + await expect(modal.getByLabel('Bot token', { exact: true })).toHaveValue('xoxb-fixture-token') + await modal.getByRole('button', { name: 'Continue', exact: true }).click() + await modal.getByLabel('Signing secret', { exact: true }).fill('fixture-signing-secret') + await modal.getByRole('button', { name: 'Connect bot', exact: true }).click() + await main.getByRole('button', { name: 'Manage Review Bot', exact: true }).click() + await page.getByRole('menuitem', { name: 'Reconnect', exact: true }).click() + const reconnect = page.getByRole('dialog') await expect( - list.getByRole('region', { name: 'Explore apps' }).getByRole('link', { name: /^Linear / }) + reconnect.getByRole('heading', { name: 'Reconnect Slack bot', exact: true }) ).toBeVisible() + await expect(reconnect.getByRole('textbox', { name: 'Bot name', exact: true })).toHaveValue( + 'Review Bot' + ) + await expect(reconnect.getByRole('button', { name: 'Add command', exact: true })).toHaveCount(0) + await reconnect.getByRole('button', { name: 'Continue', exact: true }).click() + await reconnect.getByRole('button', { name: 'Continue', exact: true }).click() + await expect(reconnect.getByLabel('Bot token', { exact: true })).toHaveValue('') + await expect(reconnect.getByRole('button', { name: 'Continue', exact: true })).toBeDisabled() + const storage = await page.evaluate(() => JSON.stringify({ ...localStorage, ...sessionStorage })) + expect(storage).not.toContain('xoxb-fixture-token') + expect(storage).not.toContain('fixture-signing-secret') +}) + +test('Dataverse retains an immutable environment binding when reconnecting a named credential', async ({ + page, +}) => { + await page.goto(`${origin}/integrations/microsoft_dataverse?state=full`) + const main = page.getByRole('main') + await main.getByRole('button', { name: 'Add credential', exact: true }).click() + const connect = page.getByRole('dialog', { name: 'Connect Microsoft Dataverse', exact: true }) + await connect + .getByRole('textbox', { name: 'Display name', exact: true }) + .fill('Sales environment') + await connect + .getByRole('textbox', { name: 'Environment URL', exact: true }) + .fill('https://sales.crm.dynamics.com/path') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await expect(connect.getByRole('alert')).toContainText('without a path') + await connect + .getByRole('textbox', { name: 'Environment URL', exact: true }) + .fill('https://sales.crm.dynamics.com/') + await connect.getByRole('button', { name: 'Connect', exact: true }).click() + await main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^Sales environment / }) + .click() + await expect(main.getByRole('textbox', { name: 'Environment URL', exact: true })).toHaveValue( + 'https://sales.crm.dynamics.com' + ) + await main.getByRole('button', { name: 'Credential actions', exact: true }).click() + await page.getByRole('menuitem', { name: 'Reconnect', exact: true }).click() + const reconnect = page.getByRole('dialog', { name: 'Reconnect Sales environment', exact: true }) + const environment = reconnect.getByRole('textbox', { name: 'Environment URL', exact: true }) + await expect(environment).toHaveValue('https://sales.crm.dynamics.com') + await expect(environment).toHaveAttribute('readonly', '') + await reconnect.getByRole('button', { name: 'Reconnect', exact: true }).click() + await expect(main.getByRole('textbox', { name: 'Environment URL', exact: true })).toHaveValue( + 'https://sales.crm.dynamics.com' + ) +}) + +test('member credentials withhold administration and personal tokens never offer sharing', async ({ + page, +}) => { + await page.goto(`${origin}/integrations/github?state=stress`) + const main = page.getByRole('main') + await expect( + main.getByRole('button', { name: 'Manage Engineering repositories', exact: true }) + ).toHaveCount(0) + await main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^Engineering repositories / }) + .click() + await expect(main.getByRole('button', { name: 'Edit', exact: true })).toHaveCount(0) + await expect(main.getByRole('button', { name: 'Credential actions', exact: true })).toHaveCount(0) + await expect(main.getByRole('button', { name: 'Add people', exact: true })).toHaveCount(0) + await main.getByRole('button', { name: 'Manage access for Emir Karabeg', exact: true }).click() + await page.getByRole('menuitem', { name: 'Leave', exact: true }).click() + await page + .getByRole('dialog', { name: 'Leave credential?', exact: true }) + .getByRole('button', { name: 'Leave', exact: true }) + .click() + await expect(main.getByRole('button', { name: /^Engineering repositories / })).toHaveCount(0) + await main.getByRole('link', { name: 'Integrations', exact: true }).click() + await main.getByRole('link', { name: /^GitLab / }).click() + await main + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^My GitLab account / }) + .click() + await expect(main.getByRole('region', { name: 'People with access', exact: true })).toHaveCount(0) + await main.getByRole('button', { name: 'Credential actions', exact: true }).click() + await page.getByRole('menuitem', { name: 'Reconnect', exact: true }).click() + const reconnect = page.getByRole('dialog', { name: 'Reconnect My GitLab account', exact: true }) + await expect(reconnect.getByRole('combobox', { name: 'Workspace', exact: true })).toHaveCount(0) + await expect(reconnect.getByLabel('Personal access token', { exact: true })).toHaveValue('') + await expect(reconnect.getByRole('button', { name: 'Reconnect', exact: true })).toBeDisabled() }) test('individual permissions inherit their default without changing other tools', async ({ page, }) => { await page.goto(`${origin}/integrations/gmail?state=full`) - const access = page.getByRole('region', { name: 'Requested permissions' }) + await page.getByRole('main').getByRole('button', { name: 'Add credential', exact: true }).click() + await page.getByRole('menuitem', { name: 'Connect with OAuth', exact: true }).click() + const connect = page.getByRole('dialog', { name: 'Connect Gmail', exact: true }) + const access = connect.getByRole('region', { name: 'Requested permissions' }) const writeScopes = access.getByRole('list', { name: 'Write and manage' }) await expect(writeScopes.getByText('Send emails', { exact: true })).toBeVisible() + await connect.getByRole('button', { name: 'Cancel', exact: true }).click() + await page + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^emir@sim.ai / }) + .click() const tools = page.getByRole('region', { name: 'Tool permissions' }) const send = tools.getByRole('group', { name: 'Gmail Send permission' }) const draft = tools.getByRole('group', { name: 'Gmail Draft permission' }) @@ -49,6 +451,10 @@ test('individual permissions inherit their default without changing other tools' await expect(draft.getByRole('radio', { name: 'Ask' })).toBeChecked() await page.getByRole('main').getByRole('link', { name: 'Integrations', exact: true }).click() await page.getByRole('link', { name: /^Gmail / }).click() + await page + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^emir@sim.ai / }) + .click() await expect(send.getByRole('radio', { name: 'Block' })).toBeChecked() await send.getByRole('radio', { name: 'Ask' }).check() await expect(send).toHaveAccessibleDescription('Inherits Ask from write tools.') @@ -59,6 +465,10 @@ test('individual permissions inherit their default without changing other tools' await query.fill('unknown-tool') await expect(tools.getByText('No matching tools', { exact: true })).toBeVisible() await page.goto(`${origin}/integrations/gmail?state=stress`) + await page + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^emir@sim.ai / }) + .click() await expect(send.getByRole('radio', { name: 'Allow' })).toBeDisabled() }) @@ -91,18 +501,20 @@ test('managed, unconfigured and retained connections expose only the actions the const fireflies = main.getByRole('link', { name: /^Fireflies / }) await expect(fireflies).toContainText('meeting transcripts and recordings') await fireflies.click() - await expect(main.getByRole('region', { name: 'Connected credential' })).toContainText( + await expect(main.getByRole('region', { name: 'Connected credentials' })).toContainText( 'Fireflies' ) + await main.getByRole('button', { name: 'Manage Fireflies', exact: true }).click() + await expect(page.getByRole('menuitem', { name: 'Reconnect', exact: true })).toHaveCount(0) + await page.keyboard.press('Escape') const reads = main .getByRole('region', { name: 'Search access' }) .getByRole('list', { name: 'Read-only tools' }) await expect(reads).toContainText('Read available meeting summaries') await expect(main.getByRole('radio')).toHaveCount(0) await main.getByRole('link', { name: 'Integrations', exact: true }).click() - const managed = main.getByRole('region', { name: 'Explore apps' }) for (const provider of ['GitLab', 'Slack', 'Granola', 'Zoom']) { - await managed.getByRole('link', { name: new RegExp(`^${provider} `) }).click() + await main.getByRole('link', { name: new RegExp(`^${provider} `) }).click() const docs = main.getByRole('link', { name: /Docs/ }) await expect(docs).toHaveAttribute( 'href', @@ -113,8 +525,8 @@ test('managed, unconfigured and retained connections expose only the actions the } await main.getByRole('link', { name: /^Confluence / }).click() await main.getByRole('button', { name: 'Manage engineering@sim.ai' }).click() - await expect(page.getByRole('menuitem', { name: 'Disconnect account' })).toBeVisible() - await expect(page.getByRole('menuitem', { name: 'Reconnect account' })).toHaveCount(0) + await expect(page.getByRole('menuitem', { name: 'Disconnect', exact: true })).toBeVisible() + await expect(page.getByRole('menuitem', { name: 'Reconnect', exact: true })).toHaveCount(0) }) test('a single click opens a member credential at 200 percent text size', async ({ page }) => { @@ -124,6 +536,10 @@ test('a single click opens a member credential at 200 percent text size', async document.documentElement.style.fontSize = '200%' }) await page.getByRole('link', { name: /^Gmail / }).click() + await page + .getByRole('region', { name: 'Connected credentials', exact: true }) + .getByRole('button', { name: /^emir@sim.ai / }) + .click() const tools = page.getByRole('region', { name: 'Tool permissions' }) const choices = tools.getByRole('group', { name: 'Gmail Send permission' }) await expect(choices).toBeVisible() diff --git a/apps/sim/platform/design-system/catalog/evidence.json b/apps/sim/platform/design-system/catalog/evidence.json index ef9b4ea2520..bde10581c65 100644 --- a/apps/sim/platform/design-system/catalog/evidence.json +++ b/apps/sim/platform/design-system/catalog/evidence.json @@ -247,7 +247,7 @@ "family": "AvatarGroup/Overflow/rest — tooltip on hover or focus", "theme": "D", "scope": "platform", - "owner": "AvatarOverflow", + "owner": "Stack", "icon": "I108", "base": ["01M6ASMG4R446K2Z96JZRXZFX7", "p-2-0", "SP-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-17-0", "2Y4E-0"] @@ -257,7 +257,7 @@ "family": "AvatarGroup/Overflow/rest — tooltip on hover or focus", "theme": "L", "scope": "platform", - "owner": "AvatarOverflow", + "owner": "Stack", "icon": "I108", "base": ["01M6ASMDKJ81HACJGPNYCJQVVT", "p-2-0", "X5-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-L-0", "YEZ-0"] @@ -267,7 +267,7 @@ "family": "AvatarGroup/Overflow/rest — tooltip on hover or focus", "theme": "L", "scope": "platform", - "owner": "AvatarOverflow", + "owner": "Stack", "icon": "I108", "base": ["01M6ASMDKJ81HACJGPNYCJQVVT", "p-2-0", "SP-0"], "use": ["01M6A91A32GBA6GTN4HASVG0ER", "p-L-0", "XVQ-0"] diff --git a/apps/sim/platform/design-system/catalog/icon-geometry.tsx b/apps/sim/platform/design-system/catalog/icon-geometry.tsx index 7d8d14b79fd..d42064cb7f6 100644 --- a/apps/sim/platform/design-system/catalog/icon-geometry.tsx +++ b/apps/sim/platform/design-system/catalog/icon-geometry.tsx @@ -888,7 +888,10 @@ export const glyphs = { label: 'key', viewBox: '0 0 24 24', draw: (): ReactNode => ( - + <> + + + ), }, I138: { diff --git a/apps/sim/platform/design-system/components/activity-row/activity-row.tsx b/apps/sim/platform/design-system/components/activity-row/activity-row.tsx index 580acf6ee14..912d2780c1b 100644 --- a/apps/sim/platform/design-system/components/activity-row/activity-row.tsx +++ b/apps/sim/platform/design-system/components/activity-row/activity-row.tsx @@ -13,7 +13,7 @@ interface ActivityRowProps { count?: number detail: string detailLead?: string - metadata?: string + metadata?: ReactNode showChevron?: boolean trailing?: ReactNode } @@ -52,7 +52,11 @@ export function ActivityRow({ {(metadata || showChevron) && ( - {metadata && {metadata}} + {typeof metadata === 'string' ? ( + {metadata} + ) : ( + metadata + )} {showChevron && } )} diff --git a/apps/sim/platform/design-system/components/avatar/avatar.module.css b/apps/sim/platform/design-system/components/avatar/avatar.module.css index 18c02db66b3..0eb712df701 100644 --- a/apps/sim/platform/design-system/components/avatar/avatar.module.css +++ b/apps/sim/platform/design-system/components/avatar/avatar.module.css @@ -44,19 +44,6 @@ object-fit: cover; } -.avatarGroup { - display: inline-flex; - align-items: center; -} - -.avatarGroup > :nth-child(2) { - margin-inline-start: calc(-1 * var(--spacing-4)); -} - -.avatarGroup > :nth-child(3) { - margin-inline-start: var(--spacing-4); -} - .peoplePopover { display: flex; flex-direction: column; diff --git a/apps/sim/platform/design-system/components/avatar/avatar.tsx b/apps/sim/platform/design-system/components/avatar/avatar.tsx index 8b064f7e938..0c45cf57d99 100644 --- a/apps/sim/platform/design-system/components/avatar/avatar.tsx +++ b/apps/sim/platform/design-system/components/avatar/avatar.tsx @@ -1,9 +1,8 @@ 'use client' import styles from '@/platform/design-system/components/avatar/avatar.module.css' -import { IconButton } from '@/platform/design-system/components/button/button' import { useScrollEdges } from '@/platform/design-system/components/scroll-area/use-scroll-edges' -import { Tooltip } from '@/platform/design-system/components/tooltip/tooltip' +import { Stack } from '@/platform/design-system/components/stack/stack' interface AvatarImageProps { src: string @@ -81,39 +80,22 @@ export function PeoplePopover({ title, people }: PeoplePopoverProps) { ) } -interface AvatarOverflowProps { - people: readonly Person[] - label?: string - visibleCount?: number -} - -export function AvatarOverflow({ - people, - label = 'People', - visibleCount = 0, -}: AvatarOverflowProps) { - if (people.length <= visibleCount) return null - return ( - }> - - - ) -} - interface AvatarGroupProps { people: readonly Person[] + total?: number label?: string } -export function AvatarGroup({ people, label }: AvatarGroupProps) { +export function AvatarGroup({ people, total, label }: AvatarGroupProps) { return ( - - {people.slice(0, 2).map((person, index) => ( - - - - ))} - - + ({ + id: `${person.name}-${index}`, + label: person.name, + content: , + }))} + total={total} + label={label} + /> ) } diff --git a/apps/sim/platform/design-system/components/icon/provider-mark-ids.generated.ts b/apps/sim/platform/design-system/components/icon/provider-mark-ids.generated.ts new file mode 100644 index 00000000000..092b9e0af1e --- /dev/null +++ b/apps/sim/platform/design-system/components/icon/provider-mark-ids.generated.ts @@ -0,0 +1,278 @@ +/** Generated by scripts/sync-platform-integration-metadata.ts. */ +export const providerMarkIds = [ + 'onepassword', + 'affinity', + 'agentmail', + 'agentphone', + 'agiloft', + 'ahrefs', + 'airtable', + 'algolia', + 'dynamodb', + 'ec2', + 'rds', + 'sqs', + 'amplitude', + 'apify', + 'apollo', + 'arxiv', + 'asana', + 'ashby', + 'athena', + 'attio', + 'appconfig', + 'iam', + 'identity_center', + 'secrets_manager', + 'ses', + 'sts', + 'ssm', + 'textract', + 'microsoft_ad', + 'azure_data_explorer', + 'azure_devops', + 'bitbucket', + 'box', + 'brandfetch', + 'brex', + 'brightdata', + 'browser_use', + 'buffer', + 'calcom', + 'calendly', + 'cbinsights', + 'checkr', + 'circleback', + 'managed_agent', + 'clay', + 'clerk', + 'clickhouse', + 'clickup', + 'cloudflare', + 'cloudformation', + 'cloudtrail', + 'cloudwatch', + 'coda', + 'codepipeline', + 'confluence', + 'context_dev', + 'convex', + 'crowdstrike', + 'crunchbase', + 'cursor', + 'dagster', + 'databricks', + 'datadog', + 'datagma', + 'daytona', + 'devin', + 'discord', + 'docusign', + 'downdetector', + 'dropbox', + 'dropcontact', + 'dspy', + 'dub', + 'duckduckgo', + 'dynatrace', + 'elasticsearch', + 'elevenlabs', + 'emailbison', + 'embeddings', + 'enrich', + 'enrow', + 'exa', + 'extend', + 'fathom', + 'findymail', + 'firecrawl', + 'fireflies', + 'fivetran', + 'flint', + 'gamma', + 'github', + 'gitlab', + 'gmail', + 'gong', + 'google_ads', + 'google_appsheet', + 'google_bigquery', + 'google_books', + 'google_calendar', + 'google_contacts', + 'google_docs', + 'google_drive', + 'google_forms', + 'google_groups', + 'google_maps', + 'google_meet', + 'google_pagespeed', + 'google_search', + 'google_sheets', + 'google_slides', + 'google_tasks', + 'google_translate', + 'google_vault', + 'grafana', + 'grain', + 'granola', + 'greenhouse', + 'greptile', + 'harmonic', + 'helpscout', + 'hex', + 'hubspot', + 'huggingface', + 'hunter', + 'icypeas', + 'incidentio', + 'infisical', + 'instantly', + 'intercom', + 'jina', + 'jira', + 'jira_service_management', + 'jotform', + 'jupyter', + 'kalshi', + 'ketch', + 'lambda', + 'langsmith', + 'latex', + 'launchdarkly', + 'leadmagic', + 'lemlist', + 'linear', + 'linkedin', + 'linkup', + 'linq', + 'logfire', + 'logrocket', + 'loops', + 'luma', + 'mailchimp', + 'mailgun', + 'manageengine_sdp', + 'mem0', + 'microsoft_dataverse', + 'microsoft_dynamics_365', + 'microsoft_excel', + 'intune', + 'microsoft_planner', + 'mssql', + 'microsoft_teams', + 'microsoft_word', + 'millionverifier', + 'mintlify', + 'mistral_parse', + 'modal', + 'monday', + 'mongodb', + 'mysql', + 'neo4j', + 'neverbounce', + 'new_relic', + 'notion', + 'obsidian', + 'okta', + 'onedrive', + 'oracledb', + 'oracle_fusion_financials', + 'netsuite', + 'otter', + 'outlook', + 'pagerduty', + 'parallel_ai', + 'peopledatalabs', + 'perplexity', + 'persona', + 'pinecone', + 'pipedrive', + 'pitchbook', + 'plane', + 'planetscale', + 'polymarket', + 'postgresql', + 'posthog', + 'powerbi', + 'profound', + 'prospeo', + 'pulse', + 'qdrant', + 'quartr', + 'quickbooks', + 'quiver', + 'rabbitmq', + 'railway', + 'ramp', + 'rb2b', + 'reddit', + 'redis', + 'reducto', + 'resend', + 'revenuecat', + 'rippling', + 'rocketlane', + 'rootly', + 's3', + 'sailpoint', + 'salesforce', + 'sap_concur', + 'sap_s4hana', + 'semrush', + 'sendblue', + 'sendgrid', + 'sentry', + 'serper', + 'servicenow', + 'sftp', + 'sharepoint', + 'shopify', + 'similarweb', + 'sixtyfour', + 'slack', + 'smartlead', + 'smtp', + 'snowflake', + 'splunk', + 'sportmonks', + 'square', + 'ssh', + 'stagehand', + 'stripe', + 'supabase', + 'tailscale', + 'tavily', + 'telegram', + 'temporal', + 'thrive', + 'tiktok', + 'tinybird', + 'tinyfish', + 'trello', + 'trigger_dev', + 'twilio_sms', + 'twilio_voice', + 'typeform', + 'upstash', + 'uptimerobot', + 'vanta', + 'vercel', + 'wealthbox', + 'webflow', + 'whatsapp', + 'wikipedia', + 'windchill', + 'wiza', + 'wordpress', + 'workday', + 'x', + 'youcom', + 'youtube', + 'zendesk', + 'zep', + 'zerobounce', + 'zoho_desk', + 'zoom', + 'zoominfo', +] as const diff --git a/apps/sim/platform/design-system/components/icon/provider-marks.ts b/apps/sim/platform/design-system/components/icon/provider-marks.ts index b1b0505a4db..72595eed719 100644 --- a/apps/sim/platform/design-system/components/icon/provider-marks.ts +++ b/apps/sim/platform/design-system/components/icon/provider-marks.ts @@ -1,4 +1,5 @@ import type { IconName } from '@/platform/design-system/catalog/icon-geometry' +import { providerMarkIds } from '@/platform/design-system/components/icon/provider-mark-ids.generated' import { publicAssetPath } from '@/platform/design-system/navigation' const SHARED_MARKS = new Map([ @@ -25,9 +26,14 @@ const ASSET_MARKS = new Set([ 'zoom', ]) +const CATALOG_MARKS: ReadonlySet = new Set(providerMarkIds) + export function providerMark(providerId: string): IconName | { href: string } { const shared = SHARED_MARKS.get(providerId) if (shared) return shared - if (!ASSET_MARKS.has(providerId)) return 'I070' - return { href: publicAssetPath(`/provider-marks/${providerId.replaceAll('_', '-')}.svg#mark`) } + if (ASSET_MARKS.has(providerId)) + return { href: publicAssetPath(`/provider-marks/${providerId.replaceAll('_', '-')}.svg#mark`) } + if (CATALOG_MARKS.has(providerId)) + return { href: publicAssetPath(`/provider-marks/catalog.svg#${providerId}`) } + return 'I070' } diff --git a/apps/sim/platform/design-system/components/index.ts b/apps/sim/platform/design-system/components/index.ts index e5eed4f4752..fc88bdb4209 100644 --- a/apps/sim/platform/design-system/components/index.ts +++ b/apps/sim/platform/design-system/components/index.ts @@ -4,7 +4,6 @@ export { Avatar, AvatarGroup, AvatarImage, - AvatarOverflow, PeoplePopover, PersonRow, } from './avatar/avatar' @@ -47,6 +46,7 @@ export { ScrollArea } from './scroll-area/scroll-area' export { MenuSearchField } from './search-field/menu-search-field' export { SearchField } from './search-field/search-field' export { SegmentedControl, SelectionItem } from './segmented-control/segmented-control' +export { Stack } from './stack/stack' export { FailureNotice, InlineNotice, StatusTag } from './status/status' export { PlatformSurface } from './surface/platform-surface' export { Switch } from './switch/switch' diff --git a/apps/sim/platform/design-system/components/stack/stack.module.css b/apps/sim/platform/design-system/components/stack/stack.module.css new file mode 100644 index 00000000000..603f11a28ed --- /dev/null +++ b/apps/sim/platform/design-system/components/stack/stack.module.css @@ -0,0 +1,29 @@ +.stack { + display: inline-flex; + flex: none; + align-items: center; +} +.item { + display: inline-flex; + position: relative; +} +.item > * { + transition: transform var(--ui-motion-position) ease; +} +.item + .item { + margin-inline-start: calc(-1 * var(--spacing-4)); +} +@media (hover: hover) { + .item:hover { + z-index: 1; + } + .item:hover > * { + transform: translateX(calc(-1 * var(--spacing-4))); + } +} +.count { + margin-inline-start: var(--ui-row-gap); + color: var(--ui-secondary); + white-space: nowrap; + font-variant-numeric: tabular-nums; +} diff --git a/apps/sim/platform/design-system/components/stack/stack.tsx b/apps/sim/platform/design-system/components/stack/stack.tsx new file mode 100644 index 00000000000..d41ceb20853 --- /dev/null +++ b/apps/sim/platform/design-system/components/stack/stack.tsx @@ -0,0 +1,35 @@ +import type { ReactElement } from 'react' +import styles from '@/platform/design-system/components/stack/stack.module.css' +import { Tooltip } from '@/platform/design-system/components/tooltip/tooltip' + +interface StackProps { + items: readonly { id: string; label: string; content: ReactElement }[] + total?: number + label?: string +} + +const compactCount = new Intl.NumberFormat('en-US', { + notation: 'compact', + maximumFractionDigits: 1, +}) + +/** A compact visual roster; the remaining count is text, not another interaction. */ +export function Stack({ items, total = items.length, label }: StackProps) { + const visible = items.slice(0, 2) + const remaining = Math.max(0, total - visible.length) + if (!visible.length && !remaining) return null + return ( + + {visible.map((item) => ( + + {item.content} + + ))} + {remaining > 0 && ( + + +{compactCount.format(remaining).replace(/K$/, 'k')} + + )} + + ) +} diff --git a/apps/sim/platform/design-system/styles/rhythm.css b/apps/sim/platform/design-system/styles/rhythm.css index edccfc6afaa..d657eb8d14d 100644 --- a/apps/sim/platform/design-system/styles/rhythm.css +++ b/apps/sim/platform/design-system/styles/rhythm.css @@ -6,6 +6,7 @@ --ui-page-inset-block: var(--ui-product-section-gap); --ui-page-heading-inset: var(--spacing-64); --ui-motion-color: 120ms; + --ui-motion-position: var(--ui-motion-color); --ui-control-radius: var(--radius-control); --ui-stack-gap: var(--spacing-2); --ui-list-gap: var(--spacing-2); diff --git a/apps/sim/platform/docs/component-ownership.md b/apps/sim/platform/docs/component-ownership.md index 1413f0b6ffe..a6c85aac0db 100644 --- a/apps/sim/platform/docs/component-ownership.md +++ b/apps/sim/platform/docs/component-ownership.md @@ -10,7 +10,7 @@ Start with the interaction. A different label, icon, data source, theme or scree | Choose a value or run a command | Picker owns Select, SearchableSelect (client filtering, or server search through `search`), MultiSelect, and calendar choices through DatePicker and DateRangePicker; `Calendar` stays private to it. Menu owns actions, nested menus and popovers. ChoiceMenu owns compact toolbar choices, including Home ranges and integration filters, with the same quiet button and radio-menu rows. Select remains the owner for form fields. These share popup and row recipes; retain their distinct ARIA roles and keyboard behavior. CommandPalette owns multi-group search and navigation inside the shared dialog. | | Edit or toggle | Field owns labeled input/textarea chrome, hints and errors, plus CopyField (read-only value with copy), SecretField (masked entry with reveal) and FileField (choose or drop; the caller reads the file). Platform globals disable manual textarea resizing. SearchField/MenuSearchField own clearable search and filtering. WorkspaceFields owns recipient parsing, editing, validation (controlled through `recipients` and `validate`), removal and logo upload. RecipientTag pairs a bounded address with an always-visible inline IconButton. The field wraps tags as a unit. ComposerInput owns draft typing, paste and submission. Switch owns a setting that applies at once, Checkbox owns a boolean in a form or grid, SegmentedControl owns mutually exclusive choices. | | Display layers and transient feedback | Modal owns title, body, multi-step progression and footer. OverlayDialog supplies the same surface to search and attachment previews. Tooltip owns bounded plain labels; a structured people panel uses its own measured content. Feedback owns clipboard success and timeout behavior. Status owns StatusTag, a read-only state on a row, InlineNotice, a persistent message in the page flow with an optional action, and FailureNotice, a failed read with its retry; a transient outcome still goes to the tray. The notification tray owns history and Undo, with one control shadow outside the scroll viewport. | -| Show files, people and media | Attachments composes ControlRow with file glyph or thumbnail, an accessible preview target and an independent quiet remove action. Avatar owns image and single-initial fallbacks across profiles, email and people details. Icon owns interface paint and distinguishes branded artwork. Product callers supply media or data. | +| Show files, people and media | Attachments composes ControlRow with file glyph or thumbnail, an accessible preview target and an independent quiet remove action. Avatar owns image and single-initial fallbacks across profiles, email and people details. Stack owns compact overlapping artwork, name tooltips, individual hover movement and passive compact +N counts; AvatarGroup adapts people for integration usage and calendar attendees. Icon owns interface paint and distinguishes branded artwork. Product callers supply media or data. | | Read or inspect data | Chart owns shared numerical formatting, point inspection and chart tooltips; BarChart stacks up to six layers, each keeping its color by position. DataDisplay owns metrics and table semantics: DataTable takes custom cells (TableLabel is a name with its leading mark), a whole-row target, a sibling row action, controlled sort, paging and windowing through `@tanstack/react-virtual`. Pagination owns explicit page steps; ScrollArea's LoadMoreFooter owns reaching the end of a paged list, for tables and pickers alike. PropertyList owns labeled values, ExecutionSteps is a noninteractive numbered plan, and EmptyState describes absent data, with an optional decorative graphic. Calendar hours/events, Home activity chart axes and chat tool payloads remain with the features that interpret them. | | Disclose and scroll | Disclosure owns keyboard-accessible expansion; tool input/output have their own disclosure content and reading rules. ScrollArea/useScrollEdges measure the actual viewport. OverflowText handles clipped text, and touch-target and layout owners handle interaction bounds and composition. PlatformSurface owns theme selection. | @@ -24,4 +24,6 @@ For a proposed addition, trace its second consumer before copying a hit area, ho The [integration center](integration-center.md) lives in `integrations/_components/integration-center/` at the organization root. Its Apps, Skills, MCPs and Credentials destinations compose DestinationTabs, the shared search control and ActivityRow. The local `resource-list/` and `resource-editor/` owners interpret integration-specific content and actions. They do not own another button, menu, tab, form-field or dialog recipe. Personal and shared data use the same renderer. Eligible workspace entry points open or redirect to this organization center; they do not mount a separate Platform integration page. Standalone workspaces and viewers without organization Search access retain their existing credential route. +IntegrationControls owns the compact control-bar layout shared by the center and app details. CredentialList, CredentialDetail, CredentialAccess and CredentialConnect own credential-specific composition; provider setup fields come from generated metadata. The Slack bot owner retains its distinct staged setup. IntegrationCapabilities owns suggested skills, template previews and bounded capability lists. Each composes EMCN controls and uses the same row and section rhythm as Home and Settings. + Organization Settings uses the [navigation catalog](../lib/data/settings-navigation.ts) for sidebar order and server-gated resolution. The [section registry](../app/%28shell%29/settings/_components/section-registry.ts) lazy-loads one owner per tab. General composes Profile, Preferences, Privacy and Account, including their detail views. Section titles and action rows use EMCN SettingsSection and SettingsRow. diff --git a/apps/sim/platform/docs/integration-center.md b/apps/sim/platform/docs/integration-center.md index 735ed4f1ead..8e94fe4bac8 100644 --- a/apps/sim/platform/docs/integration-center.md +++ b/apps/sim/platform/docs/integration-center.md @@ -11,20 +11,38 @@ | MCPs | Shared and Personal sections for custom servers. Connection details belong to the server, not a fabricated provider catalog. | | Credentials | Shared and Personal sections for named credentials and secrets. Show access in the list and ownership in the detail or editor, without exposing a secret in a list. | -Keep the heading, description, reading column and major gaps aligned with Home. DestinationTabs and the compact control bar follow the Platform Workspaces anatomy in Paper. Search sits at the start of the control bar; destination-specific sorting, filtering and create actions sit at the end. Category and access choices use ChoiceMenu, the exact Home period owner with a compact quiet trigger. Select/SelectField belong to the editor's form fields, not this toolbar. Categories and ownership sections live in the content, not as another nested tab system. +Keep the heading, description, reading column and major gaps aligned with Home. DestinationTabs and the compact control bar follow the Platform Workspaces anatomy in Paper. Search sits at the start of the control bar; destination-specific sorting, filtering and create actions sit at the end. Category and access choices use ChoiceMenu, the exact Home period owner with a compact quiet trigger. Select/SelectField belong to the editor's form fields, not this toolbar. Tabs and the control bar use the same 12px section gap as Home’s wordmark and composer. Categories and ownership sections live in the content, not as another nested tab system. Empty results sit at the normal section-title edge immediately below the controls. -The route entry stays thin. `integrations/_components/integration-center/` owns the frame and destination composition. `resource-list/` and `resource-editor/` own the feature's list content and editor fields. Reuse EMCN DestinationTabs, SearchField, ActivityRow, Avatar, Button, Menu, Modal and Field owners. Base UI supplies complex behavior inside EMCN; product code supplies data and callbacks. Leading marks align with the first line, trailing people and actions center against the whole row, and lists use the same shared rhythm as Home email and notification rows. +The route entry stays thin. `integrations/_components/integration-center/` owns the frame and destination composition. `resource-list/` and `resource-editor/` own the feature's list content and editor fields. Reuse EMCN DestinationTabs, SearchField, ActivityRow, Avatar, Button, Menu, Modal and Field owners. Base UI supplies complex behavior inside EMCN; product code supplies data and callbacks. Leading marks align with the first line, trailing people and actions center against the whole row, and lists use the same shared rhythm as Home email and notification rows. App rows end with two profile photos and a passive +N count before their navigation chevron. Individual photos reveal names on hover; the count opens nothing. Details use a natural-language usage line below the description. Skills use the slash glyph; credential keys share the central key geometry. Reconnection stays an account action, without an extra list status. ## Data and access Apps retain the existing [member inventory and credential contract](organization-integrations.md). A connected account or an organization-approved provider does not prove that its credential is shared. Usage avatars and counts require an authorized roster projection; do not derive organization usage from the viewer's personal accounts or expose another member's credential label. +The full workspace app catalog is projected at generation time from existing public block metadata, suggested skills, templates and provider connection definitions. The fixture index receives compact summaries; the server sends operations, instructions, prompts and enrollment fields only for the selected detail. The metadata audit detects upstream drift. An app's generic `authType` is not a connection form: expose only methods present in the canonical provider definitions. Live inventory continues to come from its authorized operation. + +## App and credential details + +App-level actions belong in the control bar immediately beneath the title, description and usage line. Docs and Add credential use the same compact controls as the center. Actions that apply to one credential stay in that credential's row or detail. The app shows a Connected credentials section with multiple independently named records, then available suggested skills, templates and capabilities. Suggested skills can be inspected and added to the fixture library; template prompts can be inspected and copied. Bound long collections with the shared scroll owner and pagination. + +Credentials retain their canonical ID across provider families. Editing a Google service account through Gmail updates the same record shown through Calendar and Drive. A credential detail exposes its name, description, connected identity, provider method, scope and effective access. Names and descriptions follow existing limits; secrets never enter lists or session metadata. Personal tokens have no sharing controls. Workspace credentials retain a named workspace and effective admin/member roles; organization-managed records retain their separate managed scope. Usage avatars are not permission evidence. + +Admin controls follow the existing credential contract: edit description/name, reconnect, disconnect and share with eligible workspace members. Effective workspace-admin access cannot be removed or demoted here. Keep the last active explicit administrator protected. A member may leave an explicit share when those constraints permit. Preserve pending and revoked member states. UI examples demonstrate these distinctions; authorized application operations must enforce them when the data seam is implemented. + +Connection methods preserve their actual requirements: OAuth scopes and provider environments, personal tokens, service-account fields, Google JSON, provider-specific client credentials and custom Slack bots. Choose a workspace explicitly when multiple eligible destinations exist; owner-only tokens remain personal. Reconnect preserves the credential ID and immutable provider host/environment. Transient secrets are cleared on close and before the metadata-only callback, with no storage or network mutation in fixture mode. A local metadata record does not imply successful provider authorization. + +Ordinary credential enrollment and organization Search source approval are separate capabilities. A paused or organization-managed Search source does not itself prohibit a workspace credential for the same app. The fixture projection supplies `canAddCredential` separately from Search availability. A live adapter must obtain enrollment methods and eligible workspace members from their authorized operations, including viewer, deployment and provider gates; catalog membership alone never authorizes enrollment or sharing. + New skill, MCP, sharing and credential editor interactions are UI work. Their example records are loaded only through the server fixture flag and edited in the product session. Skills and MCPs are shown only in fixture mode until their live data adapters exist. Live Apps and Credentials render only data and actions supplied by an existing authorized operation. They must not substitute fixture records when a request is loading, denied, unavailable or failed. Sharing controls in an example are not permission enforcement, and creating a local example must not call a real credential, secret or policy mutation. +The custom Slack bot connection keeps its provider-specific setup in `slack-bot-connection/`: workspace choice, bot identity, generated capability choices, optional slash commands, Slack setup instructions, bot token and signing secret. Reconnect preserves the credential and workspace identity and does not edit the existing manifest. Secret inputs stay inside the mounted dialog and are cleared before its metadata-only callback or dismissal. A deployable app manifest and creation link require an authorized service to reserve the credential ID and supply public callback URLs; the fixture flow shows the setup guide and permission review without fabricating those URLs or claiming an installation succeeded. + The organization center is the canonical destination. Workspace navigation resolves the workspace host and the viewer's organization eligibility before linking or redirecting there; it never uses the session's unrelated active organization or silently changes credential scope. Preserve the existing route for viewers who cannot use the organization center, rather than trapping them behind an unavailable page. Paper references and historical documentation do not justify another Platform workspace management surface. The browser and Electron use the same renderer. ## Verification Check destination navigation and browser history, search and empty results, sort/filter controls, create/edit/cancel flows, personal/shared grouping, dropdown placement and keyboard dismissal. Verify long names, multiple usage avatars, empty and stress data, narrow and intermediate widths, dark theme and real overflow fades. Fixture-off output must contain no sample people, credentials or shared resources. Existing live Apps detail and connection behavior must remain reachable. +For custom Slack bots, check required workspace/name fields, all generated capability choices, slash-command uniqueness and limits, back navigation, masked token entry, reconnect ownership, and clean secret fields after cancellation or submission. The fixture callback may receive only display metadata; no token or signing secret may enter session state, storage, a request, or a success notice. + Run the Platform design audit, type check, build and browser checks from the [README](../README.md). The static audit enforces styling and ownership boundaries and unused variants. Review independently that every new shared visual variant has two real consumers and that custom feature anatomy uses an established layout rhythm; a numeric JSX count cannot establish those design decisions. diff --git a/apps/sim/platform/docs/organization-integrations.md b/apps/sim/platform/docs/organization-integrations.md index b4e485f520a..a192c995fac 100644 --- a/apps/sim/platform/docs/organization-integrations.md +++ b/apps/sim/platform/docs/organization-integrations.md @@ -1,4 +1,6 @@ -# Member integrations +# Member Search integrations + +This document describes the existing live Search data contract. The [integration center](integration-center.md) extends the fixture UI to multiple workspace and personal credentials, provider-specific enrollment, suggested skills and templates. Its broader credential model does not change the legacy Search authorization or single personal-account operation until an authorized data adapter replaces it. The organization sidebar opens the [integration center](integration-center.md) at `/integrations`. Its Apps destination retains the signed-in member’s authorized Search integrations inventory and `/integrations/[providerId]` details. A provider detail shows its catalog description, personal credential and available actions. Search matches provider names, descriptions and the viewer’s credential label. Selecting a result preserves the current search on return. Clearing the search and immediately opening a result still opens that provider. Browser history and sidebar navigation restore the filter from their destination URL. The browser and Sim Desktop share these routes. The center's additional sharing and resource examples do not expand this live authorization contract. @@ -7,12 +9,12 @@ The existing [organization route](../../app/o/%5BorganizationId%5D/integrations/ | Member interaction | Contract for Phase 3 | | --- | --- | | Find a provider | Accept a server projection of visible member integrations. The inventory supplies readiness, reason, personal accounts, usable connection targets and eligible reconnects. A managed source such as GitLab has no personal login. [Inventory rules](../../app/o/%5BorganizationId%5D/integrations/utils.ts) | -| Connect, reconnect or disconnect a personal account | The Platform models one personal credential per integration. Connect uses the inline Home Email and Calendar prompt. Reconnect and disconnect act on that credential. [Account contracts](../../lib/api/contracts/organization-accounts.ts) | +| Connect, reconnect or disconnect a personal account | The live Search operation currently models one personal credential per integration. Connect uses the inline Home Email and Calendar prompt. Reconnect and disconnect act on that credential. [Account contracts](../../lib/api/contracts/organization-accounts.ts) | | Manage tool permissions | Only projected eligible credentials receive tool controls. Read and write tools have group policies and individual overrides. Automatic approval additionally depends on account status and the viewer’s permission group. [Permission contract](../../lib/api/contracts/assistant-actions.ts) · [Permission operation](../../lib/assistant-actions/application/tool-permissions.ts) | | Inspect Generic Secrets | An organization-managed source exposes its mode. A personal source exposes only the signed-in member’s key names. [Secret contracts](../../lib/api/contracts/organization-secrets.ts) | With `SIM_PLATFORM_FIXTURES=1`, open [the populated inventory](http://localhost:3100/integrations?state=full), [the empty state](http://localhost:3100/integrations?state=empty), or [the stress scenario](http://localhost:3100/integrations?state=stress). The flagged loader supplies sample credential handoffs and tool catalogs. Changes live in the current product session. The default-off route has no example providers or credentials. Real authorization, credential exchange, policy persistence and secret handling belong to Phase 3. -The detail header places the provider mark beside its name and description. **Connected credential** is a separate section below the header. Its title uses the Home section heading typography and aligns with the left edge of the permissions sections. The member’s account label sits on the next line. Its trailing menu acts on that credential. A status appears when the account needs reconnection or its organization has restricted access. In the inline connection prompt, the book icon and **Docs** link sit to the left of the connect action and open the provider’s Sim Search setup guide in a new tab. For entries under **Managed by your organization**, the same panel explains the access state and shows only **Docs**. Organization-managed Generic Secrets links to its own guide; personal secret names stay private to the member view. Providers without a dedicated guide use the member account connection guide. +The detail header places the provider mark beside its name and description. **Connected credential** is a separate section below the header. Its title uses the Home section heading typography and aligns with the left edge of the permissions sections. The member’s account label sits on the next line. Its trailing menu acts on that credential. Reconnect remains available without an extra reconnection status label. App-level actions use the control bar below the description. The book icon and **Docs** link open the provider’s Sim Search setup guide in a new tab. For entries under **Managed by your organization**, the access panel retains Docs without Connect. Organization-managed Generic Secrets links to its own guide; personal secret names stay private to the member view. Providers without a dedicated guide use the member account connection guide. Provider names and descriptions come from Sim’s workspace integration catalog, which is generated from block definitions. Lucid uses its managed connector definition. **Tool permissions** groups eligible actions by read and write. Each tool retains its own description and approval control. **Requested permissions** lists human-readable OAuth scopes in always-visible groups. These are authorization requests. **Search access** describes the content a member can search. For managed providers such as Fireflies it lists the read-only Search operations the existing adapter supports. Use hanging bullets for static scopes and Search capabilities so wrapped lines stay with their item. Editable tool rows keep the name, description and permission control together without bullets. Actual account grants and eligible assistant tools come from their own operations. Refresh canonical metadata with `bun scripts/sync-platform-integration-metadata.ts` when its sources change. diff --git a/apps/sim/platform/fixtures/index.ts b/apps/sim/platform/fixtures/index.ts index 012f45b083e..2dba9b7717e 100644 --- a/apps/sim/platform/fixtures/index.ts +++ b/apps/sim/platform/fixtures/index.ts @@ -109,12 +109,14 @@ export const loadConversationData = fixture( ) export const loadIntegrationsData = fixture( async (scenario, secrets?: string | string[]): Promise => { - const [{ memberIntegrations }, { memberSecretSource }] = await Promise.all([ - import('@/platform/fixtures/integration-data'), - import('@/platform/fixtures/member-secret-source'), - ]) + const [{ memberIntegrations }, { memberSecretSource }, { integrationCenterData }] = + await Promise.all([ + import('@/platform/fixtures/integration-data'), + import('@/platform/fixtures/member-secret-source'), + import('@/platform/fixtures/integration-center-data'), + ]) return { - integrations: memberIntegrations(scenario), + integrations: memberIntegrations(scenario, integrationCenterData(scenario)), genericSecrets: memberSecretSource(scenario, secrets), } } @@ -122,6 +124,11 @@ export const loadIntegrationsData = fixture( export const loadIntegrationCenterData = fixture(async (scenario) => (await import('@/platform/fixtures/integration-center-data')).integrationCenterData(scenario) ) +export const loadIntegrationCatalogEntry = fixture(async (scenario, providerId?: string) => { + if (scenario === 'empty' || !providerId) return null + const { integrationCatalog } = await import('@/platform/lib/integrations/catalog.generated') + return integrationCatalog.find((entry) => entry.id === providerId) ?? null +}) export const loadPanelData = fixture( async (scenario) => (await import('@/platform/fixtures/panel-data')).panelScenarios[scenario] ) diff --git a/apps/sim/platform/fixtures/integration-center-data.ts b/apps/sim/platform/fixtures/integration-center-data.ts index 18e51930941..f45879ce34c 100644 --- a/apps/sim/platform/fixtures/integration-center-data.ts +++ b/apps/sim/platform/fixtures/integration-center-data.ts @@ -1,5 +1,8 @@ import 'server-only' import type { Scenario } from '@/platform/fixtures' +import ninaPhoto from '@/platform/fixtures/media/attendee-1.jpg' +import alexPhoto from '@/platform/fixtures/media/attendee-2.jpg' +import mayaPhoto from '@/platform/fixtures/media/attendee-3.jpg' import type { IntegrationCenterData, IntegrationPerson, @@ -7,9 +10,9 @@ import type { } from '@/platform/lib/integrations/center-model' const emir: IntegrationPerson = { id: 'emir', name: 'Emir Karabeg' } -const nina: IntegrationPerson = { id: 'nina', name: 'Nina Patel' } -const alex: IntegrationPerson = { id: 'alex', name: 'Alex Chen' } -const maya: IntegrationPerson = { id: 'maya', name: 'Maya Thompson' } +const nina: IntegrationPerson = { id: 'nina', name: 'Nina Patel', src: ninaPhoto.src } +const alex: IntegrationPerson = { id: 'alex', name: 'Alex Chen', src: alexPhoto.src } +const maya: IntegrationPerson = { id: 'maya', name: 'Maya Thompson', src: mayaPhoto.src } const daniel: IntegrationPerson = { id: 'daniel', name: 'Daniel Kim' } const people = [emir, nina, alex, maya, daniel] @@ -136,8 +139,18 @@ const resources: IntegrationResource[] = [ }, ] +const workspaces = [ + { + id: 'customer-operations', + name: 'Customer operations', + memberIds: ['emir', 'nina', 'alex', 'maya'], + }, + { id: 'engineering', name: 'Engineering', memberIds: ['emir', 'alex', 'daniel'] }, +] as const + export function integrationCenterData(scenario: Scenario): IntegrationCenterData { - if (scenario === 'empty') return { viewer: emir, people, appPeople: {}, resources: [] } + if (scenario === 'empty') + return { viewer: emir, people, workspaces, appPeople: {}, appUsageTotal: {}, resources: [] } const extra = scenario === 'stress' ? Array.from({ length: 60 }, (_, index): IntegrationResource => { @@ -154,11 +167,13 @@ export function integrationCenterData(scenario: Scenario): IntegrationCenterData : [] return { viewer: emir, + workspaces, people, + appUsageTotal: { gmail: scenario === 'stress' ? 1002 : 15, google_drive: 24 }, appPeople: { - gmail: [emir, nina, alex, maya, daniel], - google_calendar: [emir, nina, alex, maya], - google_drive: [emir, nina, alex, maya, daniel], + gmail: [nina, alex, maya, emir, daniel], + google_calendar: [nina, alex, maya, emir], + google_drive: [nina, alex, maya, emir, daniel], github: [emir, alex, daniel], fireflies: [emir, nina, maya], hubspot: [nina, emir], diff --git a/apps/sim/platform/fixtures/integration-data.ts b/apps/sim/platform/fixtures/integration-data.ts index c95a14bd082..ffb384d8571 100644 --- a/apps/sim/platform/fixtures/integration-data.ts +++ b/apps/sim/platform/fixtures/integration-data.ts @@ -1,5 +1,8 @@ import 'server-only' import type { Scenario } from '@/platform/fixtures' +import { integrationCatalog } from '@/platform/lib/integrations/catalog.generated' +import type { IntegrationCenterData } from '@/platform/lib/integrations/center-model' +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' import type { AccountMethod, IntegrationAccount, @@ -7,10 +10,10 @@ import type { } from '@/platform/lib/integrations/fixture-model' import { gmailToolMetadata, providerMetadata } from '@/platform/lib/integrations/metadata.generated' -type Connection = Pick< - OrganizationIntegration, - 'account' | 'availability' | 'connectableMethod' -> & { accessDescription?: string } +type Connection = Pick & { + account: IntegrationAccount | null + accessDescription?: string +} function account(id: string, label: string, method: AccountMethod): IntegrationAccount { return { id, label, method, status: 'active', canReconnect: true } @@ -55,7 +58,10 @@ const full: Record = { }, } -export function memberIntegrations(scenario: Scenario): OrganizationIntegration[] { +export function memberIntegrations( + scenario: Scenario, + center: IntegrationCenterData +): OrganizationIntegration[] { if (scenario === 'empty') return [] const selected: Record = scenario === 'full' @@ -99,30 +105,158 @@ export function memberIntegrations(scenario: Scenario): OrganizationIntegration[ accessDescription: 'Access follows project permissions', }, } - return providerMetadata.flatMap(({ id, searchResource, ...metadata }) => { - const config = selected[id] - if (!config) return [] - const candidate = config.connectableMethod - ? account( - `${id}-available`, - config.connectableMethod === 'mcp' ? metadata.name : 'emir@sim.ai', - config.connectableMethod - ) - : undefined - return [ - { - providerId: id, - searchResource, - ...metadata, - ...config, - accessDescription: - config.accessDescription ?? - (searchResource - ? `All accessible ${searchResource === 'CRM records' ? searchResource : searchResource.toLowerCase()}` - : 'Access follows your account permissions'), - connectionCandidate: candidate, + const searchIntegrations: OrganizationIntegration[] = providerMetadata.flatMap( + ({ id, searchResource, ...metadata }) => { + const config = selected[id] + if (!config) return [] + return [ + { + providerId: id, + searchResource, + ...metadata, + availability: config.availability, + connectableMethod: config.connectableMethod, + credentials: credentialExamples(id, config.account, scenario, center), + accessDescription: + config.accessDescription ?? + (searchResource + ? `All accessible ${searchResource === 'CRM records' ? searchResource : searchResource.toLowerCase()}` + : 'Access follows your account permissions'), + fixtureAuthorization: true, + canAddCredential: true, + credentialProviders: [], + }, + ] + } + ) + const searchById = new Map( + searchIntegrations.map((integration) => [integration.providerId, integration]) + ) + const catalogIds = new Set(integrationCatalog.map((integration) => integration.id)) + return [ + ...integrationCatalog.map((entry): OrganizationIntegration => { + const existing = searchById.get(entry.id) + const credentialProviders = [ + ...new Set(entry.connections.map(({ providerId }) => providerId)), + ] + if (existing) return { ...existing, category: entry.category, credentialProviders } + return { + providerId: entry.id, + name: entry.name, + description: entry.description, + category: entry.category, + setupGuideUrl: entry.docsUrl, + searchResource: null, + searchReads: [], + requestedScopes: null, + accessDescription: '', + availability: 'catalog', fixtureAuthorization: true, - }, - ] - }) + canAddCredential: true, + credentialProviders, + connectableMethod: null, + credentials: [], + } + }), + ...searchIntegrations.filter((integration) => !catalogIds.has(integration.providerId)), + ] +} + +function credentialExamples( + appId: string, + account: IntegrationAccount | null, + scenario: Scenario, + { viewer, people }: IntegrationCenterData +): IntegrationCredential[] { + const member = (id: string, role: 'admin' | 'member', inherited = false) => { + const person = people.find((entry) => entry.id === id) + if (!person) throw new Error('Credential example member is missing') + return { + ...person, + userId: person.id, + role, + roleSource: inherited ? ('workspace-admin' as const) : ('explicit' as const), + explicitAdmin: !inherited && role === 'admin', + status: 'active' as const, + } + } + const scope = { + kind: 'workspace', + id: 'customer-operations', + name: 'Customer operations', + } as const + const credentials: IntegrationCredential[] = account + ? [ + { + id: account.id, + appId, + providerId: + integrationCatalog + .find((entry) => entry.id === appId) + ?.connections.find((entry) => entry.kind === 'oauth')?.providerId ?? appId, + type: account.method, + displayName: account.label, + description: appId === 'gmail' ? 'Customer conversations and account updates.' : '', + accountLabel: account.label, + role: 'admin', + status: account.status, + canReconnect: account.canReconnect, + scope: account.method === 'oauth' ? scope : { kind: 'personal', ownerId: viewer.id }, + members: [member(viewer.id, 'admin')], + permissions: account.permissions, + }, + ] + : [] + if (['gmail', 'google_calendar', 'google_drive'].includes(appId)) { + credentials.push({ + id: 'google-team-service', + appId: 'gmail', + providerId: 'google-service-account', + type: 'service_account', + displayName: 'Customer operations service account', + description: 'Shared automation for the customer operations team.', + accountLabel: 'operations@customer-operations.iam.gserviceaccount.com', + role: 'admin', + status: 'active', + canReconnect: true, + scope, + members: [ + member('nina', 'admin'), + member(viewer.id, 'admin', true), + member('alex', 'member'), + ], + }) + } + if (scenario === 'stress' && appId === 'github') { + credentials.push({ + id: 'github-engineering', + appId, + providerId: 'github-repo', + type: 'oauth', + displayName: 'Engineering repositories', + description: 'Repository access shared by the engineering team.', + role: 'member', + status: 'active', + canReconnect: false, + scope: { kind: 'workspace', id: 'engineering', name: 'Engineering' }, + members: [member('alex', 'admin'), member(viewer.id, 'member')], + }) + } + if (scenario === 'stress' && appId === 'gitlab') { + credentials.push({ + id: 'gitlab-personal', + appId, + providerId: 'gitlab', + type: 'personal_token', + displayName: 'My GitLab account', + description: '', + instanceUrl: 'https://gitlab.com', + role: 'admin', + status: 'active', + canReconnect: true, + scope: { kind: 'personal', ownerId: viewer.id }, + members: [member(viewer.id, 'admin')], + }) + } + return credentials } diff --git a/apps/sim/platform/fixtures/settings-sources-data.ts b/apps/sim/platform/fixtures/settings-sources-data.ts index a266f2b8cdf..aea9aa23c47 100644 --- a/apps/sim/platform/fixtures/settings-sources-data.ts +++ b/apps/sim/platform/fixtures/settings-sources-data.ts @@ -37,11 +37,11 @@ export async function sourceSettings(scenario: Scenario): Promise entry.searchResource === null) + .filter((entry) => entry.searchResource === null && entry.availability !== 'catalog') .map((entry) => ({ id: entry.providerId, name: entry.name, - account: entry.account?.label ?? null, + account: entry.credentials[0]?.accountLabel ?? null, approved: entry.availability !== 'unconfigured', })), sources, diff --git a/apps/sim/platform/lib/data/integrations-model.ts b/apps/sim/platform/lib/data/integrations-model.ts index 78a0705c2e8..ad9577a6fec 100644 --- a/apps/sim/platform/lib/data/integrations-model.ts +++ b/apps/sim/platform/lib/data/integrations-model.ts @@ -28,14 +28,6 @@ function availabilityOf(entry: MemberIntegration): OrganizationIntegration['avai function memberIntegrationStatus(entry: MemberIntegration) { if (entry.managed) return 'Organization managed' if (!entry.ready) return entry.description ?? 'Checking availability' - if ( - entry.accounts.some( - (account) => - account.status === 'needs_reauth' && - entry.reconnectAccountIds.includes(account.credentialId) - ) - ) - return 'Reconnect needed' if (entry.accounts.length) return entry.accounts.length === 1 ? '1 account' : `${entry.accounts.length} accounts` return 'Not connected' @@ -49,6 +41,7 @@ function toOrganizationIntegration(entry: MemberIntegration): OrganizationIntegr icon: entry.icon, name: entry.name, description: metadata?.description ?? `Connect your ${entry.name} account to use it here`, + category: metadata?.category ?? 'Other', setupGuideUrl: metadata?.setupGuideUrl ?? CONNECT_ACCOUNT_GUIDE, searchResource: metadata?.searchResource ?? null, searchReads: metadata?.searchReads ?? [], diff --git a/apps/sim/platform/lib/data/integrations-types.ts b/apps/sim/platform/lib/data/integrations-types.ts index 37abca886ce..c6a390a19e8 100644 --- a/apps/sim/platform/lib/data/integrations-types.ts +++ b/apps/sim/platform/lib/data/integrations-types.ts @@ -25,6 +25,7 @@ export interface OrganizationIntegration { icon: ComponentType<{ className?: string }> name: string description: string + category: string setupGuideUrl: string searchResource: string | null searchReads: readonly { id: string; label: string }[] @@ -88,7 +89,6 @@ export function isConnectable(integration: OrganizationIntegration) { return integration.availability === 'ready' && Boolean(integration.connectionTarget) } -export function accountStatus(integration: OrganizationIntegration, account: IntegrationAccount) { - if (account.status === 'needs_reauth') return 'Reconnect needed' +export function accountStatus(integration: OrganizationIntegration) { return integration.availability === 'blocked' ? integration.status : 'Connected' } diff --git a/apps/sim/platform/lib/integrations/catalog-model.ts b/apps/sim/platform/lib/integrations/catalog-model.ts new file mode 100644 index 00000000000..1cd08c0b3fd --- /dev/null +++ b/apps/sim/platform/lib/integrations/catalog-model.ts @@ -0,0 +1,22 @@ +/** Public workspace catalog content, projected at generation time without executable tools. */ +export interface IntegrationCatalogEntry { + id: string + type: string + slug: string + name: string + description: string + category: string + docsUrl: string + authType: 'oauth' | 'api-key' | 'none' + connections: readonly CredentialConnection[] + operations: readonly { name: string; description: string }[] + triggers: readonly { id: string; name: string; description: string }[] + skills: readonly { name: string; description: string; content: string }[] + templates: readonly { + title: string + prompt: string + integrations: readonly { id: string; name: string }[] + }[] +} + +import type { CredentialConnection } from '@/platform/lib/integrations/credential-model' diff --git a/apps/sim/platform/lib/integrations/catalog.generated.ts b/apps/sim/platform/lib/integrations/catalog.generated.ts new file mode 100644 index 00000000000..1d32755c0d8 --- /dev/null +++ b/apps/sim/platform/lib/integrations/catalog.generated.ts @@ -0,0 +1,6 @@ +/** Generated by scripts/sync-platform-integration-metadata.ts. */ +import 'server-only' +import type { IntegrationCatalogEntry } from '@/platform/lib/integrations/catalog-model' +export const integrationCatalog: readonly IntegrationCatalogEntry[] = JSON.parse( + '[{"id":"onepassword","type":"onepassword","slug":"1password","name":"1Password","description":"Manage secrets and items in 1Password vaults","category":"Security","docsUrl":"https://docs.sim.ai/integrations/onepassword","authType":"api-key","connections":[],"operations":[{"name":"List Vaults","description":"List all vaults accessible by the Connect token or Service Account"},{"name":"Get Vault","description":"Get details of a specific vault by ID"},{"name":"List Items","description":"List items in a vault. Returns summaries without field values."},{"name":"Get Item","description":"Get full details of an item including all fields and secrets"},{"name":"Get Item File","description":"Download the content of a file attached to an item"},{"name":"Create Item","description":"Create a new item in a vault"},{"name":"Replace Item","description":"Replace an entire item with new data (full update)"},{"name":"Update Item","description":"Update an existing item using JSON Patch operations (RFC6902)"},{"name":"Delete Item","description":"Delete an item from a vault"},{"name":"Resolve Secret","description":"Resolve a secret reference (op://vault/item/field) to its value. Service Account mode only."}],"triggers":[],"skills":[{"name":"fetch-secret-for-runtime","description":"Retrieve a secret (API key, token, or credential) from a 1Password vault to pass into a downstream step.","content":"# Fetch Secret for Runtime\\n\\nSecurely read a credential from 1Password so a later step can authenticate without hardcoding it.\\n\\n## Steps\\n1. Identify the vault and item that holds the needed secret.\\n2. Read the specific field (password, token, or key) from that item.\\n3. Pass the value to the downstream tool or request that needs it.\\n\\n## Output\\nConfirm the secret was retrieved without printing its value. Never echo, log, or include the raw secret in any summary or message."},{"name":"audit-vault-items","description":"List items in a 1Password vault and report metadata like titles, categories, and last-updated dates.","content":"# Audit Vault Items\\n\\nProduce an inventory of items in a 1Password vault for review.\\n\\n## Steps\\n1. List the items in the specified vault.\\n2. For each item collect non-sensitive metadata: title, category, tags, and last-updated date.\\n3. Flag items that look stale or duplicated based on titles and dates.\\n\\n## Output\\nA table of items with metadata only. Do not retrieve or display any secret values, just the item references."},{"name":"create-credential-item","description":"Store a new credential (login, API key, or token) as an item in a 1Password vault.","content":"# Create Credential Item\\n\\nSave a new secret into 1Password so it is centrally managed.\\n\\n## Steps\\n1. Determine the target vault and the item category (login, API credential, secure note).\\n2. Set the title and the secret fields from the provided values.\\n3. Create the item in the vault.\\n\\n## Output\\nConfirm the item was created with its title and vault. Do not repeat the secret value back in the response."}],"templates":[{"title":"1Password vault audit","prompt":"Build a scheduled monthly workflow that scans 1Password vaults for weak or reused passwords, expired items, and unused secrets, and writes a remediation queue.","integrations":[{"id":"onepassword","name":"1Password"}]},{"title":"1Password offboarding sweep","prompt":"Create a workflow that on a Workday termination rotates the shared 1Password secrets the departing employee had access to, updates the affected items, and writes the action log.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"workday","name":"Workday"}]},{"title":"1Password access-review automator","prompt":"Build a scheduled quarterly workflow that inventories 1Password items per vault, requires owner re-attestation in Slack, and writes the audit log to a compliance table.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"slack","name":"Slack"}]},{"title":"1Password secret rotation watcher","prompt":"Create a scheduled workflow that finds 1Password items older than the rotation policy, opens a Linear ticket per item to rotate, and writes the rotation status back.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"linear","name":"Linear"}]},{"title":"1Password onboarding kit","prompt":"Build a workflow that when a new hire is provisioned creates their starter 1Password items based on role and team, and writes the access record to the onboarding table.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"workday","name":"Workday"}]},{"title":"1Password Slack secret-share guard","prompt":"Create a workflow that monitors Slack for accidental secret sharing, redacts the message, and posts a polite reminder to use 1Password Secret Sharing instead.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"slack","name":"Slack"}]},{"title":"1Password compliance reporter","prompt":"Build a scheduled workflow that produces a 1Password compliance report — item counts, ages, and categories per vault — and writes the report file for auditors.","integrations":[{"id":"onepassword","name":"1Password"}]},{"title":"Secrets Manager + 1Password bridge","prompt":"Create a workflow that bridges select AWS Secrets Manager secrets into 1Password for human-shared credentials while keeping access logs aligned for audit.","integrations":[{"id":"onepassword","name":"1Password"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]}]},{"id":"affinity","type":"affinity","slug":"affinity","name":"Affinity","description":"Read and write companies, people, lists, notes, and relationships in Affinity","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/affinity","authType":"api-key","connections":[],"operations":[{"name":"List Companies","description":"Page through companies. Companies come back without field data unless Field IDs or Field Types asks for it."},{"name":"Get Company","description":"Look up one company by ID. Field data is returned only for the Field IDs or Field Types asked for."},{"name":"Search Companies","description":"Search companies by filters, sorts, and a free-text term. Requires the \\"Export All Organizations directory\\" permission."},{"name":"List People","description":"Page through persons. Persons come back without field data unless Field IDs or Field Types asks for it."},{"name":"Get Person","description":"Look up one person by ID. Field data is returned only for the Field IDs or Field Types asked for."},{"name":"Search People","description":"Search persons by filters, sorts, and a free-text term. Requires the \\"Export All People directory\\" permission."},{"name":"List Opportunities","description":"Page through opportunities. Field data lives on the list entry, not here — read it through the list or saved view the opportunity belongs to."},{"name":"Get Opportunity","description":"Read one opportunity and the list it belongs to. Its field data lives on the list entry."},{"name":"List Notes On Entity","description":"List the notes relevant to one company, person, or opportunity — directly attached notes plus notes reaching it through its people and meetings."},{"name":"List Lists Holding Entity","description":"List every list a company or person appears on that the caller can view."},{"name":"List Rows Holding Entity","description":"Page through a company\'s or person\'s rows across every list, each carrying that list\'s field values and when the entity was added."},{"name":"List Entity Relationships","description":"List who knows a company or person, scored 0.0 to 1.0 by how much the two actually interact. Strongest first by default."},{"name":"List Field Metadata","description":"List the non-list company or person fields, with the value type, filter operators, and sort support of each. Start here to find the Field IDs the read and write tools take."},{"name":"List Field Dropdown Options","description":"List the selectable options on a dropdown or ranked-dropdown company or person field. Writing such a field needs the option ID, not its text."},{"name":"List Entity Field Values","description":"Page through a company\'s or person\'s non-list field values. List fields are not returned here — read those through the list entry."},{"name":"Get Entity Field Value","description":"Read one non-list field value from a company or person."},{"name":"Update Entity Field Value","description":"Write one non-list field value on a company or person. The value type must match how the field is defined."},{"name":"Batch Update Entity Fields","description":"Write up to 100 non-list field values on one company or person in a single request."},{"name":"List Lists","description":"Page through the lists in the organization that the caller can view."},{"name":"Create List","description":"Create a list. Its type fixes which entities it can hold, and the API key holder becomes its creator and owner."},{"name":"Get List","description":"Read one list — its name, type, owner, and privacy setting."},{"name":"List List Fields","description":"List the fields available on one list, including its list-specific columns. Use these Field IDs when reading or writing list entries."},{"name":"List List Field Dropdown Options","description":"List the selectable options on a dropdown, ranked-dropdown, or status-dropdown field of a list."},{"name":"Create List Field Dropdown Option","description":"Add a selectable option to a dropdown field on a list. A ranked or status option also needs a rank and a color."},{"name":"Get List Field Dropdown Option","description":"Read one dropdown option on a list field."},{"name":"Update List Field Dropdown Option","description":"Change a dropdown option on a list field. Every field is optional — supply only what should change, and only fields the option\'s kind actually has."},{"name":"Delete List Field Dropdown Option","description":"Permanently delete a dropdown option on a list field. Every list entry currently set to it is cleared, and those values cannot be recovered."},{"name":"List List Entries","description":"Page through the rows of a list. Rows come back without field data unless Field IDs or Field Types asks for it."},{"name":"Search List Entries","description":"Search the rows of one list by filters, sorts, and a free-text term. Requires the \\"Export data from Lists\\" permission."},{"name":"Get List Entry","description":"Read one row of a list with its entity. Field data is returned only for the Field IDs or Field Types asked for."},{"name":"List List Entry Fields","description":"Page through every field value on one list row, including the list-specific columns. All fields are returned unless narrowed."},{"name":"Get List Entry Field","description":"Read one field value on a list row."},{"name":"Update List Entry Field","description":"Write one field value on a list row. Requires the \\"Export data from Lists\\" permission."},{"name":"Batch Update List Entry Fields","description":"Write up to 100 field values on one list row in a single request. Requires the \\"Export data from Lists\\" permission."},{"name":"List List Entry Field Value Changes","description":"Page through the history of one list row — who changed which field, when, and to what."},{"name":"List Saved Views","description":"List the saved views on a list that the caller can view."},{"name":"Get Saved View","description":"Read one saved view — its name, kind, and creation date."},{"name":"List Saved View Entries","description":"Page through the rows of a saved view. The view\'s own filters and columns decide which rows and which field data come back."},{"name":"List Notes","description":"Page through every note the caller can see. Replies are excluded."},{"name":"Create Note","description":"Write a note — attached to companies, persons, and opportunities, anchored to a meeting, call, or chat message, or posted as a reply to an existing note."},{"name":"Search Notes","description":"Search notes by keyword, ordered by relevance. Narrow to specific notes or to one company, or leave both unset to search the whole account."},{"name":"Get Note","description":"Read one note with its body, author, mentions, and attached records."},{"name":"Update Note","description":"Rewrite a note\'s body or replace which records it is attached to. Each list of IDs replaces that association wholesale, an empty list clears it, and omitting one leaves it untouched. A note\'s type cannot be changed."},{"name":"Delete Note","description":"Delete a note you created. Deleting a root note also deletes its replies; deleting a reply removes only that reply."},{"name":"List Note Replies","description":"Page through the replies on one note, including AI Notetaker replies."},{"name":"List Note Attached Companies","description":"List the companies directly attached to one note."},{"name":"List Note Attached People","description":"List the persons directly attached to one note."},{"name":"List Note Attached Opportunities","description":"List the opportunities directly attached to one note."},{"name":"List Calls","description":"Page through logged calls and their participants. Only calls the API key holder can see are returned."},{"name":"List Chat Messages","description":"Page through logged chat messages and their participants. Only messages the API key holder can see are returned."},{"name":"List Emails","description":"Page through email metadata — subject, participants, and timestamps. Affinity never exposes email bodies through the API."},{"name":"List Meetings","description":"Page through past and upcoming meetings with their organizer and attendees."},{"name":"List Transcripts","description":"Page through meeting transcript metadata. Read one transcript to get what was actually said."},{"name":"Get Transcript","description":"Read one transcript with its first 100 fragments. Page the fragments endpoint for a longer meeting."},{"name":"List Transcript Fragments","description":"Page through everything said in a meeting, segment by segment with the speaker."},{"name":"List Reminders","description":"Page through the reminders the caller can see. Filter by status to surface what is overdue."},{"name":"Create Reminder","description":"Create a reminder on one company, person, or opportunity. A recurring reminder resets whenever the chosen signal happens instead of firing once."},{"name":"List Merges","description":"Page through the company or person merges the organization has run, with the status and the records involved in each."},{"name":"Create Merge","description":"Fold a duplicate company or person into the record you are keeping. The merge runs asynchronously — poll the returned task to see it finish. Requires the \\"Manage duplicates\\" permission and an admin role."},{"name":"Get Merge","description":"Read the status of one company or person merge, including why it failed if it did."},{"name":"List Merge Tasks","description":"Page through merge tasks, each summarizing how many of its merges are in progress, succeeded, or failed."},{"name":"Get Merge Task","description":"Read one merge task and how its merges are progressing. Poll this after starting a merge."},{"name":"Semantic Search","description":"Find companies from a description in plain language — industry, technology, stage, or business model. Currently searches companies only."},{"name":"Search Files","description":"Search files by keyword, ordered by relevance. Narrow to specific files or to one company, or leave both unset to search the whole account."},{"name":"List Coworker Connections","description":"Find warm paths into a company through shared work history: who in your Affinity data once worked alongside the people you want to reach. Grouped by target, strongest first."},{"name":"List Investor Executive Connections","description":"Find warm paths into a company through investment history: which investors in your Affinity data backed a company the people you want to reach once led. Grouped by target, strongest first."},{"name":"List Field Value Changes","description":"Page through field value changes across the whole workspace. Built for delta sync: follow nextCursor to the end of a run, then resume from the last cursor next time."},{"name":"List Users","description":"Page through the internal users in the organization. Email addresses and roles are returned only to callers with the \\"Manage Users\\" permission."},{"name":"Get User","description":"Read one internal user. A user and their person record share the same numeric ID, so a person ID works here."},{"name":"Get Current User","description":"Verify an Affinity API key and return the tenant, the user behind the key, and the scopes the grant carries."}],"triggers":[],"skills":[{"name":"sync-affinity-pipeline","description":"Page a deal list or saved view out of Affinity with the columns a report needs. Use to mirror pipeline into a table before analysis.","content":"# Sync Affinity Pipeline\\n\\nMirror a deal list into a table you can query.\\n\\n## Steps\\n1. Find the list with List Lists, then read its columns with List List Fields and note the Field IDs the report needs.\\n2. Page List List Entries with those Field IDs, following nextCursor until a page comes back without one.\\n3. When the report should respect a view the team already curated, page List Saved View Entries instead — the view decides both the rows and the columns.\\n4. Flatten each row: the entity name and ID, plus one column per requested field value.\\n\\n## Output\\nReport how many rows were read and which fields were requested. Say explicitly when paging stopped early or a requested field was not on the list."},{"name":"update-affinity-deal-stage","description":"Move a deal to a new stage by writing its list field. Use when a workflow decides a stage change and must record it.","content":"# Update Affinity Deal Stage\\n\\nWrite a stage change back onto the deal row.\\n\\n## Steps\\n1. Read the list columns with List List Fields and find the status or stage field.\\n2. Read its options with List List Field Dropdown Options and match the target stage by text to get the option ID.\\n3. Write the row with Update List Entry Field, passing {\\"type\\":\\"ranked-dropdown\\",\\"data\\":{\\"dropdownOptionId\\":}} — or the plain dropdown shape when the field is not ranked.\\n4. When several columns move together, send them in one Batch Update List Entry Fields call instead.\\n\\n## Output\\nReport the row, the field, and the option written. Stop and say so when the stage name matches no existing option — never invent an option ID."},{"name":"enrich-affinity-company","description":"Fill in what Affinity knows about a company and write missing values back. Use before scoring or routing an account.","content":"# Enrich Affinity Company\\n\\nPull the full picture of a company and close the gaps.\\n\\n## Steps\\n1. Resolve the company — Search Companies on a name or domain, or Semantic Search when only a description is available.\\n2. Read the enriched and global fields with List Entity Field Values on that company.\\n3. Write anything the record is missing with Update Entity Field Value, matching the field\'s declared value type.\\n4. Add the lists the company already sits on with List Lists Holding Entity so the context travels with the record.\\n\\n## Output\\nReport the company matched, the fields already populated, and the fields written. Flag a name that matched more than one company rather than picking one."},{"name":"find-warm-intro","description":"Find who can introduce you into a target company, through relationship strength, shared work history, or investment history. Use before cold outreach.","content":"# Find Warm Intro\\n\\nFind the shortest real path into a company.\\n\\n## Steps\\n1. Resolve the target company to its ID with Search Companies.\\n2. Read List Entity Relationships on that company and keep the pairs with the highest interaction score — these are the paths that already exist.\\n3. Read List Coworker Connections filtered to target.currentCompany.id for people who once worked alongside the targets.\\n4. Read List Investor Executive Connections for paths through investors who backed a company a target once led.\\n5. Rank the paths by strength and name the specific person who should make each introduction.\\n\\n## Output\\nReport each path as introducer, target, and why the link exists. Say plainly when no path clears a useful threshold instead of surfacing weak ones."},{"name":"log-affinity-meeting-note","description":"Write a meeting summary into Affinity as a note attached to the right records. Use after a call or meeting.","content":"# Log Affinity Meeting Note\\n\\nPut a summary where the deal team will find it.\\n\\n## Steps\\n1. Find the interaction with List Meetings or List Calls, filtered to the window and the attendees.\\n2. When the meeting has an AI Notetaker transcript, read it with List Transcript Fragments and summarize what was actually said.\\n3. Write the note with Create Note as an interaction note anchored to that meeting or call, attaching the companies, people, and opportunities it concerns.\\n4. Reply to an existing thread with a user-reply note instead of a new root note when the summary continues a conversation.\\n\\n## Output\\nReport the note created, the interaction it is anchored to, and the records attached. Say so when no matching interaction was found and the note was attached to records only."},{"name":"affinity-followup-reminders","description":"Create reminders on deals that have gone quiet, and report the ones already overdue. Use for pipeline hygiene.","content":"# Affinity Follow-up Reminders\\n\\nStop deals from going silent.\\n\\n## Steps\\n1. Read the pipeline rows with List List Entries, including the last-interaction field the list exposes.\\n2. Read List Reminders filtered to overdue and match them against those rows so nothing is double-booked.\\n3. For a row past the staleness threshold with no live reminder, call Create Reminder against the company, person, or opportunity with a due date and a specific next step.\\n4. Use a recurring reminder with an interaction reset trigger when the deal needs standing attention rather than one nudge.\\n\\n## Output\\nReport the reminders created and the ones already overdue. Name the deals that were skipped and why."},{"name":"affinity-delta-sync","description":"Read only what changed in Affinity since the last run and apply it to a mirror. Use to keep a warehouse or table in step.","content":"# Affinity Delta Sync\\n\\nMove only the changes.\\n\\n## Steps\\n1. Start from the cursor the previous run stored. On a first run, start from a filter on changedAt instead.\\n2. Page List Field Value Changes ordered oldest first, following nextCursor until a page returns none.\\n3. Apply each change to the mirror by its action type: add, update, or delete. A change carrying a list entry belongs to that row, not to the entity as a whole.\\n4. Store the last cursor as the watermark for the next run, and store it only after the whole page applied.\\n\\n## Output\\nReport how many changes were read and applied, and the cursor to resume from. Say explicitly when the run stopped part way and the watermark was not advanced."}],"templates":[{"title":"Affinity pipeline digest","prompt":"Build a workflow that runs every Monday, pages my Affinity deal list for every row with its stage, owner, and last interaction date, and posts a Slack summary of what moved, what is stalled, and what is closing this month.","integrations":[{"id":"affinity","name":"Affinity"},{"id":"slack","name":"Slack"}]},{"title":"Affinity meeting note logger","prompt":"Create a workflow that finds yesterday’s Affinity meetings, reads the transcript of each one, writes a short summary as a note anchored to that meeting, and attaches it to the company and people who attended.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity warm intro finder","prompt":"Build an agent that takes a target company name, resolves it in Affinity, and reports who on my team can make an introduction — ranking relationships by interaction score and adding coworker and investor paths into the same company.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity deal stage sync","prompt":"Create a workflow that watches a table of deal decisions, looks up the matching Affinity list row, resolves the stage name to its dropdown option, and writes the new stage onto the row.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity company enrichment","prompt":"Build a workflow that takes new companies from my accounts table, searches Affinity for each one, reads its enriched fields, and writes headcount, location, and category back onto both the Affinity record and the table row.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity stale deal reminders","prompt":"Create a scheduled workflow that finds Affinity deals with no interaction in 30 days, creates a follow-up reminder on each one with a specific next step, and emails the owner a list of what went quiet.","integrations":[{"id":"affinity","name":"Affinity"},{"id":"gmail","name":"Gmail"}]},{"title":"Affinity semantic sourcing","prompt":"Build an agent that takes an investment thesis in plain language, runs a semantic search across my Affinity companies, and writes the best matches to a table with why each one fits and which list it already sits on.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity data room search","prompt":"Create a workflow that takes a diligence question, searches the notes and files attached to a company in Affinity, and answers with the passages it found and the note or file each one came from.","integrations":[{"id":"affinity","name":"Affinity"}]},{"title":"Affinity warehouse delta sync","prompt":"Build a scheduled workflow that reads the Affinity field value change feed from the cursor it stored last run, applies every add, update, and delete to my table mirror, and saves the new cursor only after the whole page applied.","integrations":[{"id":"affinity","name":"Affinity"}]}]},{"id":"agentmail","type":"agentmail","slug":"agentmail","name":"AgentMail","description":"Manage email inboxes, threads, and messages with AgentMail","category":"Email","docsUrl":"https://docs.sim.ai/integrations/agentmail","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send an email message from an AgentMail inbox"},{"name":"Reply to Message","description":"Reply to an existing email message in AgentMail"},{"name":"Forward Message","description":"Forward an email message to new recipients in AgentMail"},{"name":"List Threads","description":"List email threads in AgentMail"},{"name":"Get Thread","description":"Get details of a specific email thread including messages in AgentMail"},{"name":"Update Thread Labels","description":"Add or remove labels on an email thread in AgentMail"},{"name":"Delete Thread","description":"Delete an email thread in AgentMail (moves to trash, or permanently deletes if already in trash)"},{"name":"List Messages","description":"List messages in an inbox in AgentMail"},{"name":"Get Message","description":"Get details of a specific email message in AgentMail"},{"name":"Update Message Labels","description":"Add or remove labels on an email message in AgentMail"},{"name":"Create Draft","description":"Create a new email draft in AgentMail"},{"name":"List Drafts","description":"List email drafts in an inbox in AgentMail"},{"name":"Get Draft","description":"Get details of a specific email draft in AgentMail"},{"name":"Update Draft","description":"Update an existing email draft in AgentMail"},{"name":"Delete Draft","description":"Delete an email draft in AgentMail"},{"name":"Send Draft","description":"Send an existing email draft in AgentMail"},{"name":"Create Inbox","description":"Create a new email inbox with AgentMail"},{"name":"List Inboxes","description":"List all email inboxes in AgentMail"},{"name":"Get Inbox","description":"Get details of a specific email inbox in AgentMail"},{"name":"Update Inbox","description":"Update the display name of an email inbox in AgentMail"},{"name":"Delete Inbox","description":"Delete an email inbox in AgentMail"}],"triggers":[],"skills":[{"name":"triage-inbox-messages","description":"Read new messages in an AgentMail inbox, classify them, and reply or escalate as needed.","content":"# Triage Inbox Messages\\n\\nProcess unread email in an AgentMail inbox and act on each thread.\\n\\n## Steps\\n1. List recent messages in the inbox and identify which threads are unread or unanswered.\\n2. Read each thread for context including prior replies.\\n3. Classify intent (question, request, spam, follow-up needed) and urgency.\\n4. Draft and send a reply on the thread for routine items, or escalate by flagging the ones needing a human.\\n\\n## Output\\nA summary of threads handled: who, the classification, and the action taken (replied, escalated, ignored)."},{"name":"extract-verification-code","description":"Read a verification or OTP email in an AgentMail inbox and extract the code or confirmation link.","content":"# Extract Verification Code\\n\\nPull a 2FA/OTP code or confirmation link from an email so an agent can complete a signup or login flow.\\n\\n## Steps\\n1. Search the inbox for the most recent message from the expected sender or matching the subject.\\n2. Read the message body and extract the verification code or the confirmation URL.\\n3. Return only the code or link.\\n\\n## Output\\nThe extracted code or link. If multiple recent matches exist, return the newest and note its timestamp."},{"name":"send-and-track-outreach","description":"Send an email from an AgentMail inbox and monitor the thread for a reply to continue the conversation.","content":"# Send and Track Outreach\\n\\nSend an outbound email and follow the resulting thread.\\n\\n## Steps\\n1. Compose the message with a clear subject and body from the provided details.\\n2. Send it from the AgentMail inbox to the recipient.\\n3. Check the thread for a reply; when one arrives, read it and determine the next action.\\n\\n## Output\\nConfirm the message was sent with the thread ID. When a reply arrives, summarize it and recommend the next step."}],"templates":[{"title":"AgentMail inbox-per-customer","prompt":"Build a workflow that creates a dedicated AgentMail inbox for every new customer account, configures the display name and labels, and writes the inbox address back to the customer record so all customer email is isolated and threaded.","integrations":[{"id":"agentmail","name":"AgentMail"}]},{"title":"AgentMail support concierge","prompt":"Create a knowledge base from product docs and past resolutions, then build a scheduled workflow that polls an AgentMail inbox for new threads, drafts a contextual reply with citations, and either sends it or saves it as a draft based on confidence.","integrations":[{"id":"agentmail","name":"AgentMail"}]},{"title":"AgentMail draft assistant","prompt":"Build a scheduled workflow that polls AgentMail threads, drafts a reply that matches my tone using my recent sent messages as reference, and updates the existing draft each time the thread receives a new message so the draft stays current.","integrations":[{"id":"agentmail","name":"AgentMail"}]},{"title":"AgentMail label organizer","prompt":"Create a workflow that classifies new AgentMail messages by topic and customer tier, applies the matching thread labels, and moves threads with stale labels into archive labels on a weekly schedule.","integrations":[{"id":"agentmail","name":"AgentMail"}]},{"title":"AgentMail + Loops support touch-points","prompt":"Create a scheduled workflow that polls AgentMail support threads and sends a Loops event for each customer milestone — first contact, resolved, escalated — so Loops can automate the right follow-up email based on real support outcomes.","integrations":[{"id":"agentmail","name":"AgentMail"},{"id":"loops","name":"Loops"}]},{"title":"AgentMail outbound sequence sender","prompt":"Build a workflow that reads a prospects table, creates a personalized AgentMail draft per contact using their enriched profile, sends the message from a dedicated inbox, and logs the thread ID back to the row so replies can be tracked.","integrations":[{"id":"agentmail","name":"AgentMail"}]},{"title":"AgentMail thread escalation router","prompt":"Create a scheduled workflow that polls AgentMail inboxes for new messages, detects urgent or negative threads with an agent, forwards the full thread to the on-call address, and posts a Slack alert so nothing high-priority sits unanswered.","integrations":[{"id":"agentmail","name":"AgentMail"},{"id":"slack","name":"Slack"}]},{"title":"Resend + AgentMail reply handler","prompt":"Create a workflow that sends outbound messages through Resend but routes replies into a per-customer AgentMail inbox, threads them with the original send, and posts unread inbox digests to the support owner.","integrations":[{"id":"agentmail","name":"AgentMail"},{"id":"resend","name":"Resend"}]},{"title":"SES + AgentMail customer concierge","prompt":"Create a workflow that sends outbound customer messages through AWS SES but provisions a per-customer AgentMail inbox to receive replies, threads conversations across both, and tags AgentMail threads with the customer ID.","integrations":[{"id":"agentmail","name":"AgentMail"},{"id":"ses","name":"AWS SES"}]}]},{"id":"agentphone","type":"agentphone","slug":"agentphone","name":"AgentPhone","description":"Provision numbers, send SMS and iMessage, and place voice calls with AgentPhone","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/agentphone","authType":"api-key","connections":[],"operations":[{"name":"Create Number","description":"Provision a new SMS- and voice-enabled phone number"},{"name":"List Numbers","description":"List all phone numbers provisioned for this AgentPhone account"},{"name":"Release Number","description":"Release (delete) a phone number. This action is irreversible."},{"name":"Get Number Messages","description":"Fetch messages received on a specific phone number"},{"name":"Create Call","description":"Initiate an outbound voice call from an AgentPhone agent"},{"name":"List Calls","description":"List voice calls for this AgentPhone account"},{"name":"Get Call","description":"Fetch a call and its full transcript"},{"name":"Get Call Transcript","description":"Get the full ordered transcript for a call"},{"name":"List Conversations","description":"List conversations (message threads) for this AgentPhone account"},{"name":"Get Conversation","description":"Get a conversation along with its recent messages"},{"name":"Update Conversation","description":"Update conversation metadata (stored state). Pass null to clear existing metadata."},{"name":"Get Conversation Messages","description":"Get paginated messages for a conversation"},{"name":"Send Message","description":"Send an outbound SMS or iMessage from an AgentPhone agent"},{"name":"React to Message","description":"Send an iMessage tapback reaction to a message (iMessage only)"},{"name":"Create Contact","description":"Create a new contact in AgentPhone"},{"name":"List Contacts","description":"List contacts for this AgentPhone account"},{"name":"Get Contact","description":"Fetch a single contact by ID"},{"name":"Update Contact","description":"Update a contact\'s fields"},{"name":"Delete Contact","description":"Delete a contact by ID"},{"name":"Get Usage","description":"Retrieve current usage statistics for the AgentPhone account"},{"name":"Get Daily Usage","description":"Get a daily breakdown of usage (messages, calls, webhooks) for the last N days"},{"name":"Get Monthly Usage","description":"Get monthly usage aggregation (messages, calls, webhooks) for the last N months"}],"triggers":[],"skills":[{"name":"send-sms-notification","description":"Send an SMS or iMessage from an AgentPhone number to notify or remind a recipient.","content":"# Send SMS Notification\\n\\nSend a text message to a person from an AgentPhone number.\\n\\n## Steps\\n1. Determine the sending number and the recipient phone number.\\n2. Write a clear, concise message (reminder, alert, confirmation, or update).\\n3. Send the SMS or iMessage.\\n\\n## Output\\nConfirm the message was sent with the recipient number and a short preview of the text. Note any send failure."},{"name":"place-outbound-call","description":"Place a voice call from an AgentPhone number to deliver a message or run a short scripted interaction.","content":"# Place Outbound Call\\n\\nMake a voice call from an AgentPhone number for reminders, confirmations, or notifications.\\n\\n## Steps\\n1. Determine the AgentPhone number to call from and the destination number.\\n2. Prepare the spoken message or script to deliver.\\n3. Place the call and deliver the message.\\n\\n## Output\\nConfirm the call was placed with the destination number and the message delivered. Report call status or transcript if available."},{"name":"provision-and-respond","description":"Provision a phone number and handle inbound SMS by reading the message and sending an appropriate reply.","content":"# Provision and Respond\\n\\nSet up a phone number and respond to incoming texts.\\n\\n## Steps\\n1. Provision a US or Canadian phone number if one is not already assigned.\\n2. Read inbound SMS messages received on that number.\\n3. For each message, determine intent and send a relevant reply.\\n\\n## Output\\nReport the provisioned number, the inbound messages handled, and the replies sent."}],"templates":[{"title":"AgentPhone SMS support line","prompt":"Create a workflow that provisions an AgentPhone number, replies to inbound support texts with an agent that pulls answers from context, and logs each conversation to a support table.","integrations":[{"id":"agentphone","name":"AgentPhone"}]},{"title":"AgentPhone lead call + transcript scoring","prompt":"Build a workflow that places an outbound AgentPhone call to a new inbound lead, retrieves the call transcript afterward, scores qualification with an agent, and writes the result into HubSpot.","integrations":[{"id":"agentphone","name":"AgentPhone"},{"id":"hubspot","name":"HubSpot"}]},{"title":"AgentPhone post-call summary","prompt":"Create a workflow that runs after every AgentPhone call, summarizes the transcript with action items, and updates the linked Salesforce or HubSpot record with next steps.","integrations":[{"id":"agentphone","name":"AgentPhone"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"AgentPhone appointment reminder","prompt":"Build a workflow that reads upcoming Calendly bookings and sends an AgentPhone SMS reminder to each attendee, then texts a confirmation when they reply.","integrations":[{"id":"agentphone","name":"AgentPhone"},{"id":"calendly","name":"Calendly"}]},{"title":"AgentPhone NPS texter","prompt":"Create a scheduled workflow that texts recent customers an NPS survey over AgentPhone, reads their SMS replies, and writes structured ratings to a feedback table.","integrations":[{"id":"agentphone","name":"AgentPhone"}]},{"title":"AgentPhone collections reminder","prompt":"Build a workflow that picks up Stripe overdue invoices, sends a polite AgentPhone SMS payment reminder with the amount due, and reads the customer reply to update the invoice record.","integrations":[{"id":"agentphone","name":"AgentPhone"},{"id":"stripe","name":"Stripe"}]},{"title":"AgentPhone call-to-ticket logger","prompt":"Create a scheduled workflow that lists recent AgentPhone calls, pulls each transcript, and opens a Zendesk ticket summarizing the issue so no call goes untracked.","integrations":[{"id":"agentphone","name":"AgentPhone"},{"id":"zendesk","name":"Zendesk"}]}]},{"id":"agiloft","type":"agiloft","slug":"agiloft","name":"Agiloft","description":"Manage records in Agiloft CLM","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/agiloft","authType":"api-key","connections":[],"operations":[{"name":"List Tables & Fields","description":"List the tables and fields in an Agiloft knowledge base, to discover the logical names other operations need."},{"name":"Create Record","description":"Create a new record in an Agiloft table."},{"name":"Read Record","description":"Read a record by ID from an Agiloft table."},{"name":"Update Record","description":"Update an existing record in an Agiloft table."},{"name":"Upsert Record","description":"Create an Agiloft record, or update it when a record already matches the given fields."},{"name":"Delete Record","description":"Delete a record from an Agiloft table."},{"name":"Search Records","description":"Search for records in an Agiloft table using a query."},{"name":"Natural Language Search","description":"Search Agiloft records by describing what you want in plain language, such as \\"active NDAs submitted last month\\"."},{"name":"Select Records","description":"Select record IDs matching a SQL WHERE clause from an Agiloft table."},{"name":"Attach File","description":"Attach a file to a field in an Agiloft record."},{"name":"Retrieve Attachment","description":"Download an attached file from an Agiloft record field."},{"name":"Remove Attachment","description":"Remove an attached file from a field in an Agiloft record."},{"name":"Attachment Info","description":"Get information about file attachments on a record field."},{"name":"Lock Record","description":"Lock, unlock, or check the lock status of an Agiloft record."},{"name":"Run Action Button","description":"Run an action button on an Agiloft record, such as an approval or send-for-signature step."},{"name":"Async Status","description":"Check whether an asynchronous Agiloft call, such as a run action button, has completed."},{"name":"Saved Search","description":"List the saved searches defined for an Agiloft table."},{"name":"Get Choice Line ID","description":"Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields."}],"triggers":[],"skills":[{"name":"flag-expiring-contracts","description":"Query Agiloft for contracts approaching their renewal or expiration date and report the ones at risk.","content":"# Flag Expiring Contracts\\n\\nFind contracts in Agiloft that are nearing expiration or auto-renewal so the team can act in time.\\n\\n## Steps\\n1. Query the contract records for upcoming expiration or renewal dates within the target window.\\n2. For each match, read key terms: counterparty, value, renewal type, and notice period.\\n3. Identify contracts with auto-renewal clauses that need a decision before the notice deadline.\\n\\n## Output\\nA list of at-risk contracts sorted by date, with counterparty, expiration date, renewal type, and recommended action."},{"name":"create-contract-record","description":"Create a new contract or related record in Agiloft from provided deal or request details.","content":"# Create Contract Record\\n\\nAdd a new contract record to Agiloft from intake details.\\n\\n## Steps\\n1. Map the provided details to the contract record fields (counterparty, type, value, start/end dates, owner).\\n2. Set status to the correct initial stage in the lifecycle.\\n3. Create the record and capture its ID.\\n\\n## Output\\nConfirm the record was created with its ID and key fields. Note any required fields that were missing."},{"name":"summarize-contract-terms","description":"Read a contract record in Agiloft and produce a plain-language summary of its key obligations and dates.","content":"# Summarize Contract Terms\\n\\nTurn an Agiloft contract record into a concise brief.\\n\\n## Steps\\n1. Read the contract record and its key fields and attached terms.\\n2. Identify obligations, payment terms, renewal/termination clauses, and critical dates.\\n3. Note any unusual or high-risk terms.\\n\\n## Output\\nA short brief: parties, term, value, key obligations, critical dates, and any risk flags. Keep it readable for non-lawyers."},{"name":"collect-executed-contract-documents","description":"Pull the signed documents attached to Agiloft contract records so they can be archived or reviewed elsewhere.","content":"# Collect Executed Contract Documents\\n\\nGather the executed files attached to Agiloft contract records.\\n\\n## Steps\\n1. Identify the contract records in scope, by saved search or by an ad hoc query.\\n2. For each record, list the attachments on the document field to see what is present and how large each file is.\\n3. Download the attachment at the position that holds the executed copy.\\n\\n## Output\\nOne entry per contract: record ID, counterparty, file name, and size. Call out any record where the document field is empty or holds an unexpected number of files."},{"name":"safely-edit-a-locked-record","description":"Check and manage the record lock on an Agiloft record before and after an automated edit.","content":"# Safely Edit a Locked Record\\n\\nAvoid clobbering another user\'s in-progress edit when a workflow updates an Agiloft record.\\n\\n## Steps\\n1. Check the lock status on the record before writing. If it reports LOCKED, report who holds it and stop rather than overwriting.\\n2. When the record is free, take the lock, apply the update, then release it.\\n3. Locks expire on their own, so keep the locked window as short as the update needs.\\n\\n## Output\\nState what the lock status was, whether the update was applied or deferred, and confirm the lock was released."}],"templates":[{"title":"Agiloft contract launcher","prompt":"Build a workflow that on a closed-won Salesforce opportunity creates an Agiloft contract record from the right template, fills key fields from the opportunity, and routes for legal review.","integrations":[{"id":"agiloft","name":"Agiloft"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Agiloft clause analyzer","prompt":"Create a workflow that pulls Agiloft contracts on a schedule, extracts key clauses, writes deviations from the standard template to a legal review table.","integrations":[{"id":"agiloft","name":"Agiloft"}]},{"title":"Agiloft renewal tracker","prompt":"Build a scheduled workflow that finds Agiloft contracts with renewals due in the next 90 days, creates a renewal-prep task in the CRM, and emails the account owner.","integrations":[{"id":"agiloft","name":"Agiloft"},{"id":"salesforce","name":"Salesforce"},{"id":"gmail","name":"Gmail"}]},{"title":"Agiloft approval router","prompt":"Create a scheduled workflow that searches Agiloft for contracts needing approval, posts a Microsoft Teams adaptive card to the approver, captures the decision, and updates Agiloft.","integrations":[{"id":"agiloft","name":"Agiloft"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Agiloft compliance audit","prompt":"Build a scheduled monthly workflow that audits Agiloft contracts against compliance requirements, flags missing clauses or expired terms, and writes a remediation backlog.","integrations":[{"id":"agiloft","name":"Agiloft"}]},{"title":"Agiloft DocuSign bridge","prompt":"Create a scheduled workflow that searches Agiloft for contracts marked ready-to-sign, creates a DocuSign envelope from the template, sends it, and writes the envelope ID back to Agiloft.","integrations":[{"id":"agiloft","name":"Agiloft"},{"id":"docusign","name":"DocuSign"}]},{"title":"Agiloft + Linear ticket bridge","prompt":"Build a scheduled workflow that searches Agiloft for contracts flagged for engineering review and creates a Linear ticket with the contract context and a link, keeping status synced both ways.","integrations":[{"id":"agiloft","name":"Agiloft"},{"id":"linear","name":"Linear"}]}]},{"id":"ahrefs","type":"ahrefs","slug":"ahrefs","name":"Ahrefs","description":"SEO analysis with Ahrefs","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/ahrefs","authType":"api-key","connections":[],"operations":[{"name":"Domain Rating","description":"Get the Domain Rating (DR) and Ahrefs Rank for a target domain. Domain Rating shows the strength of a website\'s backlink profile on a scale from 0 to 100."},{"name":"Metrics Overview","description":"Get a one-call organic and paid search overview for a target domain or URL: organic traffic, organic keywords, paid traffic, paid keywords, and estimated traffic cost."},{"name":"Backlinks","description":"Get a list of backlinks pointing to a target domain or URL. Returns details about each backlink including source URL, anchor text, and domain rating."},{"name":"Backlinks Stats","description":"Get backlink and referring domain totals for a target domain or URL, both currently live and across all time."},{"name":"Referring Domains","description":"Get a list of domains that link to a target domain or URL. Returns unique referring domains with their domain rating, backlink counts, and discovery dates."},{"name":"Broken Backlinks","description":"Get a list of broken backlinks pointing to a target domain or URL. Useful for identifying link reclamation opportunities."},{"name":"Organic Keywords","description":"Get organic keywords that a target domain or URL ranks for in Google search results. Returns keyword details including search volume, ranking position, and estimated traffic."},{"name":"Organic Competitors","description":"Get domains that compete with a target domain or URL for the same organic keywords, ranked by keyword overlap."},{"name":"Top Pages","description":"Get the top pages of a target domain sorted by organic traffic. Returns page URLs with their traffic, keyword counts, and estimated traffic value."},{"name":"Paid Pages","description":"Get a target domain\'s pages that receive paid search traffic, sorted by estimated paid traffic. Returns page URLs with their paid traffic, keyword counts, and estimated spend."},{"name":"Anchors","description":"Get the anchor text distribution for a target domain or URL\'s backlinks, showing how many links and referring domains use each anchor text."},{"name":"Keyword Overview","description":"Get detailed metrics for a keyword including search volume, keyword difficulty, CPC, clicks, and traffic potential."},{"name":"Related Terms","description":"Get keyword ideas related to a seed keyword: terms the same top-ranking pages also rank for (\\"also rank for\\") or also discuss (\\"also talk about\\"), with volume, difficulty, and CPC."},{"name":"Domain Rating History","description":"Get the historical Domain Rating (DR) trend for a target domain or URL over a date range, grouped daily, weekly, or monthly."},{"name":"Metrics History","description":"Get the historical organic and paid traffic trend for a target domain or URL over a date range: organic traffic/cost and paid traffic/cost at each point in time."},{"name":"Referring Domains History","description":"Get the historical referring domains trend for a target domain or URL over a date range, grouped daily, weekly, or monthly."},{"name":"Keywords History","description":"Get the historical organic keyword ranking distribution for a target domain or URL over a date range: how many keywords rank in each position bucket at each point in time."},{"name":"Batch Analysis","description":"Get bulk SEO metrics (Domain Rating, backlinks, referring domains, organic traffic, and more) for multiple domains or URLs in a single request. Useful for comparing many competitors at once."},{"name":"Site Audit Page Explorer","description":"Get crawled pages from an Ahrefs Site Audit project with health and SEO metrics: HTTP status, title, link counts, backlinks, indexability, and traffic. Optionally filter to pages affected by a specific issue."},{"name":"Rank Tracker Overview","description":"Get ranking overview metrics for the keywords tracked in an Ahrefs Rank Tracker project: position, search volume, keyword difficulty, and estimated traffic. This endpoint is free and does not consume API units."},{"name":"Rank Tracker SERP Overview","description":"Get the full SERP (search engine results page) for a keyword tracked in an Ahrefs Rank Tracker project, including every ranking URL with its position, title, and authority metrics. This endpoint is free and does not consume API units."},{"name":"Rank Tracker Competitors Overview","description":"Get competitor rankings for the keywords tracked in an Ahrefs Rank Tracker project: each tracked keyword\'s volume and difficulty alongside every competitor\'s position, traffic, and traffic value. This endpoint is free and does not consume API units."},{"name":"Rank Tracker Competitors Stats","description":"Get aggregate competitor stats for an Ahrefs Rank Tracker project: each competitor\'s traffic, traffic value, average position, and share of voice across all tracked keywords. This endpoint is free and does not consume API units."}],"triggers":[],"skills":[{"name":"analyze-competitor-backlinks","description":"Pull a competitor domain\'s backlink profile from Ahrefs and surface link-building opportunities.","content":"# Analyze Competitor Backlinks\\n\\nUse Ahrefs to study a competitor\'s backlinks and find outreach targets.\\n\\n## Steps\\n1. Run a backlink/referring-domains report for the competitor URL or domain.\\n2. Identify high-authority referring domains and the anchor texts they use.\\n3. Compare against your own domain to find sites linking to them but not you.\\n\\n## Output\\nA prioritized list of link opportunities: referring domain, authority, linked page, and why it is worth pursuing."},{"name":"keyword-research-report","description":"Research keywords in Ahrefs for a topic and report volume, difficulty, and ranking opportunities.","content":"# Keyword Research Report\\n\\nBuild a keyword opportunity report from Ahrefs data.\\n\\n## Steps\\n1. Pull the organic keywords a competitor domain already ranks for to source candidate keywords for the topic.\\n2. Run a keyword overview on the most relevant candidates to collect search volume and keyword difficulty.\\n3. Highlight keywords with meaningful volume and lower difficulty as quick wins.\\n\\n## Output\\nA table of keywords with volume and difficulty, grouped into quick wins vs long-term targets, with a short recommendation."},{"name":"track-organic-rankings","description":"Pull a domain\'s organic keyword rankings from Ahrefs and report top movers and lost positions.","content":"# Track Organic Rankings\\n\\nReport how a domain is ranking in organic search using Ahrefs.\\n\\n## Steps\\n1. Pull the organic keywords report for the target domain.\\n2. Identify the top-ranking keywords and their positions.\\n3. Compare against a prior snapshot if available to find gains and losses.\\n\\n## Output\\nA summary of top organic keywords, notable position gains and drops, and pages that may need attention."},{"name":"find-organic-competitors","description":"Use Ahrefs organic competitors data to identify sites competing for the same search traffic.","content":"# Find Organic Competitors\\n\\nSurface who actually competes with a domain in organic search using Ahrefs.\\n\\n## Steps\\n1. Run an organic competitors report for the target domain.\\n2. Rank results by common keyword overlap and competitor traffic.\\n3. Cross-reference against the known competitor list to flag new entrants.\\n\\n## Output\\nA ranked list of organic competitors with keyword overlap and traffic, highlighting any that are not yet being tracked."}],"templates":[{"title":"Ahrefs keyword tracker","prompt":"Create a scheduled weekly workflow that queries Ahrefs for ranking positions of my tracked keywords, logs the results into a tables-based SEO scorecard, and posts a Slack summary of gainers and losers.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs competitor backlink monitor","prompt":"Build a scheduled workflow that pulls new Ahrefs referring domains for my competitors weekly, flags high-authority links, and posts a Slack digest with the linking page and anchor text.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs content gap finder","prompt":"Create a workflow that pulls Ahrefs organic keywords for both my domain and a competitor, has an agent diff the lists to find keywords the competitor ranks for that I do not, and writes a prioritized content brief table.","integrations":[{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs broken-link sweeper","prompt":"Build a scheduled workflow that runs an Ahrefs broken-backlinks check weekly, writes broken referring pages to a remediation table, and proposes redirects for the SEO lead to approve.","integrations":[{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs organic competitor finder","prompt":"Build a monthly workflow that pulls Ahrefs organic competitors for my domain, cross-references them against my tracked competitor list, and posts newly surfaced competitors to Slack for review.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs + Similarweb growth scoreboard","prompt":"Build a scheduled monthly workflow that joins Ahrefs SEO data with Similarweb traffic intelligence, writes a growth scoreboard table, and emails leadership.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"similarweb","name":"Similarweb"},{"id":"gmail","name":"Gmail"}]},{"title":"Ahrefs + Profound combined visibility","prompt":"Create a scheduled weekly workflow that combines Ahrefs SEO rankings with Profound AI-visibility scores, writes a combined visibility report, and surfaces gaps to Slack.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"profound","name":"Profound"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs domain-health watchdog","prompt":"Build a scheduled workflow that checks Ahrefs domain rating and backlink stats for my site daily, logs the values to a trend table, and posts a Slack alert when domain rating drops or a spike of lost referring domains is detected.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs Rank Tracker daily digest","prompt":"Build a scheduled daily workflow that pulls the Ahrefs Rank Tracker overview for my project, has an agent summarize position and traffic movers, and posts the digest to Slack.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Ahrefs batch competitor snapshot","prompt":"Create a workflow that runs an Ahrefs batch analysis across a list of competitor domains, writes the resulting Domain Rating, backlinks, and organic traffic to a comparison table, and has an agent call out the biggest gaps.","integrations":[{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs Site Audit issue tracker","prompt":"Build a scheduled weekly workflow that pulls crawled pages from an Ahrefs Site Audit project, writes non-compliant or broken pages to a remediation table, and posts a Slack summary for the SEO lead.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Semrush + Ahrefs visibility scoreboard","prompt":"Build a scheduled monthly workflow that joins Semrush domain overview data with Ahrefs backlink metrics, writes a combined visibility scoreboard table, and emails leadership.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"semrush","name":"Semrush"},{"id":"gmail","name":"Gmail"}]},{"title":"WordPress SEO refresher","prompt":"Create a scheduled monthly workflow that finds underperforming WordPress posts, runs Ahrefs keyword analysis, drafts refreshed sections, and stages the update as a draft revision.","integrations":[{"id":"ahrefs","name":"Ahrefs"},{"id":"wordpress","name":"WordPress"}]}]},{"id":"airtable","type":"airtable","slug":"airtable","name":"Airtable","description":"Read, create, and update Airtable","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/airtable","authType":"oauth","connections":[{"id":"airtable","kind":"oauth","label":"Connect with OAuth","providerId":"airtable","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/airtable","requiredScopes":[{"id":"data.records:read","label":"Read records"},{"id":"data.records:write","label":"Create, edit, and delete records"},{"id":"schema.bases:read","label":"View bases and tables"},{"id":"user.email:read","label":"Read email address"},{"id":"webhook:manage","label":"Create, view, and delete base webhooks and read their payloads"}],"fields":[]},{"id":"airtable-service-account","kind":"service_account","providerId":"airtable-service-account","label":"Add personal access token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/airtable-service-account","fields":[{"id":"apiToken","label":"Personal access token","placeholder":"pat...","secret":true,"hint":"Airtable personal access tokens usually start with pat."}]}],"operations":[{"name":"List Bases","description":"List all bases the authenticated user has access to"},{"name":"List Tables","description":"List all tables and their schema in an Airtable base"},{"name":"Get Base Schema","description":"Get the schema of all tables, fields, and views in an Airtable base"},{"name":"List Records","description":"Read records from an Airtable table"},{"name":"Get Record","description":"Retrieve a single record from an Airtable table by its ID"},{"name":"Create Records","description":"Write new records to an Airtable table"},{"name":"Update Record","description":"Update an existing record in an Airtable table by ID"},{"name":"Update Multiple Records","description":"Update multiple existing records in an Airtable table"},{"name":"Upsert Records","description":"Update existing records or create new ones in an Airtable table, matching on the specified merge fields"},{"name":"Delete Records","description":"Delete one or more records from an Airtable table by ID"}],"triggers":[{"id":"airtable_webhook","name":"Airtable Webhook","description":"Trigger workflow from Airtable record changes like create, update, and delete events (requires Airtable credentials)"}],"skills":[{"name":"sync-records-to-table","description":"Parse incoming emails, forms, or documents and create or update structured Airtable records.","content":"# Sync Records to Airtable\\n\\nTurn unstructured inbound data into clean Airtable records.\\n\\n## Steps\\n1. Read the source content (email body, form payload, or document text).\\n2. Extract the fields that map to the target table columns (name, email, company, amount, status, etc.).\\n3. Search the table for an existing record matching a unique key (such as email or order ID).\\n4. Update the existing record if found; otherwise create a new one.\\n5. Set any derived fields (category, priority, owner) based on the content.\\n\\n## Output\\nReport how many records were created vs updated and list the record IDs. Flag any rows skipped for missing required fields."},{"name":"triage-and-route-records","description":"Classify new Airtable records (leads, tickets, requests) and assign owner, priority, and due dates.","content":"# Triage and Route Records\\n\\nAutomatically qualify and route new Airtable records.\\n\\n## Steps\\n1. List recently created records in the target table.\\n2. For each record, read the free-text fields (notes, message, transcript) and classify intent, urgency, and category.\\n3. Set the owner, priority, and status fields based on the classification.\\n4. Compute and set a due date for time-sensitive items.\\n\\n## Output\\nSummarize the records triaged grouped by owner and priority. Note any records that need human review."},{"name":"generate-status-report","description":"Query an Airtable table or view and produce a rolled-up status report of progress, blockers, and trends.","content":"# Generate Status Report\\n\\nBuild a concise report from an Airtable table or view.\\n\\n## Steps\\n1. Read records from the specified table or filtered view.\\n2. Group by the relevant dimension (project, status, owner, or stage).\\n3. Count totals per group and identify overdue or stalled items.\\n4. Highlight notable changes or anomalies in the data.\\n\\n## Output\\nA short report: totals per group, items at risk, and 2-3 takeaways. Keep it scannable with bullet points."}],"templates":[{"title":"Airtable data sync","prompt":"Create a scheduled workflow that syncs records from my Airtable base into a Sim table every hour, keeping both in sync. Use an agent to detect changes, resolve conflicts, and flag any discrepancies for review in Slack.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"slack","name":"Slack"}]},{"title":"Airtable two-way sync","prompt":"Build a scheduled workflow that mirrors records between an Airtable base and a Sim table, detects conflicts, and pings Slack on records that need manual resolution.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"slack","name":"Slack"}]},{"title":"Airtable form-to-CRM","prompt":"Create a workflow that watches Airtable form submissions, enriches each row with company data, and pushes qualifying leads into HubSpot with the right owner.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Airtable content calendar publisher","prompt":"Build a workflow that reads an Airtable content calendar, publishes due posts to WordPress with proper formatting, and writes the live URL back to the row.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"wordpress","name":"WordPress"}]},{"title":"Airtable approval workflow","prompt":"Create a workflow that watches Airtable for new approval rows, posts a Slack message with quick-action buttons, captures the decision, and updates the row state.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"slack","name":"Slack"}]},{"title":"Airtable digest reporter","prompt":"Build a scheduled weekly workflow that summarizes activity in a chosen Airtable base — new rows, status changes, completed items — and emails a digest to the project owner.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"gmail","name":"Gmail"}]},{"title":"Airtable to data-warehouse sync","prompt":"Create a scheduled workflow that exports an Airtable base to BigQuery nightly with schema mapping, partitions by ingestion date, and writes the run history to a control table.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"Trigger Gmail from Airtable records","prompt":"Build a workflow that watches Airtable for new or updated records and sends a personalised Gmail message for each one, so outreach and follow-ups go out automatically.","integrations":[{"id":"airtable","name":"Airtable"},{"id":"gmail","name":"Gmail"}]}]},{"id":"algolia","type":"algolia","slug":"algolia","name":"Algolia","description":"Search and manage Algolia indices","category":"Search","docsUrl":"https://docs.sim.ai/integrations/algolia","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search an Algolia index"},{"name":"Add Record","description":"Add or replace a record in an Algolia index"},{"name":"Get Record","description":"Get a record by objectID from an Algolia index"},{"name":"Get Records","description":"Retrieve multiple records by objectID from one or more Algolia indices"},{"name":"Partial Update Record","description":"Partially update a record in an Algolia index without replacing it entirely"},{"name":"Delete Record","description":"Delete a record by objectID from an Algolia index"},{"name":"Browse Records","description":"Browse and iterate over all records in an Algolia index using cursor pagination"},{"name":"Batch Operations","description":"Perform batch add, update, partial update, or delete operations on records in an Algolia index"},{"name":"List Indices","description":"List all indices in an Algolia application"},{"name":"Get Settings","description":"Retrieve the settings of an Algolia index"},{"name":"Update Settings","description":"Update the settings of an Algolia index"},{"name":"Delete Index","description":"Delete an entire Algolia index and all its records"},{"name":"Copy/Move Index","description":"Copy or move an Algolia index to a new destination"},{"name":"Clear Records","description":"Clear all records from an Algolia index while keeping settings, synonyms, and rules"},{"name":"Delete By Filter","description":"Delete all records matching a filter from an Algolia index"},{"name":"Get Task Status","description":"Check whether an Algolia indexing task has finished publishing"}],"triggers":[],"skills":[{"name":"answer-from-search-index","description":"Search an Algolia index for a user question and return a grounded answer with the matching records.","content":"# Answer From Search Index\\n\\nUse Algolia retrieval to answer questions over indexed content (docs, products, knowledge base).\\n\\n## Steps\\n1. Take the user question and run a search against the relevant Algolia index.\\n2. Apply filters or facets to narrow results (category, status, language) when appropriate.\\n3. Read the top hits and synthesize an answer grounded only in the returned records.\\n4. If no relevant hits are returned, say so rather than guessing.\\n\\n## Output\\nA concise answer plus the titles and IDs of the records used. Do not invent content not present in the hits."},{"name":"index-new-records","description":"Take new or updated content and push it into an Algolia index as searchable records.","content":"# Index New Records\\n\\nKeep an Algolia index in sync with new content.\\n\\n## Steps\\n1. Collect the source items to index (products, articles, entries).\\n2. Map each item to a record object with a stable objectID and the searchable/filterable attributes.\\n3. Save the records to the target index, updating existing objectIDs in place.\\n4. Verify by running a quick search for one of the new records.\\n\\n## Output\\nReport how many records were added or updated and confirm one is retrievable via search."},{"name":"audit-search-relevance","description":"Run a set of test queries against an Algolia index and report which return weak or empty results.","content":"# Audit Search Relevance\\n\\nCheck that important queries return good results from an Algolia index.\\n\\n## Steps\\n1. Run each query in the provided test set against the index.\\n2. Record the top results, total hit count, and whether the expected record appears.\\n3. Flag queries that return zero hits, too many hits, or miss the expected record.\\n\\n## Output\\nA table of queries with result counts and pass/fail, plus suggestions for synonyms or ranking tweaks where relevance is weak."},{"name":"tune-index-ranking","description":"Read an Algolia index configuration, propose ranking and searchable-attribute changes, and apply the update.","content":"# Tune Index Ranking\\n\\nAdjust how an Algolia index ranks results without touching the underlying data.\\n\\n## Steps\\n1. Fetch the current index settings (searchable attributes, custom ranking, ranking criteria).\\n2. Compare them against the desired outcome (e.g., surface newer or more popular items first).\\n3. Propose specific changes to customRanking, searchableAttributes order, or attributesForFaceting.\\n4. Apply the approved settings update to the index.\\n\\n## Output\\nA before/after summary of the settings changed and why, plus confirmation the update succeeded."},{"name":"snapshot-index-before-change","description":"Copy an Algolia index to a timestamped backup before applying a risky settings or data change.","content":"# Snapshot Index Before Change\\n\\nProtect against a bad settings or batch update by copying the index first.\\n\\n## Steps\\n1. Copy the source index to a new destination index named with a date or version suffix.\\n2. Confirm the copy completed by checking the resulting task status.\\n3. Apply the intended change (settings update, batch operation, or delete-by-filter) to the original index.\\n4. If the change causes problems, the snapshot index can be copied back or used for comparison.\\n\\n## Output\\nThe name of the backup index created and confirmation the source change was applied afterward."}],"templates":[{"title":"Algolia content indexer","prompt":"Build a workflow that watches a content source — WordPress, knowledge base — and upserts records into an Algolia index, removing deleted items for accurate search.","integrations":[{"id":"algolia","name":"Algolia"},{"id":"wordpress","name":"WordPress"}]},{"title":"Algolia search-quality auditor","prompt":"Create a scheduled workflow that runs benchmark queries against an Algolia index weekly, scores top-result relevance, and writes a quality report.","integrations":[{"id":"algolia","name":"Algolia"}]},{"title":"Algolia settings tuner","prompt":"Build a workflow that reads an Algolia index settings, has an agent propose improvements to searchable attributes and ranking, and applies the approved settings update.","integrations":[{"id":"algolia","name":"Algolia"}]},{"title":"Algolia index reconciler","prompt":"Create a workflow that browses all records in an Algolia index, compares them against a source-of-truth table, and batches adds, updates, and deletes to keep the index accurate.","integrations":[{"id":"algolia","name":"Algolia"}]},{"title":"Algolia + knowledge base sync","prompt":"Build a workflow that mirrors a Sim knowledge base into an Algolia index, keeping vector retrieval and keyword search aligned for hybrid retrieval.","integrations":[{"id":"algolia","name":"Algolia"}]},{"title":"Algolia index inventory","prompt":"Create a scheduled workflow that lists all Algolia indices and their record counts, writes a daily inventory snapshot to a table, and pings on-call in Slack when an index record count drops unexpectedly.","integrations":[{"id":"algolia","name":"Algolia"},{"id":"slack","name":"Slack"}]},{"title":"Algolia stale-record sweeper","prompt":"Build a scheduled workflow that browses an Algolia index, flags records older than a freshness threshold, writes them to a cleanup table, and deletes the confirmed stale records.","integrations":[{"id":"algolia","name":"Algolia"}]},{"title":"Convex search index sync","prompt":"Build a scheduled workflow that uses Convex Document Deltas to mirror changed documents into an Algolia index, removes deleted documents, and writes sync lag to a tables-based monitor.","integrations":[{"id":"algolia","name":"Algolia"},{"id":"convex","name":"Convex"}]},{"title":"Supabase + Algolia search sync","prompt":"Build a scheduled workflow that mirrors Supabase tables into an Algolia index, propagates new and changed rows on each run, and writes sync lag to a tables-based monitor.","integrations":[{"id":"algolia","name":"Algolia"},{"id":"supabase","name":"Supabase"}]}]},{"id":"dynamodb","type":"dynamodb","slug":"amazon-dynamodb","name":"Amazon DynamoDB","description":"Get, put, query, scan, update, and delete items in Amazon DynamoDB tables","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/dynamodb","authType":"api-key","connections":[],"operations":[{"name":"Get Item","description":"Get an item from a DynamoDB table by primary key"},{"name":"Put Item","description":"Put an item into a DynamoDB table"},{"name":"Query","description":"Query items from a DynamoDB table using key conditions"},{"name":"Scan","description":"Scan all items in a DynamoDB table"},{"name":"Update Item","description":"Update an item in a DynamoDB table"},{"name":"Delete Item","description":"Delete an item from a DynamoDB table"},{"name":"Introspect","description":"Introspect DynamoDB to list tables or get detailed schema information for a specific table"}],"triggers":[],"skills":[{"name":"lookup-item-by-key","description":"Get a single DynamoDB item by its primary key and return the requested attributes.","content":"# Lookup Item by Key\\n\\nRetrieve one record from a DynamoDB table by its key.\\n\\n## Steps\\n1. Identify the table and the partition key (and sort key if the table uses one).\\n2. Get the item by its key.\\n3. Return the requested attributes, or report that no item exists for that key.\\n\\n## Output\\nThe item attributes if found, or a clear \\"not found\\" result. Do not fabricate values for missing attributes."},{"name":"query-table-records","description":"Query a DynamoDB table or index by partition key with optional filters and return the matching items.","content":"# Query Table Records\\n\\nFetch a set of related items from DynamoDB using a query.\\n\\n## Steps\\n1. Determine the table or secondary index and the partition key value to query.\\n2. Add a sort-key condition or filter expression if needed to narrow results.\\n3. Run the query and collect the items, paginating if there are more.\\n\\n## Output\\nThe matching items and a count. Note if results were truncated by a limit or pagination boundary."},{"name":"upsert-item","description":"Create or update a DynamoDB item, setting attributes from provided values.","content":"# Upsert Item\\n\\nWrite a record into a DynamoDB table.\\n\\n## Steps\\n1. Build the item with its primary key and the attributes to set.\\n2. Put the item, or use an update expression to modify only specific attributes.\\n3. Confirm the write succeeded.\\n\\n## Output\\nConfirm the item key written and which attributes were set or updated."}],"templates":[{"title":"DynamoDB hot-partition watcher","prompt":"Build a scheduled workflow that pulls DynamoDB CloudWatch metrics, identifies hot partitions and throttled requests, and writes the report to a Slack channel with mitigation suggestions.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"cloudwatch","name":"CloudWatch"},{"id":"slack","name":"Slack"}]},{"title":"DynamoDB TTL backfill","prompt":"Create a workflow that scans a DynamoDB table for items missing the TTL attribute, computes the correct TTL based on creation time, and updates in batches with throttling.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"}]},{"title":"DynamoDB to S3 archive","prompt":"Build a scheduled workflow that exports DynamoDB items older than the retention horizon to S3 with Parquet partitioning and removes the rows from the table, writing the archive manifest.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"s3","name":"S3"}]},{"title":"DynamoDB change publisher","prompt":"Create a scheduled workflow that scans a DynamoDB table for items changed since the last run, transforms each into a typed event, and publishes it to an SQS queue for downstream processing.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"sqs","name":"Amazon SQS"}]},{"title":"DynamoDB capacity recommender","prompt":"Build a scheduled weekly workflow that analyzes DynamoDB capacity consumption, recommends switches between provisioned and on-demand per table, and writes the savings projection to a finance review file.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"}]},{"title":"DynamoDB GSI health audit","prompt":"Create a scheduled workflow that scans DynamoDB GSIs for skew, low projection efficiency, and unused indexes, and writes a remediation plan to engineering Slack.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"slack","name":"Slack"}]},{"title":"DynamoDB + Athena unified analytics","prompt":"Create a workflow that exports DynamoDB tables nightly into Athena-queryable Parquet, registers the schema, and writes a sample query for analyst use.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"athena","name":"Athena"}]},{"title":"Upstash + DynamoDB hybrid store","prompt":"Create a workflow that uses Upstash for hot keys and DynamoDB for cold storage, transparently promotes/demotes records based on access frequency.","integrations":[{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"upstash","name":"Upstash"}]}]},{"id":"ec2","type":"ec2","slug":"amazon-ec2","name":"Amazon EC2","description":"Manage EC2 instances, Elastic IPs, VPC networking, and EBS","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/ec2","authType":"api-key","connections":[],"operations":[{"name":"Describe Instances","description":"List EC2 instances with their state, type, networking, and tags"},{"name":"Describe Instance Status","description":"Get status checks and scheduled events for EC2 instances"},{"name":"Start Instances","description":"Start one or more stopped EC2 instances"},{"name":"Stop Instances","description":"Stop one or more running EC2 instances"},{"name":"Reboot Instances","description":"Request a reboot of one or more EC2 instances"},{"name":"Terminate Instances","description":"Permanently terminate one or more EC2 instances"},{"name":"Describe Elastic IPs","description":"List Elastic IP addresses and what they are associated with"},{"name":"Allocate Elastic IP","description":"Allocate a new Elastic IP address for use in a VPC"},{"name":"Associate Elastic IP","description":"Associate an Elastic IP address with an instance or network interface"},{"name":"Disassociate Elastic IP","description":"Disassociate an Elastic IP address from its instance or network interface"},{"name":"Release Elastic IP","description":"Release an Elastic IP address back to AWS"},{"name":"Describe NAT Gateways","description":"List NAT gateways with their state, subnet, and IP addresses"},{"name":"Describe Route Tables","description":"List VPC route tables with their routes and subnet associations"},{"name":"Describe VPCs","description":"List VPCs with their CIDR blocks and state"},{"name":"Describe Subnets","description":"List subnets with their CIDR, Availability Zone, and free IP count"},{"name":"Describe Security Groups","description":"List security groups with their inbound and outbound rules"},{"name":"Authorize Security Group Ingress","description":"Add an inbound rule to a security group"},{"name":"Revoke Security Group Ingress","description":"Remove inbound rules from a security group by rule ID or by matching protocol, ports, and source"},{"name":"Describe Network ACLs","description":"List network ACLs with their inbound and outbound rules and subnet associations"},{"name":"Describe Internet Gateways","description":"List internet gateways and the VPCs they are attached to"},{"name":"Describe Network Interfaces","description":"List elastic network interfaces with their IPs, attachment, and security groups"},{"name":"Describe VPC Endpoints","description":"List VPC endpoints with their service, type, state, and network placement"},{"name":"Describe VPC Peering Connections","description":"List VPC peering connections with their status and both VPCs"},{"name":"Describe EBS Volumes","description":"List EBS volumes with their size, type, state, and attachments"},{"name":"Delete EBS Volume","description":"Permanently delete an EBS volume that is not attached to an instance"},{"name":"Describe EBS Snapshots","description":"List EBS snapshots owned by the account (or by the owners you specify)"},{"name":"Create EBS Snapshot","description":"Create a point-in-time snapshot of an EBS volume"},{"name":"Delete EBS Snapshot","description":"Permanently delete an EBS snapshot"},{"name":"Describe AMIs","description":"List AMIs owned by the account (or by the owners you specify)"},{"name":"Describe Key Pairs","description":"List EC2 key pairs with their type, fingerprint, and creation time"},{"name":"Create Tags","description":"Add or overwrite tags on one or more EC2 resources"},{"name":"Delete Tags","description":"Remove tags from one or more EC2 resources"},{"name":"Describe Regions","description":"List AWS Regions available to the account"},{"name":"Describe Availability Zones","description":"List Availability Zones, Local Zones, and Wavelength Zones in the region"}],"triggers":[],"skills":[{"name":"map-subnet-egress-ips","description":"Use Amazon EC2 route tables, NAT gateways, and Elastic IPs to work out which public IP each subnet reaches the internet through. Use when a partner or vendor needs your outbound IPs for an allowlist.","content":"# Map Subnet Egress IPs\\n\\nWork out the public IPs that outbound traffic from each subnet uses.\\n\\n## Steps\\n1. Describe route tables (filter by vpc-id when the VPC is known) and read each table\'s subnet associations and its 0.0.0.0/0 route.\\n2. For routes that target a NAT gateway, describe that NAT gateway and read the public IPs in its addresses.\\n3. For routes that target an internet gateway, note that instances egress through their own public or Elastic IP; describe Elastic IPs to list them.\\n4. Subnets with no explicit association use the main route table for the VPC.\\n\\n## Output\\nA table of subnet ID, route table ID, egress target (NAT gateway or internet gateway), and the public egress IPs."},{"name":"find-unassociated-elastic-ips","description":"List Amazon EC2 Elastic IP addresses that are not associated with any instance or network interface, which AWS bills for while idle. Use for cost reviews.","content":"# Find Unassociated Elastic IPs\\n\\nFind Elastic IPs that are allocated but unused.\\n\\n## Steps\\n1. Describe Elastic IP addresses in the region.\\n2. Keep addresses with no association ID, instance ID, or network interface ID.\\n3. Exclude addresses whose tags mark them as reserved.\\n4. Only release an address after explicit confirmation, because a released IP cannot be guaranteed back.\\n\\n## Output\\nEach unassociated address with its public IP, allocation ID, and tags."},{"name":"audit-open-security-groups","description":"Check Amazon EC2 security groups for inbound rules open to the whole internet (0.0.0.0/0 or ::/0), especially on SSH, RDP, and database ports. Use for security reviews.","content":"# Audit Open Security Groups\\n\\nFind inbound rules that expose resources to the internet.\\n\\n## Steps\\n1. Describe security groups, optionally filtered by VPC.\\n2. For each ingress rule, check IPv4 ranges for 0.0.0.0/0 and IPv6 ranges for ::/0.\\n3. Treat protocol -1 (all traffic) and ports 22, 3389, 3306, and 5432 as high severity.\\n4. Ports 80 and 443 open to the internet are usually expected for public load balancers; report them separately.\\n5. Only after the owner approves, revoke the offending rule by group ID, protocol, port range, and the open CIDR.\\n\\n## Output\\nEach finding with the group ID, group name, VPC, protocol, port range, and open CIDR, and whether it was revoked."},{"name":"stop-instances-off-hours","description":"Stop Amazon EC2 instances tagged for office-hours scheduling outside working hours and start them again in the morning. Use to cut cost on dev and test environments.","content":"# Stop Instances Off Hours\\n\\nRun non-production instances only when they are needed.\\n\\n## Steps\\n1. Describe instances with filters tag:Schedule = office-hours and instance-state-name = running (or stopped for the morning run).\\n2. Collect the instance IDs.\\n3. Stop the instances in the evening, or start them in the morning.\\n4. Report the state transitions returned for each instance.\\n\\n## Output\\nThe instance IDs acted on with their previous and current states."},{"name":"snapshot-tagged-volumes","description":"Create EBS snapshots of every Amazon EC2 volume carrying a backup tag. Use for scheduled backups.","content":"# Snapshot Tagged Volumes\\n\\nBack up EBS volumes that are marked for backup.\\n\\n## Steps\\n1. Describe volumes with the filter tag:Backup = true.\\n2. For each volume, create a snapshot with a dated description and tags that record the source volume and run date.\\n3. Record the snapshot ID and state for each volume.\\n4. Describe snapshots later to confirm they reached the completed state.\\n\\n## Output\\nA list of volume IDs and the snapshot IDs created for them."},{"name":"clean-up-old-snapshots","description":"Delete Amazon EBS snapshots older than a retention window, keeping the most recent ones per volume. Use to control snapshot storage cost.","content":"# Clean Up Old Snapshots\\n\\nApply a retention policy to EBS snapshots.\\n\\n## Steps\\n1. Describe snapshots owned by the account, optionally filtered by tag.\\n2. Group them by source volume and sort each group by start time.\\n3. Keep the newest snapshots per volume and anything tagged to retain; mark the rest older than the retention window.\\n4. Delete each marked snapshot. A snapshot used by a registered AMI cannot be deleted; report it instead.\\n\\n## Output\\nThe snapshot IDs deleted and any that were skipped with the reason."},{"name":"find-blackhole-routes","description":"Find Amazon EC2 VPC routes in the blackhole state, which happen when a route targets a deleted NAT gateway, instance, or network interface. Use when a subnet suddenly loses connectivity.","content":"# Find Blackhole Routes\\n\\nLocate routes that point at targets that no longer exist.\\n\\n## Steps\\n1. Describe route tables with the filter route.state = blackhole, optionally narrowed by vpc-id.\\n2. For each table, list the routes whose state is blackhole and their target IDs.\\n3. List the subnets associated with each affected table.\\n\\n## Output\\nEach blackhole route with its route table, destination CIDR, missing target, and affected subnets."},{"name":"check-instance-scheduled-events","description":"Check Amazon EC2 instance status for failed status checks and scheduled maintenance events such as retirement or system reboot. Use to plan around AWS maintenance.","content":"# Check Instance Scheduled Events\\n\\nSurface instances that need attention.\\n\\n## Steps\\n1. Describe instance status, including stopped instances if needed.\\n2. Flag instances whose instance or system status check is impaired.\\n3. List scheduled events with their code, description, and not-before and not-after window.\\n\\n## Output\\nEach affected instance with its failed checks and upcoming events."}],"templates":[{"title":"EC2 egress IP map","prompt":"Build a workflow that lists Elastic IPs, NAT gateways, and route tables in Amazon EC2, works out which public IPs each private subnet egresses through, and writes the subnet-to-egress-IP map to a table so partners can allowlist the right addresses.","integrations":[{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 off-hours scheduler","prompt":"Create a scheduled workflow that every weekday evening finds Amazon EC2 instances tagged Schedule=office-hours that are running, stops them, starts them again each morning, and posts a summary of the instances changed to Slack.","integrations":[{"id":"ec2","name":"Amazon EC2"},{"id":"slack","name":"Slack"}]},{"title":"EC2 unused Elastic IP finder","prompt":"Build a scheduled weekly workflow that lists Amazon EC2 Elastic IP addresses, flags any with no association, records them in a cost table with their allocation IDs and tags, and asks for approval in Slack before releasing them.","integrations":[{"id":"ec2","name":"Amazon EC2"},{"id":"slack","name":"Slack"}]},{"title":"EC2 open security group audit","prompt":"Create a scheduled daily workflow that describes Amazon EC2 security groups, flags inbound rules open to 0.0.0.0/0 or ::/0 on ports other than 80 and 443, files a finding for each with the group, VPC, and offending rule, and revokes the rule once the owner approves in Slack.","integrations":[{"id":"ec2","name":"Amazon EC2"},{"id":"slack","name":"Slack"}]},{"title":"EBS nightly snapshot","prompt":"Build a scheduled nightly workflow that lists Amazon EC2 EBS volumes tagged Backup=true, creates a snapshot of each with a dated description and tags, and logs the snapshot IDs to a backup table.","integrations":[{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 unattached volume cleanup","prompt":"Create a scheduled weekly workflow that finds Amazon EC2 EBS volumes in the available state, estimates their monthly cost from size and type, snapshots each one, sends the list to Slack for approval, and deletes the approved volumes.","integrations":[{"id":"ec2","name":"Amazon EC2"},{"id":"slack","name":"Slack"}]},{"title":"EC2 scheduled event watcher","prompt":"Build a scheduled workflow that checks Amazon EC2 instance status for impaired status checks and scheduled events such as instance retirement or system reboot, and opens a ticket for each affected instance with the event window.","integrations":[{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 tag compliance enforcer","prompt":"Create a scheduled workflow that lists Amazon EC2 instances, volumes, and Elastic IPs, finds resources missing the Owner or CostCenter tag, applies a default tag where the owner can be inferred, and reports the rest to Slack.","integrations":[{"id":"ec2","name":"Amazon EC2"},{"id":"slack","name":"Slack"}]}]},{"id":"rds","type":"rds","slug":"amazon-rds","name":"Amazon RDS","description":"Connect to Amazon RDS via Data API","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/rds","authType":"none","connections":[],"operations":[{"name":"Query (SELECT)","description":"Execute a SELECT query on Amazon RDS using the Data API"},{"name":"Insert Data","description":"Insert data into an Amazon RDS table using the Data API"},{"name":"Update Data","description":"Update data in an Amazon RDS table using the Data API"},{"name":"Delete Data","description":"Delete data from an Amazon RDS table using the Data API"},{"name":"Execute Raw SQL","description":"Execute raw SQL on Amazon RDS using the Data API"},{"name":"Introspect Schema","description":"Introspect Amazon RDS Aurora database schema to retrieve table structures, columns, and relationships"}],"triggers":[],"skills":[{"name":"run-readonly-query","description":"Run a parameterized SELECT against Amazon RDS via the Data API and return the rows.","content":"# Run Read-only Query\\n\\nQuery an RDS database through the Data API to answer a question.\\n\\n## Steps\\n1. Write a SELECT statement that returns only the columns needed.\\n2. Use parameters for any user-supplied values instead of string concatenation.\\n3. Execute the statement and collect the result rows.\\n\\n## Output\\nThe returned rows in a readable table plus a row count. If the result is large, summarize and note that it was limited."},{"name":"lookup-record","description":"Fetch a specific record from Amazon RDS by an identifier and return its fields.","content":"# Lookup Record\\n\\nRetrieve one row from an RDS table by a key.\\n\\n## Steps\\n1. Identify the table and the unique identifier (id, email, order number).\\n2. Run a parameterized SELECT filtered by that identifier.\\n3. Return the matching row, or report that no record was found.\\n\\n## Output\\nThe record fields if found, or a clear \\"not found\\" result. Do not invent field values."},{"name":"insert-record","description":"Insert a new row into an Amazon RDS table from provided field values via the Data API.","content":"# Insert Record\\n\\nWrite a new record into an RDS table through the Data API.\\n\\n## Steps\\n1. Identify the target table and map the input values to its columns as key-value pairs.\\n2. Run the insert operation with that data object.\\n3. To load several rows, repeat the insert for each item, or use the Execute Raw SQL operation with a multi-row INSERT statement.\\n\\n## Output\\nConfirm the table written to and how many rows were inserted. Flag any items skipped for missing required fields."}],"templates":[{"title":"RDS daily metrics digest","prompt":"Build a scheduled workflow that runs an aggregate SQL query against my Amazon RDS database each morning, summarizes the key numbers with an agent, and posts the digest to Slack.","integrations":[{"id":"rds","name":"Amazon RDS"},{"id":"slack","name":"Slack"}]},{"title":"RDS natural-language query agent","prompt":"Create an agent that introspects my Amazon RDS schema, turns plain-English questions into SQL, runs the query through the Data API, and returns the results in a readable answer.","integrations":[{"id":"rds","name":"Amazon RDS"}]},{"title":"RDS lead capture","prompt":"Build a workflow triggered by a form submission that validates the payload and inserts a new lead row into my Amazon RDS database, then confirms the write back to the submitter.","integrations":[{"id":"rds","name":"Amazon RDS"}]},{"title":"RDS to spreadsheet export","prompt":"Create a scheduled workflow that queries Amazon RDS for the latest records, writes the rows into a Sim table, and keeps a running export the operations team can review.","integrations":[{"id":"rds","name":"Amazon RDS"}]},{"title":"RDS record updater from Slack","prompt":"Build a workflow that reads update requests posted in a Slack channel, parses the target record and fields with an agent, and runs the matching UPDATE against Amazon RDS with the conditions applied.","integrations":[{"id":"rds","name":"Amazon RDS"},{"id":"slack","name":"Slack"}]},{"title":"RDS row-change alerter","prompt":"Create a scheduled workflow that queries Amazon RDS for rows matching a watch condition, compares them to the previous run stored in a table, and posts a Slack alert when a tracked record changes.","integrations":[{"id":"rds","name":"Amazon RDS"},{"id":"slack","name":"Slack"}]},{"title":"RDS + BigQuery analytics mirror","prompt":"Build a scheduled workflow that queries analytical tables from Amazon RDS, loads the rows into BigQuery for downstream BI, and writes a sync log to a table.","integrations":[{"id":"rds","name":"Amazon RDS"},{"id":"google_bigquery","name":"Google BigQuery"}]}]},{"id":"sqs","type":"sqs","slug":"amazon-sqs","name":"Amazon SQS","description":"Connect to Amazon SQS","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/sqs","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send a message to an Amazon SQS queue"},{"name":"Send Message Batch","description":"Send up to 10 messages to an Amazon SQS queue in a single request"},{"name":"Receive Message","description":"Receive up to 10 messages from an Amazon SQS queue, with optional long polling"},{"name":"Delete Message","description":"Delete a received message from an Amazon SQS queue using its receipt handle"},{"name":"Delete Message Batch","description":"Delete up to 10 received messages from an Amazon SQS queue in a single request"},{"name":"Change Message Visibility","description":"Change how long a received Amazon SQS message stays hidden from other consumers"},{"name":"Change Message Visibility Batch","description":"Change the visibility timeout of up to 10 received Amazon SQS messages at once"},{"name":"List Queues","description":"List Amazon SQS queue URLs in a region, optionally filtered by name prefix"},{"name":"Get Queue URL","description":"Resolve an Amazon SQS queue name to its queue URL"},{"name":"Get Queue Attributes","description":"Read configuration and message-count attributes of an Amazon SQS queue"},{"name":"Set Queue Attributes","description":"Update configuration attributes of an existing Amazon SQS queue"},{"name":"Create Queue","description":"Create a standard or FIFO Amazon SQS queue"},{"name":"Delete Queue","description":"Delete an Amazon SQS queue and every message still in it"},{"name":"Purge Queue","description":"Delete every message in an Amazon SQS queue while keeping the queue itself"},{"name":"List Dead-Letter Source Queues","description":"List the Amazon SQS queues that use a given queue as their dead-letter queue"},{"name":"List Queue Tags","description":"List the cost-allocation tags attached to an Amazon SQS queue"},{"name":"Tag Queue","description":"Add or overwrite cost-allocation tags on an Amazon SQS queue"},{"name":"Untag Queue","description":"Remove cost-allocation tags from an Amazon SQS queue"},{"name":"Start Message Move Task","description":"Start redriving messages out of an Amazon SQS dead-letter queue"},{"name":"List Message Move Tasks","description":"List the most recent message move tasks for an Amazon SQS source queue"},{"name":"Cancel Message Move Task","description":"Cancel an in-progress Amazon SQS message move task"}],"triggers":[],"skills":[{"name":"enqueue-job-message","description":"Send a structured job message to an Amazon SQS queue to hand off background work.","content":"# Enqueue Job Message\\n\\nPublish a task onto an SQS queue for a worker to process asynchronously.\\n\\n## Steps\\n1. Identify the target queue URL.\\n2. Build the message body as JSON describing the job (type, payload, identifiers).\\n3. For a FIFO queue, set the message group and deduplication IDs.\\n4. Send the message.\\n\\n## Output\\nConfirm the message was sent with its message ID and the queue it was placed on."},{"name":"send-ordered-fifo-message","description":"Send a message to an Amazon SQS FIFO queue with a message group ID and deduplication ID for ordered, exactly-once delivery.","content":"# Send Ordered FIFO Message\\n\\nDispatch a message to a FIFO queue when ordering within a stream and de-duplication matter.\\n\\n## Steps\\n1. Identify the FIFO queue URL.\\n2. Build the JSON message body.\\n3. Set the message group ID so messages in the same group stay ordered, and set a deduplication ID to prevent duplicate sends.\\n4. Send the message.\\n\\n## Output\\nConfirm the message was sent with its message ID, group ID, and the queue it was placed on."},{"name":"drain-queue-batch","description":"Receive a batch of Amazon SQS messages with long polling, process them, and delete each one so it is not redelivered.","content":"# Drain Queue Batch\\n\\nPull a batch of work off an SQS queue, act on it, and acknowledge it. This is the standard consumer loop: a message stays invisible for its visibility timeout and reappears unless it is deleted.\\n\\n## Steps\\n1. Receive from the queue with a max message count of up to 10 and a wait time of up to 20 seconds so the call long-polls instead of returning empty.\\n2. Process each returned message body.\\n3. Delete each processed message by its receipt handle, using the batch delete when more than one succeeded.\\n4. Leave any message you could not process undeleted so it becomes visible again or lands in the dead-letter queue.\\n\\n## Output\\nReport how many messages were received, how many were processed, and how many were deleted."},{"name":"extend-processing-lease","description":"Extend the visibility timeout of an in-flight Amazon SQS message so long-running work finishes before the message is redelivered.","content":"# Extend Processing Lease\\n\\nWhen handling a message takes longer than the queue visibility timeout, extend the timeout so another consumer does not pick up the same message and the eventual delete does not fail.\\n\\n## Steps\\n1. Note the receipt handle of the message being processed.\\n2. Before the current visibility timeout expires, change the message visibility to a new timeout that covers the remaining work, up to 43200 seconds.\\n3. Repeat while processing continues.\\n4. Delete the message once the work is done.\\n\\n## Output\\nReport the message the lease was extended for and the new timeout in seconds."},{"name":"redrive-dead-letter-queue","description":"Move messages out of an Amazon SQS dead-letter queue back to their source queue, and track the move task to completion.","content":"# Redrive Dead-Letter Queue\\n\\nAfter fixing the defect that caused failures, replay the messages parked in a dead-letter queue.\\n\\n## Steps\\n1. List the source queues that redrive to the dead-letter queue to confirm which workloads are affected.\\n2. Start a message move task from the dead-letter queue ARN, leaving the destination empty to return each message to its original source queue. Throttle it with a per-second cap if the consumers are fragile.\\n3. List the move tasks for the queue to watch status, messages moved, and messages left to move.\\n4. Cancel the task if the replay needs to stop; only a running task can be cancelled.\\n\\n## Output\\nReport the task handle, its status, and how many messages were moved."},{"name":"check-queue-backlog","description":"Read the message counts and configuration of an Amazon SQS queue to judge backlog and consumer health.","content":"# Check Queue Backlog\\n\\nInspect a queue before scaling consumers or opening an incident.\\n\\n## Steps\\n1. Resolve the queue URL from its name if you only have the name.\\n2. Read the queue attributes, requesting ApproximateNumberOfMessages, ApproximateNumberOfMessagesNotVisible, ApproximateNumberOfMessagesDelayed, VisibilityTimeout, and RedrivePolicy.\\n3. Compare the visible backlog against the in-flight count to tell a slow consumer from an absent one.\\n4. If a redrive policy is set, check the dead-letter queue backlog too.\\n\\n## Output\\nReport the visible, in-flight, and delayed message counts, the visibility timeout, and whether a dead-letter queue is configured."},{"name":"provision-worker-queue","description":"Create an Amazon SQS queue with a dead-letter queue, a visibility timeout matched to the work, and cost-allocation tags.","content":"# Provision Worker Queue\\n\\nStand up a queue for a new background workload with the settings a production consumer needs.\\n\\n## Steps\\n1. Create the dead-letter queue first so its ARN exists.\\n2. Read the dead-letter queue attributes to get its QueueArn.\\n3. Create the main queue, setting VisibilityTimeout to comfortably exceed the expected processing time, MessageRetentionPeriod to the replay window you want, and RedrivePolicy pointing at the dead-letter queue ARN with a maxReceiveCount. Add FifoQueue when ordering matters, naming the queue with a .fifo suffix.\\n4. Tag both queues with owner and environment for cost allocation.\\n\\n## Output\\nReport the URLs of the created queues and the redrive policy linking them."},{"name":"reset-queue-for-test","description":"Clear every message from a non-production Amazon SQS queue so a test run starts from a known empty state.","content":"# Reset Queue For Test\\n\\nEmpty a scratch or staging queue between test runs. Purging deletes every message and cannot be undone, so confirm the queue is not production.\\n\\n## Steps\\n1. Resolve the queue URL and read its attributes to confirm the environment tag and current message count.\\n2. Purge the queue.\\n3. Wait before purging again; SQS rejects a second purge within 60 seconds of the first.\\n4. Re-read the message count to confirm the queue is empty.\\n\\n## Output\\nReport the queue purged and how many messages it held beforehand."}],"templates":[{"title":"DynamoDB change publisher","prompt":"Create a scheduled workflow that scans a DynamoDB table for items changed since the last run, transforms each into a typed event, and publishes it to an SQS queue for downstream processing.","integrations":[{"id":"sqs","name":"Amazon SQS"},{"id":"dynamodb","name":"Amazon DynamoDB"}]},{"title":"SQS event dispatcher","prompt":"Build a workflow that runs after a customer event is processed, formats a structured message, and pushes it onto an Amazon SQS queue so downstream worker services can pick it up. Log every dispatched event into a table for audit and replay.","integrations":[{"id":"sqs","name":"Amazon SQS"}]},{"title":"SQS dead-letter replayer","prompt":"Create a scheduled workflow that runs every morning, scans a table of failed jobs, regenerates the original payload, and republishes each failed message to its Amazon SQS queue with retry metadata so transient failures are recovered automatically.","integrations":[{"id":"sqs","name":"Amazon SQS"}]},{"title":"Webhook to SQS bridge","prompt":"Build a workflow exposed as a webhook endpoint that accepts inbound events from third-party services, validates the payload against a schema, transforms it into your internal event format, sends it to Amazon SQS for asynchronous processing, and returns an acknowledgement to the caller.","integrations":[{"id":"sqs","name":"Amazon SQS"}]},{"title":"SQS alert enricher","prompt":"Create a workflow triggered by PagerDuty or Datadog alerts that classifies severity, decorates the payload with runbook context, and pushes the enriched alert to an Amazon SQS queue so multiple downstream notifiers and ticketing systems can consume it independently.","integrations":[{"id":"sqs","name":"Amazon SQS"},{"id":"pagerduty","name":"PagerDuty"},{"id":"datadog","name":"Datadog"}]},{"title":"SQS batch order queue","prompt":"Build a workflow that takes a list of orders from a table and queues each one as a separate Amazon SQS message for parallel downstream processing. Track each enqueued message ID in the table so you can correlate downstream results back to the originating row.","integrations":[{"id":"sqs","name":"Amazon SQS"}]},{"title":"Scheduled SQS fan-out","prompt":"Create a scheduled workflow that runs every fifteen minutes, queries pending items from a table, batches them, and pushes one Amazon SQS message per batch to your worker queue. Update the table with batch IDs and timestamps so reprocessing is deterministic.","integrations":[{"id":"sqs","name":"Amazon SQS"}]},{"title":"SQS cross-service notifier","prompt":"Build a workflow that listens for completed builds in your CI tool, composes a status payload with build metadata and artifact links, and sends the payload to an Amazon SQS queue so internal services like deploy, audit, and notification workers can react asynchronously.","integrations":[{"id":"sqs","name":"Amazon SQS"}]}]},{"id":"amplitude","type":"amplitude","slug":"amplitude","name":"Amplitude","description":"Track events and query analytics from Amplitude","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/amplitude","authType":"api-key","connections":[],"operations":[{"name":"Send Event","description":"Track an event in Amplitude using the HTTP V2 API."},{"name":"Identify User","description":"Set user properties in Amplitude using the Identify API. Supports $set, $setOnce, $add, $append, $unset operations."},{"name":"Group Identify","description":"Set group-level properties in Amplitude. Supports $set, $setOnce, $add, $append, $unset operations."},{"name":"User Search","description":"Search for a user by User ID, Device ID, or Amplitude ID using the Dashboard REST API."},{"name":"User Activity","description":"Get the event stream for a specific user by their Amplitude ID."},{"name":"User Profile","description":"Get a user profile including properties, cohort memberships, and computed properties. Not available for EU data-residency projects."},{"name":"Event Segmentation","description":"Query event analytics data with segmentation. Get event counts, uniques, averages, and more."},{"name":"Get Active Users","description":"Get active or new user counts over a date range from the Dashboard REST API."},{"name":"Real-time Active Users","description":"Get real-time active user counts at 5-minute granularity for the last 2 days."},{"name":"List Events","description":"List all event types in the Amplitude project with their weekly totals and unique counts."},{"name":"Get Revenue","description":"Get revenue LTV data including ARPU, ARPPU, total revenue, and paying user counts."},{"name":"Funnels","description":"Analyze conversion rates and drop-off between a sequence of events."},{"name":"Retention","description":"Measure how many users return to perform an action after a starting action."}],"triggers":[],"skills":[{"name":"track-product-event","description":"Send a behavioral event to Amplitude with user and event properties for analytics.","content":"# Track Product Event\\n\\nLog a user action to Amplitude so it shows up in analytics.\\n\\n## Steps\\n1. Determine the event name and the user identifier (user ID or device ID).\\n2. Attach relevant event properties (plan, source, value) and user properties.\\n3. Send the event to Amplitude.\\n\\n## Output\\nConfirm the event was sent with its name and the user it was attributed to. Note any required field that was missing."},{"name":"segment-event-counts","description":"Run Amplitude event segmentation over a date range and report unique and total counts, optionally grouped by a property.","content":"# Segment Event Counts\\n\\nMeasure how often an event fires in Amplitude over a time window.\\n\\n## Steps\\n1. Identify the event type and the start and end dates (YYYYMMDD) to analyze.\\n2. Pick the measurement (uniques, totals, or average) and the interval (daily, weekly, monthly).\\n3. Optionally group by a user or event property to break the counts down by segment.\\n4. Run the event segmentation query and read the resulting time series.\\n\\n## Output\\nThe series of counts per interval, the segment breakdown if grouped, and a callout of the largest movement versus the start of the range."},{"name":"summarize-engagement-metrics","description":"Pull Amplitude active users, top events, and revenue and summarize product engagement for a period.","content":"# Summarize Engagement Metrics\\n\\nProduce a short product engagement summary from Amplitude data.\\n\\n## Steps\\n1. Query active and new users for the target period.\\n2. Pull the most-triggered events with event segmentation to see what users do most.\\n3. Pull revenue metrics for the same period.\\n4. Compare each against the prior period to spot trends.\\n\\n## Output\\nA concise summary: active users, top events, revenue, and notable trends versus the prior period."},{"name":"lookup-user-activity","description":"Find a user in Amplitude by ID and pull their recent event activity and profile properties.","content":"# Lookup User Activity\\n\\nInvestigate a single user in Amplitude for support or debugging.\\n\\n## Steps\\n1. Search for the user by user ID, device ID, or Amplitude ID to resolve their Amplitude ID.\\n2. Pull the user activity stream for that Amplitude ID, ordered latest first.\\n3. Optionally fetch the user profile to see their current properties.\\n\\n## Output\\nA timeline of the user recent events plus key profile properties. Note the time range covered."},{"name":"analyze-conversion-funnel","description":"Run an Amplitude funnel across a sequence of events to find conversion rates and drop-off points.","content":"# Analyze Conversion Funnel\\n\\nMeasure how users progress through a multi-step flow in Amplitude.\\n\\n## Steps\\n1. Define the ordered sequence of events that make up the funnel (e.g., signup, activation, purchase).\\n2. Pick the date range and, if useful, a property to group by.\\n3. Run the funnel query and read the step-by-step and cumulative conversion numbers.\\n\\n## Output\\nConversion counts and rates at each step, the biggest drop-off point, and any group-by breakdown."}],"templates":[{"title":"Amplitude product analytics digest","prompt":"Create a scheduled weekly workflow that pulls key product metrics from Amplitude — active users, event segmentation for top events, and revenue — generates an executive summary with week-over-week trends, and posts it to Slack.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"slack","name":"Slack"}]},{"title":"Amplitude event regression watcher","prompt":"Build a scheduled workflow that runs event segmentation on key Amplitude events every morning, compares the counts against the trailing 14-day baseline, and posts a Slack alert when any event drops more than a configurable threshold.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"slack","name":"Slack"}]},{"title":"Amplitude active-user tracker","prompt":"Create a scheduled workflow that pulls daily and monthly active users from Amplitude, writes the values into a tracking table, and feeds the trend to downstream marketing automations.","integrations":[{"id":"amplitude","name":"Amplitude"}]},{"title":"Amplitude revenue digest","prompt":"Build a scheduled weekly workflow that pulls Amplitude revenue data, breaks it down by week-over-week change, and posts a digest to the product Slack channel.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"slack","name":"Slack"}]},{"title":"Amplitude + PostHog cross-tool dashboard","prompt":"Build a scheduled workflow that aggregates equivalent active-user and event metrics from both Amplitude and PostHog, writes a side-by-side comparison to a table, and surfaces discrepancies to the product team in Slack.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"posthog","name":"PostHog"},{"id":"slack","name":"Slack"}]},{"title":"Amplitude + Fathom unified analytics","prompt":"Build a scheduled workflow that joins Amplitude product analytics with Fathom web analytics, writes a unified active-user and engagement report, and surfaces anomalies.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"fathom","name":"Fathom"}]},{"title":"Amplitude + Hex deep-dive notebook","prompt":"Create a workflow that triggers a Hex deep-dive notebook when an Amplitude metric crosses an anomaly threshold, runs analysis, and posts the notebook output to Slack.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"hex","name":"Hex"},{"id":"slack","name":"Slack"}]},{"title":"Hex + Amplitude product notebook","prompt":"Create a scheduled workflow that runs a Hex notebook joining Amplitude data with internal sources weekly, captures retention and feature adoption, and emails a summary with the notebook link to the product team.","integrations":[{"id":"amplitude","name":"Amplitude"},{"id":"hex","name":"Hex"},{"id":"gmail","name":"Gmail"}]}]},{"id":"apify","type":"apify","slug":"apify","name":"Apify","description":"Run Apify actors and retrieve results","category":"Search","docsUrl":"https://docs.sim.ai/integrations/apify","authType":"api-key","connections":[],"operations":[{"name":"Run Actor","description":"Run an APIFY actor synchronously and get results (max 5 minutes)"},{"name":"Run Actor (Async)","description":"Start an APIFY Actor run and poll it within the same workflow step until completion or the polling deadline"},{"name":"Run Task","description":"Run a saved APIFY actor task synchronously and get dataset items (max 5 minutes)"},{"name":"Get Dataset Items","description":"Retrieve items stored in an APIFY dataset"},{"name":"Get Run","description":"Get the status and details of an APIFY actor run"}],"triggers":[],"skills":[{"name":"scrape-site-to-table","description":"Run an Apify actor to scrape a target website and write the extracted rows into a structured table. Use for one-off or recurring data extraction jobs.","content":"# Scrape Site to Table\\n\\nRun an Apify actor against a target site and load the results into a clean table.\\n\\n## Steps\\n1. Pick the actor or saved task (e.g. a web scraper) and assemble its JSON input — start URLs, page or request limits, and proxy settings.\\n2. Run the actor synchronously for small jobs, or asynchronously and poll Get Run for larger crawls.\\n3. Once the run status is SUCCEEDED, fetch the dataset items, selecting only the fields you need.\\n4. Normalize each item into consistent columns and write the rows to the destination table.\\n\\n## Output\\nReport the run ID, final status, and row count. If the run failed, surface the error and the actor input that produced it so it can be retried."},{"name":"monitor-prices","description":"Use an Apify scraper to capture competitor or product prices on a schedule, track history, and alert on changes. Use for price and stock monitoring.","content":"# Monitor Prices\\n\\nTrack pricing on target product pages over time and flag meaningful changes.\\n\\n## Steps\\n1. Run the scraping actor with the product or category URLs to watch.\\n2. From the dataset, extract product name, price, currency, and stock status for each item.\\n3. Compare each price against the last recorded value for that product.\\n4. Append the new snapshot to a price-history table.\\n\\n## Output\\nList any products whose price dropped, rose, or went out of stock, with old and new values. If nothing changed, say so briefly."},{"name":"build-lead-list","description":"Run an Apify directory or maps scraper to collect business listings and produce a deduplicated, CRM-ready lead list. Use for prospecting and lead generation.","content":"# Build Lead List\\n\\nCollect business listings from a directory and turn them into a usable prospect list.\\n\\n## Steps\\n1. Run the directory or maps scraper actor with the search terms, location, and result limit.\\n2. Fetch the dataset and pull company name, website, phone, email, and address for each listing.\\n3. Drop entries missing the fields you require, then deduplicate by domain or phone.\\n4. Write the cleaned rows to a lead table ready for enrichment or CRM import.\\n\\n## Output\\nReport total listings scraped, how many passed filtering, and how many duplicates were removed."},{"name":"collect-content-for-knowledge-base","description":"Use an Apify crawler to extract article or documentation text from a site and prepare it for ingestion into a knowledge base or RAG pipeline.","content":"# Collect Content for Knowledge Base\\n\\nCrawl a content site and gather clean text for downstream ingestion.\\n\\n## Steps\\n1. Run the crawler actor with the start URLs and a request limit, scoped to the relevant section of the site.\\n2. Fetch dataset items and extract title, URL, and main body text for each page.\\n3. Strip navigation, boilerplate, and empty pages.\\n4. Hand the cleaned documents to the knowledge base for chunking and indexing.\\n\\n## Output\\nReport the number of pages crawled and ingested, and list any URLs that failed or returned no usable text."}],"templates":[{"title":"Apify scraper orchestrator","prompt":"Build a workflow that triggers Apify scrapers on a schedule, captures the output, transforms into structured rows, and writes them to a downstream Sim table.","integrations":[{"id":"apify","name":"Apify"}]},{"title":"Apify lead-list builder","prompt":"Create a workflow that runs an Apify scraper on a target site, enriches each row with Clay, and writes the enriched lead list into HubSpot.","integrations":[{"id":"apify","name":"Apify"},{"id":"clay","name":"Clay"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Apify monitor digest","prompt":"Build a scheduled workflow that watches an Apify actor’s runs for failures, captures error patterns, and posts a digest to engineering Slack.","integrations":[{"id":"apify","name":"Apify"},{"id":"slack","name":"Slack"}]},{"title":"Apify ecommerce price tracker","prompt":"Create a workflow that uses Apify scrapers to capture competitor pricing daily, writes the price history to a table, and posts price-drop alerts to Slack.","integrations":[{"id":"apify","name":"Apify"},{"id":"slack","name":"Slack"}]},{"title":"Apify event-data collector","prompt":"Build a workflow that uses Apify to scrape event sites — speakers, agendas, sponsors — and writes the data into a target-events research table.","integrations":[{"id":"apify","name":"Apify"}]},{"title":"Apify directory scraper","prompt":"Create a workflow that runs an Apify directory scraper, captures business listings, enriches via Hunter or Apollo, and writes the prospect list to a CRM-ready table.","integrations":[{"id":"apify","name":"Apify"},{"id":"apollo","name":"Apollo"}]},{"title":"Apify job-listing monitor","prompt":"Build a scheduled workflow that uses Apify to scrape job sites for tracked companies, flags new role types, and writes intel into a sales-research table.","integrations":[{"id":"apify","name":"Apify"}]}]},{"id":"apollo","type":"apollo","slug":"apollo","name":"Apollo","description":"Search, enrich, and manage contacts with Apollo.io","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/apollo","authType":"api-key","connections":[],"operations":[{"name":"Search People","description":"Search Apollo\'s database for people using demographic filters"},{"name":"Enrich Person","description":"Enrich data for a single person using Apollo"},{"name":"Bulk Enrich People","description":"Enrich data for up to 10 people at once using Apollo"},{"name":"Search Organizations","description":"Search Apollo\'s database for companies using filters"},{"name":"Enrich Organization","description":"Enrich data for a single organization using Apollo"},{"name":"Bulk Enrich Organizations","description":"Enrich data for up to 10 organizations at once using Apollo"},{"name":"Create Contact","description":"Create a new contact in your Apollo database"},{"name":"Update Contact","description":"Update an existing contact in your Apollo database"},{"name":"Search Contacts","description":"Search your team\'s contacts in Apollo"},{"name":"Bulk Create Contacts","description":"Create up to 100 contacts at once in your Apollo database. Supports deduplication to prevent creating duplicate contacts. Master key required."},{"name":"Bulk Update Contacts","description":"Update up to 100 existing contacts at once in your Apollo database. Each contact must include an id field. Master key required."},{"name":"Create Account","description":"Create a new account (company) in your Apollo database"},{"name":"Update Account","description":"Update an existing account in your Apollo database"},{"name":"Search Accounts","description":"Search your team\'s accounts in Apollo. Display limit: 50,000 records (100 records per page, 500 pages max). Use filters to narrow results. Master key required."},{"name":"Bulk Create Accounts","description":"Create up to 100 accounts at once in your Apollo database. Set run_dedupe=true to deduplicate by domain, organization_id, and name. Master key required."},{"name":"Bulk Update Accounts","description":"Update up to 1000 existing accounts at once in your Apollo database (higher limit than contacts!). Each account must include an id field. Master key required."},{"name":"Create Opportunity","description":"Create a new deal for an account in your Apollo database (master key required)"},{"name":"Search Opportunities","description":"Search and list all deals/opportunities in your team\'s Apollo account"},{"name":"Get Opportunity","description":"Retrieve complete details of a specific deal/opportunity by ID"},{"name":"Update Opportunity","description":"Update an existing deal/opportunity in your Apollo database"},{"name":"Search Sequences","description":"Search for sequences/campaigns in your team\'s Apollo account (master key required)"},{"name":"Add to Sequence","description":"Add contacts to an Apollo sequence"},{"name":"Create Task","description":"Create one or more tasks in Apollo (one task per contact_id, master key required)"},{"name":"Search Tasks","description":"Search for tasks in Apollo"},{"name":"Get Email Accounts","description":"Get list of team\'s linked email accounts in Apollo"}],"triggers":[],"skills":[{"name":"build-prospect-list","description":"Search Apollo for people matching an ideal customer profile and produce a targeted prospect list. Use for outbound prospecting and territory building.","content":"# Build Prospect List\\n\\nFind decision-makers that match an ICP and assemble a clean prospect list.\\n\\n## Steps\\n1. Translate the ICP into an Apollo people search — job titles, seniorities, locations, and company size or industry filters.\\n2. Run the search, paging through results up to the requested count.\\n3. For each person capture name, title, company, verified email status, and LinkedIn URL.\\n4. Write the deduplicated prospects to a table for review or sequencing.\\n\\n## Output\\nReport how many prospects matched and the filters used. Flag any with unverified or missing emails."},{"name":"enrich-contacts","description":"Enrich one or many contacts through Apollo to refresh titles, emails, phones, and company data. Use to keep CRM records accurate before outreach.","content":"# Enrich Contacts\\n\\nFill in or refresh missing contact data using Apollo enrichment.\\n\\n## Steps\\n1. Gather the contacts to enrich — a single person, or a batch for bulk enrich.\\n2. Provide the strongest identifiers available (email, name plus company domain).\\n3. Run people enrich or bulk enrich, optionally revealing personal emails or phone numbers.\\n4. Merge the returned fields back onto each record, keeping existing values when enrichment returns nothing.\\n\\n## Output\\nReport how many records were enriched versus left unmatched, and which fields were newly filled. Note any credits consumed."},{"name":"sync-leads-to-crm","description":"Create or update Apollo contacts and accounts from an inbound lead, then map them into your CRM. Use to route new signups into pipeline.","content":"# Sync Leads to CRM\\n\\nTurn an inbound lead into structured Apollo records.\\n\\n## Steps\\n1. Take the lead details and enrich the person and their company through Apollo.\\n2. Create or update the matching Apollo account for the company.\\n3. Create or update the contact, linking it to the account and setting owner and stage.\\n4. Pass the enriched fields to the connected CRM to create or update the matching records.\\n\\n## Output\\nReport whether each record was created or updated, with the resulting contact and account IDs."},{"name":"add-prospects-to-sequence","description":"Search for matching contacts and add them to an Apollo email sequence. Use to launch or top up outbound campaigns.","content":"# Add Prospects to Sequence\\n\\nEnroll the right contacts into an outbound sequence.\\n\\n## Steps\\n1. Identify the target sequence by name or ID, and confirm the sending email account.\\n2. Gather the contact IDs to enroll — from a prior search or a provided list.\\n3. Add the contacts to the sequence with the chosen sending account and initial status.\\n4. Review which contacts were added versus skipped.\\n\\n## Output\\nReport totals added and skipped, and the reason for each skip (already enrolled, unverified, missing ownership)."},{"name":"pipeline-deal-digest","description":"Search Apollo opportunities by stage and summarize new and at-risk deals into a digest. Use for recurring pipeline reviews.","content":"# Pipeline Deal Digest\\n\\nSummarize opportunity movement for a sales pipeline review.\\n\\n## Steps\\n1. Search Apollo opportunities filtered by the stages you care about.\\n2. For each deal capture name, amount, stage, owner, and close date.\\n3. Group deals into new, advancing, and at-risk (stalled or past close date).\\n4. Write a concise digest grouped by category.\\n\\n## Output\\nA short digest: deal counts and total value per stage, with at-risk deals called out by name, owner, and reason."}],"templates":[{"title":"Apify directory scraper","prompt":"Create a workflow that runs an Apify directory scraper, captures business listings, enriches via Hunter or Apollo, and writes the prospect list to a CRM-ready table.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"apify","name":"Apify"}]},{"title":"Apollo lead enrichment","prompt":"Build a workflow that watches my leads table for new entries, enriches each lead with company size, funding, tech stack, and decision-maker contacts using Apollo and web search, then updates the table with the enriched information.","integrations":[{"id":"apollo","name":"Apollo"}]},{"title":"Apollo prospect researcher","prompt":"Create an agent that takes a company name, deep-researches them across the web and Apollo, finds key decision-makers, recent news, funding rounds, and pain points, then compiles a prospect brief I can review before outreach.","integrations":[{"id":"apollo","name":"Apollo"}]},{"title":"Apollo ICP account builder","prompt":"Build a workflow that runs an Apollo organization search for accounts matching my ideal customer profile — industry, headcount, and tech stack — creates each as an Apollo account, and writes the new target list to a table for the SDR team.","integrations":[{"id":"apollo","name":"Apollo"}]},{"title":"Apollo buying committee mapper","prompt":"Create a workflow that takes a target account, runs an Apollo people search across the relevant titles, enriches each contact with verified email and role, and writes a mapped buying committee to a table so reps know exactly who to engage.","integrations":[{"id":"apollo","name":"Apollo"}]},{"title":"Apollo enrichment to HubSpot","prompt":"Build a workflow that on a new inbound signup enriches the person and their company with Apollo, scores fit against my ICP, and creates or updates the matching contact and company in HubSpot with the enriched fields.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Apollo pipeline tracker","prompt":"Create a scheduled workflow that searches Apollo opportunities by stage, summarizes new and at-risk deals with an agent, logs the snapshot to a pipeline table, and posts a daily deal-movement digest to the sales Slack channel.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"slack","name":"Slack"}]},{"title":"Apollo contact freshness sweep","prompt":"Build a scheduled workflow that pulls contacts from my CRM, bulk-enriches them through Apollo to refresh titles, emails, and company data, and bulk-updates the records so the database stays accurate for outbound.","integrations":[{"id":"apollo","name":"Apollo"}]},{"title":"Attio enrichment pipeline","prompt":"Build a workflow that watches new Attio records, enriches each contact with company size, funding, and tech stack via Apollo, and writes the enriched fields back to Attio.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"attio","name":"Attio"}]},{"title":"Cal.com booking prep brief","prompt":"Build a workflow that runs 30 minutes before a Cal.com booking, researches the attendee with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"calcom","name":"Cal.com"},{"id":"gmail","name":"Gmail"}]},{"title":"Calendly meeting-prep brief","prompt":"Build a workflow that runs 30 minutes before a Calendly booking, researches the attendee and company with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"calendly","name":"Calendly"},{"id":"gmail","name":"Gmail"}]},{"title":"Email Bison + Apollo lead feeder","prompt":"Build a workflow that runs an Apollo search for an ICP, enriches each prospect, creates the lead in Email Bison with personalization variables, and attaches the leads to the matching active campaign.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Google Contacts enricher","prompt":"Build a scheduled workflow that scans Google Contacts for entries missing company or title, enriches each via Apollo, and writes the enriched contact back to Google Contacts.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Granola meeting brief","prompt":"Build a scheduled workflow that reads upcoming meetings from Granola notes, researches attendees and topic with Apollo, and posts a prep brief to Slack before each meeting.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"granola","name":"Granola"},{"id":"slack","name":"Slack"}]},{"title":"Hunter + Apollo prospect builder","prompt":"Build a workflow that runs an Apollo search for an ICP, finds verified emails via Hunter, and writes the deliverable prospect list to a sender table.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"hunter","name":"Hunter.io"}]},{"title":"Intercom contact enrichment","prompt":"Create a workflow triggered when a new Intercom contact is created that enriches the contact with company, title, and seniority data from Apollo, updates the Intercom contact attributes, and adds a note with the enrichment source.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"intercom","name":"Intercom"}]},{"title":"Lemlist + Apollo prospect feeder","prompt":"Create a workflow that runs an Apollo search for an ICP, enriches each prospect with role and company signals, and sends a personalized first-touch email through Lemlist with a custom opening line per prospect.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"lemlist","name":"Lemlist"}]},{"title":"Luma registrant enricher","prompt":"Build a scheduled workflow that pulls the Luma event guest list, enriches each registrant with company data via Apollo, and pushes high-value attendees into HubSpot as leads.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"luma","name":"Luma"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Pipedrive lead enrichment pipeline","prompt":"Build a scheduled workflow that polls Pipedrive for new leads, enriches each via Apollo with role, seniority, and tech stack, and updates the lead with the enriched details.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"pipedrive","name":"Pipedrive"}]},{"title":"Typeform lead enricher","prompt":"Create a workflow that watches Typeform lead-gen submissions, enriches each lead with company size and tech stack via Apollo, and pushes the enriched lead into Salesforce.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"typeform","name":"Typeform"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Webflow lead capture pipeline","prompt":"Create a workflow that monitors new Webflow form submissions, enriches each lead with company and contact data using Apollo and web search, adds them to a tracking table with a lead score, and sends a Slack notification to the sales team for high-potential leads.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"webflow","name":"Webflow"},{"id":"slack","name":"Slack"}]},{"title":"Webflow form-to-CRM","prompt":"Build a workflow that watches Webflow form submissions, enriches each with Apollo company data, and pushes qualifying leads into HubSpot with the right owner and source.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"webflow","name":"Webflow"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Zoom meeting prep brief","prompt":"Create a scheduled workflow that runs each morning, lists today’s Zoom meetings, researches attendees with Apollo and the web, and emails a prep brief 30 minutes before each meeting.","integrations":[{"id":"apollo","name":"Apollo"},{"id":"zoom","name":"Zoom"},{"id":"gmail","name":"Gmail"}]}]},{"id":"arxiv","type":"arxiv","slug":"arxiv","name":"ArXiv","description":"Search and retrieve academic papers from ArXiv","category":"Search","docsUrl":"https://docs.sim.ai/integrations/arxiv","authType":"none","connections":[],"operations":[{"name":"Search Papers","description":"Search for academic papers on ArXiv by keywords, authors, titles, or other fields."},{"name":"Get Paper Details","description":"Get detailed information about a specific ArXiv paper by its ID."},{"name":"Get Author Papers","description":"Search for papers by a specific author on ArXiv."}],"triggers":[],"skills":[{"name":"search-recent-papers","description":"Search ArXiv for the most relevant or most recent papers on a topic and return a ranked, summarized list. Use for literature discovery and topic scans.","content":"# Search Recent Papers\\n\\nFind the papers most worth reading on a given topic.\\n\\n## Steps\\n1. Build the ArXiv query from the topic, choosing the search field (title, abstract, or all) and a result limit.\\n2. Sort by relevance for a broad scan, or by submitted date to surface the newest work.\\n3. For each result capture title, authors, ArXiv ID, publication date, and abstract.\\n4. Write a one-line summary per paper highlighting the contribution.\\n\\n## Output\\nA ranked list of papers with ID, title, authors, date, and a one-line takeaway each. Lead with the most relevant."},{"name":"summarize-paper","description":"Fetch a specific ArXiv paper by ID and produce a structured summary of its contribution, method, and results. Use to digest a single paper quickly.","content":"# Summarize Paper\\n\\nProduce a structured read of one ArXiv paper.\\n\\n## Steps\\n1. Fetch the paper details using its ArXiv ID.\\n2. Read the abstract and metadata to identify the problem, approach, and headline results.\\n3. Note the authors, publication date, and primary category.\\n4. Write a structured summary.\\n\\n## Output\\nA brief covering: problem addressed, method, key results, and why it matters — plus the ArXiv ID and link. Keep it tight and skip filler."},{"name":"track-author-publications","description":"Retrieve an author\'s recent ArXiv papers and report new work since the last check. Use to follow specific researchers or labs.","content":"# Track Author Publications\\n\\nMonitor a researcher for new ArXiv output.\\n\\n## Steps\\n1. Fetch the author\'s papers by name, sorted by submitted date.\\n2. Compare the results against the previously seen list to find new entries.\\n3. For each new paper capture title, ID, date, and abstract.\\n4. Summarize what is new since the last check.\\n\\n## Output\\nList only the new papers with title, ID, date, and a one-line summary. If there is nothing new, say so."},{"name":"build-literature-review","description":"Search ArXiv on a topic, summarize the key papers, and assemble a themed literature review. Use to bootstrap research on a new area.","content":"# Build Literature Review\\n\\nAssemble a starting literature review for a research topic.\\n\\n## Steps\\n1. Search ArXiv for the most relevant and most cited recent papers on the topic.\\n2. Fetch details and summarize each selected paper.\\n3. Cluster the papers into themes or sub-questions.\\n4. Write a review that introduces the topic, walks through each theme citing the papers, and notes open gaps.\\n\\n## Output\\nA structured review document with a theme-by-theme synthesis and a reference list of ArXiv IDs and titles."}],"templates":[{"title":"ArXiv paper alerter","prompt":"Build a scheduled workflow that queries ArXiv for new papers on tracked topics, summarizes abstracts with an agent, and emails the digest to the research team.","integrations":[{"id":"arxiv","name":"ArXiv"},{"id":"gmail","name":"Gmail"}]},{"title":"ArXiv literature review builder","prompt":"Create a workflow that takes a research topic, queries ArXiv for the most cited recent papers, summarizes each, and writes a literature review file.","integrations":[{"id":"arxiv","name":"ArXiv"}]},{"title":"ArXiv knowledge-base feeder","prompt":"Build a scheduled workflow that polls ArXiv for new papers in a topic, fetches PDFs, parses with Mistral Parser, and upserts the chunks into a research knowledge base.","integrations":[{"id":"arxiv","name":"ArXiv"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"ArXiv top-author tracker","prompt":"Create a scheduled workflow that monitors ArXiv for new papers by tracked authors and posts a Slack alert when a watched author publishes new work.","integrations":[{"id":"arxiv","name":"ArXiv"},{"id":"slack","name":"Slack"}]},{"title":"ArXiv weekly digest","prompt":"Build a scheduled weekly workflow that gathers the top ArXiv papers per tracked category, clusters them by theme, and writes a digest file.","integrations":[{"id":"arxiv","name":"ArXiv"}]},{"title":"ArXiv author-topic grapher","prompt":"Create a workflow that for a chosen ArXiv topic pulls papers and their authors, builds a co-authorship and topic graph in Neo4j, and exposes a visualization for the research team.","integrations":[{"id":"arxiv","name":"ArXiv"},{"id":"neo4j","name":"Neo4j"}]},{"title":"ArXiv survey-paper generator","prompt":"Build a workflow that takes a topic, finds the most influential ArXiv papers, summarizes themes, and writes a survey-style file as a starting point for research.","integrations":[{"id":"arxiv","name":"ArXiv"}]},{"title":"LaTeX paper digest compiler","prompt":"Build a scheduled workflow that fetches new ArXiv papers on tracked topics, has an agent summarize each one, typesets the digest as a LaTeX document, and compiles a weekly PDF.","integrations":[{"id":"arxiv","name":"ArXiv"},{"id":"latex","name":"LaTeX"}]}]},{"id":"asana","type":"asana","slug":"asana","name":"Asana","description":"Interact with Asana","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/asana","authType":"oauth","connections":[{"id":"asana","kind":"oauth","label":"Connect with OAuth","providerId":"asana","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/asana","requiredScopes":[{"id":"default","label":"Full access to everything the account can reach in Asana"}],"fields":[]},{"id":"asana-service-account","kind":"service_account","providerId":"asana-service-account","label":"Add access token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/asana-service-account","fields":[{"id":"apiToken","label":"Access token","placeholder":"Paste a service account token or personal access token","secret":true}]}],"operations":[{"name":"Get Task","description":"Retrieve a single task by GID or get multiple tasks with filters"},{"name":"Create Task","description":"Create a new task in Asana"},{"name":"Update Task","description":"Update an existing task in Asana"},{"name":"Get Projects","description":"Retrieve all projects from an Asana workspace"},{"name":"Search Tasks","description":"Search for tasks in an Asana workspace"},{"name":"Add Comment","description":"Add a comment (story) to an Asana task"},{"name":"Create Subtask","description":"Create a subtask under an existing Asana task"},{"name":"Delete Task","description":"Delete an Asana task by its GID (moves it to the trash)"},{"name":"Add Followers","description":"Add one or more followers to an Asana task"},{"name":"Create Project","description":"Create a new project in an Asana workspace"},{"name":"Get Project","description":"Retrieve a single Asana project by its GID"},{"name":"List Workspaces","description":"List all Asana workspaces and organizations the authenticated user belongs to"},{"name":"Create Section","description":"Create a new section in an Asana project"},{"name":"List Sections","description":"List all sections in an Asana project"}],"triggers":[],"skills":[{"name":"create-task-from-request","description":"Turn an incoming request or message into a well-formed Asana task in the right project with assignee and due date. Use for intake and ticket creation.","content":"# Create Task from Request\\n\\nConvert an incoming request into a structured Asana task.\\n\\n## Steps\\n1. Extract the work to be done, the relevant project, an assignee if named, and any due date.\\n2. If the project is referenced by name, list projects to resolve its ID.\\n3. Create the task with a clear name, a description capturing the request details, the project, assignee, and due date.\\n4. Add a comment with any links or source context if helpful.\\n\\n## Output\\nReport the created task name, its URL or ID, project, assignee, and due date."},{"name":"summarize-project-tasks","description":"Search tasks in an Asana project and summarize status, overdue items, and who owns what. Use for standups and project status checks.","content":"# Summarize Project Tasks\\n\\nProduce a status snapshot of an Asana project.\\n\\n## Steps\\n1. Resolve the project, then search its tasks.\\n2. For each task capture name, assignee, due date, and completion state.\\n3. Group into completed, in progress, and overdue or due soon.\\n4. Note any unassigned tasks or tasks with no due date.\\n\\n## Output\\nA concise status summary: counts per group, overdue tasks called out by name and owner, and any gaps to address."},{"name":"update-task-status","description":"Find an Asana task and update its fields — assignee, due date, completion, or add a progress comment. Use to keep tasks current from other systems.","content":"# Update Task Status\\n\\nKeep an Asana task in sync with the latest state.\\n\\n## Steps\\n1. Identify the target task by ID, or search to find it by name.\\n2. Read the current task to confirm it is the right one.\\n3. Update the relevant fields — completion, assignee, or due date.\\n4. Add a comment summarizing what changed and why.\\n\\n## Output\\nReport which fields changed and confirm the task ID. If no matching task was found, say so."}],"templates":[{"title":"Asana sprint planner","prompt":"Build a workflow that on Monday morning compiles uncompleted Asana tasks, rebalances against capacity, and posts the sprint plan to the team Slack channel.","integrations":[{"id":"asana","name":"Asana"},{"id":"slack","name":"Slack"}]},{"title":"Asana stuck-task surfacer","prompt":"Create a scheduled workflow that finds Asana tasks with no progress for 5+ days, pings the assignee in Slack with a quick-action prompt, and updates the task status based on their answer.","integrations":[{"id":"asana","name":"Asana"},{"id":"slack","name":"Slack"}]},{"title":"Asana cross-team blocker watcher","prompt":"Build a scheduled workflow that searches Asana for tasks tagged blocked, identifies the blocking team based on dependency metadata, and posts a request to the right channel in Slack.","integrations":[{"id":"asana","name":"Asana"},{"id":"slack","name":"Slack"}]},{"title":"Asana onboarding task launcher","prompt":"Create a workflow that on a new Salesforce opportunity creates a customer-onboarding Asana task with the right assignee and due date, and writes the task link back to the opportunity.","integrations":[{"id":"asana","name":"Asana"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Asana weekly project digest","prompt":"Build a scheduled weekly workflow that summarizes Asana project progress — completed, in-progress, at-risk — and emails a status update to each project sponsor.","integrations":[{"id":"asana","name":"Asana"},{"id":"gmail","name":"Gmail"}]},{"title":"Asana retro generator","prompt":"Create a workflow that pulls Asana tasks completed in a sprint, summarizes wins, blockers, and patterns, and writes a retro doc shared with the team via Slack.","integrations":[{"id":"asana","name":"Asana"},{"id":"slack","name":"Slack"}]},{"title":"Asana bug intake triager","prompt":"Build a workflow that searches Asana for newly created tasks in the bug project, classifies each by severity and component with an agent, adds a triage comment, and creates a matching GitHub issue for engineering pickup.","integrations":[{"id":"asana","name":"Asana"},{"id":"github","name":"GitHub"}]},{"title":"Clear report to onboarding","prompt":"Create a workflow that runs when a Checkr report completes with a clear result, engages the report, tags it as onboarded, and creates the new hire’s onboarding tasks in your project tracker with their start date.","integrations":[{"id":"asana","name":"Asana"},{"id":"checkr","name":"Checkr"}]},{"title":"Fireflies action-item ticket creator","prompt":"Build a workflow that extracts action items from a Fireflies meeting transcript, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"asana","name":"Asana"},{"id":"fireflies","name":"Fireflies"},{"id":"linear","name":"Linear"}]},{"title":"Granola action-item ticket creator","prompt":"Create a workflow that extracts action items from Granola meeting notes, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"asana","name":"Asana"},{"id":"granola","name":"Granola"},{"id":"linear","name":"Linear"}]},{"title":"Meeting notes to Linear tasks","prompt":"Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.","integrations":[{"id":"asana","name":"Asana"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]}]},{"id":"ashby","type":"ashby","slug":"ashby","name":"Ashby","description":"Manage candidates, jobs, and applications in Ashby","category":"HR","docsUrl":"https://docs.sim.ai/integrations/ashby","authType":"api-key","connections":[],"operations":[{"name":"List Candidates","description":"Lists all candidates in an Ashby organization with cursor-based pagination."},{"name":"Get Candidate","description":"Retrieves full details about a single candidate by their ID."},{"name":"Create Candidate","description":"Creates a new candidate record in Ashby."},{"name":"Update Candidate","description":"Updates an existing candidate record in Ashby. Only provided fields are changed."},{"name":"Search Candidates","description":"Searches for candidates by name and/or email with AND logic. Results are limited to 100 matches. Use candidate.list for full pagination."},{"name":"List Jobs","description":"Lists all jobs in an Ashby organization. By default returns Open, Closed, and Archived jobs. Specify status to filter."},{"name":"Get Job","description":"Retrieves full details about a single job by its ID."},{"name":"Create Note","description":"Creates a note on a candidate in Ashby. Supports plain text and HTML content (bold, italic, underline, links, lists, code)."},{"name":"List Notes","description":"Lists all notes on a candidate with pagination support."},{"name":"List Applications","description":"Lists all applications in an Ashby organization with pagination and optional filters for status, job, and creation date."},{"name":"Get Application","description":"Retrieves full details about a single application by its ID."},{"name":"Create Application","description":"Creates a new application for a candidate on a job. Optionally specify interview plan, stage, source, and credited user."},{"name":"Delete Application","description":"Permanently deletes an application in Ashby. Requires the candidatesDelete permission, which is a separate module permission from candidatesWrite - a read and write key returns 403 here. There is no equivalent endpoint for deleting a candidate; candidate deletion is UI-only."},{"name":"List Offers","description":"Lists all offers with their latest version in an Ashby organization."},{"name":"Change Application Stage","description":"Moves an application to a different interview stage. Requires an archive reason when moving to an Archived stage."},{"name":"Change Application Source","description":"Changes the source attributed to an existing application, so programmatically created applications report correctly on the recruiting side. Requires the candidatesWrite permission."},{"name":"Anonymize Candidate","description":"Remove personally identifiable information from an Ashby candidate while retaining the candidate record and its applications. This operation does not delete the candidate. Requires the candidatesWrite permission."},{"name":"Add Candidate Tag","description":"Adds a tag to a candidate in Ashby and returns the updated candidate."},{"name":"Remove Candidate Tag","description":"Removes a tag from a candidate in Ashby and returns the updated candidate."},{"name":"Get Offer","description":"Retrieves full details about a single offer by its ID."},{"name":"List Sources","description":"Lists all candidate sources configured in Ashby."},{"name":"List Candidate Tags","description":"Lists all candidate tags configured in Ashby."},{"name":"List Archive Reasons","description":"Lists all archive reasons configured in Ashby."},{"name":"List Custom Fields","description":"Lists all custom field definitions configured in Ashby."},{"name":"Set Custom Field Value","description":"Sets the value of a single custom field on an Ashby Application, Candidate, Job, or Opening. Custom fields are the only way to annotate a job or req, since Ashby has no job notes and no job tags. Requires the candidatesWrite permission."},{"name":"Set Custom Field Values","description":"Sets several custom field values on one Ashby Application, Candidate, Job, or Opening in a single call. Prefer this over repeated single-field writes to the same object - Ashby recommends it because concurrent single-field calls can race and overwrite each other. Requires the candidatesWrite permission."},{"name":"List Departments","description":"Lists all departments in Ashby."},{"name":"List Locations","description":"Lists all locations configured in Ashby."},{"name":"List Job Postings","description":"Lists all job postings in Ashby."},{"name":"Get Job Posting","description":"Retrieves full details about a single job posting by its ID."},{"name":"List Openings","description":"Lists all openings in Ashby with pagination."},{"name":"List Users","description":"Lists all users in Ashby with pagination."},{"name":"List Interviews","description":"Lists interview schedules in Ashby, optionally filtered by application or interview stage."},{"name":"List Interview Plans","description":"Lists Ashby interview plans, including optional archived plans and incremental changes."},{"name":"List Interview Stages","description":"Lists the ordered stages in an Ashby interview plan."},{"name":"List Application Feedback","description":"Lists submitted interview feedback, optionally for one application, with pagination and incremental sync."},{"name":"List Application History","description":"Lists the full stage history and allowed actions for an application."},{"name":"Search Jobs","description":"Searches Ashby jobs by title and/or requisition ID. Provide at least one of these filters."},{"name":"Search Users","description":"Searches Ashby users by exact email address."},{"name":"Get Opening","description":"Retrieves one Ashby headcount opening by UUID."},{"name":"Search Openings","description":"Searches Ashby headcount openings by human-readable identifier."},{"name":"Transfer Application","description":"Transfers an application to another job, interview plan, and stage."},{"name":"Upload Resume","description":"Securely uploads a resume and sets it as the Ashby candidate resume."},{"name":"Upload Candidate File","description":"Securely uploads a file and attaches it to an Ashby candidate."}],"triggers":[{"id":"ashby_application_submit","name":"Ashby Application Submitted","description":"Trigger workflow when a new application is submitted"},{"id":"ashby_application_update","name":"Ashby Application Updated","description":"Trigger workflow when an application is updated"},{"id":"ashby_candidate_stage_change","name":"Ashby Candidate Stage Change","description":"Trigger workflow when a candidate changes interview stages"},{"id":"ashby_candidate_hire","name":"Ashby Candidate Hired","description":"Trigger workflow when a candidate is hired"},{"id":"ashby_candidate_delete","name":"Ashby Candidate Deleted","description":"Trigger workflow when a candidate is deleted"},{"id":"ashby_candidate_merge","name":"Ashby Candidate Merged","description":"Trigger workflow when two candidate records are merged"},{"id":"ashby_interview_schedule_create","name":"Ashby Interview Schedule Created","description":"Trigger workflow when an interview schedule is created"},{"id":"ashby_interview_schedule_update","name":"Ashby Interview Schedule Updated","description":"Trigger workflow when an interview schedule is updated"},{"id":"ashby_job_create","name":"Ashby Job Created","description":"Trigger workflow when a new job is created"},{"id":"ashby_job_update","name":"Ashby Job Updated","description":"Trigger workflow when a job is updated"},{"id":"ashby_job_posting_update","name":"Ashby Job Posting Updated","description":"Trigger workflow when a job posting is updated"},{"id":"ashby_job_posting_delete","name":"Ashby Job Posting Deleted","description":"Trigger workflow when a job posting is deleted"},{"id":"ashby_offer_create","name":"Ashby Offer Created","description":"Trigger workflow when a new offer is created"},{"id":"ashby_offer_update","name":"Ashby Offer Updated","description":"Trigger workflow when an offer is updated"},{"id":"ashby_offer_delete","name":"Ashby Offer Deleted","description":"Trigger workflow when an offer is deleted"},{"id":"ashby_opening_create","name":"Ashby Opening Created","description":"Trigger workflow when a headcount opening is created"},{"id":"ashby_signature_request_update","name":"Ashby Signature Request Updated","description":"Trigger workflow when an e-signature request changes state"}],"skills":[{"name":"add-candidate","description":"Create a candidate in Ashby from an inbound application or referral and attach them to a job. Use for sourcing and referral intake.","content":"# Add Candidate\\n\\nCapture a new candidate into Ashby and link them to the right role.\\n\\n## Steps\\n1. Gather the candidate name, email, source, and the target job.\\n2. If the job is named, list jobs to resolve its ID.\\n3. Create the candidate, then create an application linking them to the job with the correct source.\\n4. Add a note with referral context or screening details, and apply any relevant tags.\\n\\n## Output\\nReport the created candidate and application IDs, the linked job, and the source applied."},{"name":"advance-candidate-stage","description":"Move a candidate application to a new interview stage in Ashby and log the decision. Use to keep the pipeline moving after interviews.","content":"# Advance Candidate Stage\\n\\nProgress a candidate through the hiring pipeline.\\n\\n## Steps\\n1. Find the application — by ID, or list applications for the candidate or job.\\n2. Confirm the current stage by getting the application.\\n3. Change the application stage to the target stage.\\n4. Add a note capturing the rationale and any interview feedback.\\n\\n## Output\\nConfirm the candidate, the stage moved from and to, and the note added."},{"name":"pipeline-status-report","description":"List candidates and applications by status or job in Ashby and summarize pipeline health. Use for recruiting standups and weekly reports.","content":"# Pipeline Status Report\\n\\nSummarize the state of an Ashby hiring pipeline.\\n\\n## Steps\\n1. List the relevant jobs, or focus on one role.\\n2. List applications, grouping candidates by current stage and status (active, hired, archived).\\n3. Flag candidates stalled in a stage or awaiting feedback.\\n4. Note new candidates added since the last report.\\n\\n## Output\\nA pipeline summary: candidate counts per stage and status, stalled candidates called out by name and role, and recent additions."},{"name":"interview-feedback-chase","description":"Find scheduled interviews with missing feedback and notify the responsible interviewers. Use after interview loops to keep decisions moving.","content":"# Interview Feedback Chase\\n\\nClose feedback gaps after an interview loop.\\n\\n## Steps\\n1. List interview schedules for the application or stage.\\n2. Inspect each interview event and list the application feedback already submitted.\\n3. Identify interviewers whose events are complete but have no feedback.\\n4. Send each interviewer a concise reminder with the candidate, role, and feedback link.\\n\\n## Output\\nReport the interview events checked, completed feedback, missing feedback, and reminders sent."},{"name":"opening-finance-reconciliation","description":"Reconcile Ashby headcount openings with a finance or workforce-planning table. Use for hiring-plan and budget reviews.","content":"# Opening Finance Reconciliation\\n\\nCompare approved headcount with the active recruiting plan.\\n\\n## Steps\\n1. List or search Ashby openings and resolve their linked jobs.\\n2. Compare identifier, state, target dates, hiring team, and custom fields with the planning table.\\n3. Flag openings that are missing, duplicated, closed unexpectedly, or attached to the wrong job.\\n4. Write a reconciliation report without changing Ashby records unless explicitly requested.\\n\\n## Output\\nReturn matched openings, discrepancies, budget-risk flags, and the exact records that need review."},{"name":"offer-signature-handoff","description":"Coordinate the offer-to-preboarding handoff from offer and signature events. Use to prevent accepted candidates from falling into an operations gap.","content":"# Offer Signature Handoff\\n\\nTurn an accepted and signed offer into a reliable preboarding handoff.\\n\\n## Steps\\n1. Listen for offer updates and signature-request completion.\\n2. Retrieve the offer and application, then confirm the candidate, role, opening, and final status.\\n3. Create the downstream People, IT, and manager tasks only when the signature is completed.\\n4. Record the Ashby offer, application, and opening IDs for idempotent follow-up.\\n\\n## Output\\nConfirm the signed offer, candidate, linked opening, downstream owners, and every task created."}],"templates":[{"title":"Ashby pipeline digest","prompt":"Build a scheduled daily workflow that lists open Ashby jobs, summarizes candidate counts per stage, flags applications stalled for more than five days, logs metrics to a tracking table, and Slacks hiring managers a personalized pipeline digest.","integrations":[{"id":"ashby","name":"Ashby"},{"id":"slack","name":"Slack"}]},{"title":"Resume to Ashby candidate","prompt":"Create a workflow that watches a folder of inbound resumes, extracts contact info and work history, deduplicates against existing Ashby candidates, creates new candidate records when needed, and tags them with the source job they applied through.","integrations":[{"id":"ashby","name":"Ashby"}]},{"title":"Ashby interview note logger","prompt":"Build a workflow that runs after every interview is logged in your meeting tool, summarizes the transcript, scores the candidate against the job requirements, creates a structured note on the matching Ashby candidate, and notifies the hiring manager in Slack.","integrations":[{"id":"ashby","name":"Ashby"},{"id":"slack","name":"Slack"}]},{"title":"Ashby stage-change responder","prompt":"Create a workflow that detects when an Ashby application moves into a new stage, sends the candidate a stage-appropriate email, prepares the interviewer brief in a file, and updates a recruiting tracking table so coordinators always know who is next.","integrations":[{"id":"ashby","name":"Ashby"},{"id":"gmail","name":"Gmail"}]},{"title":"Ashby DEI snapshot","prompt":"Build a scheduled monthly workflow that pulls Ashby candidates, applications, and openings, computes funnel diversity metrics by stage, role, and source, and writes a confidential report file shared with people leadership and compliance.","integrations":[{"id":"ashby","name":"Ashby"}]},{"title":"Ashby candidate enricher","prompt":"Create a workflow that takes new Ashby candidates, researches each across LinkedIn and the web for relevant background, writes a structured profile summary onto the candidate as an Ashby note, and updates a recruiting table with research links.","integrations":[{"id":"ashby","name":"Ashby"},{"id":"linkedin","name":"LinkedIn"}]},{"title":"Ashby offer-ready brief","prompt":"Build a workflow that runs when an Ashby application reaches the offer stage, gathers compensation benchmarks, interview feedback, and candidate priorities, drafts an offer brief file for the hiring manager, and Slacks the people team to start the offer process.","integrations":[{"id":"ashby","name":"Ashby"},{"id":"slack","name":"Slack"}]}]},{"id":"athena","type":"athena","slug":"athena","name":"Athena","description":"Run SQL queries on data in Amazon S3 using AWS Athena","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/athena","authType":"none","connections":[],"operations":[{"name":"Start Query","description":"Start an SQL query execution in AWS Athena"},{"name":"Get Query Execution","description":"Get the status and details of an Athena query execution"},{"name":"Get Query Results","description":"Retrieve the results of a completed Athena query execution"},{"name":"Get Query Runtime Statistics","description":"Get runtime statistics (timeline, row counts, and output stage) for a completed Athena query execution"},{"name":"Stop Query","description":"Stop a running Athena query execution"},{"name":"List Query Executions","description":"List recent Athena query execution IDs"},{"name":"Batch Get Query Executions","description":"Get the status and details of up to 50 Athena query executions in one call"},{"name":"Create Named Query","description":"Create a saved/named query in AWS Athena"},{"name":"Get Named Query","description":"Get details of a saved/named query in AWS Athena"},{"name":"Batch Get Named Queries","description":"Get the details of up to 50 Athena named queries by ID in a single call"},{"name":"Update Named Query","description":"Update the name, description, or SQL of an existing Athena named query (database and workgroup cannot change)"},{"name":"List Named Queries","description":"List saved/named query IDs in AWS Athena"},{"name":"Delete Named Query","description":"Delete a saved/named query in AWS Athena"},{"name":"Create Prepared Statement","description":"Create a parameterized prepared statement in an Athena workgroup for use with EXECUTE or execution parameters"},{"name":"Get Prepared Statement","description":"Get the SQL and metadata of a prepared statement in an Athena workgroup"},{"name":"Batch Get Prepared Statements","description":"Get the details of up to 256 prepared statements in an Athena workgroup by name in a single call"},{"name":"Update Prepared Statement","description":"Replace the SQL and description of an existing prepared statement in an Athena workgroup"},{"name":"List Prepared Statements","description":"List the prepared statements saved in an Athena workgroup"},{"name":"Delete Prepared Statement","description":"Delete a prepared statement from an Athena workgroup"},{"name":"List Data Catalogs","description":"List the data catalogs (data sources) registered in the AWS account"},{"name":"Get Data Catalog","description":"Get the type, status, and connection parameters of an Athena data catalog"},{"name":"List Databases","description":"List the databases available in an Athena data catalog"},{"name":"Get Database","description":"Get a single database (name, description, and parameters) from an Athena data catalog"},{"name":"List Table Metadata","description":"List tables and their column/partition metadata for an Athena database"},{"name":"Get Table Metadata","description":"Get the columns, partition keys, and properties of a single table in an Athena data catalog database"},{"name":"List Workgroups","description":"List the Athena workgroups available in the AWS account"},{"name":"Get Workgroup","description":"Get the configuration of an Athena workgroup, including its result location, encryption, and limits"}],"triggers":[],"skills":[{"name":"run-query","description":"Run a SQL query against data in S3 via Athena, wait for completion, and return the results. Use for ad-hoc analysis and reporting over your data lake.","content":"# Run Query\\n\\nExecute a SQL query in Athena and return the results.\\n\\n## Steps\\n1. Compose the SQL, naming the database and confirming the output location.\\n2. Start the query to obtain a query execution ID.\\n3. Poll get query execution until the state is SUCCEEDED, FAILED, or CANCELLED.\\n4. On success, fetch the query results and shape the rows into a clean table.\\n\\n## Output\\nReturn the result rows plus the execution ID, data scanned, and runtime. On failure, surface the Athena error message and the SQL that caused it."},{"name":"scheduled-metrics-report","description":"Run a saved or composed Athena query on a schedule to compute metrics and produce a report. Use for recurring KPI and usage reporting.","content":"# Scheduled Metrics Report\\n\\nCompute recurring metrics from data in S3.\\n\\n## Steps\\n1. Use a named query, or compose the metrics SQL for the reporting period.\\n2. Start the query and poll execution until it completes.\\n3. Fetch the results and format the metrics for reporting.\\n4. Compare against the prior period to highlight movement where relevant.\\n\\n## Output\\nA metrics summary with current values, period-over-period change, and the execution ID for traceability."},{"name":"explore-data-lake-schema","description":"Discover what data is available by listing data catalogs, databases, and tables, then reading a table\'s columns and partition keys before writing SQL. Use when an agent needs to ground a query in the real schema.","content":"# Explore Data Lake Schema\\n\\nFind the right tables and columns before querying.\\n\\n## Steps\\n1. List data catalogs, then list databases in the relevant catalog.\\n2. List table metadata in the database, filtering by a name pattern when the database is large.\\n3. Get table metadata for the candidate table to read its columns, types, partition keys, and location.\\n4. Use partition keys in WHERE clauses to limit the data scanned.\\n\\n## Output\\nThe fully qualified table name, its columns with types, and the partition keys to filter on."},{"name":"parameterized-query-with-prepared-statements","description":"Save a parameterized SQL statement once and run it safely with different values each time. Use for recurring reports and agent-driven lookups where inputs change but the SQL should not.","content":"# Parameterized Query with Prepared Statements\\n\\nRun vetted SQL with runtime values instead of string-building queries.\\n\\n## Steps\\n1. Create a prepared statement in the workgroup with ? placeholders for each variable.\\n2. Start a query with EXECUTE and pass the values as execution parameters in placeholder order.\\n3. Poll get query execution until the state is SUCCEEDED, FAILED, or CANCELLED.\\n4. Fetch the query results; update the prepared statement when the SQL needs to change.\\n\\n## Output\\nThe result rows plus the statement name and execution ID used, or the Athena error if the parameters did not match the placeholders."},{"name":"manage-named-queries","description":"Create, look up, and list saved (named) queries in Athena to standardize reusable SQL. Use to maintain a library of vetted analytics queries.","content":"# Manage Named Queries\\n\\nMaintain a library of reusable Athena queries.\\n\\n## Steps\\n1. To save a query, create a named query with a clear name, description, database, and the SQL body.\\n2. To reuse one, list named queries or get a named query by ID to retrieve its SQL.\\n3. Run the retrieved SQL via start query when execution is needed.\\n4. Keep names and descriptions accurate so the right query is easy to find.\\n\\n## Output\\nReport the named query ID and name for creates, or the resolved SQL for lookups."}],"templates":[{"title":"Athena scheduled report runner","prompt":"Create a scheduled workflow that runs a saved AWS Athena query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.","integrations":[{"id":"athena","name":"Athena"},{"id":"slack","name":"Slack"}]},{"title":"Athena S3 access audit","prompt":"Build a workflow that runs Athena queries against S3 access logs weekly, identifies unusual access patterns or new principals, and writes findings to a security audit table.","integrations":[{"id":"athena","name":"Athena"},{"id":"s3","name":"S3"}]},{"title":"Athena cost-explorer query","prompt":"Build a scheduled workflow that runs Athena queries against AWS cost-and-usage reports daily, writes top cost movers per service to a table, and posts an anomaly digest to Slack.","integrations":[{"id":"athena","name":"Athena"},{"id":"slack","name":"Slack"}]},{"title":"Athena + Tinybird real-time bridge","prompt":"Build a workflow that combines historical Athena queries with realtime Tinybird endpoints into a unified reporting view, writes results to a dashboard table.","integrations":[{"id":"athena","name":"Athena"},{"id":"tinybird","name":"Tinybird"}]},{"title":"Athena + PostHog data-warehouse join","prompt":"Create a scheduled workflow that joins PostHog event exports with Athena historical data, computes funnel conversion across the join, and writes a daily report.","integrations":[{"id":"athena","name":"Athena"},{"id":"posthog","name":"PostHog"}]},{"title":"Athena ad-hoc query agent","prompt":"Build a Slack agent that translates natural-language analytics questions into safe AWS Athena queries, executes them, and returns the table answer with the query for review.","integrations":[{"id":"athena","name":"Athena"},{"id":"slack","name":"Slack"}]},{"title":"Athena weekly executive metrics","prompt":"Create a scheduled weekly workflow that runs a set of AWS Athena queries against the data lake for revenue, retention, and usage metrics, writes the results to a metrics table, and emails a formatted scorecard to leadership.","integrations":[{"id":"athena","name":"Athena"},{"id":"gmail","name":"Gmail"}]},{"title":"DynamoDB + Athena unified analytics","prompt":"Create a workflow that exports DynamoDB tables nightly into Athena-queryable Parquet, registers the schema, and writes a sample query for analyst use.","integrations":[{"id":"athena","name":"Athena"},{"id":"dynamodb","name":"Amazon DynamoDB"}]}]},{"id":"attio","type":"attio","slug":"attio","name":"Attio","description":"Manage records, notes, tasks, lists, comments, and more in Attio CRM","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/attio","authType":"oauth","connections":[{"id":"attio","kind":"oauth","label":"Connect with OAuth","providerId":"attio","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/attio","requiredScopes":[{"id":"record_permission:read-write","label":"Read and write CRM records"},{"id":"object_configuration:read-write","label":"Read and manage object schemas"},{"id":"list_configuration:read-write","label":"Read and manage list configurations"},{"id":"list_entry:read-write","label":"Read and write list entries"},{"id":"note:read-write","label":"Read and write notes"},{"id":"task:read-write","label":"Read and write tasks"},{"id":"comment:read-write","label":"Read and write comments and threads"},{"id":"user_management:read","label":"View workspace members"},{"id":"webhook:read-write","label":"Manage webhooks"}],"fields":[]},{"id":"attio-service-account","kind":"service_account","providerId":"attio-service-account","label":"Add API key","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/attio-service-account","fields":[{"id":"apiToken","label":"API key","placeholder":"Paste workspace API key","secret":true}]}],"operations":[{"name":"List Records","description":"Query and list records for a given object type (e.g. people, companies)"},{"name":"Get Record","description":"Get a single record by ID from Attio"},{"name":"Create Record","description":"Create a new record in Attio for a given object type"},{"name":"Update Record","description":"Update an existing record in Attio (appends multiselect values)"},{"name":"Delete Record","description":"Delete a record from Attio"},{"name":"Search Records","description":"Fuzzy search for records across object types in Attio"},{"name":"Assert Record (Upsert)","description":"Upsert a record in Attio — creates it if no match is found, updates it if a match exists"},{"name":"List Notes","description":"List notes in Attio, optionally filtered by parent record"},{"name":"Get Note","description":"Get a single note by ID from Attio"},{"name":"Create Note","description":"Create a note on a record in Attio"},{"name":"Delete Note","description":"Delete a note from Attio"},{"name":"List Tasks","description":"List tasks in Attio, optionally filtered by record, assignee, or completion status"},{"name":"Get Task","description":"Get a single task by ID from Attio"},{"name":"Create Task","description":"Create a task in Attio"},{"name":"Update Task","description":"Update a task in Attio (deadline, completion status, linked records, assignees)"},{"name":"Delete Task","description":"Delete a task from Attio"},{"name":"List Objects","description":"List all objects (system and custom) in the Attio workspace"},{"name":"Get Object","description":"Get a single object by ID or slug"},{"name":"Create Object","description":"Create a custom object in Attio"},{"name":"Update Object","description":"Update a custom object in Attio"},{"name":"List Lists","description":"List all lists in the Attio workspace"},{"name":"Get List","description":"Get a single list by ID or slug"},{"name":"Create List","description":"Create a new list in Attio"},{"name":"Update List","description":"Update a list in Attio"},{"name":"Query List Entries","description":"Query entries in an Attio list with optional filter, sort, and pagination"},{"name":"Get List Entry","description":"Get a single list entry by ID"},{"name":"Create List Entry","description":"Add a record to an Attio list as a new entry"},{"name":"Update List Entry","description":"Update entry attribute values on an Attio list entry (appends multiselect values)"},{"name":"Delete List Entry","description":"Remove an entry from an Attio list"},{"name":"List Members","description":"List all workspace members in Attio"},{"name":"Get Member","description":"Get a single workspace member by ID"},{"name":"Create Comment","description":"Create a comment on a list entry in Attio"},{"name":"Get Comment","description":"Get a single comment by ID from Attio"},{"name":"Delete Comment","description":"Delete a comment in Attio (if head of thread, deletes entire thread)"},{"name":"List Threads","description":"List comment threads in Attio, optionally filtered by record or list entry"},{"name":"Get Thread","description":"Get a single comment thread by ID from Attio"},{"name":"List Webhooks","description":"List all webhooks in the Attio workspace"},{"name":"Get Webhook","description":"Get a single webhook by ID from Attio"},{"name":"Create Webhook","description":"Create a webhook in Attio to receive event notifications"},{"name":"Update Webhook","description":"Update a webhook in Attio (target URL and/or subscriptions)"},{"name":"Delete Webhook","description":"Delete a webhook from Attio"},{"name":"List Attributes","description":"List the attributes (schema fields) defined on an Attio object or list"},{"name":"Get Attribute","description":"Get a single attribute (schema field) on an Attio object or list"},{"name":"Create Attribute","description":"Create a new attribute (schema field) on an Attio object or list"},{"name":"Update Attribute","description":"Update an attribute (schema field) on an Attio object or list"}],"triggers":[{"id":"attio_record_created","name":"Attio Record Created","description":"Trigger workflow when a new record is created in Attio"},{"id":"attio_record_updated","name":"Attio Record Updated","description":"Trigger workflow when a record is updated in Attio"},{"id":"attio_record_deleted","name":"Attio Record Deleted","description":"Trigger workflow when a record is deleted in Attio"},{"id":"attio_record_merged","name":"Attio Record Merged","description":"Trigger workflow when two records are merged in Attio"},{"id":"attio_note_created","name":"Attio Note Created","description":"Trigger workflow when a new note is created in Attio"},{"id":"attio_note_updated","name":"Attio Note Updated","description":"Trigger workflow when a note is updated in Attio"},{"id":"attio_note_deleted","name":"Attio Note Deleted","description":"Trigger workflow when a note is deleted in Attio"},{"id":"attio_task_created","name":"Attio Task Created","description":"Trigger workflow when a new task is created in Attio"},{"id":"attio_task_updated","name":"Attio Task Updated","description":"Trigger workflow when a task is updated in Attio"},{"id":"attio_task_deleted","name":"Attio Task Deleted","description":"Trigger workflow when a task is deleted in Attio"},{"id":"attio_comment_created","name":"Attio Comment Created","description":"Trigger workflow when a new comment is created in Attio"},{"id":"attio_comment_resolved","name":"Attio Comment Resolved","description":"Trigger workflow when a comment thread is resolved in Attio"},{"id":"attio_comment_unresolved","name":"Attio Comment Unresolved","description":"Trigger workflow when a comment thread is unresolved in Attio"},{"id":"attio_comment_deleted","name":"Attio Comment Deleted","description":"Trigger workflow when a comment is deleted in Attio"},{"id":"attio_list_entry_created","name":"Attio List Entry Created","description":"Trigger workflow when a new list entry is created in Attio"},{"id":"attio_list_entry_updated","name":"Attio List Entry Updated","description":"Trigger workflow when a list entry is updated in Attio"},{"id":"attio_list_entry_deleted","name":"Attio List Entry Deleted","description":"Trigger workflow when a list entry is deleted in Attio"},{"id":"attio_list_created","name":"Attio List Created","description":"Trigger workflow when a list is created in Attio"},{"id":"attio_list_updated","name":"Attio List Updated","description":"Trigger workflow when a list is updated in Attio"},{"id":"attio_list_deleted","name":"Attio List Deleted","description":"Trigger workflow when a list is deleted in Attio"},{"id":"attio_workspace_member_created","name":"Attio Workspace Member Created","description":"Trigger workflow when a new member is added to the Attio workspace"},{"id":"attio_webhook","name":"Attio Webhook (All Events)","description":"Trigger workflow on any Attio webhook event"}],"skills":[{"name":"upsert-record","description":"Create or update a person, company, or deal record in Attio, matching on a key field to avoid duplicates. Use to sync external data into the CRM.","content":"# Upsert Record\\n\\nKeep an Attio record in sync without creating duplicates.\\n\\n## Steps\\n1. Identify the target object (people, companies, or a custom object) and the matching attribute, such as email or domain.\\n2. Assemble the record values to set.\\n3. Use assert record to upsert on the matching attribute so an existing record is updated and a new one is created only when needed.\\n4. Verify the resulting record by getting it back.\\n\\n## Output\\nReport whether the record was created or updated and its record ID."},{"name":"log-note-on-record","description":"Attach a note to an Attio record capturing a call, meeting, or update. Use to keep CRM context current after interactions.","content":"# Log Note on Record\\n\\nRecord context against the right Attio record.\\n\\n## Steps\\n1. Find the target record — by ID, or search records to locate it by name or domain.\\n2. Compose the note title and body summarizing the interaction or update.\\n3. Create the note on that record.\\n4. Optionally create a follow-up task if next steps were agreed.\\n\\n## Output\\nConfirm the record the note was attached to and the note ID, plus any follow-up task created."},{"name":"create-followup-task","description":"Create a task in Attio linked to a record with an owner and due date. Use to capture follow-ups and next steps from deals or conversations.","content":"# Create Follow-up Task\\n\\nTurn a next step into a tracked Attio task.\\n\\n## Steps\\n1. Identify the related record and the work to be done.\\n2. Determine the assignee and a due date.\\n3. Create the task with a clear description, linked record, owner, and deadline.\\n4. Confirm the task was created against the right record.\\n\\n## Output\\nReport the created task ID, the linked record, assignee, and due date."},{"name":"manage-list-pipeline","description":"Query and update entries in an Attio list to move records through a pipeline or segment. Use for managing deal stages and curated segments.","content":"# Manage List Pipeline\\n\\nMove records through an Attio list-based pipeline.\\n\\n## Steps\\n1. Resolve the target list, then query list entries to see current state.\\n2. Identify which entries need to change stage or attributes.\\n3. Create, update, or remove list entries as needed to reflect the new state.\\n4. Summarize the pipeline distribution after the changes.\\n\\n## Output\\nReport which entries moved and their new stage, plus the resulting count of records per stage."}],"templates":[{"title":"Attio enrichment pipeline","prompt":"Build a workflow that watches new Attio records, enriches each contact with company size, funding, and tech stack via Apollo, and writes the enriched fields back to Attio.","integrations":[{"id":"attio","name":"Attio"},{"id":"apollo","name":"Apollo"}]},{"title":"Attio deal pipeline tracker","prompt":"Create a scheduled workflow that mirrors Attio deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.","integrations":[{"id":"attio","name":"Attio"},{"id":"slack","name":"Slack"}]},{"title":"Attio email-to-record logger","prompt":"Build a workflow that watches Gmail for emails to or from Attio contacts, logs each as an interaction on the matching record, and creates a follow-up task if mentioned.","integrations":[{"id":"attio","name":"Attio"},{"id":"gmail","name":"Gmail"}]},{"title":"Attio call-summary updater","prompt":"Create a workflow that runs after a Fireflies sales call, summarizes the transcript into a deal-ready summary, and updates the matching Attio deal record.","integrations":[{"id":"attio","name":"Attio"},{"id":"fireflies","name":"Fireflies"}]},{"title":"Attio win/loss analyzer","prompt":"Build a scheduled monthly workflow that pulls closed Attio deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.","integrations":[{"id":"attio","name":"Attio"}]},{"title":"Attio outreach orchestrator","prompt":"Create a workflow that watches Attio for contacts entering the outreach stage, drafts a personalized first-touch email, and queues it for the rep to review and send.","integrations":[{"id":"attio","name":"Attio"},{"id":"gmail","name":"Gmail"}]},{"title":"Attio Slack channel-per-deal","prompt":"Build a workflow that for Attio deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.","integrations":[{"id":"attio","name":"Attio"},{"id":"slack","name":"Slack"}]}]},{"id":"appconfig","type":"appconfig","slug":"aws-appconfig","name":"AWS AppConfig","description":"Manage and retrieve configuration with AWS AppConfig","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/appconfig","authType":"api-key","connections":[],"operations":[{"name":"Get Configuration","description":"Retrieve the latest deployed configuration for an AppConfig application, environment, and profile"},{"name":"List Applications","description":"List applications in AWS AppConfig"},{"name":"Create Application","description":"Create an application in AWS AppConfig"},{"name":"Get Application","description":"Get details about a single AWS AppConfig application"},{"name":"Update Application","description":"Update the name or description of an AWS AppConfig application"},{"name":"Delete Application","description":"Delete an AWS AppConfig application"},{"name":"List Environments","description":"List environments for an AWS AppConfig application"},{"name":"Create Environment","description":"Create an environment for an AWS AppConfig application"},{"name":"Get Environment","description":"Get details about a single AWS AppConfig environment"},{"name":"Update Environment","description":"Update the name or description of an AWS AppConfig environment"},{"name":"Delete Environment","description":"Delete an AWS AppConfig environment"},{"name":"List Configuration Profiles","description":"List configuration profiles for an AWS AppConfig application"},{"name":"Create Configuration Profile","description":"Create a configuration profile in an AWS AppConfig application"},{"name":"Get Configuration Profile","description":"Get details about a single AWS AppConfig configuration profile"},{"name":"Update Configuration Profile","description":"Update the name, description, or retrieval role of an AppConfig configuration profile"},{"name":"Delete Configuration Profile","description":"Delete an AWS AppConfig configuration profile"},{"name":"Create Hosted Configuration Version","description":"Create a new hosted configuration version for an AppConfig configuration profile"},{"name":"Get Hosted Configuration Version","description":"Retrieve a specific hosted configuration version from an AppConfig profile"},{"name":"List Hosted Configuration Versions","description":"List hosted configuration versions for an AWS AppConfig configuration profile"},{"name":"Delete Hosted Configuration Version","description":"Delete a specific hosted configuration version from an AppConfig profile"},{"name":"List Deployment Strategies","description":"List deployment strategies available in AWS AppConfig"},{"name":"Start Deployment","description":"Start deploying a configuration version to an AWS AppConfig environment"},{"name":"Get Deployment","description":"Get details about a specific AWS AppConfig deployment"},{"name":"List Deployments","description":"List deployments for an AWS AppConfig environment"},{"name":"Stop Deployment","description":"Stop an in-progress AWS AppConfig deployment"}],"triggers":[],"skills":[{"name":"read-feature-flags","description":"Retrieve the latest deployed AWS AppConfig configuration for an application, environment, and profile and use the values to drive feature flags or dynamic settings.","content":"# Read AppConfig Feature Flags\\n\\nLoad live configuration to branch workflow behavior.\\n\\n## Steps\\n1. Identify the target application, environment, and configuration profile (IDs or names).\\n2. Get the latest deployed configuration for that combination.\\n3. Parse the returned content (usually JSON) into a structured object.\\n4. Use the flag or setting values to decide which downstream path to take.\\n\\n## Output\\nThe resolved configuration values and the decision they drive. Do not hardcode flag values — always read them fresh from AppConfig."},{"name":"publish-and-deploy-config","description":"Create a new hosted AWS AppConfig configuration version from a document and deploy it to an environment with a chosen deployment strategy.","content":"# Publish and Deploy Config\\n\\nShip a new configuration version safely.\\n\\n## Steps\\n1. Assemble the configuration content (JSON, YAML, or text) and confirm the target application and configuration profile.\\n2. Create a new hosted configuration version with the correct content type.\\n3. Start a deployment of that version to the target environment using an appropriate deployment strategy.\\n4. Record the returned deployment number for follow-up monitoring.\\n\\n## Output\\nThe new version number and the started deployment number, plus the deployment state."},{"name":"monitor-deployment-rollback","description":"Watch in-progress AWS AppConfig deployments for an environment and surface rollbacks or stalled rollouts so they can be acted on.","content":"# Monitor Deployment Rollback\\n\\nKeep an eye on configuration rollouts.\\n\\n## Steps\\n1. List deployments for the target environment and find in-progress ones.\\n2. Get the status of each active deployment, capturing state and percentage complete.\\n3. Flag deployments that are rolling back or have stopped making progress.\\n4. Optionally stop a deployment that needs to be halted.\\n\\n## Output\\nA per-deployment status summary with any rollbacks or stalls called out for action."},{"name":"inventory-appconfig","description":"List AWS AppConfig applications, environments, and configuration profiles to build a single inventory of what configuration exists across the account.","content":"# Inventory AppConfig\\n\\nBuild a unified view of all AppConfig resources.\\n\\n## Steps\\n1. List every application and capture its ID, name, and description.\\n2. For each application, list its environments and configuration profiles.\\n3. Note the profile type (freeform vs feature flags) and where each profile is stored.\\n4. Assemble the results into a single structured inventory.\\n\\n## Output\\nAn inventory of applications with their environments and configuration profiles, suitable for writing to a tracking table."}],"templates":[{"title":"AppConfig runtime config loader","prompt":"Build a workflow that retrieves the latest deployed AWS AppConfig configuration for a given application, environment, and profile, parses the JSON, and uses the feature flags to branch downstream agent behavior.","integrations":[{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig feature-flag publisher","prompt":"Create a workflow that takes a JSON feature-flag document, creates a new hosted configuration version in an AWS AppConfig configuration profile, and starts a deployment to the target environment using a chosen deployment strategy.","integrations":[{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig deployment monitor","prompt":"Build a scheduled workflow that lists in-progress AWS AppConfig deployments for an environment, gets each deployment status, and posts a Slack alert when a deployment is rolling back or has stalled.","integrations":[{"id":"appconfig","name":"AWS AppConfig"},{"id":"slack","name":"Slack"}]},{"title":"AppConfig config inventory","prompt":"Create a scheduled workflow that lists every AWS AppConfig application, its environments, and its configuration profiles, and writes a unified inventory into a tracking table so the platform team has a single source of truth.","integrations":[{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig change auditor","prompt":"Build a scheduled workflow that lists recent AWS AppConfig deployments across environments, summarizes which configuration versions were deployed when, and writes an audit report file for compliance review.","integrations":[{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig drift checker","prompt":"Create a scheduled workflow that retrieves the live AWS AppConfig configuration and compares it against an expected baseline stored in a table, alerting Slack when the deployed configuration drifts from the approved version.","integrations":[{"id":"appconfig","name":"AWS AppConfig"},{"id":"slack","name":"Slack"}]},{"title":"AppConfig bootstrap from GitHub","prompt":"Build a workflow triggered when a config file changes in a GitHub pull request that creates a new hosted AWS AppConfig configuration version from the file contents and deploys it to a staging environment for validation.","integrations":[{"id":"appconfig","name":"AWS AppConfig"},{"id":"github","name":"GitHub"}]},{"title":"AppConfig gated rollout","prompt":"Create a workflow that gates an AWS AppConfig deployment behind a Slack approval: it creates the configuration version, waits for sign-off, starts the deployment with a linear strategy, and monitors completion before reporting back.","integrations":[{"id":"appconfig","name":"AWS AppConfig"},{"id":"slack","name":"Slack"}]}]},{"id":"iam","type":"iam","slug":"aws-iam","name":"AWS IAM","description":"Manage AWS IAM users, roles, policies, and groups","category":"Security","docsUrl":"https://docs.sim.ai/integrations/iam","authType":"api-key","connections":[],"operations":[{"name":"List Users","description":"List IAM users in your AWS account"},{"name":"Get User","description":"Get detailed information about an IAM user"},{"name":"Create User","description":"Create a new IAM user"},{"name":"Delete User","description":"Delete an IAM user"},{"name":"List Roles","description":"List IAM roles in your AWS account"},{"name":"Get Role","description":"Get detailed information about an IAM role"},{"name":"Create Role","description":"Create a new IAM role with a trust policy"},{"name":"Delete Role","description":"Delete an IAM role"},{"name":"Attach User Policy","description":"Attach a managed policy to an IAM user"},{"name":"Detach User Policy","description":"Remove a managed policy from an IAM user"},{"name":"Attach Role Policy","description":"Attach a managed policy to an IAM role"},{"name":"Detach Role Policy","description":"Remove a managed policy from an IAM role"},{"name":"List Policies","description":"List managed IAM policies"},{"name":"Get Policy","description":"Get details about a managed IAM policy, including its description — the field ListPolicies never returns"},{"name":"Create Access Key","description":"Create a new access key pair for an IAM user"},{"name":"Delete Access Key","description":"Delete an access key pair for an IAM user"},{"name":"List Access Keys","description":"List an IAM user\'s access key IDs with their status and age — use to find stale keys and to confirm which keys remain after a rotation"},{"name":"Update Access Key","description":"Activate or deactivate an IAM access key — deactivate an old key and verify nothing breaks before deleting it"},{"name":"List Groups","description":"List IAM groups in your AWS account"},{"name":"Add User to Group","description":"Add an IAM user to a group"},{"name":"Remove User from Group","description":"Remove an IAM user from a group"},{"name":"List Attached Role Policies","description":"List all managed policies attached to an IAM role"},{"name":"List Attached User Policies","description":"List all managed policies attached to an IAM user"},{"name":"Simulate Principal Policy","description":"Simulate whether a user, role, or group is allowed to perform specific AWS actions — useful for pre-flight access checks"}],"triggers":[],"skills":[{"name":"audit-iam-permissions","description":"List IAM users, roles, and their attached policies to produce an access audit. Use for security reviews and least-privilege checks.","content":"# Audit IAM Permissions\\n\\nReport who and what has access in IAM.\\n\\n## Steps\\n1. List users and roles to establish the inventory.\\n2. For each principal of interest, list attached user or role policies. Get a policy by ARN when you need its description to judge intent — list policies never returns one.\\n3. List each user’s access keys to find keys that are stale or still Active but unused.\\n4. Optionally simulate principal policy to confirm whether a principal can perform sensitive actions, reading the per-resource verdict from resourceSpecificResults.\\n5. Flag overly broad policies, unused principals, or access keys that should be rotated.\\n\\n## Output\\nAn audit summary: principals, their attached policies, and their access key inventory, with risky or excessive grants called out. Do not expose secret values."},{"name":"check-effective-permissions","description":"Use IAM policy simulation to verify whether a user or role can perform specific actions on resources. Use for troubleshooting access and validating changes.","content":"# Check Effective Permissions\\n\\nDetermine whether a principal is actually allowed to do something.\\n\\n## Steps\\n1. Identify the principal (user or role) and the actions and resource ARNs to test.\\n2. Run simulate principal policy for those actions against the resources. If any policy is gated by a condition, supply the condition context keys so it does not simulate as denied for missing context.\\n3. Read the per-resource verdict from resourceSpecificResults — evalResourceName plus evalResourceDecision. The top-level evalDecision is the aggregate across every ARN you passed, so one explicitly denied bucket makes the whole action read as explicitDeny; do not report that as a denial on the other resources. The top-level evalResourceName is a resource-type ARN template, not one of your ARNs.\\n4. If a resource is denied unexpectedly, read its matchedStatements and missingContextValues, then inspect the attached policies to explain why.\\n\\n## Output\\nA verdict per action AND per resource ARN, with the governing policy for each, and a plain-language explanation of any denial."},{"name":"provision-iam-principal","description":"Create an IAM user or role, attach managed policies, and place users into groups to grant scoped access. Use for onboarding and standing up service roles.","content":"# Provision IAM Principal\\n\\nStand up a new IAM user or role with the right permissions.\\n\\n## Steps\\n1. Decide whether to create a user (for a person or app) or a role (for a service or cross-account access).\\n2. For a user, create the user, then add them to the relevant groups or attach the needed managed policy ARNs. For a role, create the role with a trust policy that names the allowed principal, then attach the policy ARNs.\\n3. Prefer attaching existing managed policies over broad wildcards; grant only the actions required.\\n4. Confirm the result by listing the attached user or role policies.\\n\\n## Output\\nReport the created principal name and ARN and the policies now attached. Do not print any generated secret values."},{"name":"rotate-access-keys","description":"Create a fresh IAM access key for a user and delete the old one to complete a safe rotation. Use for scheduled key rotation and remediating aged keys.","content":"# Rotate Access Keys\\n\\nReplace a user’s access key following the two-step rotation pattern.\\n\\n## Steps\\n1. List the user’s access keys to see which keys exist, their status, and their age.\\n2. Create a new access key for the target user so two keys exist briefly.\\n3. Hand the new key to its consumer securely and let dependents switch over and verify they still work.\\n4. Deactivate the old key by updating its status to Inactive, and leave it that way long enough to prove nothing still depends on it. Reactivate it if something breaks.\\n5. Once the new key is confirmed in use, delete the old access key by its ID.\\n6. List the access keys again to confirm only the intended key remains for the user.\\n\\n## Output\\nReport the user, that a new key was issued, and the old key ID that was deactivated and then deleted. Never print the secret access key value — reference keys only by their access key ID."}],"templates":[{"title":"CloudTrail IAM change review","prompt":"Build a daily workflow that looks up AWS CloudTrail events from iam.amazonaws.com, summarizes every policy attach, role creation, and access key change with the principal who made it, and writes the review to a compliance table.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"IAM permission drift detector","prompt":"Build a scheduled workflow that diffs AWS IAM policies against the Terraform source of truth, alerts on drift, and writes the drift report to a security Slack channel.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"slack","name":"Slack"}]},{"title":"IAM wildcard policy auditor","prompt":"Create a scheduled workflow that scans AWS IAM policies for wildcard permissions, scores each by blast radius, and writes a remediation queue to a security table.","integrations":[{"id":"iam","name":"AWS IAM"}]},{"title":"IAM access-review automator","prompt":"Build a scheduled quarterly workflow that posts AWS IAM access-review requests to role owners in Slack, captures attestations, and writes the audit log to a compliance table.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"slack","name":"Slack"}]},{"title":"IAM stale-key sweeper","prompt":"Create a scheduled workflow that reviews IAM users for aged access keys, notifies the owner via Slack, and rotates the key with a fresh one or removes it after a grace period.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"slack","name":"Slack"}]},{"title":"IAM unused-role cleaner","prompt":"Build a scheduled monthly workflow that finds IAM roles with no recent activity, requires owner approval in Slack, and removes the role to reduce attack surface.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"slack","name":"Slack"}]},{"title":"IAM least-privilege recommender","prompt":"Create a workflow that simulates IAM principal policies against expected actions, generates least-privilege policy suggestions for over-permissioned roles, and opens Linear tickets for engineers to apply.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"linear","name":"Linear"}]},{"title":"IAM policy guardrail watcher","prompt":"Build a scheduled workflow that snapshots AWS IAM managed policies and role attachments, classifies risk on each change, and pings the security team in Slack when a change broadens permissions.","integrations":[{"id":"iam","name":"AWS IAM"},{"id":"slack","name":"Slack"}]}]},{"id":"identity_center","type":"identity_center","slug":"aws-identity-center","name":"AWS Identity Center","description":"Manage account access in AWS IAM Identity Center","category":"Security","docsUrl":"https://docs.sim.ai/integrations/identity_center","authType":"api-key","connections":[],"operations":[{"name":"List Instances","description":"List all AWS IAM Identity Center instances in your account"},{"name":"List Accounts","description":"List all AWS accounts in your organization"},{"name":"Describe Account","description":"Retrieve details about a specific AWS account by its ID"},{"name":"List Permission Sets","description":"List all permission sets defined in an IAM Identity Center instance"},{"name":"Get User","description":"Look up a user in the Identity Store by email address"},{"name":"Describe User","description":"Resolve an Identity Store user ID to the user behind it. Use to turn the principalId on an account assignment into a name and email."},{"name":"Get Group","description":"Look up a group in the Identity Store by display name"},{"name":"Describe Group","description":"Resolve an Identity Store group ID to the group behind it. Use to turn the principalId on an account assignment into a group name."},{"name":"List Groups","description":"List all groups in the Identity Store"},{"name":"List Group Memberships","description":"List the users who belong to an Identity Store group"},{"name":"Create Account Assignment","description":"Grant a user or group access to an AWS account via a permission set (temporary elevated access)"},{"name":"Delete Account Assignment","description":"Revoke a user or group access to an AWS account by removing a permission set assignment"},{"name":"Check Assignment Status","description":"Check the provisioning status of an account assignment creation request"},{"name":"Check Assignment Deletion Status","description":"Check the deprovisioning status of an account assignment deletion request"},{"name":"List Account Assignments For Principal","description":"List every account and permission set a specific user or group is assigned. Use List Assignments For Account to go the other way, from an account to its principals."},{"name":"List Assignments For Account","description":"List every principal assigned a specific permission set on a specific AWS account. Use for per-account access reviews."}],"triggers":[],"skills":[{"name":"grant-temporary-access","description":"Assign a permission set to a user or group on an AWS account through Identity Center and confirm the assignment completes. Use for just-in-time elevated access.","content":"# Grant Temporary Access\\n\\nProvision elevated access via an Identity Center account assignment.\\n\\n## Steps\\n1. Resolve the Identity Center instance, target account, and permission set.\\n2. Resolve the principal — get the user or group to confirm the correct ID and type.\\n3. Create the account assignment for that principal, permission set, and account.\\n4. Poll check assignment status until it reports SUCCEEDED.\\n\\n## Output\\nConfirm the principal, account, permission set, and final assignment status. If it failed, surface the failure reason."},{"name":"revoke-access","description":"Remove a permission set assignment from a user or group in Identity Center and confirm deletion. Use to wind down temporary or expired access.","content":"# Revoke Access\\n\\nRemove an account assignment to revoke access.\\n\\n## Steps\\n1. List account assignments for principal to confirm the principal currently holds the permission set on the account.\\n2. Delete the account assignment for that principal, permission set, and account.\\n3. Poll check assignment deletion status until it reports SUCCEEDED.\\n4. Re-list assignments to verify the grant is gone.\\n\\n## Output\\nConfirm what was revoked and the final deletion status. Note if the assignment did not exist."},{"name":"access-audit-report","description":"Enumerate permission sets, account assignments, and group memberships in Identity Center to produce an access report. Use for compliance and periodic reviews.","content":"# Access Audit Report\\n\\nReport who has access to what across accounts.\\n\\n## Steps\\n1. List instances and accounts to scope the report, and note the instance ARN and Identity Store ID.\\n2. List permission sets for the instance.\\n3. For every account and permission set pair, list assignments for account to collect the assigned principals.\\n4. Resolve each principal by ID — describe user for USER principals, describe group for GROUP principals — and expand groups with list group memberships.\\n5. Compile assignments grouped by account and permission set.\\n\\n## Output\\nAn access report: per account, which principals hold which permission sets, with anything unexpected flagged for review."}],"templates":[{"title":"Identity Center access-review","prompt":"Build a scheduled quarterly workflow that surfaces AWS Identity Center permission sets and group memberships, requests owner attestation in Slack, and writes the audit log to a compliance table.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"slack","name":"Slack"}]},{"title":"Identity Center new-hire onboarder","prompt":"Create a workflow that on a Workday new-hire event provisions AWS Identity Center permission sets based on role, and writes the assignment to a tracking table.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"workday","name":"Workday"}]},{"title":"Identity Center offboarder","prompt":"Build a workflow that on a Workday termination revokes the user’s AWS Identity Center assignments and writes the action log to the security audit table.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"workday","name":"Workday"}]},{"title":"Identity Center assignment monitor","prompt":"Create a scheduled workflow that snapshots AWS Identity Center account assignments and permission sets, flags new or broadened access, and pings the security Slack channel on changes.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"slack","name":"Slack"}]},{"title":"Identity Center permission-set drift","prompt":"Build a scheduled workflow that diffs AWS Identity Center permission sets against the Terraform source of truth, alerts on drift, and writes the report.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"slack","name":"Slack"}]},{"title":"Identity Center orphaned-access finder","prompt":"Create a scheduled workflow that lists AWS Identity Center account assignments, flags principals with stale or unexpected access, emails owners for confirmation, and writes the findings to a security dashboard table.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"gmail","name":"Gmail"}]},{"title":"Identity Center compliance reporter","prompt":"Build a scheduled workflow that produces an AWS Identity Center compliance report — permission sets, group memberships, and account assignments — and writes the file for auditors.","integrations":[{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"STS Identity-Center role broker","prompt":"Build a workflow that takes an Identity Center user request, assumes the matching AWS STS role to mint scoped short-lived credentials, writes the issuance to a session log, and alerts Slack when a request targets a privileged role.","integrations":[{"id":"identity_center","name":"AWS Identity Center"},{"id":"sts","name":"AWS STS"},{"id":"slack","name":"Slack"}]}]},{"id":"secrets_manager","type":"secrets_manager","slug":"aws-secrets-manager","name":"AWS Secrets Manager","description":"Connect to AWS Secrets Manager","category":"Security","docsUrl":"https://docs.sim.ai/integrations/secrets_manager","authType":"none","connections":[],"operations":[{"name":"Get Secret","description":"Retrieve a secret value from AWS Secrets Manager"},{"name":"List Secrets","description":"List secrets stored in AWS Secrets Manager"},{"name":"Create Secret","description":"Create a new secret in AWS Secrets Manager"},{"name":"Update Secret","description":"Update the value of an existing secret in AWS Secrets Manager"},{"name":"Delete Secret","description":"Delete a secret from AWS Secrets Manager"},{"name":"Describe Secret","description":"Retrieve full metadata for a secret in AWS Secrets Manager, including rotation configuration and replication status, without exposing the secret value"},{"name":"Tag Secret","description":"Attach tags to a secret in AWS Secrets Manager"},{"name":"Untag Secret","description":"Remove tags from a secret in AWS Secrets Manager"},{"name":"Restore Secret","description":"Cancel a scheduled deletion for a secret in AWS Secrets Manager, restoring access to it"},{"name":"Rotate Secret","description":"Start or reconfigure rotation for a secret in AWS Secrets Manager"}],"triggers":[],"skills":[{"name":"rotate-secret-value","description":"Update a stored secret in AWS Secrets Manager with a new value as part of a rotation flow. Use to push refreshed credentials without manual console edits.","content":"# Rotate Secret Value\\n\\nUpdate a secret with a new value.\\n\\n## Steps\\n1. Confirm the target secret exists by getting it (do not log the returned value).\\n2. Obtain the new secret value to store, as a string or JSON key/value payload.\\n3. Update the secret with the new value, creating a new version.\\n4. Verify by getting the secret and checking the updated version metadata, not the raw value.\\n\\n## Output\\nConfirm the secret name and that a new version was created. Never print the secret value itself."},{"name":"audit-secret-inventory","description":"List secrets in AWS Secrets Manager and report metadata like last-changed and rotation status. Use for hygiene checks and finding stale secrets.","content":"# Audit Secret Inventory\\n\\nReport on the secrets that exist without exposing their values.\\n\\n## Steps\\n1. List secrets to enumerate names, descriptions, and tags.\\n2. For each secret of interest, read metadata such as last changed and last rotated dates.\\n3. Flag secrets that are stale, undescribed, or appear unused.\\n4. Summarize without ever fetching or printing secret values.\\n\\n## Output\\nAn inventory summary: secret names with last-changed and rotation status, and stale or unrotated secrets called out. No secret values."},{"name":"store-new-secret","description":"Create a new secret in AWS Secrets Manager from a provided credential or generated value. Use to register app credentials, API keys, or DB passwords centrally.","content":"# Store New Secret\\n\\nRegister a new credential in Secrets Manager.\\n\\n## Steps\\n1. Choose a clear hierarchical name for the secret, such as my-app/prod/db-password.\\n2. Assemble the value to store — a plain string, or a JSON object of key/value pairs for structured credentials.\\n3. Create the secret with that name, value, and a description of what it is and where it is used.\\n4. Confirm creation by reading back the version metadata, not the value.\\n\\n## Output\\nConfirm the secret name, ARN, and new version ID. Never echo the stored secret value back."},{"name":"decommission-secret","description":"Schedule deletion of a secret in AWS Secrets Manager with a recovery window so it can be restored if needed. Use to retire unused or rotated-out credentials safely.","content":"# Decommission Secret\\n\\nRetire a secret without permanently losing it immediately.\\n\\n## Steps\\n1. Confirm the target secret and that nothing still depends on it.\\n2. Schedule deletion with a recovery window (e.g. 30 days) so it can be restored during that period; reserve force delete for confirmed-orphaned secrets only.\\n3. Record the scheduled deletion date.\\n4. Re-list secrets to confirm it is marked for deletion.\\n\\n## Output\\nConfirm the secret name and the scheduled deletion date, or that immediate deletion was requested. Do not print the secret value."},{"name":"start-native-rotation","description":"Start or reconfigure AWS Secrets Manager native rotation for a secret that already has a rotation Lambda configured. Use when compliance requires automatic, scheduled rotation rather than manual updates.","content":"# Start Native Rotation\\n\\nConfigure or trigger built-in Secrets Manager rotation.\\n\\n## Steps\\n1. Describe the target secret to confirm it has a rotation Lambda ARN configured (or supply one).\\n2. Decide the rotation schedule: a fixed interval in days, or a cron/rate schedule expression, plus an optional rotation window duration.\\n3. Start rotation with the chosen schedule; rotation runs immediately unless configured to wait for the next window.\\n4. Re-describe the secret afterward to confirm the next rotation date and rotation-enabled status.\\n\\n## Output\\nConfirm the secret name, whether rotation is now enabled, and the next scheduled rotation date. Never print the secret value."},{"name":"restore-deleted-secret","description":"Cancel a scheduled deletion in AWS Secrets Manager to restore access to a secret before its recovery window elapses. Use to reverse an accidental or premature delete.","content":"# Restore Deleted Secret\\n\\nUndo a pending deletion while the recovery window is still open.\\n\\n## Steps\\n1. Describe the secret to confirm it has a scheduled deletion date.\\n2. Restore the secret, which clears the scheduled deletion.\\n3. Re-describe the secret to confirm the deletion date is cleared.\\n\\n## Output\\nConfirm the secret name and ARN, and that it is no longer scheduled for deletion."},{"name":"tag-secret-for-governance","description":"Attach or remove ownership, environment, or cost-center tags on an AWS Secrets Manager secret for governance and cost allocation. Use to keep secret metadata consistent with tagging policy.","content":"# Tag Secret for Governance\\n\\nKeep secret tags aligned with organizational tagging policy.\\n\\n## Steps\\n1. Describe the secret to see its current tags.\\n2. Attach the required tags (e.g. owner, environment, cost-center) as key/value pairs, or remove tags that no longer apply by key.\\n3. Re-describe the secret to confirm the tag set matches policy.\\n\\n## Output\\nConfirm the secret name and the resulting tag keys. Do not print the secret value."}],"templates":[{"title":"Secrets Manager scheduled rotation","prompt":"Build a scheduled workflow that lists AWS Secrets Manager secrets, generates a new value for each secret past its rotation window, updates it with the new value, and writes the rotation status to a compliance table.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"}]},{"title":"Secrets Manager inventory auditor","prompt":"Create a scheduled workflow that lists all AWS Secrets Manager secrets, flags ones missing descriptions or older than a chosen age, writes a security review, and posts the findings to Slack.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"slack","name":"Slack"}]},{"title":"Secrets Manager stale-secret cleaner","prompt":"Build a scheduled workflow that lists AWS Secrets Manager secrets, identifies ones created before a chosen cutoff, requests owner approval in Slack, deletes the approved secrets, and writes the cleanup audit.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"slack","name":"Slack"}]},{"title":"Secrets Manager + Infisical mirror","prompt":"Create a workflow that mirrors secrets between AWS Secrets Manager and Infisical for cross-cloud applications, normalizes naming, and writes a sync log.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"infisical","name":"Infisical"}]},{"title":"Secrets Manager break-glass retrieval","prompt":"Build a workflow that gates retrieval of a sensitive AWS Secrets Manager secret behind a Slack approval, captures the requester and justification, fetches the secret only after sign-off, and writes the audit record.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"slack","name":"Slack"}]},{"title":"Secrets Manager + 1Password bridge","prompt":"Create a workflow that bridges select AWS Secrets Manager secrets into 1Password for human-shared credentials while keeping access logs aligned for audit.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"onepassword","name":"1Password"}]},{"title":"Secrets Manager change watcher","prompt":"Build a scheduled workflow that polls AWS Secrets Manager secret version IDs, compares them against a baseline stored in a table, and pings the security Slack channel when a secret changes unexpectedly.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"},{"id":"slack","name":"Slack"}]},{"title":"Secrets Manager native rotation kickoff","prompt":"Build a scheduled workflow that describes AWS Secrets Manager secrets nearing their next rotation date, starts native rotation for the ones that are due, and writes the outcome to a compliance table.","integrations":[{"id":"secrets_manager","name":"AWS Secrets Manager"}]}]},{"id":"ses","type":"ses","slug":"aws-ses","name":"AWS SES","description":"Send emails and manage templates with AWS Simple Email Service","category":"Email","docsUrl":"https://docs.sim.ai/integrations/ses","authType":"api-key","connections":[],"operations":[{"name":"Send Email","description":"Send an email via AWS SES using simple or HTML content"},{"name":"Send Templated Email","description":"Send an email using an SES email template with dynamic template data"},{"name":"Send Bulk Email","description":"Send emails to multiple recipients using an SES template with per-recipient data"},{"name":"List Identities","description":"List all verified email identities (email addresses and domains) in your SES account"},{"name":"Get Account","description":"Get SES account sending quota and status information"},{"name":"Create Template","description":"Create a new SES email template for use with templated email sending"},{"name":"Get Template","description":"Retrieve the content and details of an SES email template"},{"name":"List Templates","description":"List all SES email templates in your account"},{"name":"Delete Template","description":"Delete an existing SES email template"},{"name":"Update Template","description":"Update the subject, HTML, and text content of an existing SES email template"},{"name":"Send Custom Verification Email","description":"Send a branded custom verification email to an address using a custom verification email template"},{"name":"Create Email Identity","description":"Start verification of a new SES email address or domain identity"},{"name":"Get Email Identity","description":"Retrieve verification status, DKIM, Mail-From, and policy details for an SES identity"},{"name":"Delete Email Identity","description":"Delete a verified SES email address or domain identity"},{"name":"Put Suppressed Destination","description":"Add an email address to the account-level SES suppression list"},{"name":"Get Suppressed Destination","description":"Retrieve details for a specific email address on the SES suppression list"},{"name":"List Suppressed Destinations","description":"List email addresses on the account-level SES suppression list"},{"name":"Delete Suppressed Destination","description":"Remove an email address from the account-level SES suppression list"},{"name":"Create Configuration Set","description":"Create an SES configuration set to control tracking, delivery, reputation, sending, and suppression behavior for emails"}],"triggers":[],"skills":[{"name":"send-notification-email","description":"Send a transactional email through AWS SES to one or more recipients. Use for alerts, confirmations, and one-off notifications from a workflow.","content":"# Send Notification Email\\n\\nSend a transactional email via SES.\\n\\n## Steps\\n1. Determine the verified sender identity, the recipients, subject, and body.\\n2. Choose a plain-text or HTML body to match the message.\\n3. Send the email, including reply-to or CC recipients if needed.\\n4. Confirm the send succeeded and capture the message ID.\\n\\n## Output\\nReport the SES message ID and the recipients. If the send was rejected, surface the SES error (for example, an unverified sender or sandbox restriction)."},{"name":"send-templated-campaign","description":"Send a templated SES email to many recipients with per-recipient personalization. Use for newsletters, onboarding sequences, and bulk notifications.","content":"# Send Templated Campaign\\n\\nSend personalized emails using an SES template.\\n\\n## Steps\\n1. Confirm the template exists with get template, or create it first.\\n2. Assemble the recipient list with each recipient\'s template data for personalization.\\n3. Use send bulk email for many recipients, or send templated email for a single message.\\n4. Collect per-recipient send status.\\n\\n## Output\\nReport how many messages were accepted versus failed, with message IDs and the reason for any failures."},{"name":"manage-email-templates","description":"Create, fetch, list, update, and delete reusable email templates in AWS SES. Use to maintain a consistent, version-controlled template library.","content":"# Manage Email Templates\\n\\nMaintain the SES template library.\\n\\n## Steps\\n1. To add a template, create it with a name, subject, and HTML and text parts using placeholder variables.\\n2. To review, get a template by name or list templates.\\n3. To revise copy without changing the name, update the template with new subject, HTML, or text content.\\n4. To retire one, delete the template by name.\\n5. Keep template names descriptive so they are easy to reference when sending.\\n\\n## Output\\nReport the template name affected and the action taken, or the template contents for a fetch."},{"name":"manage-suppression-list","description":"Add, remove, look up, and list addresses on the AWS SES account-level suppression list. Use to keep bounced or complained addresses out of future sends.","content":"# Manage Suppression List\\n\\nKeep the SES suppression list accurate so future sends skip unreachable or unwilling recipients.\\n\\n## Steps\\n1. To suppress an address after a bounce or complaint, put a suppressed destination with the matching reason (BOUNCE or COMPLAINT).\\n2. To check whether an address is already suppressed, get the suppressed destination by email address.\\n3. To audit the list, list suppressed destinations, optionally filtered by reason or a date range.\\n4. To re-enable sending to an address (for example, after a customer confirms a new inbox), delete the suppressed destination.\\n\\n## Output\\nReport the email address affected and the action taken. For a list, report the count of suppressed addresses and their reasons."},{"name":"onboard-sending-domain","description":"Verify a new sending domain or address in AWS SES and check DKIM and verification status. Use before sending from a new identity.","content":"# Onboard Sending Domain\\n\\nVerify a new SES identity before sending from it.\\n\\n## Steps\\n1. Create the email identity for the domain or address you want to send from.\\n2. If DKIM tokens are returned, hand them to whoever manages DNS to add as CNAME records.\\n3. Get the email identity periodically to check verification status and DKIM signing status until it reports success.\\n4. Once verified, optionally create a configuration set to control tracking, delivery, and reputation options for emails sent from the identity.\\n5. If the identity is no longer needed, delete the email identity.\\n\\n## Output\\nReport the identity, its verification status, and DKIM status. If verification is pending, report the DNS records that still need to be added."},{"name":"check-sending-health","description":"Inspect AWS SES account sending limits, quota usage, and verified identities. Use to confirm capacity and deliverability readiness before a send.","content":"# Check Sending Health\\n\\nVerify SES is ready to send.\\n\\n## Steps\\n1. Get the account to read the sending quota, send rate, and whether the account is out of the sandbox.\\n2. List identities to confirm the intended sender domain or address is verified.\\n3. Compare planned volume against the remaining 24-hour quota.\\n4. Flag any blockers — sandbox mode, unverified senders, or quota nearly exhausted.\\n\\n## Output\\nReport sending enabled status, quota used versus max, and any unverified identities that would block the send."}],"templates":[{"title":"SendGrid + SES enterprise sender","prompt":"Build a workflow that splits transactional traffic between SendGrid and AWS SES based on message category and recipient region, balances volume to stay under per-provider limits, and writes provider, status, and latency to a delivery table.","integrations":[{"id":"ses","name":"AWS SES"},{"id":"sendgrid","name":"SendGrid"}]},{"title":"SES bulk announcement","prompt":"Create a workflow that takes a recipient list from a table and an SES email template, sends the announcement using SES bulk send with per-recipient template data, and writes the per-recipient send status back to the table.","integrations":[{"id":"ses","name":"AWS SES"}]},{"title":"SES verified-identity audit","prompt":"Build a scheduled workflow that lists AWS SES verified identities, checks the account sending quota and reputation, and posts a Slack report when any identity is unverified or the account approaches the daily quota.","integrations":[{"id":"ses","name":"AWS SES"},{"id":"slack","name":"Slack"}]},{"title":"SES templated nurture","prompt":"Create a workflow that walks each contact in a tables-based nurture sequence through staged SES templated sends with delays between steps, branches on open or click, and stops the sequence when the contact replies.","integrations":[{"id":"ses","name":"AWS SES"}]},{"title":"SES + Mailgun multi-region sender","prompt":"Build a workflow that routes transactional emails through SES in primary regions and through Mailgun for regions where SES is not provisioned, normalizing template variables and writing one unified send log to a table.","integrations":[{"id":"ses","name":"AWS SES"},{"id":"mailgun","name":"Mailgun"}]},{"title":"SES + AgentMail customer concierge","prompt":"Create a workflow that sends outbound customer messages through AWS SES but provisions a per-customer AgentMail inbox to receive replies, threads conversations across both, and tags AgentMail threads with the customer ID.","integrations":[{"id":"ses","name":"AWS SES"},{"id":"agentmail","name":"AgentMail"}]},{"title":"SES suppression list sync","prompt":"Build a workflow that reads bounce and complaint webhook events, adds the affected addresses to the SES account suppression list with the matching reason, and periodically lists suppressed destinations to reconcile a marketing contacts table so unreachable addresses are excluded from future sends.","integrations":[{"id":"ses","name":"AWS SES"}]},{"title":"SES new-domain onboarding","prompt":"Create a workflow that takes a new sending domain from a table, creates the SES email identity, polls get email identity until DKIM verification succeeds, creates a dedicated configuration set with open and click tracking enabled, and posts the DNS tokens to Slack for the infrastructure team to add.","integrations":[{"id":"ses","name":"AWS SES"},{"id":"slack","name":"Slack"}]},{"title":"SES domain reputation monitor","prompt":"Build a scheduled daily workflow that pulls SES account sending statistics and per-identity reputation indicators, logs them to a tracking table for trend lines, and flags any identity whose complaint or bounce rate is trending up.","integrations":[{"id":"ses","name":"AWS SES"}]},{"title":"SES template library sync","prompt":"Build a workflow that reads my approved email templates from a table, creates or updates each one in AWS SES with create template, lists existing SES templates to detect drift, and deletes templates that have been removed from the table so the SES library stays in sync.","integrations":[{"id":"ses","name":"AWS SES"}]}]},{"id":"sts","type":"sts","slug":"aws-sts","name":"AWS STS","description":"Connect to AWS Security Token Service","category":"Security","docsUrl":"https://docs.sim.ai/integrations/sts","authType":"api-key","connections":[],"operations":[{"name":"Assume Role","description":"Assume an IAM role and receive temporary security credentials"},{"name":"Assume Role With Web Identity","description":"Assume an IAM role using an OIDC/OAuth 2.0 web identity token (e.g. GitHub Actions OIDC, EKS IRSA, Google/Facebook federation) and receive temporary security credentials"},{"name":"Assume Role With SAML","description":"Assume an IAM role using a SAML 2.0 authentication response from an enterprise identity provider and receive temporary security credentials"},{"name":"Get Caller Identity","description":"Get details about the IAM user or role whose credentials are used to call the API"},{"name":"Get Session Token","description":"Get temporary security credentials for an IAM user, optionally with MFA"},{"name":"Get Access Key Info","description":"Get the AWS account ID associated with an access key"}],"triggers":[],"skills":[{"name":"assume-cross-account-role","description":"Call AWS STS to assume a role and obtain temporary credentials for a target account. Use for cross-account access in a workflow.","content":"# Assume Cross-Account Role\\n\\nObtain temporary credentials by assuming an IAM role.\\n\\n## Steps\\n1. Identify the role ARN to assume and a descriptive session name.\\n2. Set the session duration and any external ID required by the trust policy.\\n3. Call assume role to receive temporary access key, secret key, and session token.\\n4. Pass the temporary credentials to the downstream step that needs cross-account access.\\n\\n## Output\\nConfirm the assumed role ARN and credential expiration. Never print the secret access key or session token in plain logs."},{"name":"verify-caller-identity","description":"Use AWS STS get caller identity to confirm which account, user, or role the current credentials resolve to. Use to validate setup and debug auth issues.","content":"# Verify Caller Identity\\n\\nConfirm which AWS identity the workflow is operating as.\\n\\n## Steps\\n1. Call get caller identity with the active credentials.\\n2. Read the returned account ID, user ID, and principal ARN.\\n3. Compare against the expected account and role for the task.\\n4. If it does not match, flag a likely credential or assume-role misconfiguration.\\n\\n## Output\\nReport the account ID and ARN of the active identity, and whether it matches the expected principal."},{"name":"mint-mfa-session-token","description":"Use AWS STS to mint short-lived session credentials, optionally backed by an MFA token, for IAM-user workflows that require MFA. Use for time-boxed elevated sessions.","content":"# Mint MFA Session Token\\n\\nIssue temporary credentials, optionally enforcing MFA.\\n\\n## Steps\\n1. Decide the session duration the downstream task needs.\\n2. If MFA is required, supply the MFA device serial number and the current token code.\\n3. Call get session token to receive a temporary access key, secret key, and session token.\\n4. Hand the temporary credentials to the step that needs them and let them expire naturally.\\n\\n## Output\\nConfirm that a session token was issued and its expiration time. Never print the secret access key or session token value."},{"name":"identify-access-key-owner","description":"Use AWS STS get access key info to resolve which account an access key ID belongs to. Use for incident triage of leaked or unexpected keys.","content":"# Identify Access Key Owner\\n\\nFind out which account owns an access key ID.\\n\\n## Steps\\n1. Take the access key ID under investigation (for example, one found in a leak or an unexpected log).\\n2. Call get access key info to resolve the owning AWS account ID.\\n3. Compare the account against your known and expected accounts.\\n4. If it belongs to an unexpected account, escalate for investigation.\\n\\n## Output\\nReport the access key ID (never the secret) and its owning account ID, plus whether that account is expected."},{"name":"assume-role-with-oidc-token","description":"Use AWS STS assume role with web identity to exchange an OIDC/OAuth 2.0 token (e.g. from GitHub Actions, EKS IRSA, or Google/Facebook federation) for short-lived AWS credentials without any static IAM keys.","content":"# Assume Role with OIDC Token\\n\\nExchange a federated identity token for temporary AWS credentials.\\n\\n## Steps\\n1. Obtain the OIDC/OAuth 2.0 token issued by the identity provider (CI/CD pipeline, Kubernetes service account, or social login).\\n2. Identify the role ARN whose trust policy trusts that identity provider, and choose a descriptive session name.\\n3. Call assume role with web identity, passing the token and any session policy to further restrict permissions.\\n4. Pass the returned temporary credentials to the downstream step that needs AWS access.\\n\\n## Output\\nConfirm the assumed role ARN, the token subject, and credential expiration. Never print the secret access key or session token in plain logs."},{"name":"assume-role-with-saml-assertion","description":"Use AWS STS assume role with SAML to exchange a SAML 2.0 assertion from an enterprise identity provider for short-lived AWS credentials, for enterprise SSO access patterns.","content":"# Assume Role with SAML Assertion\\n\\nExchange a SAML authentication response for temporary AWS credentials.\\n\\n## Steps\\n1. Obtain the base64-encoded SAML assertion issued by the corporate identity provider after user sign-in.\\n2. Identify the role ARN and the ARN of the SAML provider entity configured in IAM.\\n3. Call assume role with SAML, passing the assertion and any session policy to further restrict permissions.\\n4. Pass the returned temporary credentials to the downstream step that needs AWS access.\\n\\n## Output\\nConfirm the assumed role ARN, the assertion subject, and credential expiration. Never print the secret access key or session token in plain logs."}],"templates":[{"title":"AWS STS access key identifier","prompt":"Build a workflow that takes an AWS access key ID, uses AWS STS to look up the owning account and entity, flags keys that belong to unexpected accounts, and pings the security Slack channel.","integrations":[{"id":"sts","name":"AWS STS"},{"id":"slack","name":"Slack"}]},{"title":"STS short-lived credential provisioner","prompt":"Create a workflow that on a request grants short-lived AWS STS credentials with the minimum required scope, captures the audit record, and revokes on completion.","integrations":[{"id":"sts","name":"AWS STS"}]},{"title":"STS caller identity verifier","prompt":"Build a scheduled workflow that calls AWS STS get caller identity for each configured set of credentials, confirms the resolved account and ARN match the expected principal, and writes a verification report.","integrations":[{"id":"sts","name":"AWS STS"}]},{"title":"STS session token rotator","prompt":"Create a scheduled daily workflow that mints fresh AWS STS session tokens for service accounts that need them, records each token expiration in a security log, and flags any token issuance that fails.","integrations":[{"id":"sts","name":"AWS STS"}]},{"title":"STS just-in-time access grant","prompt":"Build a workflow that handles JIT-access requests, captures Slack-based approval, mints short-lived AWS STS credentials, and writes the access record.","integrations":[{"id":"sts","name":"AWS STS"},{"id":"slack","name":"Slack"}]},{"title":"STS cross-account access grant","prompt":"Create a workflow that handles cross-account access requests, assumes the target AWS STS role with the supplied external ID, requires owner attestation in Slack, and writes the grant record to a compliance table.","integrations":[{"id":"sts","name":"AWS STS"},{"id":"slack","name":"Slack"}]},{"title":"STS Identity-Center role broker","prompt":"Build a workflow that takes an Identity Center user request, assumes the matching AWS STS role to mint scoped short-lived credentials, writes the issuance to a session log, and alerts Slack when a request targets a privileged role.","integrations":[{"id":"sts","name":"AWS STS"},{"id":"identity_center","name":"AWS Identity Center"},{"id":"slack","name":"Slack"}]},{"title":"STS CI/CD OIDC credential broker","prompt":"Build a workflow that receives an OIDC token from a CI/CD pipeline (e.g. GitHub Actions), calls AWS STS assume role with web identity to mint short-lived deployment credentials, and writes the issuance to an audit log.","integrations":[{"id":"sts","name":"AWS STS"}]},{"title":"STS SAML SSO role broker","prompt":"Create a workflow that takes a SAML assertion from a corporate identity provider, calls AWS STS assume role with SAML to grant scoped temporary credentials, and logs the session details for compliance review.","integrations":[{"id":"sts","name":"AWS STS"}]}]},{"id":"ssm","type":"ssm","slug":"aws-systems-manager","name":"AWS Systems Manager","description":"Run commands, manage parameters, and audit managed nodes","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/ssm","authType":"api-key","connections":[],"operations":[{"name":"Send Command","description":"Run an SSM document on managed nodes with AWS Systems Manager Run Command"},{"name":"List Commands","description":"List Run Command executions in an AWS account"},{"name":"List Command Invocations","description":"List the per-node invocations of Run Command executions"},{"name":"Get Command Invocation","description":"Read the output and status of a Run Command execution on one managed node"},{"name":"Cancel Command","description":"Cancel an in-flight Run Command execution"},{"name":"Get Parameter","description":"Read one parameter from AWS Systems Manager Parameter Store"},{"name":"Get Parameters","description":"Read up to ten parameters from AWS Systems Manager Parameter Store by name"},{"name":"Get Parameters By Path","description":"Read parameters under a Parameter Store hierarchy path"},{"name":"Put Parameter","description":"Create or update a parameter in AWS Systems Manager Parameter Store"},{"name":"Delete Parameter","description":"Delete a parameter from AWS Systems Manager Parameter Store"},{"name":"Describe Parameters","description":"List Parameter Store parameter metadata without reading any values"},{"name":"Describe Instance Information","description":"List managed nodes registered with AWS Systems Manager and their agent status"},{"name":"Describe Instance Patches","description":"List the patches reported for one managed node"},{"name":"Describe Instance Patch States","description":"Read patch compliance summaries for a set of managed nodes"},{"name":"List Compliance Items","description":"List individual compliance findings reported to AWS Systems Manager"},{"name":"List Compliance Summaries","description":"Read compliant and non-compliant counts per compliance type"},{"name":"Start Automation Execution","description":"Start an AWS Systems Manager Automation runbook execution"},{"name":"Describe Automation Executions","description":"List Automation runbook executions in an AWS account"},{"name":"Get Automation Execution","description":"Read the status, outputs, and step results of one Automation execution"},{"name":"Stop Automation Execution","description":"Stop a running AWS Systems Manager Automation execution"},{"name":"List Documents","description":"List SSM documents and runbooks available to an AWS account"},{"name":"Get Document","description":"Read the content of an SSM document or Automation runbook"}],"triggers":[],"skills":[{"name":"run-fleet-command","description":"Run an SSM document such as AWS-RunShellScript across managed nodes and collect the per-node result. Use for fleet-wide diagnostics, log collection, or a scripted remediation.","content":"# Run Fleet Command\\n\\nExecute a command on managed nodes and report what happened on each one.\\n\\n## Steps\\n1. Choose the SSM document to run (for example AWS-RunShellScript or AWS-RunPowerShellScript) and the parameters it needs.\\n2. Pick the targets: explicit instance IDs, or tag targets such as tag:Environment = prod. Set concurrency and an error threshold so a bad script cannot roll through the whole fleet.\\n3. Send the command and keep the returned command ID.\\n4. List the invocations for that command ID to see per-node status, then read the invocation on each node of interest for its stdout and stderr.\\n5. Summarize successes, failures, and any node that never acknowledged the command.\\n\\n## Output\\nThe command ID, a per-node status table, and the captured output for every failed node."},{"name":"triage-command-failure","description":"Investigate why a Run Command execution failed on specific managed nodes. Use when a deployment or maintenance command reports errors.","content":"# Triage Command Failure\\n\\nFind out which nodes failed a command and why.\\n\\n## Steps\\n1. List recent commands, filtering by status to find the failed execution.\\n2. List that command’s invocations to identify the nodes that failed or timed out.\\n3. Read the invocation on each failing node, including per-plugin detail, to get the exit code and captured stderr.\\n4. Separate genuine script errors from delivery problems, where the node never acknowledged the command.\\n5. If the command is still running and clearly wrong, cancel it.\\n\\n## Output\\nThe failing nodes, their exit codes, the error text from each, and whether the cause was the script or node connectivity."},{"name":"read-app-configuration","description":"Read application configuration from a Parameter Store hierarchy path so a workflow can act on live settings. Use to load environment configuration without hardcoding it.","content":"# Read App Configuration\\n\\nLoad configuration for an environment from Parameter Store.\\n\\n## Steps\\n1. Identify the hierarchy path that holds the environment’s settings, such as /prod/app.\\n2. Read the parameters under that path recursively when the settings are nested.\\n3. Only request decryption of SecureString values when the workflow genuinely needs the plaintext; leave it off for a settings inventory.\\n4. Map each parameter name to the setting it represents.\\n\\n## Output\\nThe configuration keys and their values. Never echo a decrypted SecureString value into a summary, a log, or a chat message."},{"name":"promote-parameter-value","description":"Write or update a Parameter Store value as part of a controlled configuration change. Use to promote a setting between environments or apply an approved change.","content":"# Promote Parameter Value\\n\\nApply a configuration change through Parameter Store.\\n\\n## Steps\\n1. Read the current value and metadata of the target parameter so the change can be reversed.\\n2. Confirm the parameter type: use SecureString for anything secret, and name the KMS key when the account default is not wanted.\\n3. Write the new value with overwrite enabled for an existing parameter, or set the type explicitly when creating a new one.\\n4. Read back the parameter metadata to confirm the new version number.\\n\\n## Output\\nThe parameter name, the new version number, and the tier it was stored in. Never print the value itself."},{"name":"audit-node-inventory","description":"Report which managed nodes are registered with Systems Manager, their agent version, and whether they are reachable. Use for fleet hygiene and onboarding checks.","content":"# Audit Node Inventory\\n\\nReport the state of the managed node fleet.\\n\\n## Steps\\n1. List managed nodes, filtering by ping status or platform type when the audit is scoped.\\n2. Group nodes by ping status to find ones that have lost connection.\\n3. Flag nodes that are not on the latest agent version, and nodes with no recent successful association run.\\n4. Note nodes registered as managed instances rather than EC2 instances, since they onboard differently.\\n\\n## Output\\nA fleet summary: total nodes, unreachable nodes, outdated agents, and the platform mix."},{"name":"report-patch-compliance","description":"Summarize patch compliance across managed nodes and drill into missing patches on a specific node. Use for monthly patching reviews and vulnerability follow-up.","content":"# Report Patch Compliance\\n\\nShow where the fleet stands on patching.\\n\\n## Steps\\n1. Read patch states for the nodes in scope to get installed, missing, failed, and non-compliant counts per node.\\n2. Rank the nodes by critical and security non-compliant counts.\\n3. For the worst nodes, list the individual patches and filter to the ones in a Missing or Failed state to get titles, KB IDs, severities, and CVE IDs.\\n4. Note nodes whose last patch operation never completed.\\n\\n## Output\\nA ranked compliance table plus, for the top offenders, the specific missing patches and their severities."},{"name":"run-automation-runbook","description":"Start an SSM Automation runbook, follow it to completion, and report the step results. Use for scripted remediation such as restarting an instance or rotating an AMI.","content":"# Run Automation Runbook\\n\\nDrive an Automation runbook and report what it did.\\n\\n## Steps\\n1. Find the runbook by listing documents filtered to the Automation type, and read its content to confirm the parameters it expects.\\n2. Start the execution with those parameters. For a fleet-wide run, set the target parameter name and a rate-control target, plus concurrency and error limits.\\n3. Poll the execution until its status leaves the in-progress states.\\n4. Read the step executions to see which step failed and why, if it did not succeed.\\n5. Stop the execution if it needs to be aborted; cancelling stops it immediately, completing lets the current step finish.\\n\\n## Output\\nThe execution ID, the final status, the runbook outputs, and the failing step with its failure message when applicable."},{"name":"review-compliance-findings","description":"Pull Systems Manager compliance findings for a managed node and explain what is non-compliant. Use when a compliance dashboard flags a resource and someone needs the detail.","content":"# Review Compliance Findings\\n\\nExplain a node’s compliance status in detail.\\n\\n## Steps\\n1. Read the compliance summaries to see which compliance types are non-compliant and at what severity.\\n2. For the affected type, list the compliance items for the specific managed node, filtering to non-compliant status.\\n3. Read each item’s title, severity, and details to explain what the finding actually is.\\n4. Separate association findings from patch findings, since they are remediated differently.\\n\\n## Output\\nA per-node list of non-compliant findings with severity and a short explanation of each, grouped by compliance type."}],"templates":[{"title":"Systems Manager patch reporter","prompt":"Build a scheduled workflow that reads AWS Systems Manager patch compliance for every managed node, flags nodes with missing critical or security patches, and posts a ranked remediation list to Slack.","integrations":[{"id":"ssm","name":"AWS Systems Manager"},{"id":"slack","name":"Slack"}]},{"title":"Systems Manager agent health watch","prompt":"Create a scheduled workflow that lists AWS Systems Manager managed nodes, identifies nodes whose agent has lost connection or is running an outdated version, and opens a Jira ticket for each one.","integrations":[{"id":"ssm","name":"AWS Systems Manager"},{"id":"jira","name":"Jira"}]},{"title":"Systems Manager runbook responder","prompt":"Build a workflow that receives an incident alert, starts the matching AWS Systems Manager Automation runbook, polls the execution until it finishes, and reports the step results back to the incident channel.","integrations":[{"id":"ssm","name":"AWS Systems Manager"},{"id":"slack","name":"Slack"}]},{"title":"Systems Manager config promoter","prompt":"Create a workflow that reads application configuration from one AWS Systems Manager Parameter Store path, requests approval in Slack, writes the approved values to the production path, and records the change in a table.","integrations":[{"id":"ssm","name":"AWS Systems Manager"},{"id":"slack","name":"Slack"}]},{"title":"Systems Manager fleet command runner","prompt":"Build a workflow that runs a diagnostic shell script on every AWS Systems Manager managed node carrying a chosen tag, collects the per-node output, and summarizes the failures for the on-call engineer.","integrations":[{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Systems Manager compliance digest","prompt":"Create a scheduled workflow that pulls AWS Systems Manager compliance summaries, compares them with last week’s counts stored in a table, and emails leadership a short trend report.","integrations":[{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Systems Manager parameter auditor","prompt":"Build a scheduled workflow that lists AWS Systems Manager Parameter Store metadata, flags SecureString parameters that have not changed within the rotation window and plaintext parameters that look like credentials, and files the findings for security review.","integrations":[{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Systems Manager runbook catalog","prompt":"Create a workflow that lists AWS Systems Manager Automation runbooks, reads the content of each one, and writes a plain-English catalog of what every runbook does and which parameters it needs.","integrations":[{"id":"ssm","name":"AWS Systems Manager"}]}]},{"id":"textract","type":"textract_v2","slug":"aws-textract","name":"AWS Textract","description":"Extract text, tables, and forms from documents","category":"AI","docsUrl":"https://docs.sim.ai/integrations/textract","authType":"api-key","connections":[],"operations":[{"name":"Analyze Document (Text, Tables, Forms)","description":""},{"name":"Analyze Expense (Invoices & Receipts)","description":"Extract structured invoice and receipt fields using AWS Textract AnalyzeExpense"},{"name":"Analyze Identity Document","description":"Extract identity document fields using AWS Textract AnalyzeID"}],"triggers":[],"skills":[{"name":"extract-invoice-fields","description":"Run an invoice or receipt through AWS Textract Analyze Expense and return clean structured fields (vendor, date, totals, line items). Use when you need to digitize finance documents.","content":"# Extract Invoice Fields\\n\\nUse AWS Textract Analyze Expense to pull structured data from an invoice or receipt image/PDF.\\n\\n## Steps\\n1. Set Operation to \\"Analyze Expense\\". Choose Single Page for JPEG, PNG, or one-page PDF, or Multi-Page for a PDF/TIFF staged in S3.\\n2. Provide the document (upload, file reference, or S3 URI) and run the extraction.\\n3. Read `expenseDocuments[].summaryFields` for header data (vendor, invoice number, invoice date, due date, subtotal, tax, total) and `expenseDocuments[].lineItemGroups[].lineItems` for purchased items.\\n4. Map each summary field\'s normalized `type.text` (e.g., VENDOR_NAME, TOTAL, INVOICE_DATE) to your target schema, and read `valueDetection.text` for the value.\\n\\n## Output\\nReturn a clean JSON record with the header fields and a line-items array. Flag any field where confidence is low or the totals do not reconcile so a human can review."},{"name":"extract-form-key-values","description":"Turn a scanned form into structured key-value pairs and tables using AWS Textract. Use for intake forms, applications, and contracts.","content":"# Extract Form Key-Values\\n\\nDigitize a scanned form into structured data.\\n\\n## Steps\\n1. Select Single Page mode for an image or one-page PDF, or Multi-Page mode with an S3 URI for longer documents.\\n2. Enable Extract Forms (key-value pairs) and, if the form has tables, Extract Tables. Enable Analyze Document Layout for complex multi-column forms.\\n3. Run the extraction and parse the KEY_VALUE_SET blocks into field-name to field-value pairs.\\n4. Normalize field names (trim labels, lowercase keys) and coerce values like dates and numbers.\\n\\n## Output\\nReturn a flat object of normalized field names to values, plus any extracted tables as arrays of rows. Note pages or fields with low confidence for review."},{"name":"ocr-document-to-text","description":"Convert a scanned document or image into plain readable text with AWS Textract OCR. Use to digitize handwritten notes, faxes, or image-only PDFs for indexing or search.","content":"# OCR Document To Text\\n\\nExtract readable text from a scanned or image-only document.\\n\\n## Steps\\n1. Pick the processing mode that matches the file: Single Page for an image or one-page PDF, Multi-Page (S3) for multi-page documents.\\n2. Provide the document and run the extraction. Plain OCR does not require the Forms or Tables features.\\n3. Read the LINE and WORD blocks and join LINE blocks in reading order to reconstruct the text.\\n4. Preserve paragraph and page breaks using the PAGE blocks.\\n\\n## Output\\nReturn the full extracted text as clean Markdown, grouped by page. Include the page count from document metadata and surface any low-confidence lines so they can be reviewed before indexing."},{"name":"verify-identity-document","description":"Run a government-issued ID through AWS Textract Analyze ID and return normalized identity fields (name, date of birth, ID number, expiration date). Use for KYC and identity-verification workflows.","content":"# Verify Identity Document\\n\\nUse AWS Textract Analyze ID to extract normalized fields from a driver\'s license, passport, or other identity document.\\n\\n## Steps\\n1. Set Operation to \\"Analyze Identity Document\\".\\n2. Upload the front of the ID. If the document carries data on both sides (e.g., a driver\'s license), also upload the back.\\n3. Run the extraction and read `identityDocuments[].identityDocumentFields`, where each field has a normalized `type.text` (e.g., FIRST_NAME, LAST_NAME, DATE_OF_BIRTH, DOCUMENT_NUMBER, EXPIRATION_DATE) and a `valueDetection.text` (with `valueDetection.normalizedValue` for dates).\\n4. Compare the extracted fields against the customer record you already have on file.\\n\\n## Output\\nReturn a normalized identity record and flag any mismatch between the extracted fields and the existing customer record for human review."}],"templates":[{"title":"SAP Concur receipt OCR","prompt":"Create a workflow that processes SAP Concur receipt images with AWS Textract, validates the extracted vendor and amount against the report line, and flags mismatches.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"sap_concur","name":"SAP Concur"}]},{"title":"Textract invoice extractor","prompt":"Create a scheduled workflow that polls an S3 folder for new PDFs, runs AWS Textract to extract line items and totals, writes the structured fields to a table, and flags invoices that fail validation.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"s3","name":"S3"}]},{"title":"Textract receipt OCR","prompt":"Build a workflow that processes Gmail attachments with AWS Textract, extracts vendor, date, total, and category, logs each receipt to an expense table, and tags reimbursable items.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"gmail","name":"Gmail"}]},{"title":"Textract ID verification","prompt":"Build a workflow that runs uploaded ID documents through AWS Textract analyze-id, extracts name, DOB, and ID number, validates against a customer record, and flags mismatches for review.","integrations":[{"id":"textract","name":"AWS Textract"}]},{"title":"Textract form-to-table","prompt":"Build a workflow that pushes scanned forms from Google Drive through AWS Textract analyze-document, extracts key-value pairs and tables, and writes structured rows to a Sim table for downstream automations.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Textract + Reducto cross-format extractor","prompt":"Create a workflow that ingests mixed PDF and image files, routes images through AWS Textract and dense PDFs through Reducto, normalizes fields, and writes rows to a table.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"reducto","name":"Reducto"}]},{"title":"Textract + Extend pipeline composer","prompt":"Build a workflow that uses AWS Textract for layout-aware OCR and Extend for structured field extraction, fusing outputs into clean records for downstream automations.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"extend","name":"Extend"}]},{"title":"Textract handwritten-note digitizer","prompt":"Build a workflow that runs scanned handwritten intake notes through AWS Textract, converts the recognized text into clean Markdown, indexes it into a knowledge base, and posts a confidence summary to Slack so low-confidence pages get a human review.","integrations":[{"id":"textract","name":"AWS Textract"},{"id":"slack","name":"Slack"}]}]},{"id":"microsoft_ad","type":"microsoft_ad","slug":"azure-ad","name":"Azure AD","description":"Manage identities, licenses, roles, and access in Azure AD (Microsoft Entra ID)","category":"Security","docsUrl":"https://docs.sim.ai/integrations/microsoft_ad","authType":"oauth","connections":[{"id":"microsoft-ad","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-ad","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_ad","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"User.ReadWrite.All","label":"Read and write all user profiles"},{"id":"Group.ReadWrite.All","label":"Read and write all groups"},{"id":"GroupMember.ReadWrite.All","label":"Read and write all group memberships"},{"id":"LicenseAssignment.Read.All","label":"Read license assignments and subscribed SKUs"},{"id":"LicenseAssignment.ReadWrite.All","label":"Assign and remove user licenses"},{"id":"UserAuthenticationMethod.ReadWrite.All","label":"Read and reset authentication methods and passwords for all users"},{"id":"AuditLog.Read.All","label":"Read sign-in and directory audit logs"},{"id":"Application.Read.All","label":"Read all applications and service principals"},{"id":"AppRoleAssignment.ReadWrite.All","label":"Manage app role assignments and permission grants for any app"},{"id":"RoleManagement.ReadWrite.Directory","label":"Read and manage directory role assignments"},{"id":"Device.Read.All","label":"Read all devices"},{"id":"Policy.Read.All","label":"Read conditional access and other policies"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"List Users","description":"List users in Azure AD (Microsoft Entra ID)"},{"name":"Get User","description":"Get a user by ID or user principal name from Azure AD"},{"name":"Create User","description":"Create a new user in Azure AD (Microsoft Entra ID)"},{"name":"Update User","description":"Update user properties in Azure AD (Microsoft Entra ID)"},{"name":"Delete User","description":"Delete a user from Azure AD (Microsoft Entra ID). The user is moved to a temporary container and can be restored within 30 days."},{"name":"List Groups","description":"List groups in Azure AD (Microsoft Entra ID)"},{"name":"Get Group","description":"Get a group by ID from Azure AD (Microsoft Entra ID)"},{"name":"Create Group","description":"Create a new group in Azure AD (Microsoft Entra ID)"},{"name":"Update Group","description":"Update group properties in Azure AD (Microsoft Entra ID)"},{"name":"Delete Group","description":"Delete a group from Azure AD (Microsoft Entra ID). Microsoft 365 groups can be restored within 30 days. Cloud security-group recovery is a public-cloud preview with tenant restrictions; confirm eligibility before deleting."},{"name":"List Group Members","description":"List members of a group in Azure AD (Microsoft Entra ID)"},{"name":"Add Group Member","description":"Add a member to a group in Azure AD (Microsoft Entra ID)"},{"name":"Remove Group Member","description":"Remove a member from a group in Azure AD (Microsoft Entra ID)"},{"name":"Assign License","description":"Add or remove subscription licenses (SKUs) on a user in Microsoft Entra ID. Removing a license immediately revokes the access it granted to the associated services."},{"name":"List User Licenses","description":"List the subscription licenses assigned to a user in Microsoft Entra ID"},{"name":"List Subscribed SKUs","description":"List the subscription SKUs the tenant owns, including how many license units are prepaid and how many are consumed"},{"name":"Revoke Sign-In Sessions","description":"Invalidate every refresh token and session cookie issued to a user, forcing them to sign in again on all applications and devices. Revocation can take a few minutes to take effect and does not apply to external users."},{"name":"Set Password","description":"Set a specific password on a user by updating their password profile. Cannot be used for federated users. Requires an administrator role in Microsoft Entra ID."},{"name":"Reset Password","description":"Reset another user\'s password through their password authentication method. Leave the new password empty to have Microsoft generate one and return it. The user is prompted to change the password at their next sign-in. Cannot be run against your own account."},{"name":"List Authentication Methods","description":"List the authentication methods a user has registered, such as passwords, phone numbers, FIDO2 keys, and authenticator apps"},{"name":"List Sign-Ins","description":"List sign-in events from the Microsoft Entra ID sign-in logs, newest first. Requires a Microsoft Entra ID P1 or P2 license. Apply a date filter to keep large queries from timing out."},{"name":"List Directory Audits","description":"List directory audit records showing who changed what in Microsoft Entra ID, such as user creation, group membership changes, and role assignments"},{"name":"List User App Role Assignments","description":"List the application role assignments granted to a user, including assignments the user inherits from groups they are a direct member of"},{"name":"Grant App Role To User","description":"Grant a user an application role on a service principal, giving them access to that application"},{"name":"Revoke App Role From User","description":"Revoke an application role assignment from a user, removing their access to that application. Takes the assignment\'s own ID, not the app role ID."},{"name":"List Service Principals","description":"List the enterprise applications and service principals in the tenant, including the app roles each one exposes"},{"name":"List Application Assignments","description":"List every user, group, and service principal assigned to an application, by reading the app role assignments on its service principal. Recently granted or removed assignments can take time to appear."},{"name":"List Directory Roles","description":"List the administrator roles that are activated in the tenant, such as Global Administrator and User Administrator. Roles that have never been activated are not returned."},{"name":"List Directory Role Members","description":"List the principals holding an administrator role. Returns up to 1000 members; this endpoint does not support paging."},{"name":"Add Directory Role Member","description":"Grant a user an administrator role in Microsoft Entra ID. This is a privileged change that expands what the user can do across the tenant."},{"name":"Remove Directory Role Member","description":"Revoke an administrator role from a user in Microsoft Entra ID. Removes only the role membership; the user account itself is not deleted."},{"name":"List Devices","description":"List the devices registered in Microsoft Entra ID"},{"name":"Get Device","description":"Get a registered device by its object ID from Microsoft Entra ID"},{"name":"List User Devices","description":"List the devices a user has registered or owns. Devices the caller cannot read are returned with only their ID and the remaining fields null."},{"name":"List Conditional Access Policies","description":"List the conditional access policies configured in the tenant, including their state and the conditions and controls they enforce. Read-only."},{"name":"Get Conditional Access Policy","description":"Get a single conditional access policy by ID, including the conditions it matches and the controls it enforces. Read-only."}],"triggers":[],"skills":[{"name":"provision-new-user","description":"Create a new Azure AD (Entra ID) user account and add it to the right groups. Use when onboarding an employee or contractor.","content":"# Provision New User\\n\\nCreate an Azure AD user and grant initial group access.\\n\\n## Steps\\n1. Use Create User with the required fields: display name, mail nickname, user principal name (e.g. name@yourdomain.com), and an initial password. Set Account Enabled to Yes.\\n2. Fill optional profile fields when available: first name, last name, job title, department, office location, and mobile phone.\\n3. For each group the person should belong to, resolve the group with Get Group or List Groups, then call Add Group Member with the new user id.\\n4. Confirm membership with List Group Members.\\n\\n## Output\\nReturn the created user id, user principal name, and the list of groups they were added to. If a username collision or password-policy error occurs, report it clearly instead of retrying blindly."},{"name":"offboard-user","description":"Disable an Azure AD account and strip its group memberships when someone leaves. Use for secure offboarding.","content":"# Offboard User\\n\\nRevoke access for a departing user.\\n\\n## Steps\\n1. Resolve the account with Get User by user principal name or id.\\n2. Use Update User to set Account Enabled to No so the user can no longer sign in.\\n3. Use List Group Members or the user record to enumerate the groups the user belongs to.\\n4. For each group, call Remove Group Member with the user id.\\n\\n## Output\\nReturn the disabled user id and the list of groups the user was removed from. Note any group where removal failed so it can be handled manually, and recommend writing the action to an audit record."},{"name":"audit-group-membership","description":"List the members of an Azure AD group for an access review. Use for periodic attestation of privileged or sensitive groups.","content":"# Audit Group Membership\\n\\nProduce a current membership snapshot for a group.\\n\\n## Steps\\n1. Resolve the target group with Get Group or List Groups (filter or search by name).\\n2. Call List Group Members for the group id, raising Max Results if the group is large. If the response includes a Next Page link, keep calling List Group Members with that link until it comes back empty to capture every member.\\n3. For each member, optionally call Get User to enrich with job title, department, and account-enabled status.\\n\\n## Output\\nReturn a table of members with id, display name, email, department, and whether the account is enabled. Highlight disabled or stale accounts that still hold membership and should be reviewed for removal."},{"name":"search-directory-users","description":"Search Azure AD (Entra ID) for users matching a name, department, or other attribute. Use for directory lookups and reporting.","content":"# Search Directory Users\\n\\nFind users in the directory by attribute instead of enumerating everyone.\\n\\n## Steps\\n1. Use List Users with Search set to the name or email fragment, or Filter set to an OData expression (e.g. `department eq \'Sales\'`) for attribute-based lookups. Search and Filter cannot be combined in one call.\\n2. If the result set is large, follow the Next Page link returned in the response to page through additional results.\\n3. Optionally call Get User for a specific match to retrieve full profile detail.\\n\\n## Output\\nReturn the matching users with id, display name, user principal name, department, and account-enabled status. State clearly when Max Results or pagination limits mean the list may be incomplete."},{"name":"manage-group-membership","description":"Add or remove specific users from an Azure AD (Entra ID) group on demand, outside of onboarding/offboarding flows. Use for ad hoc access changes and team restructuring.","content":"# Manage Group Membership\\n\\nApply a one-off membership change to a group.\\n\\n## Steps\\n1. Resolve the group with Get Group or List Groups, and resolve each affected user with Get User or List Users.\\n2. Call Add Group Member or Remove Group Member with the group id and each user id.\\n3. Confirm the change with List Group Members.\\n\\n## Output\\nReturn which users were added or removed and the group\'s current member count. Report any member that failed to add or remove (e.g. already a member, or not found) instead of silently skipping it."}],"templates":[{"title":"Azure AD provisioning","prompt":"Build a workflow that on a Workday new-hire event creates the Azure AD user account, assigns the right group memberships, and writes the provisioning record to an audit table.","integrations":[{"id":"microsoft_ad","name":"Azure AD"},{"id":"workday","name":"Workday"}]},{"title":"Azure AD offboarding sweep","prompt":"Create a workflow that on a Workday termination disables the Azure AD account, removes its group memberships, and writes the security audit record.","integrations":[{"id":"microsoft_ad","name":"Azure AD"},{"id":"workday","name":"Workday"}]},{"title":"Azure AD access review","prompt":"Build a scheduled quarterly workflow that lists Azure AD group memberships, requests owner attestation in Microsoft Teams, and writes the audit log to a compliance table.","integrations":[{"id":"microsoft_ad","name":"Azure AD"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Azure AD password-age reminder","prompt":"Create a scheduled workflow that lists Azure AD users, flags accounts whose last password change is older than the policy window, sends targeted reset reminders, and writes the compliance audit.","integrations":[{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Azure AD stale-account sweeper","prompt":"Build a scheduled workflow that lists Azure AD accounts inactive for 90+ days, requests owner re-attestation, and disables accounts that fail attestation.","integrations":[{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Azure AD privileged-group auditor","prompt":"Create a scheduled monthly workflow that lists the members of privileged Azure AD groups, requests owner attestation for each, and writes the review to an audit table.","integrations":[{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Azure AD privileged-access monitor","prompt":"Build a scheduled workflow that lists privileged Azure AD group members each run, compares against the last snapshot in a table, and pings the security Microsoft Teams channel on any add or removal.","integrations":[{"id":"microsoft_ad","name":"Azure AD"},{"id":"microsoft_teams","name":"Microsoft Teams"}]}]},{"id":"azure_data_explorer","type":"azure_data_explorer","slug":"azure-data-explorer","name":"Azure Data Explorer","description":"Query and manage Azure Data Explorer (Kusto) clusters with KQL","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/azure_data_explorer","authType":"api-key","connections":[],"operations":[{"name":"Run Query","description":"Run a Kusto Query Language (KQL) query against an Azure Data Explorer database and return the primary result table."},{"name":"List Databases","description":"List the databases on an Azure Data Explorer cluster that the service principal can access."},{"name":"List Tables","description":"List the tables in an Azure Data Explorer database, with their folder and docstring."},{"name":"Show Table Schema","description":"Read the column schema of an Azure Data Explorer table in CSL form (e.g., \\"Timestamp:datetime,Level:string\\"). Use this before writing a KQL query against an unfamiliar table."},{"name":"Show Database Schema","description":"Read the full schema of an Azure Data Explorer database as a flat list of every table and column, so an agent can discover the data model in one call."},{"name":"Show Table Details","description":"Read size, row count, hot-cache footprint, and effective policies for a table — or for every table in the database when no table is given. Use it to see how much data a table actually holds before querying it."},{"name":"List Functions","description":"List the stored functions in an Azure Data Explorer database, with their parameters and bodies, so an agent can reuse existing logic instead of rewriting it."},{"name":"Ingest Rows Inline","description":"Push rows directly into an Azure Data Explorer table with .ingest inline. Data is parsed as CSV against the table schema unless an ingestion property says otherwise. Intended for small batches — use queued or streaming ingestion for production volumes."},{"name":"Ingest From Query","description":"Materialize the result of a KQL query into a table with .set, .append, .set-or-append, or .set-or-replace. Use this to build rollup or summary tables instead of pushing rows from a workflow. Kusto matches the query result to the target table by column type and position, NOT by column name, so project the columns in exactly the table\'s order or the data lands in the wrong columns."},{"name":"Create Table","description":"Create a table in an Azure Data Explorer database from a CSL column schema. Succeeds without changing anything if a table of the same name already exists."},{"name":"Drop Table","description":"Drop a table from an Azure Data Explorer database. The table becomes unavailable to queries; data recovery depends on the retention policy. Returns the tables that remain."},{"name":"Show Ingestion Failures","description":"List ingestion failures recorded for a database, with the failing table, error code, root cause detail, and whether the failure is permanent or transient. Failures are retained for 14 days."},{"name":"Show Operations","description":"Check the state of administrative operations on a cluster, such as an async ingestion. Given an operation ID it returns that operation latest update; with no ID it returns the operations from the last two weeks."},{"name":"Management Command (advanced)","description":"Run an Azure Data Explorer management command (a control command starting with \\".\\") such as .show, .create, .alter, or .drop. Write commands can change data or configuration; use the Query operation for reads."}],"triggers":[],"skills":[{"name":"explore-kusto-schema","description":"Discover what data an Azure Data Explorer cluster holds before writing a query against it.","content":"# Explore Kusto Schema\\n\\nMap out a cluster before querying it, so queries reference columns that actually exist.\\n\\n## Steps\\n1. Run List Databases to see what the service principal can reach.\\n2. Run List Tables on the database that looks relevant.\\n3. Run Show Table Schema on each candidate table to read its columns and types, or Show Database Schema to pull every table and column in one call.\\n\\n## Output\\nReturn the database name, the tables that matter for the question at hand, and each relevant column with its type."},{"name":"answer-with-kql","description":"Answer a data question by writing and running a KQL query, then explaining it.","content":"# Answer With KQL\\n\\nTurn a question about the data into a query and a trustworthy answer.\\n\\n## Steps\\n1. Run Show Table Schema on the table involved so column names and types are known rather than guessed.\\n2. Write the KQL: filter with `where`, aggregate with `summarize ... by`, bound the result with `take` or `top N by`.\\n3. Run Query with the read-only option enabled so the request cannot change data.\\n4. If the result looks wrong or empty, widen the time filter or relax the string comparison and try again.\\n\\n## Output\\nReport the answer, the row count, and the exact KQL that produced it so the result can be re-run and checked."},{"name":"materialize-a-rollup-table","description":"Build or refresh a summary table in Azure Data Explorer from a query over raw data.","content":"# Materialize A Rollup Table\\n\\nTurn an expensive query over raw telemetry into a small table that is cheap to read.\\n\\n## Steps\\n1. Run Show Table Details on the source table to see how much data the query will scan.\\n2. Run Show Table Schema on the **target** table. Kusto matches an ingested query result to the table by column position and type, never by name, so you need its exact column order before writing the query.\\n3. Write the aggregating KQL — `summarize` the raw rows into the shape you want, bucketing time with `bin()` where relevant — and end it with an explicit `project` listing the columns in the target table order.\\n4. Run Ingest From Query against the target table. Use `set-or-append` to add the new window to an existing rollup, `set-or-replace` to rebuild it from scratch, and `set` only for the first run.\\n5. For a large backfill, enable the background option and poll Show Operations with the returned operation ID until the state is Completed.\\n6. Run Query against the rollup and spot-check a few rows to confirm each column holds what it should, not just that the row count is plausible.\\n\\n## Output\\nReport the target table, the mode used, the rows or extents produced, and the verification query result. Call out that `set-or-replace` discards the existing data in the table, and that a mismatched column order corrupts data silently rather than failing."},{"name":"debug-ingestion-failures","description":"Diagnose why data is missing from an Azure Data Explorer table and say whether it will retry.","content":"# Debug Ingestion Failures\\n\\nFind out why expected rows never arrived.\\n\\n## Steps\\n1. Run Show Ingestion Failures for the database. Failures are kept for 14 days, so anything older will not appear.\\n2. Group what comes back by table, error code, and failure kind. `Permanent` failures will not retry on their own; `Transient` ones may already have succeeded on a later attempt.\\n3. Read the failure detail for the root cause — schema mismatch, a malformed source file, or a missing ingestion mapping are the usual ones.\\n4. Run Show Table Schema on the target table and compare it against the source data shape named in the failure.\\n5. Take the operation ID from a failure and run Show Operations on it for the fuller history of that operation.\\n\\n## Output\\nReport the affected tables, the distinct error codes with counts, the likely root cause, and whether each failure is permanent (needs a fix) or transient (may self-resolve). Confirm with a Query against the table whether the rows are genuinely absent."},{"name":"ingest-rows-into-kusto","description":"Push a small batch of records into an Azure Data Explorer table.","content":"# Ingest Rows Into Kusto\\n\\nLoad a handful of records into a table without setting up a pipeline.\\n\\n## Steps\\n1. Run Show Table Schema on the target table to learn the column order and types.\\n2. Format the records as CSV in that exact column order, one record per line, quoting any value containing a comma.\\n3. Run Ingest Rows Inline against the table.\\n4. Run Query to read the newly ingested rows back and confirm they landed as intended.\\n\\n## Output\\nReport how many rows were sent, the extent IDs returned, and the verification query result. Note that inline ingestion is for small batches — recommend queued or streaming ingestion for ongoing volume."}],"templates":[{"title":"Ask questions of Kusto data","prompt":"Build an agent that turns plain-English questions about our telemetry into KQL, reads the Azure Data Explorer table schema first so the columns are real, runs the query, and answers with the numbers plus the query it used.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"Daily telemetry digest","prompt":"Create a scheduled workflow that queries Azure Data Explorer every morning for yesterday error rates, latency percentiles, and traffic by service, summarizes what moved against the prior week, and posts the digest to our engineering Slack channel.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"},{"id":"slack","name":"Slack"}]},{"title":"Kusto anomaly alerts","prompt":"Build a workflow that runs every 15 minutes, queries Azure Data Explorer for request failures grouped by endpoint, compares each endpoint against its own trailing baseline, and pages the on-call engineer through PagerDuty only when a real spike appears.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Incident timeline from telemetry","prompt":"Create a workflow that takes an incident window and service name, pulls the matching logs, traces, and deploy events out of Azure Data Explorer, and writes an ordered timeline file that an engineer can drop straight into a postmortem.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"Event pipeline into Kusto","prompt":"Build a workflow triggered by a webhook that validates each incoming event payload, maps it onto our Azure Data Explorer table schema, ingests the rows inline, and records any rejected payloads in a table so nothing is lost silently.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"Kusto cluster inventory","prompt":"Create a scheduled workflow that lists every Azure Data Explorer database and table, reads their schemas, and keeps a Sim table up to date as a searchable data-model catalog with a note on what changed since the last run.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"Usage report to stakeholders","prompt":"Build a scheduled weekly workflow that queries Azure Data Explorer for product usage by account and feature, ranks the biggest movers, generates a report file with the supporting numbers, and emails it to the account team.","integrations":[{"id":"azure_data_explorer","name":"Azure Data Explorer"}]}]},{"id":"azure_devops","type":"azure_devops","slug":"azure-devops","name":"Azure DevOps","description":"Interact with Azure DevOps pipelines, builds, and work items","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/azure_devops","authType":"api-key","connections":[],"operations":[{"name":"List Pipelines","description":"List all pipelines in an Azure DevOps project. Returns pipeline ID, name, folder, revision, and URL."},{"name":"Get Pipeline","description":"Get details for a specific pipeline in an Azure DevOps project, including configuration and repository info."},{"name":"List Pipeline Runs","description":"List runs for a specific pipeline in an Azure DevOps project. Returns run ID, name, state, result, and timestamps."},{"name":"Get Pipeline Run","description":"Get details for a specific pipeline run in an Azure DevOps project. Returns run state, result, timestamps, and the pipeline reference."},{"name":"List Builds","description":"List builds in an Azure DevOps project. Optionally filter by pipeline definition, status, result, or branch."},{"name":"List Build Logs","description":"List all log entries for a specific build in Azure DevOps. Returns log IDs, types, and line counts — use the log ID with the Get Build Log tool to fetch actual log text."},{"name":"Get Build Log","description":"Fetch the text content of a specific build log in Azure DevOps. Use List Build Logs first to get the log ID. Optionally retrieve only a line range with startLine/endLine."},{"name":"Get Build Timeline","description":"Get the execution timeline for an Azure DevOps build — every stage, job, and task with its result and log ID. Use this to identify which steps failed before fetching their logs with Get Build Log."},{"name":"Get Work Items Between Builds","description":"Get work item references associated with commits between two builds in Azure DevOps. Returns work item IDs and URLs — use Get Work Items Batch for full field details."},{"name":"Query Work Items","description":"Execute a WIQL query to search for work items in Azure DevOps and return full field details. Use TOP N in your query to limit results (Azure enforces a 200-item maximum per batch fetch)."},{"name":"Get Work Item","description":"Fetch full details of a single work item by ID from Azure DevOps, including title, state, type, assignee, and area path."},{"name":"Get Work Items Batch","description":"Fetch full details for multiple work items by ID from Azure DevOps. Pass comma-separated IDs (e.g. \\"123,456,789\\"). Requests with more than 200 IDs are automatically split into chunks."},{"name":"Create Work Item","description":"Create a new Basic-process work item (Issue, Task, or Epic) in Azure DevOps. Returns the created work item with its assigned ID."},{"name":"Update Work Item","description":"Update one or more fields on an existing work item in Azure DevOps. Provide only the fields you want to change."},{"name":"Add Comment","description":"Add a comment to a work item in Azure DevOps."},{"name":"Get Comments","description":"List comments for an Azure DevOps work item."}],"triggers":[{"id":"azure_devops_build_failed","name":"Azure DevOps Build Failed","description":"Trigger workflow when an Azure DevOps build fails, is canceled, or partially succeeds"},{"id":"azure_devops_work_item_created","name":"Azure DevOps Work Item Created","description":"Trigger workflow when a work item is created in Azure DevOps"},{"id":"azure_devops_webhook","name":"Azure DevOps Webhook (All Service Hook Events)","description":"Trigger on whichever service hook event types you configure in Azure DevOps. Sim does not filter deliveries for this trigger."}],"skills":[{"name":"triage-build-failure","description":"Investigate a failed Azure DevOps build, pinpoint the failing stage, and summarize the root cause. Use when a pipeline run breaks.","content":"# Triage Build Failure\\n\\nDiagnose why an Azure DevOps build failed.\\n\\n## Steps\\n1. Use Get Build Timeline for the build id to find which stage, job, or task failed.\\n2. Use List Build Logs to locate the log id for the failing step, then Get Build Log to read its contents.\\n3. Scan the log for the first error, the failing command, and the exit code; ignore noise after the initial failure.\\n4. Optionally use Get Work Items Between Builds against the last successful build to see what changed.\\n\\n## Output\\nReturn a concise root-cause summary: the failing stage/task, the key error line, the likely cause, and a suggested next action. Include a deep link to the run when available."},{"name":"create-work-item","description":"Create a new Azure DevOps work item (Issue, Task, or Epic) with the right fields. Use to file bugs, tasks, or features from another system.","content":"# Create Work Item\\n\\nFile a structured Azure DevOps work item.\\n\\n## Steps\\n1. Choose the work item type: Issue, Task, or Epic, matching the request.\\n2. Use Create Work Item with a clear title and an HTML or plain-text description.\\n3. Set context fields where known: assignee, priority (1-4), area path, iteration path, and semicolon-separated tags.\\n4. For a Task, set Activity, Remaining Work, and Completed Work; for an Epic, set Start Date and Target Date.\\n\\n## Output\\nReturn the new work item id, type, title, state, and a link. Confirm the assignee and iteration. If a required field is missing, ask for it rather than guessing."},{"name":"generate-release-notes","description":"Compile release notes from the work items completed between two Azure DevOps builds. Use at release time to summarize what shipped.","content":"# Generate Release Notes\\n\\nProduce release notes for a build range.\\n\\n## Steps\\n1. Identify the From Build ID (previous release) and To Build ID (current release).\\n2. Use Get Work Items Between Builds to list the associated work items.\\n3. For each work item, use Get Work Items Batch or Get Work Item to pull title, type, and state.\\n4. Group items by type (Features/Epics, Tasks, Bugs/Issues) and write a one-line summary per item.\\n\\n## Output\\nReturn formatted Markdown release notes grouped by category, each line linking the work item id and title. Add a short headline summary of the most user-facing changes at the top."},{"name":"report-pipeline-health","description":"Summarize recent Azure DevOps pipeline run results to surface pass rate and regressions. Use for daily or weekly engineering health reports.","content":"# Report Pipeline Health\\n\\nSummarize recent pipeline reliability.\\n\\n## Steps\\n1. Use List Pipelines to enumerate the pipelines you care about.\\n2. For each, use List Pipeline Runs to pull recent runs within your window.\\n3. Compute pass rate (succeeded vs total), average duration, and the count of recent failures per pipeline.\\n4. Flag pipelines whose pass rate dropped or whose duration increased noticeably versus prior runs.\\n\\n## Output\\nReturn a per-pipeline summary table (name, pass rate, avg duration, recent failures) and a short narrative calling out regressions and any pipeline that is consistently red."}],"templates":[{"title":"Azure DevOps build failure alerter","prompt":"Build a workflow triggered when an Azure DevOps build fails that fetches the build timeline and failing-stage logs, summarizes the root cause with an agent, and posts an actionable Slack alert with a deep link to the run.","integrations":[{"id":"azure_devops","name":"Azure DevOps"},{"id":"slack","name":"Slack"}]},{"title":"Azure DevOps work-item triager","prompt":"Create a workflow triggered when an Azure DevOps work item is created that classifies it by type and priority, enriches the description, assigns the right area path, and posts a summary to the team channel.","integrations":[{"id":"azure_devops","name":"Azure DevOps"},{"id":"slack","name":"Slack"}]},{"title":"Azure DevOps release notes generator","prompt":"Build a workflow that pulls the work items completed between two Azure DevOps builds, groups them by type with an agent, and writes formatted release notes to a file for the release manager.","integrations":[{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Azure DevOps pipeline health report","prompt":"Create a scheduled daily workflow that lists Azure DevOps pipeline runs, computes pass rate and average duration per pipeline, logs them to a table for trend tracking, and Slacks a morning summary highlighting any regressions.","integrations":[{"id":"azure_devops","name":"Azure DevOps"},{"id":"slack","name":"Slack"}]},{"title":"Azure DevOps to Linear bridge","prompt":"Build a workflow that watches new Azure DevOps work items, mirrors each as a Linear issue with full context and a back-link, and keeps the team aligned across both trackers.","integrations":[{"id":"azure_devops","name":"Azure DevOps"},{"id":"linear","name":"Linear"}]},{"title":"Azure DevOps PR review summarizer","prompt":"Create a workflow triggered on a new Azure DevOps pull request that fetches the diff and linked work items, drafts a concise review summary and risk callouts with an agent, and posts it as a PR comment for reviewers.","integrations":[{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Azure DevOps sprint burndown digest","prompt":"Build a scheduled daily workflow that queries Azure DevOps work items in the active sprint, computes remaining effort and at-risk items, logs the burndown to a table, and posts a morning summary to the team Slack channel.","integrations":[{"id":"azure_devops","name":"Azure DevOps"},{"id":"slack","name":"Slack"}]}]},{"id":"bitbucket","type":"bitbucket","slug":"bitbucket","name":"Bitbucket","description":"Work with Bitbucket Cloud repositories, pull requests, and pipelines","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/bitbucket","authType":"oauth","connections":[{"id":"bitbucket","kind":"oauth","label":"Connect with OAuth","providerId":"bitbucket","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/bitbucket","requiredScopes":[{"id":"account","label":"View your Bitbucket account and workspace memberships"},{"id":"repository","label":"View repositories and source code"},{"id":"repository:write","label":"Push to repositories and create or delete branches"},{"id":"pullrequest","label":"View and comment on pull requests"},{"id":"pullrequest:write","label":"Create, update, approve, decline, and merge pull requests"},{"id":"pipeline","label":"View pipelines, steps, and logs"},{"id":"pipeline:write","label":"Run and stop pipelines"},{"id":"webhook","label":"Manage repository webhooks"}],"fields":[]}],"operations":[{"name":"List Workspaces","description":"List Bitbucket Cloud workspaces available to the authenticated account"},{"name":"List Repositories","description":"List repositories in a Bitbucket Cloud workspace"},{"name":"Get Repository","description":"Get a Bitbucket Cloud repository"},{"name":"List Branches","description":"List branches in a Bitbucket Cloud repository"},{"name":"Create Branch","description":"Create a branch at a commit hash or existing ref"},{"name":"Delete Branch","description":"Delete a branch from a Bitbucket Cloud repository"},{"name":"List Commits","description":"List repository commits in reverse chronological order"},{"name":"Get Commit","description":"Get a repository commit by its full SHA-1"},{"name":"List Directory","description":"List one shallow repository directory at a full commit SHA-1"},{"name":"Get File Metadata","description":"Inspect file size and attributes at a full repository commit SHA-1"},{"name":"Get File","description":"Read bounded UTF-8 text from a file at a full repository commit SHA-1"},{"name":"List Pull Requests","description":"List pull requests in a Bitbucket Cloud repository"},{"name":"Get Pull Request","description":"Get a pull request by repository-scoped ID"},{"name":"Create Pull Request","description":"Create a pull request between repository branches"},{"name":"Merge Pull Request","description":"Start an asynchronous pull request merge and return a task to poll when needed"},{"name":"Get Pull Request Merge Task Status","description":"Poll the status of an asynchronous pull request merge task"},{"name":"Decline Pull Request","description":"Decline an open pull request"},{"name":"Approve Pull Request","description":"Approve a pull request as the authenticated account"},{"name":"Request Pull Request Changes","description":"Request changes on a pull request as the authenticated account"},{"name":"Get Pull Request Diff","description":"Read a bounded UTF-8 unified diff for one pull request file"},{"name":"Get Pull Request Diffstat","description":"List per-file change statistics for a pull request"},{"name":"List Pull Request Comments","description":"List global, inline, and reply comments on a pull request"},{"name":"Create Pull Request Comment","description":"Create a global comment or reply on a pull request"},{"name":"List Pull Request Commit Statuses","description":"List commit statuses associated with a pull request"},{"name":"List Pipelines","description":"List pipelines for a Bitbucket Cloud repository"},{"name":"Get Pipeline","description":"Get a pipeline by UUID"},{"name":"Trigger Pipeline","description":"Run the repository pipeline selected by a branch or ref target"},{"name":"Stop Pipeline","description":"Stop a running pipeline"},{"name":"List Pipeline Steps","description":"List the steps in a pipeline"},{"name":"Get Pipeline Step Log","description":"Read a bounded UTF-8 tail of a pipeline step log"}],"triggers":[{"id":"bitbucket_push","name":"Bitbucket Push","description":"Trigger workflow when commits are pushed to a Bitbucket repository"},{"id":"bitbucket_repository_forked","name":"Bitbucket Repository Forked","description":"Trigger workflow when a Bitbucket repository is forked"},{"id":"bitbucket_repository_updated","name":"Bitbucket Repository Updated","description":"Trigger workflow when a Bitbucket repository is updated"},{"id":"bitbucket_commit_comment_created","name":"Bitbucket Commit Comment Created","description":"Trigger workflow when a comment is created on a Bitbucket commit"},{"id":"bitbucket_build_status_created","name":"Bitbucket Build Status Created","description":"Trigger workflow when a build status is created for a Bitbucket commit"},{"id":"bitbucket_build_status_updated","name":"Bitbucket Build Status Updated","description":"Trigger workflow when a build status is updated for a Bitbucket commit"},{"id":"bitbucket_pull_request_created","name":"Bitbucket Pull Request Created","description":"Trigger workflow when a Bitbucket pull request is created"},{"id":"bitbucket_pull_request_updated","name":"Bitbucket Pull Request Updated","description":"Trigger workflow when a Bitbucket pull request is updated"},{"id":"bitbucket_pull_request_approved","name":"Bitbucket Pull Request Approved","description":"Trigger workflow when a Bitbucket pull request is approved"},{"id":"bitbucket_pull_request_approval_removed","name":"Bitbucket Pull Request Approval Removed","description":"Trigger workflow when approval is removed from a Bitbucket pull request"},{"id":"bitbucket_pull_request_changes_requested","name":"Bitbucket Pull Request Changes Requested","description":"Trigger workflow when changes are requested on a Bitbucket pull request"},{"id":"bitbucket_pull_request_changes_request_removed","name":"Bitbucket Pull Request Changes Request Removed","description":"Trigger workflow when a changes request is removed from a Bitbucket pull request"},{"id":"bitbucket_pull_request_merged","name":"Bitbucket Pull Request Merged","description":"Trigger workflow when a Bitbucket pull request is merged"},{"id":"bitbucket_pull_request_declined","name":"Bitbucket Pull Request Declined","description":"Trigger workflow when a Bitbucket pull request is declined"},{"id":"bitbucket_pull_request_comment_created","name":"Bitbucket Pull Request Comment Created","description":"Trigger workflow when a comment is created on a Bitbucket pull request"},{"id":"bitbucket_pull_request_comment_updated","name":"Bitbucket Pull Request Comment Updated","description":"Trigger workflow when a comment is updated on a Bitbucket pull request"},{"id":"bitbucket_pull_request_comment_deleted","name":"Bitbucket Pull Request Comment Deleted","description":"Trigger workflow when a comment is deleted from a Bitbucket pull request"},{"id":"bitbucket_pull_request_comment_resolved","name":"Bitbucket Pull Request Comment Resolved","description":"Trigger workflow when a comment is resolved on a Bitbucket pull request"},{"id":"bitbucket_pull_request_comment_reopened","name":"Bitbucket Pull Request Comment Reopened","description":"Trigger workflow when a resolved comment is reopened on a Bitbucket pull request"}],"skills":[{"name":"review-bitbucket-pull-request","description":"Review a Bitbucket pull request file by file and produce a concise, evidence-backed general comment.","content":"# Review a Bitbucket Pull Request\\n\\n## Steps\\n1. Read the pull request and use diffstat to discover changed files.\\n2. Fetch each file-scoped diff separately and respect truncation metadata.\\n3. Evaluate correctness, security, tests, and maintainability using only evidence in the diff.\\n4. Group duplicate findings and distinguish blockers from suggestions.\\n5. Post one general pull request comment only when asked.\\n\\n## Output\\nSummarize the risk, list findings with file paths, and state whether human review is still needed."},{"name":"diagnose-bitbucket-pipeline","description":"Trace a failed Bitbucket pipeline to the failing step and explain the most likely root cause.","content":"# Diagnose a Bitbucket Pipeline\\n\\n## Steps\\n1. Read the pipeline and list all steps.\\n2. Focus on failed or stopped steps.\\n3. Read bounded log tails and account for partial or truncated output.\\n4. Identify the first causal error rather than downstream noise.\\n5. Recommend the smallest verifiable fix.\\n\\n## Output\\nReport the failed step, evidence from the log, likely cause, and next diagnostic or fix."},{"name":"assess-bitbucket-merge-readiness","description":"Assess approvals, commit statuses, and changed-file risk before a Bitbucket merge.","content":"# Assess Bitbucket Merge Readiness\\n\\n## Steps\\n1. Read the pull request and current participants.\\n2. List commit statuses and changed files.\\n3. Identify missing approvals, failed or pending checks, and risky changes.\\n4. Do not infer that a status is required or claim conflict status when the API data does not say so.\\n5. Never merge unless the user explicitly requests it.\\n\\n## Output\\nReturn a ready, blocked, or needs-review assessment with each observed blocker and its evidence."},{"name":"draft-bitbucket-release-notes","description":"Turn Bitbucket commit history into audience-friendly release notes without inventing changes.","content":"# Draft Bitbucket Release Notes\\n\\n## Steps\\n1. List recent commits in the requested repository.\\n2. Read commit details where summaries are ambiguous.\\n3. Group changes into features, fixes, performance, and maintenance.\\n4. Preserve contributor attribution and relevant links when present.\\n5. Flag unclear commits rather than guessing their user impact.\\n\\n## Output\\nProduce a short release summary followed by categorized bullets and known upgrade risks."},{"name":"triage-stale-bitbucket-pull-requests","description":"Identify stale Bitbucket pull requests and recommend the next owner and action for each.","content":"# Triage Stale Bitbucket Pull Requests\\n\\n## Steps\\n1. List open pull requests and read candidates that have not changed recently.\\n2. Check reviewers, comments, changed files, and commit statuses.\\n3. Distinguish waiting-for-author, waiting-for-review, failing-CI, and obsolete work.\\n4. Recommend a next action and responsible participant.\\n5. Decline or comment only when explicitly requested.\\n\\n## Output\\nReturn a prioritized table of stale pull requests, age, blocker, owner, and next action."},{"name":"summarize-bitbucket-activity","description":"Summarize repository commits, pull requests, and pipeline activity for an engineering update.","content":"# Summarize Bitbucket Activity\\n\\n## Steps\\n1. Gather recent commits, pull requests, and pipelines for the repository.\\n2. Deduplicate activity that represents the same change.\\n3. Highlight merged work, active reviews, failures, and delivery risks.\\n4. Link to source records when URLs are available.\\n\\n## Output\\nProvide a concise digest with shipped, in review, CI health, and attention-needed sections."},{"name":"sync-bitbucket-delivery-to-jira","description":"Connect Bitbucket pull request and pipeline evidence to the matching Jira delivery record.","content":"# Sync Bitbucket Delivery to Jira\\n\\n## Steps\\n1. Read the pull request, source branch, head commit, and pipeline status.\\n2. Extract Jira keys conservatively and verify the intended Jira issue.\\n3. Summarize implementation, review state, and CI status.\\n4. Add a Jira update only when a unique issue match is established.\\n5. Never transition or close the Jira issue unless explicitly requested.\\n\\n## Output\\nReport the matched issue, linked pull request, delivery state, and any ambiguity that blocked an update."}],"templates":[{"title":"Bitbucket pull request review assistant","prompt":"Build a workflow that reads a Bitbucket pull request, discovers its changed files with diffstat, reviews each bounded file diff against our engineering standards, and posts one concise general pull request comment with findings and suggested fixes.","integrations":[{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Bitbucket pipeline failure diagnosis","prompt":"Create a workflow that inspects a failed Bitbucket pipeline, lists its steps, reads the bounded tail of each failed step log, identifies the likely root cause, and sends an actionable diagnosis to Slack.","integrations":[{"id":"bitbucket","name":"Bitbucket"},{"id":"slack","name":"Slack"}]},{"title":"Bitbucket merge readiness report","prompt":"Build a workflow that reads an open Bitbucket pull request, its reviewers, commit statuses, and changed-file summary, then reports approvals, failing checks, risky changes, and the remaining review work without merging it.","integrations":[{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Bitbucket release notes generator","prompt":"Create a workflow that lists recent Bitbucket commits in a repository, reads ambiguous commit details, groups the changes by area, and drafts clear release notes for review.","integrations":[{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Bitbucket stale pull request review","prompt":"Build a scheduled workflow that lists open Bitbucket pull requests, identifies stale work from its update timestamps and review state, summarizes the next action for each, and posts a weekly reminder in Slack.","integrations":[{"id":"bitbucket","name":"Bitbucket"},{"id":"slack","name":"Slack"}]},{"title":"Bitbucket engineering activity digest","prompt":"Create a scheduled workflow that summarizes recent Bitbucket commits, pull request activity, and pipeline results across a repository into a concise engineering digest delivered by email.","integrations":[{"id":"bitbucket","name":"Bitbucket"},{"id":"gmail","name":"Gmail"}]},{"title":"Bitbucket and Jira delivery automation","prompt":"Build a workflow that reads a Bitbucket pull request and its head commit, extracts Jira issue keys from the title, description, source branch, and commit message, summarizes delivery and pipeline status, and adds the update to the matching Jira issue.","integrations":[{"id":"bitbucket","name":"Bitbucket"},{"id":"jira","name":"Jira"}]}]},{"id":"box","type":"box_v2","slug":"box","name":"Box","description":"Manage files, folders, and e-signatures with Box","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/box","authType":"oauth","connections":[{"id":"box","kind":"oauth","label":"Connect with OAuth","providerId":"box","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/box","requiredScopes":[{"id":"root_readwrite","label":"Read and write all files and folders in Box account"},{"id":"sign_requests.readwrite","label":"Create and manage Box Sign e-signature requests"}],"fields":[]},{"id":"box-service-account","kind":"service_account","providerId":"box-service-account","label":"Add service account","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/box-service-account","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true},{"id":"orgId","label":"Enterprise ID","placeholder":"1234567","secret":false,"hint":"Box Enterprise IDs are numeric."}]}],"operations":[{"name":"Upload File","description":"Upload a file to a Box folder"},{"name":"Download File","description":"Download a file from Box"},{"name":"Get File Info","description":"Get detailed information about a file in Box"},{"name":"List Folder Items","description":"List files and folders in a Box folder"},{"name":"Create Folder","description":"Create a new folder in Box"},{"name":"Delete File","description":"Delete a file from Box"},{"name":"Delete Folder","description":"Delete a folder from Box"},{"name":"Copy File","description":"Copy a file to another folder in Box"},{"name":"Search","description":"Search for files and folders in Box"},{"name":"Update File","description":"Update file info in Box (rename, move, change description, add tags)"},{"name":"Create Sign Request","description":"Create a new Box Sign request to send documents for e-signature"},{"name":"Get Sign Request","description":"Get the details and status of a Box Sign request"},{"name":"List Sign Requests","description":"List all Box Sign requests"},{"name":"Cancel Sign Request","description":"Cancel a pending Box Sign request"},{"name":"Resend Sign Request","description":"Resend a Box Sign request to signers who have not yet signed"}],"triggers":[],"skills":[{"name":"send-document-for-signature","description":"Send a Box document for e-signature and confirm the request. Use for contracts, NDAs, and approval forms that need a signer.","content":"# Send Document For Signature\\n\\nKick off a Box Sign request for one or more documents.\\n\\n## Steps\\n1. Identify the Box file id(s) to sign (use Search or List Folder Items if you only have a name).\\n2. Use Create Sign Request with the source file ids and the primary signer email; set the signer role (signer, approver, or final copy reader).\\n3. Add a clear email subject and message, and add any additional signers as a JSON array of email/role objects.\\n4. Optionally set a destination folder for the signed copy, days valid, and reminders.\\n\\n## Output\\nReturn the sign request id, status, signer list, and the prepare/sign URL. Tell the user the request was sent and how to track it. If a file id cannot be resolved, ask for clarification."},{"name":"track-signature-status","description":"Check the status of Box Sign requests and follow up on pending signers. Use to monitor outstanding e-signature requests.","content":"# Track Signature Status\\n\\nReport on outstanding and completed Box Sign requests.\\n\\n## Steps\\n1. Use List Sign Requests to retrieve recent requests, paging with the marker when needed.\\n2. For a specific request, use Get Sign Request with the sign request id to read per-signer status.\\n3. Identify requests that are still pending versus signed, declined, or expired.\\n4. For stalled requests, use Resend Sign Request to nudge signers, or Cancel Sign Request if it is no longer needed.\\n\\n## Output\\nReturn a status summary per request: name, overall status, which signers have signed, and which are outstanding. Recommend resend or cancel actions for stale requests."},{"name":"organize-files-into-folder","description":"Upload files into a structured Box folder, creating folders as needed. Use to file documents into a standard organized layout.","content":"# Organize Files Into Folder\\n\\nPlace documents into the correct Box folder structure.\\n\\n## Steps\\n1. Determine the destination. Use List Folder Items or Search to find an existing folder, or Create Folder under the right parent (use \\"0\\" for root) if it does not exist.\\n2. Upload each file with Upload File, setting the parent folder id and an explicit file name when needed.\\n3. To reorganize existing files, use Update File to rename, move (set Move to Folder ID), tag, or describe them.\\n4. Use Copy File when a document must live in more than one folder.\\n\\n## Output\\nReturn the created folder id (if any) and a list of the files placed, each with its id, name, and final folder. Confirm the resulting structure."},{"name":"search-box-content","description":"Find files and folders in Box matching a query and return their details. Use to locate documents before acting on them.","content":"# Search Box Content\\n\\nLocate documents in Box.\\n\\n## Steps\\n1. Use Search with the query string. Narrow with optional filters: ancestor folder id, file extensions (e.g. pdf,docx), and content type (file, folder, or web link).\\n2. Page through results with limit and offset if there are many matches.\\n3. For promising hits, use Get File Info to confirm name, size, owner, and modified date.\\n\\n## Output\\nReturn the matching items with id, name, type, owner, and last-modified date. If the query is ambiguous or returns too many results, suggest a tighter query or folder scope."}],"templates":[{"title":"Box folder onboarding","prompt":"Create a workflow that watches a Box folder for new customer subfolders, applies the standard permissions matrix, seeds template files, and notifies the account owner.","integrations":[{"id":"box","name":"Box"}]},{"title":"Box external-share auditor","prompt":"Build a scheduled weekly workflow that lists Box shared links shared with external collaborators, flags items above the sensitivity threshold, and writes a security review.","integrations":[{"id":"box","name":"Box"}]},{"title":"Box compliance retention","prompt":"Create a scheduled workflow that finds Box documents past retention, applies legal hold or archives them, and writes the disposition record to an audit table.","integrations":[{"id":"box","name":"Box"}]},{"title":"Box document Q&A agent","prompt":"Build an agent that indexes Box content into a knowledge base, answers user questions with sourced citations, and deploys as a chat endpoint for internal teams.","integrations":[{"id":"box","name":"Box"}]},{"title":"Box to S3 backup","prompt":"Create a scheduled workflow that mirrors a Box folder tree into S3 nightly with incremental sync, captures the manifest, and pings Slack on any failed files.","integrations":[{"id":"box","name":"Box"},{"id":"s3","name":"S3"}]},{"title":"Box new-vendor folder setup","prompt":"Build a workflow triggered when a new vendor is created in a CRM that provisions a standard Box folder structure for that vendor, invites the right users, and writes the folder link to the vendor record.","integrations":[{"id":"box","name":"Box"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Box approval-flow router","prompt":"Create a workflow that watches a Box approval folder, posts a Slack request with quick-action buttons for each new doc, captures the decision, and labels the file accordingly.","integrations":[{"id":"box","name":"Box"},{"id":"slack","name":"Slack"}]}]},{"id":"brandfetch","type":"brandfetch","slug":"brandfetch","name":"Brandfetch","description":"Look up brand assets, logos, colors, and company info","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/brandfetch","authType":"api-key","connections":[],"operations":[{"name":"Get Brand","description":"Retrieve brand assets including logos, colors, fonts, and company info by domain, ticker, ISIN, or crypto symbol"},{"name":"Search Brands","description":"Search for brands by name and find their domains and logos"}],"triggers":[],"skills":[{"name":"enrich-company-by-domain","description":"Look up a company by domain and return its brand assets and firmographics. Use to enrich a CRM record, lead, or account with logo, colors, and company data.","content":"# Enrich Company By Domain\\n\\nFetch brand and company data for a known domain.\\n\\n## Steps\\n1. Use Get Brand with the company domain as the identifier (e.g. nike.com). A stock ticker, ISIN, or crypto symbol also works.\\n2. Read the returned logos, colors, fonts, links, description, and company firmographics.\\n3. Pick the best logo for the use case (prefer a transparent or themed variant) and the primary brand color.\\n\\n## Output\\nReturn a tidy record: company name, domain, description, primary logo URL, primary brand color hex, social links, and key firmographics. If the quality score is low or the brand is unclaimed, note that the data may be incomplete."},{"name":"resolve-brand-by-name","description":"Search for a brand by name to find its domain and logo when you only have the company name. Use to disambiguate or resolve a domain before deeper enrichment.","content":"# Resolve Brand By Name\\n\\nFind a brand when you only know its name.\\n\\n## Steps\\n1. Use Search Brands with the company name (e.g. \\"Nike\\").\\n2. Review the results array; each entry has a brand name, domain, and icon.\\n3. Choose the best match by exact name and most likely official domain.\\n4. Optionally follow up with Get Brand on the chosen domain for full assets and firmographics.\\n\\n## Output\\nReturn the resolved brand name, domain, and icon URL. If several plausible matches exist, list the top candidates with their domains so the user can confirm."},{"name":"collect-brand-assets-for-personalization","description":"Gather a prospect or customer brand kit (logo, colors, fonts) for personalizing decks, emails, or portals. Use ahead of personalized outreach or design work.","content":"# Collect Brand Assets For Personalization\\n\\nBuild a usable brand kit for a target company.\\n\\n## Steps\\n1. Resolve the company domain (use Search Brands first if you only have a name).\\n2. Use Get Brand to retrieve logos, colors, and fonts.\\n3. Select assets fit for purpose: a high-contrast logo for a deck cover, the primary and secondary colors, and the brand font names.\\n\\n## Output\\nReturn a brand kit object: logo URLs by theme (light/dark), an ordered color palette with hex values, and font names. Note any missing asset so the design step can fall back to a neutral default."}],"templates":[{"title":"Brandfetch logo enricher","prompt":"Build a workflow that pulls company logos and brand colors from Brandfetch for each lead in a table, writes the asset URLs back, and uses them in personalized outreach.","integrations":[{"id":"brandfetch","name":"Brandfetch"}]},{"title":"Brandfetch CRM enrichment","prompt":"Create a workflow that watches new HubSpot accounts, pulls Brandfetch data for each company domain, and writes brand colors and logo URLs to the company record.","integrations":[{"id":"brandfetch","name":"Brandfetch"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Brandfetch deck personalizer","prompt":"Build a workflow that on a new opportunity pulls the prospect’s brand assets from Brandfetch, generates a personalized pitch deck with their logo and colors, and attaches it.","integrations":[{"id":"brandfetch","name":"Brandfetch"},{"id":"salesforce","name":"Salesforce"},{"id":"gamma","name":"Gamma"}]},{"title":"Brandfetch competitor logo collector","prompt":"Create a workflow that takes a list of competitor domains, pulls Brandfetch brand assets for each, and writes a competitive matrix file the marketing team can use.","integrations":[{"id":"brandfetch","name":"Brandfetch"}]},{"title":"Brandfetch customer-portal personalizer","prompt":"Build a workflow that auto-themes a customer portal experience using Brandfetch brand colors for each new enterprise account.","integrations":[{"id":"brandfetch","name":"Brandfetch"}]},{"title":"Brandfetch outbound enricher","prompt":"Create a workflow that enriches outbound prospect data with Brandfetch logos and brand metadata, and writes the enriched contact record to Email Bison for personalization.","integrations":[{"id":"brandfetch","name":"Brandfetch"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Brandfetch contract personalizer","prompt":"Build a workflow that pulls Brandfetch assets for the counterparty on a DocuSign envelope, embeds the right logo in the cover sheet, and sends.","integrations":[{"id":"brandfetch","name":"Brandfetch"},{"id":"docusign","name":"DocuSign"}]}]},{"id":"brex","type":"brex","slug":"brex","name":"Brex","description":"Manage expenses, receipts, transactions, and team data in Brex","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/brex","authType":"api-key","connections":[],"operations":[{"name":"List Expenses","description":"List expenses in the Brex account with optional filters for user, status, payment status, and purchase date range"},{"name":"Get Expense","description":"Get a single Brex expense by its ID, including merchant, user, and receipt details"},{"name":"Update Expense Memo","description":"Update the memo of a Brex card expense"},{"name":"Upload Receipt","description":"Upload a receipt file and attach it to a specific Brex card expense"},{"name":"Match Receipt","description":"Upload a receipt file and let Brex automatically match it with existing expenses"},{"name":"List Card Transactions","description":"List settled card transactions for all Brex card accounts"},{"name":"List Cash Transactions","description":"List transactions for a Brex cash account"},{"name":"List Card Accounts","description":"List all Brex card accounts with balances and limits"},{"name":"List Cash Accounts","description":"List all Brex cash accounts with balances and account details"},{"name":"Get Cash Account","description":"Get a Brex cash account by ID, or the primary cash account when no ID is provided"},{"name":"List Card Statements","description":"List finalized statements for the primary Brex card account"},{"name":"List Cash Statements","description":"List finalized statements for a Brex cash account"},{"name":"List Users","description":"List users in the Brex account, optionally filtered by email"},{"name":"Get User","description":"Get a Brex user by their ID"},{"name":"Get Current User","description":"Get the Brex user associated with the API token"},{"name":"List Departments","description":"List departments in the Brex account, optionally filtered by name"},{"name":"List Locations","description":"List locations in the Brex account, optionally filtered by name"},{"name":"List Titles","description":"List job titles in the Brex account, optionally filtered by name"},{"name":"List Cards","description":"List cards in the Brex account, optionally filtered by card owner"},{"name":"Get Company","description":"Get the Brex company associated with the API token"},{"name":"List Budgets","description":"List budgets in the Brex account"},{"name":"Get Budget","description":"Get a Brex budget by its ID"},{"name":"Create Budget","description":"Create a new budget in the Brex account"},{"name":"Archive Budget","description":"Archive a Brex budget, making any spend limits beneath it unusable for future expenses and removing it from the UI"},{"name":"List Spend Limits","description":"List spend limits in the Brex account, optionally filtered by member user"},{"name":"Get Spend Limit","description":"Get a Brex spend limit by its ID"},{"name":"Create Spend Limit","description":"Create a new spend limit (hard-authorization card program) in the Brex account"},{"name":"List Vendors","description":"List vendors in the Brex account, optionally filtered by name"},{"name":"Get Vendor","description":"Get a Brex vendor by its ID"},{"name":"Create Vendor","description":"Create a new vendor in the Brex account"},{"name":"Update Vendor","description":"Update an existing vendor in the Brex account"},{"name":"List Transfers","description":"List money transfers in the Brex account"},{"name":"Get Transfer","description":"Get a Brex money transfer by its ID"},{"name":"Create Transfer","description":"Create a money transfer from a Brex cash account to a vendor"}],"triggers":[],"skills":[{"name":"spend-report","description":"Summarize Brex spend over a period, broken down by category, merchant, and user.","content":"# Spend Report\\n\\nBuild a clear summary of company spend from Brex expenses.\\n\\n## Steps\\n1. List expenses filtered to the requested period using the purchased-at date filters.\\n2. Group expenses by merchant category, merchant, and user, totaling billing amounts (amounts are in cents).\\n3. Highlight the largest expenses and any with OUT_OF_POLICY status.\\n\\n## Output\\nReturn total spend, a breakdown by category and merchant, the top spenders, and any flagged out-of-policy expenses with dashboard links."},{"name":"attach-receipt","description":"Upload a receipt file and attach it to the right Brex expense.","content":"# Attach a Receipt\\n\\nGet a receipt onto the correct Brex expense.\\n\\n## Steps\\n1. If the target expense is known, use Upload Receipt with the expense ID.\\n2. If not, use Match Receipt so Brex pairs the receipt with the right expense automatically.\\n3. Confirm the upload succeeded and capture the receipt ID.\\n\\n## Output\\nReturn the receipt ID, the receipt name, and the expense it was attached to (or note that Brex is matching it automatically)."},{"name":"memo-cleanup","description":"Find Brex expenses missing memos and fill them in from merchant details.","content":"# Memo Cleanup\\n\\nKeep expense memos complete for accounting.\\n\\n## Steps\\n1. List recent expenses and find ones with an empty memo.\\n2. For each, draft a short memo from the merchant descriptor, category, and amount.\\n3. Update each expense with the drafted memo using Update Expense Memo.\\n\\n## Output\\nReturn the list of expenses updated, each with its new memo, and any expenses that could not be updated."},{"name":"budget-utilization","description":"Report utilization for Brex budgets and spend limits.","content":"# Budget Utilization\\n\\nShow how much of each budget and spend limit has been used.\\n\\n## Steps\\n1. List budgets and capture each amount and status.\\n2. List spend limits and capture each current period balance.\\n3. Compute utilization where both an amount and a balance are available (amounts are in cents).\\n\\n## Output\\nReturn each budget and spend limit with its owner, period, amount, and utilization, flagging any that are near or over their limit."},{"name":"cash-balance-check","description":"Check Brex cash account balances and recent account activity.","content":"# Cash Balance Check\\n\\nGive a quick read on company cash in Brex.\\n\\n## Steps\\n1. List cash accounts and capture current and available balances (amounts are in cents).\\n2. For the primary account, list recent cash transactions.\\n3. Note any unusually large recent movements.\\n\\n## Output\\nReturn each account with its balances, the most recent transactions for the primary account, and any large movements worth a look."},{"name":"statement-reconciliation","description":"Reconcile a Brex card statement period against its settled transactions.","content":"# Statement Reconciliation\\n\\nTie a card statement back to its underlying transactions.\\n\\n## Steps\\n1. List card statements and pick the period to reconcile.\\n2. List card transactions posted within that period using the posted-at filter.\\n3. Compare transaction totals to the statement start and end balances and flag gaps.\\n\\n## Output\\nReturn the statement period, its balances, the transaction total for the period, and any discrepancy that needs review."},{"name":"pay-vendor","description":"Pay a vendor from a Brex cash account, creating the vendor first if needed.","content":"# Pay a Vendor\\n\\nSend a payment to a vendor through Brex.\\n\\n## Steps\\n1. List vendors and check if the target vendor already exists by name.\\n2. If not, use Create Vendor with the company name (and email/phone if known).\\n3. Use the vendor\'s payment_accounts entry to get the payment_instrument_id, then use Create Transfer with that ID, the cash account to pay from, the amount (in cents), a description, and an external memo.\\n4. Confirm the transfer was created and note its status.\\n\\n## Output\\nReturn the vendor used, the transfer ID and status, and the amount sent. Flag anything that requires manual approval (PENDING_APPROVAL status)."}],"templates":[{"title":"Brex receipt auto-attach","prompt":"Build a workflow that takes an uploaded receipt file and sends it to Brex with the Match Receipt operation so Brex automatically pairs it with the right card expense.","integrations":[{"id":"brex","name":"Brex"}]},{"title":"Brex daily expense digest","prompt":"Build a scheduled workflow that runs every weekday morning, lists Brex expenses settled in the last 24 hours, summarizes total spend by merchant category, and posts the digest to a Slack channel.","integrations":[{"id":"brex","name":"Brex"},{"id":"slack","name":"Slack"}]},{"title":"Brex memo enforcer","prompt":"Build a scheduled workflow that lists approved Brex expenses, finds ones missing a memo, has an agent draft a memo from the merchant and amount details, and updates each expense with the drafted memo.","integrations":[{"id":"brex","name":"Brex"}]},{"title":"Brex spend anomaly alert","prompt":"Build a scheduled workflow that lists recent Brex card transactions, flags any transaction above a configurable threshold, and emails the finance team a report of flagged transactions with merchant details.","integrations":[{"id":"brex","name":"Brex"},{"id":"gmail","name":"Gmail"}]},{"title":"Brex cash balance monitor","prompt":"Build a scheduled workflow that checks Brex cash account balances every morning and sends a Slack alert when the available balance of any account drops below a set threshold.","integrations":[{"id":"brex","name":"Brex"},{"id":"slack","name":"Slack"}]},{"title":"Brex budget utilization report","prompt":"Build a weekly workflow that lists Brex budgets and spend limits, computes utilization for each budget from its amount and current period balance, stores the results in a table, and emails a summary report.","integrations":[{"id":"brex","name":"Brex"},{"id":"gmail","name":"Gmail"}]},{"title":"Brex approved-invoice payment automation","prompt":"Build a workflow that takes an approved invoice (vendor name, amount, and memo), creates the vendor in Brex if it does not already exist, and creates a transfer from the company cash account to pay it.","integrations":[{"id":"brex","name":"Brex"}]},{"title":"Brex team directory assistant","prompt":"Build an agent that answers questions about company spend and team structure by looking up Brex users, departments, locations, and their expenses on demand.","integrations":[{"id":"brex","name":"Brex"}]},{"title":"Brex vendor payment tracker","prompt":"Build a workflow that lists Brex vendors and recent transfers, reconciles transfer statuses against expected payments stored in a table, and flags any failed or delayed payments.","integrations":[{"id":"brex","name":"Brex"}]}]},{"id":"brightdata","type":"brightdata","slug":"bright-data","name":"Bright Data","description":"Scrape websites, search engines, and extract structured data","category":"Search","docsUrl":"https://docs.sim.ai/integrations/brightdata","authType":"api-key","connections":[],"operations":[{"name":"Scrape URL","description":"Fetch page content with Bright Data Web Unlocker, including its supported anti-bot, CAPTCHA, and IP-block handling. Access depends on the target site and zone configuration."},{"name":"SERP Search","description":"Search Google, Bing, DuckDuckGo, or Yandex and get structured search results using Bright Data SERP API."},{"name":"Discover","description":"AI-powered web discovery that finds and ranks results by intent. Returns up to 20 results with optional cleaned page content for RAG and verification."},{"name":"Sync Scrape","description":"Scrape URLs synchronously using a Bright Data pre-built scraper and get structured results directly. Supports up to 20 URLs with a 1-minute timeout."},{"name":"Scrape Dataset","description":"Trigger a Bright Data pre-built scraper to extract structured data from URLs. Supports 660+ scrapers for platforms like Amazon, LinkedIn, Instagram, and more."},{"name":"Snapshot Status","description":"Check the progress of an async Bright Data scraping job. Returns status: starting, running, ready, or failed."},{"name":"Download Snapshot","description":"Download the results of a completed Bright Data scraping job using its snapshot ID. The snapshot must have ready status."},{"name":"Cancel Snapshot","description":"Cancel an active Bright Data scraping job using its snapshot ID. Terminates data collection in progress."}],"triggers":[],"skills":[{"name":"scrape-page-content","description":"Fetch the content of a single web page through Bright Data Web Unlocker, bypassing bot blocks and geo-restrictions. Use to read a page an agent cannot otherwise access.","content":"# Scrape Page Content\\n\\nRetrieve a page that is normally blocked or geo-restricted.\\n\\n## Steps\\n1. Use Scrape URL with the target URL and your unlocker zone (e.g. web_unlocker1).\\n2. Choose the format: Raw HTML for full markup, or JSON for a parsed response.\\n3. Set the Country code when the page differs by region.\\n4. Run it and read the returned content and HTTP status code.\\n\\n## Output\\nReturn the cleaned page content (text or relevant HTML) and the status code. If the status indicates a block or error, report it and suggest a different zone or country rather than returning empty content."},{"name":"search-the-web","description":"Run a search-engine query through Bright Data SERP API and return ranked results. Use for keyword research, competitive monitoring, or grounding an answer in fresh results.","content":"# Search The Web\\n\\nGet structured search results for a query.\\n\\n## Steps\\n1. Use SERP Search with the query and your SERP zone.\\n2. Pick the search engine (Google, Bing, DuckDuckGo, or Yandex) and set country/language for localized results.\\n3. Set the number of results to the amount you need.\\n4. Read the results array (title, URL, snippet, rank).\\n\\n## Output\\nReturn the ranked results as a list with title, URL, and snippet. Summarize the top findings for the user, and note the engine, country, and query used so the result is reproducible."},{"name":"discover-pages-by-intent","description":"Find web pages that match a described intent using Bright Data Discover, optionally pulling page content. Use to gather sources on a topic without crafting exact queries.","content":"# Discover Pages By Intent\\n\\nFind relevant pages from a natural-language description.\\n\\n## Steps\\n1. Use Discover with a search query and an Intent describing what you actually want (e.g. \\"official pricing pages and recent change notes\\").\\n2. Set the number of results, country, and language as needed.\\n3. Enable Include Page Content and choose Markdown or JSON when you want the page bodies, not just links.\\n\\n## Output\\nReturn the discovered pages ranked by relevance with URL, title, and (if requested) extracted content. Summarize what was found and flag any low-relevance results so they can be filtered out."},{"name":"run-dataset-scraper","description":"Trigger a Bright Data pre-built dataset scraper for structured extraction across many URLs and retrieve the results. Use for bulk structured data from sites like e-commerce or social.","content":"# Run Dataset Scraper\\n\\nExtract structured records across many URLs with a pre-built scraper.\\n\\n## Steps\\n1. Identify the dataset scraper id for the target site (e.g. gd_...).\\n2. For small batches (up to 20 URLs), use Sync Scrape to get results back inline; choose JSON, NDJSON, or CSV.\\n3. For larger jobs, use Scrape Dataset, which returns a snapshot id.\\n4. Poll Snapshot Status until it is ready, then use Download Snapshot to fetch the data. Use Cancel Snapshot to abort a job that is no longer needed.\\n\\n## Output\\nReturn the structured records (or the snapshot id and status for async jobs). For async runs, report progress and only return data once the snapshot is complete."}],"templates":[{"title":"Bright Data scraper orchestrator","prompt":"Build a workflow that uses Bright Data unblockers to scrape geo-restricted competitor pages, captures the data daily, and writes to a tracking table.","integrations":[{"id":"brightdata","name":"Bright Data"}]},{"title":"Bright Data competitor pricing","prompt":"Create a workflow that uses Bright Data to track competitor pricing across regions, captures geo-priced data, and posts notable price changes to Slack.","integrations":[{"id":"brightdata","name":"Bright Data"},{"id":"slack","name":"Slack"}]},{"title":"Bright Data SERP collector","prompt":"Build a scheduled workflow that uses Bright Data SERP scraping to capture rankings for tracked keywords across regions, and writes the results to an SEO scoreboard.","integrations":[{"id":"brightdata","name":"Bright Data"}]},{"title":"Bright Data review collector","prompt":"Create a workflow that uses Bright Data to scrape product reviews across geos, classifies sentiment, and writes findings into a product-feedback table.","integrations":[{"id":"brightdata","name":"Bright Data"}]},{"title":"Bright Data localization checker","prompt":"Build a scheduled workflow that uses Bright Data geo-targeted browsing to verify the brand’s site renders correctly in tracked regions, and writes findings to Slack.","integrations":[{"id":"brightdata","name":"Bright Data"},{"id":"slack","name":"Slack"}]},{"title":"Bright Data brand mention search","prompt":"Create a workflow that uses Bright Data to scrape mentions of the brand across global forums and review sites, writes mentions into a tracking table, and pings on spikes.","integrations":[{"id":"brightdata","name":"Bright Data"},{"id":"slack","name":"Slack"}]},{"title":"Bright Data inventory tracker","prompt":"Build a scheduled workflow that uses Bright Data to track competitor stock availability across regions, writes the data, and pings on low-stock signals indicating shifts.","integrations":[{"id":"brightdata","name":"Bright Data"}]}]},{"id":"browser_use","type":"browser_use","slug":"browser-use","name":"Browser Use","description":"Run browser automation tasks","category":"AI","docsUrl":"https://docs.sim.ai/integrations/browser_use","authType":"api-key","connections":[],"operations":[{"name":"Browser Use","description":"Runs a browser automation task using BrowserUse"}],"triggers":[],"skills":[{"name":"automate-web-task","description":"Drive a browser agent to complete a multi-step task on a website, like navigating, clicking, and submitting. Use when a site has no API and a human would normally do the clicks.","content":"# Automate Web Task\\n\\nHave the browser agent perform a goal-oriented task on the web.\\n\\n## Steps\\n1. Write a clear, step-by-step Task describing the goal and any success condition (e.g. \\"log in, open Billing, download the latest invoice\\").\\n2. Set the Start URL so the agent begins on the right page.\\n3. Put any credentials or sensitive inputs in Variables (Secrets) and reference them in the task by name rather than pasting them inline.\\n4. Restrict Allowed Domains to keep the agent on the intended site, and raise Max Steps for longer flows.\\n\\n## Output\\nReturn whether the task succeeded, the final output, and the share URL for the recorded session so the run can be audited. If the agent gets stuck, report the last step and what blocked it."},{"name":"extract-structured-data-from-site","description":"Use a browser agent to navigate a site and return data in a defined JSON schema. Use to pull structured records (prices, listings, table rows) from pages without an API.","content":"# Extract Structured Data From Site\\n\\nNavigate a website and return structured data.\\n\\n## Steps\\n1. Write a Task that tells the agent what to find and where (e.g. \\"go to the pricing page and collect every plan name and monthly price\\").\\n2. Set the Start URL and limit Allowed Domains to the target site.\\n3. Provide a Structured Output Schema (stringified JSON schema) describing the exact fields you want back.\\n4. Run it; the agent fills the schema from what it observes on the page.\\n\\n## Output\\nReturn the data as objects matching the provided schema. Confirm each field was actually found on the page; if a field could not be located, leave it null and note it rather than fabricating a value."},{"name":"fill-and-submit-form","description":"Have a browser agent fill out and submit a web form using supplied field values. Use for vendor portals, questionnaires, or applications that have no API.","content":"# Fill And Submit Form\\n\\nComplete a web form end to end.\\n\\n## Steps\\n1. Describe the form and the mapping of values to fields in the Task (e.g. \\"fill the contact form: name, company, message, then submit\\").\\n2. Set the Start URL to the form page and constrain Allowed Domains.\\n3. Pass any private values through Variables (Secrets) so they are injected securely.\\n4. Ask the agent to confirm the submission succeeded (look for a success message or confirmation page) before finishing.\\n\\n## Output\\nReturn whether the form submitted successfully, any confirmation text or reference number shown, and the session share URL as an audit trail. If a required field was missing or validation failed, report which field and why."}],"templates":[{"title":"Browser Use form filler","prompt":"Build a workflow that uses Browser Use to automate filling complex web forms — vendor portals, compliance questionnaires — with data pulled from a table, and captures screenshots to a file as audit trail.","integrations":[{"id":"browser_use","name":"Browser Use"}]},{"title":"Browser Use competitor pricing scraper","prompt":"Create a scheduled workflow that runs Browser Use weekly to navigate competitor pricing pages, captures the current plans and prices, diffs against last week, and posts changes to Slack.","integrations":[{"id":"browser_use","name":"Browser Use"},{"id":"slack","name":"Slack"}]},{"title":"Browser Use legacy ERP scraper","prompt":"Create a workflow that uses Browser Use to log into a legacy ERP without an API, exports daily reports, parses them into a table, and posts a summary to Slack so old systems still feed modern ops.","integrations":[{"id":"browser_use","name":"Browser Use"},{"id":"slack","name":"Slack"}]},{"title":"Browser Use + Stagehand cross-tool QA","prompt":"Create a workflow that uses Browser Use and Stagehand together to run scripted browser flows against staging, captures screenshots, and writes a regression report.","integrations":[{"id":"browser_use","name":"Browser Use"},{"id":"stagehand","name":"Stagehand"}]},{"title":"Browser Use + Stagehand expense-portal grabber","prompt":"Build a workflow that uses Browser Use and Stagehand to automate expense-portal data pulls from suppliers, captures the structured data, and writes to a finance table.","integrations":[{"id":"browser_use","name":"Browser Use"},{"id":"stagehand","name":"Stagehand"}]},{"title":"Browser Use invoice-portal collector","prompt":"Create a workflow that uses Browser Use to log into vendor invoice portals weekly, downloads outstanding invoices, and writes the metadata to a finance table.","integrations":[{"id":"browser_use","name":"Browser Use"}]},{"title":"Browser Use review-site monitor","prompt":"Build a workflow that uses Browser Use to scrape G2 and Capterra review pages for brand mentions, classifies sentiment, and writes notable reviews to a tracking table.","integrations":[{"id":"browser_use","name":"Browser Use"}]}]},{"id":"buffer","type":"buffer","slug":"buffer","name":"Buffer","description":"Schedule and publish social media posts across connected channels","category":"Marketing","docsUrl":"https://docs.sim.ai/integrations/buffer","authType":"api-key","connections":[],"operations":[{"name":"Create Post","description":"Create a post in Buffer for a channel — add it to the queue, share it immediately, schedule it for a specific time, or save it as a draft, optionally with an image or video attachment"},{"name":"Edit Post","description":"Edit an existing Buffer post — update its text, schedule, or media. Attaching new media replaces the existing attachments"},{"name":"Get Posts","description":"List posts in a Buffer organization, optionally filtered by channel and status (draft, needs_approval, scheduled, sending, sent, error)"},{"name":"Get Post","description":"Get a single Buffer post by ID, including its status, schedule, and media"},{"name":"Delete Post","description":"Delete a Buffer post by ID"},{"name":"Get Channels","description":"List the social media channels connected to a Buffer organization, including their channel IDs (needed to create posts)"},{"name":"Get Channel","description":"Get one connected channel, including its posting schedule, limits and network settings"},{"name":"Get Aggregated Post Metrics","description":"Aggregate published post metrics across an organization or selected channels over a date range of up to 365 days"},{"name":"Get Daily Posting Limits","description":"Check sent and scheduled post counts against each channel’s daily limit for a date"},{"name":"Create Idea","description":"Save a content idea to a Buffer organization for later drafting and scheduling"},{"name":"Get Ideas","description":"List content ideas saved in a Buffer organization"},{"name":"Get Idea Groups","description":"List idea groups (board columns) in a Buffer organization, including the group IDs used when creating ideas"},{"name":"Get Account","description":"Get the authenticated Buffer account, including its organizations and their IDs (needed for channel and post operations)"}],"triggers":[],"skills":[{"name":"schedule-social-post","description":"Create and schedule a Buffer post on a channel — queued, shared immediately, or at a specific time. Use to publish content to social media.","content":"# Schedule Social Post\\n\\nPublish or schedule a post on a connected Buffer channel.\\n\\n## Steps\\n1. If the channel ID is unknown, use Get Account to find the organization ID, then Get Channels to list channels and pick the right one.\\n2. Use Create Post with the channel ID and the post text.\\n3. Pick the share mode: addToQueue (next open queue slot), shareNext (front of the queue), shareNow (publish immediately), or customScheduled with an ISO 8601 dueAt time.\\n4. Optionally attach an image or video (uploaded file or public URL) and set alt text for images.\\n\\n## Output\\nReturn the new post id, its status, the channel, and the scheduled time (dueAt) so the user knows when it will publish."},{"name":"post-with-media","description":"Attach an image or video to a Buffer post from an uploaded file, a previous block output, or a public URL. Use for visual content.","content":"# Post With Media\\n\\nCreate a Buffer post with an image or video attachment.\\n\\n## Steps\\n1. Provide the media as an uploaded file, a file reference from a previous block (e.g. an image-generation output), or a publicly accessible URL.\\n2. Use Create Post with the channel ID, caption text, and the media input — Buffer detects images vs videos automatically.\\n3. For images, set alt text to keep posts accessible.\\n4. Choose the share mode and, for customScheduled, the dueAt publish time.\\n\\n## Output\\nReturn the post id, status, and the attached asset details (type and source URL) from the response."},{"name":"review-post-queue","description":"List scheduled, draft, sent, or failed posts across channels with pagination. Use to inspect what is coming up or what already went out.","content":"# Review Post Queue\\n\\nInspect posts in a Buffer organization.\\n\\n## Steps\\n1. Use Get Account to find the organization ID if unknown.\\n2. Use Get Posts with the organization ID; filter by comma-separated channel IDs and statuses (draft, needs_approval, scheduled, sending, sent, error).\\n3. Sort by dueAt ascending to see the upcoming schedule, or createdAt descending for recent activity.\\n4. Page through results with pageInfo.endCursor passed as the cursor until hasNextPage is false.\\n\\n## Output\\nReturn a concise list per post: id, channel service, status, due/sent time, and a text preview. Note any posts in error status."},{"name":"fix-failed-posts","description":"Find Buffer posts that failed to publish, read their errors, and reschedule them. Use to recover from publishing failures.","content":"# Fix Failed Posts\\n\\nRecover posts that failed to publish.\\n\\n## Steps\\n1. Use Get Posts filtered to status error to find failed posts.\\n2. Read each post\'s error message (and support URL) to understand why it failed.\\n3. If the content needs adjusting, use Edit Post to update the text or media.\\n4. Reschedule by editing the post with mode addToQueue or customScheduled and a new dueAt, or delete it with Delete Post if it is no longer wanted.\\n\\n## Output\\nReturn a summary per failed post: the failure reason and the action taken (rescheduled, edited, or deleted)."},{"name":"capture-content-idea","description":"Save a content idea to Buffer\'s ideas board for later drafting. Use when inspiration arrives before it is ready to schedule.","content":"# Capture Content Idea\\n\\nSave rough content to Buffer\'s ideas board.\\n\\n## Steps\\n1. Use Get Account to find the organization ID if unknown.\\n2. Use Create Idea with the organization ID and the idea text; add a short title so it is easy to scan on the board.\\n3. Optionally place it in a specific idea group (board column) — use Get Idea Groups to find the group ID.\\n\\n## Output\\nReturn the idea id and title, and confirm it is saved on the ideas board ready to be drafted into posts."}],"templates":[{"title":"Buffer blog-to-social queue","prompt":"Build a workflow that takes a blog post URL and summary, writes a short social caption for it, and adds a Buffer post to the queue for each connected channel returned by Get Channels.","integrations":[{"id":"buffer","name":"Buffer"}]},{"title":"Buffer weekly content calendar","prompt":"Create a workflow that reads next week\'s content calendar from a table and creates a custom-scheduled Buffer post for each row with its channel, caption, and publish time, then writes the new post IDs back to the table.","integrations":[{"id":"buffer","name":"Buffer"}]},{"title":"Buffer post from generated art","prompt":"Build a workflow that generates an on-brand image with an AI image model, writes a matching caption, and creates a Buffer post with the image attached, scheduled for tomorrow morning.","integrations":[{"id":"buffer","name":"Buffer"}]},{"title":"Buffer failed-post alert to Slack","prompt":"Create a scheduled workflow that lists Buffer posts with status error, and for each failed post sends a Slack alert with the channel, the post text, and the publishing error message so the team can fix and reschedule it.","integrations":[{"id":"buffer","name":"Buffer"},{"id":"slack","name":"Slack"}]},{"title":"Buffer daily queue health check","prompt":"Build a scheduled daily workflow that gets all Buffer channels, flags any with a paused queue or disconnected account, counts scheduled posts per channel for the next 3 days, and emails a digest highlighting channels with an empty queue.","integrations":[{"id":"buffer","name":"Buffer"}]},{"title":"Buffer ideas from Slack","prompt":"Create a workflow triggered by a Slack message in the content-ideas channel that cleans up the message text and saves it as a Buffer idea with a short title so the marketing team can draft it later.","integrations":[{"id":"buffer","name":"Buffer"},{"id":"slack","name":"Slack"}]},{"title":"Buffer launch announcement","prompt":"Build a workflow that takes launch notes, writes a tailored announcement per social network, and shares a Buffer post immediately on every connected channel, then reports the external links of the published posts.","integrations":[{"id":"buffer","name":"Buffer"}]},{"title":"Buffer evergreen recycler","prompt":"Create a scheduled weekly workflow that lists Buffer posts sent more than 90 days ago, picks the top evergreen ones, refreshes their captions, and re-adds them to the queue as new posts.","integrations":[{"id":"buffer","name":"Buffer"}]}]},{"id":"calcom","type":"calcom","slug":"cal-com","name":"Cal.com","description":"Manage Cal.com bookings, event types, schedules, and availability","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/calcom","authType":"oauth","connections":[{"id":"calcom","kind":"oauth","label":"Connect with OAuth","providerId":"calcom","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/calcom","requiredScopes":[],"fields":[]},{"id":"calcom-service-account","kind":"service_account","providerId":"calcom-service-account","label":"Add API key","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/calcom-service-account","fields":[{"id":"apiToken","label":"API key","placeholder":"cal_live_...","secret":true,"hint":"Cal.com API keys usually start with cal_."}]}],"operations":[{"name":"List Bookings","description":"List all bookings with optional status filter"},{"name":"Create Booking","description":"Create a new booking on Cal.com"},{"name":"Get Booking","description":"Get details of a specific booking by its UID"},{"name":"Cancel Booking","description":"Cancel an existing booking"},{"name":"Reschedule Booking","description":"Reschedule an existing booking to a new time"},{"name":"Confirm Booking","description":"Confirm a pending booking that requires confirmation"},{"name":"Decline Booking","description":"Decline a pending booking request"},{"name":"Create Event Type","description":"Create a new event type in Cal.com"},{"name":"Get Event Type","description":"Get detailed information about a specific event type"},{"name":"List Event Types","description":"Retrieve a list of all event types"},{"name":"Update Event Type","description":"Update an existing event type in Cal.com"},{"name":"Delete Event Type","description":"Delete an event type from Cal.com"},{"name":"Create Schedule","description":"Create a new availability schedule in Cal.com"},{"name":"Get Schedule","description":"Get a specific schedule by ID from Cal.com"},{"name":"List Schedules","description":"List all availability schedules from Cal.com"},{"name":"Update Schedule","description":"Update an existing schedule in Cal.com"},{"name":"Delete Schedule","description":"Delete a schedule from Cal.com"},{"name":"Get Default Schedule","description":"Get the default availability schedule from Cal.com"},{"name":"Get Available Slots","description":"Get available booking slots for a Cal.com event type within a time range"}],"triggers":[{"id":"calcom_booking_created","name":"CalCom Booking Created","description":"Trigger workflow when a new booking is created in Cal.com"},{"id":"calcom_booking_cancelled","name":"CalCom Booking Cancelled","description":"Trigger workflow when a booking is cancelled in Cal.com"},{"id":"calcom_booking_rescheduled","name":"CalCom Booking Rescheduled","description":"Trigger workflow when a booking is rescheduled in Cal.com"},{"id":"calcom_booking_requested","name":"CalCom Booking Requested","description":"Trigger workflow when a booking request is submitted (pending confirmation)"},{"id":"calcom_booking_rejected","name":"CalCom Booking Rejected","description":"Trigger workflow when a booking request is rejected by the host"},{"id":"calcom_booking_paid","name":"CalCom Booking Paid","description":"Trigger workflow when payment is completed for a paid booking"},{"id":"calcom_meeting_ended","name":"CalCom Meeting Ended","description":"Trigger workflow when a Cal.com meeting ends"},{"id":"calcom_recording_ready","name":"CalCom Recording Ready","description":"Trigger workflow when a meeting recording is ready for download"},{"id":"calcom_webhook","name":"CalCom Webhook (All Events)","description":"Trigger workflow on any Cal.com webhook event (configure event types in Cal.com)"}],"skills":[{"name":"book-a-meeting","description":"Create a Cal.com booking for an attendee on a chosen event type and time. Use to schedule a call once you know the slot and attendee details.","content":"# Book A Meeting\\n\\nCreate a confirmed Cal.com booking.\\n\\n## Steps\\n1. Identify the event type to book (select it or pass its numeric event type id).\\n2. Set the Start Time as an ISO 8601 UTC timestamp.\\n3. Provide the attendee name, email, and IANA time zone (e.g. America/New_York). Add guests or a duration override if needed.\\n4. Create the booking.\\n\\n## Output\\nReturn the booking UID, start and end time, attendee, and the meeting URL. Confirm the booking to the user. If the slot is unavailable, suggest checking available slots first and propose alternatives."},{"name":"find-available-slots","description":"Look up open time slots for a Cal.com event type within a date range. Use before booking to offer the attendee valid times.","content":"# Find Available Slots\\n\\nRetrieve bookable time slots for an event type.\\n\\n## Steps\\n1. Select the event type (or pass its id, or an event type slug plus username).\\n2. Set the Start Time and End Time of the window to search (ISO 8601 UTC).\\n3. Set the attendee time zone so slots are returned in their local time, and a duration if the event supports multiple lengths.\\n4. Read the returned slots.\\n\\n## Output\\nReturn the available slots as a clean list of start times in the requested time zone. Summarize the next few openings for the user; if none exist in the window, widen the range and retry."},{"name":"reschedule-or-cancel-booking","description":"Move a Cal.com booking to a new time or cancel it, with a reason. Use to handle change or cancellation requests for an existing booking.","content":"# Reschedule Or Cancel Booking\\n\\nChange or cancel an existing Cal.com booking.\\n\\n## Steps\\n1. Identify the booking by its UID (use List Bookings to find it if you only have attendee or date details).\\n2. To move it, use Reschedule Booking with the new Start Time (ISO 8601) and an optional rescheduling reason.\\n3. To cancel, use Cancel Booking with an optional cancellation reason.\\n4. For request-based event types, use Confirm Booking or Decline Booking instead.\\n\\n## Output\\nReturn the booking UID and its new status (rescheduled, cancelled, confirmed, or declined) plus the updated time when applicable. Confirm the change to the user."},{"name":"summarize-upcoming-bookings","description":"List and summarize upcoming Cal.com bookings for a period. Use for a daily agenda or to brief a host on their schedule.","content":"# Summarize Upcoming Bookings\\n\\nProduce an agenda from Cal.com bookings.\\n\\n## Steps\\n1. Use List Bookings with status Upcoming.\\n2. For each booking, read the title, start/end time, attendees, and meeting URL.\\n3. Sort chronologically and group by day if the range spans multiple days.\\n\\n## Output\\nReturn an ordered agenda: each entry with time, title, attendee name, and join link. Add a short headline like the number of meetings and the first start time so the host gets a quick read on the day."}],"templates":[{"title":"Cal.com booking prep brief","prompt":"Build a workflow that runs 30 minutes before a Cal.com booking, researches the attendee with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"apollo","name":"Apollo"},{"id":"gmail","name":"Gmail"}]},{"title":"Cal.com post-meeting recap","prompt":"Create a workflow that runs after a Cal.com meeting ends, summarizes the meeting notes, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Cal.com no-show recovery","prompt":"Build a workflow that detects Cal.com no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"gmail","name":"Gmail"}]},{"title":"Cal.com + Loops nurture","prompt":"Create a workflow that on a Cal.com booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"loops","name":"Loops"}]},{"title":"Cal.com round-robin balancer","prompt":"Build a workflow that watches Cal.com round-robin assignments, ensures equitable distribution across the team weekly, and adjusts the weights based on capacity.","integrations":[{"id":"calcom","name":"Cal.com"}]},{"title":"Cal.com webhook to CRM","prompt":"Create a workflow triggered by a Cal.com booking webhook that creates or updates the contact in HubSpot, sets the lifecycle stage, and assigns the right owner.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Cal.com reschedule chaser","prompt":"Build a scheduled workflow that finds Cal.com bookings that have been rescheduled more than twice, posts a Slack alert to the host, and proposes a fixed time.","integrations":[{"id":"calcom","name":"Cal.com"},{"id":"slack","name":"Slack"}]}]},{"id":"calendly","type":"calendly","slug":"calendly","name":"Calendly","description":"Manage Calendly scheduling and events","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/calendly","authType":"api-key","connections":[],"operations":[{"name":"Get Current User","description":"Get information about the currently authenticated Calendly user"},{"name":"Get User","description":"Get information about a specific Calendly user"},{"name":"List Event Types","description":"Retrieve a list of all event types for a user or organization"},{"name":"Get Event Type","description":"Get detailed information about a specific event type"},{"name":"List Event Type Available Times","description":"Retrieve bookable time slots for an event type within a date range"},{"name":"List Scheduled Events","description":"Retrieve a list of scheduled events for a user or organization"},{"name":"Get Scheduled Event","description":"Get detailed information about a specific scheduled event"},{"name":"List Event Invitees","description":"Retrieve a list of invitees for a scheduled event"},{"name":"Get Event Invitee","description":"Retrieve a single invitee of a scheduled event, including their intake answers"},{"name":"Book Meeting","description":"Book a meeting by creating an invitee on an event type at a chosen time. Requires a paid Calendly plan"},{"name":"Cancel Event","description":"Cancel a scheduled event"},{"name":"Mark Invitee No-Show","description":"Mark an invitee of a scheduled event as a no-show"},{"name":"Unmark Invitee No-Show","description":"Remove the no-show status from an invitee"},{"name":"Create Scheduling Link","description":"Create a single-use scheduling link for an event type"},{"name":"List User Busy Times","description":"Retrieve a user\'s internal and external busy times within a date range, based on their connected calendars"},{"name":"List User Availability Schedules","description":"Retrieve a user\'s availability schedules, working hours, and date overrides"},{"name":"List Organization Memberships","description":"Retrieve the members of an organization, including each member profile and role"},{"name":"List Routing Forms","description":"Retrieve the routing forms of an organization, including their questions"},{"name":"List Routing Form Submissions","description":"Retrieve the submissions of a routing form, including answers and routing result"}],"triggers":[{"id":"calendly_invitee_created","name":"Calendly Invitee Created","description":"Trigger workflow when someone schedules a new event on Calendly"},{"id":"calendly_invitee_canceled","name":"Calendly Invitee Canceled","description":"Trigger workflow when someone cancels a scheduled event on Calendly"},{"id":"calendly_routing_form_submitted","name":"Calendly Routing Form Submitted","description":"Trigger workflow when someone submits a Calendly routing form"},{"id":"calendly_webhook","name":"Calendly Webhook","description":"Trigger workflow from any Calendly webhook event"}],"skills":[{"name":"book-a-meeting","description":"Find an open slot on a Calendly event type and book an invitee into it. Use to schedule a meeting end to end without sending the invitee a link.","content":"# Book a Meeting\\n\\nSchedule a Calendly meeting directly.\\n\\n## Steps\\n1. Use List Event Types to find the event type to book, and take its URI.\\n2. Use List Event Type Available Times with that event type and a start/end window (ISO 8601 UTC, at most 31 days apart) to get open slots.\\n3. Pick a slot and use Book Meeting with the event type, the slot start time, and the invitee email, timezone, and name. Add event guests to copy others on the invite.\\n\\n## Output\\nReturn the booked start time, the invitee, and the reschedule and cancel URLs. Booking requires a paid Calendly plan; if the call is rejected as forbidden, say so rather than retrying. If no slot matches the request, report the nearest available times instead of booking a different one."},{"name":"check-availability","description":"Read a Calendly user\'s busy times and working hours for a date range. Use to find when someone is free before proposing times.","content":"# Check Availability\\n\\nInspect when a host is free.\\n\\n## Steps\\n1. Get the user URI (Get Current User for yourself, or List Organization Memberships to find a teammate by email).\\n2. Use List User Busy Times with that user and a start/end window (ISO 8601 UTC, at most 7 days apart) to get booked and externally blocked time.\\n3. Use List User Availability Schedules to read the working hours and date overrides the busy times sit inside.\\n\\n## Output\\nReturn the free windows implied by the working hours minus the busy blocks, in the schedule\'s timezone. Note which busy blocks are Calendly events versus external calendar holds. Both endpoints cap the range, so split a longer request into several calls rather than widening the window."},{"name":"share-a-single-use-link","description":"Create a one-time Calendly booking link for an event type. Use to invite someone to schedule without exposing a reusable link.","content":"# Share a Single-Use Link\\n\\nHand out a booking link that works once.\\n\\n## Steps\\n1. Use List Event Types to find the event type and take its URI.\\n2. Use Create Scheduling Link with that event type.\\n3. Send the returned booking URL to the invitee.\\n\\n## Output\\nReturn the booking URL and the event type it books. Make clear the link expires after one booking, so generate a new one per invitee rather than reusing it."},{"name":"mark-a-no-show","description":"Flag a Calendly invitee who did not attend, or clear that flag. Use when reconciling attendance after a meeting.","content":"# Mark a No-Show\\n\\nRecord attendance for a past meeting.\\n\\n## Steps\\n1. Use List Event Invitees for the scheduled event and take the URI of the invitee who did not attend.\\n2. Use Mark Invitee No-Show with that invitee URI.\\n3. To reverse it, take the no-show URI from the invitee record and use Unmark Invitee No-Show.\\n\\n## Output\\nReturn which invitees were marked and the no-show URI for each, so the flag can be reversed later. Only mark meetings that have already ended."},{"name":"list-upcoming-meetings","description":"Pull upcoming Calendly scheduled events for a date range and summarize them. Use to brief a host on their schedule or build a daily agenda.","content":"# List Upcoming Meetings\\n\\nSummarize upcoming Calendly events.\\n\\n## Steps\\n1. Use List Scheduled Events. Filter to status active and set Min Start Time and Max Start Time (ISO 8601 UTC) for the window.\\n2. Filter by user or organization URI when scoping to a specific host (Get Current User returns your URI if needed).\\n3. For each event, read name, start_time, end_time, location, and scheduling_url; page with the page token if there are many.\\n\\n## Output\\nReturn an ordered agenda: each meeting with time, name, location/join link, and the invitee. Add a one-line headline (count and first start time) for a quick read."},{"name":"get-event-attendees","description":"Retrieve the invitees for a Calendly scheduled event, including answers and contact info. Use to prep for a meeting or sync attendees to a CRM.","content":"# Get Event Attendees\\n\\nList who is attending a Calendly event.\\n\\n## Steps\\n1. Identify the scheduled event by its UUID or URI (use List Scheduled Events to locate it).\\n2. Use List Event Invitees for that event; optionally filter by email or status.\\n3. Read each invitee record: name, email, status, and any questions and answers captured at booking.\\n\\n## Output\\nReturn the invitees with name, email, status, and their intake answers. Flag canceled or no-show invitees so they can be handled differently from confirmed attendees."},{"name":"cancel-scheduled-event","description":"Cancel a Calendly scheduled event with an optional reason. Use to call off a meeting and notify the invitee through Calendly.","content":"# Cancel Scheduled Event\\n\\nCall off a Calendly meeting.\\n\\n## Steps\\n1. Find the scheduled event UUID or URI (use List Scheduled Events filtered by invitee email or time if you only have those details).\\n2. Use Cancel Event with the event UUID and a clear cancellation reason.\\n3. Calendly notifies the invitee automatically.\\n\\n## Output\\nReturn the event UUID and confirmation that it was canceled. Echo the reason. If the event is already canceled or cannot be found, report that instead of retrying."}],"templates":[{"title":"AgentPhone appointment reminder","prompt":"Build a workflow that reads upcoming Calendly bookings and sends an AgentPhone SMS reminder to each attendee, then texts a confirmation when they reply.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"agentphone","name":"AgentPhone"}]},{"title":"Calendly booking follow-up","prompt":"Build a workflow that monitors new Calendly bookings, researches each attendee and their company, prepares a pre-meeting brief with relevant context, and sends a personalized confirmation email with an agenda and any prep materials.","integrations":[{"id":"calendly","name":"Calendly"}]},{"title":"Calendly meeting-prep brief","prompt":"Build a workflow that runs 30 minutes before a Calendly booking, researches the attendee and company with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"apollo","name":"Apollo"},{"id":"gmail","name":"Gmail"}]},{"title":"Calendly post-meeting recap","prompt":"Create a workflow that runs after a Calendly meeting ends, pulls the meeting notes from the calendar, writes a CRM-ready summary, and updates the linked Salesforce opportunity.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Calendly no-show recovery","prompt":"Build a workflow that detects Calendly no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"gmail","name":"Gmail"}]},{"title":"Calendly + Loops nurture","prompt":"Create a workflow that on a Calendly booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic, ensuring follow-up emails reach them before the meeting.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"loops","name":"Loops"}]},{"title":"Calendly no-show tracker","prompt":"Build a scheduled workflow that lists yesterday\'s Calendly scheduled events, checks invitee status to find no-shows, logs them to a table for follow-up, and posts a recap of attended versus missed meetings to Slack.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"slack","name":"Slack"}]},{"title":"Calendly booking prep brief","prompt":"Create a workflow that on a new Calendly booking fetches the scheduled event and invitee details, researches the attendee and their company, and emails the meeting owner a one-page prep brief before the call.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"gmail","name":"Gmail"}]},{"title":"Booking-to-calendar scheduler","prompt":"Build a workflow that on a new Calendly booking creates the matching Google Calendar event, invites the attendees, attaches the meeting agenda, and writes the event link back so both systems stay in sync.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Lemlist interested-lead booker","prompt":"Build a workflow triggered when a Lemlist lead is marked interested that drafts a Calendly link tailored to the lead, replies to them through Lemlist with the link, and creates a follow-up task for the rep.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"lemlist","name":"Lemlist"}]},{"title":"Stripe customer welcome flow","prompt":"Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.","integrations":[{"id":"calendly","name":"Calendly"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]}]},{"id":"cbinsights","type":"cbinsights","slug":"cb-insights","name":"CB Insights","description":"Research private markets — firmographics, funding, and predictive scores","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/cbinsights","authType":"api-key","connections":[],"operations":[{"name":"Look Up Organizations","description":"Resolve company names or websites to CB Insights organization IDs. The integration contract describes lookup as credit-free; confirm current credit terms with CB Insights before requesting paid datasets."},{"name":"Search Firmographics","description":"Search profiles of private companies, public companies, and investors by market, industry, geography, headcount, funding, and valuation. Each field is ANDed together; values within a field are ORed."},{"name":"Get Organization Fundings","description":"Retrieve the funding rounds one organization has received, its cap table history, and AI-generated insights extracting the key themes of each deal."},{"name":"Get Organization Investments","description":"Retrieve the rounds in which one organization invested in another, with AI-generated insights extracting the key themes of each deal."},{"name":"Get Organization Portfolio Exits","description":"Retrieve exit rounds for companies this organization invested in before the exit, with AI-generated insights on each deal."},{"name":"Get Organization Business Relationships","description":"Retrieve one organization\'s partnerships, client/vendor relationships, and licensing activity, with AI-generated insights on each."},{"name":"Get Organization Management and Board","description":"Retrieve an organization\'s leadership team and board members with their education, work history, and board seats, plus the Management factor of its Mosaic Score."},{"name":"Get Organization Outlook","description":"Retrieve an organization\'s current Mosaic Score, Commercial Maturity level, and two-year IPO and M&A exit probabilities, with the signals driving each."},{"name":"Get Organization Funding Window","description":"Retrieve the estimated window in which an organization is likely to raise its next round, with the cohort it was compared against."},{"name":"Get Organization Revenue","description":"Retrieve reported and estimated revenue by calendar year for one organization, with the sources behind each figure."},{"name":"Get Mosaic History","description":"Retrieve an organization\'s historical Mosaic Scores — overall plus the management, market, momentum, and money factors — so a trend can be read rather than a single snapshot."},{"name":"Get Commercial Maturity History","description":"Retrieve an organization\'s historical Commercial Maturity levels, tracking how its ability to compete for customers or serve as a partner has moved over time."},{"name":"Get Exit Probability History","description":"Retrieve an organization\'s historical two-year IPO and M&A exit probabilities, each alongside the mean for comparable companies."},{"name":"Get Strategy Map","description":"Retrieve the companies related to an organization, grouped into industry categories, with the relationships, investments, and acquisitions that connect them."},{"name":"Get Scouting Report","description":"Generate an AI-written Scouting Report on a private company covering its business model, market position, strengths, and opportunities. Only active companies are eligible, and generation can take several minutes."},{"name":"List Fundings","description":"Retrieve funding rounds and cap table history for up to 100 organizations at once, with AI-generated insights extracting the key themes of each deal."},{"name":"List Investments","description":"Retrieve the rounds up to 100 organizations participated in as investors, with AI-generated insights extracting the key themes of each deal."},{"name":"List Portfolio Exits","description":"Retrieve exit rounds for companies up to 100 organizations invested in before the exit, with AI-generated insights on each deal."},{"name":"List Business Relationships","description":"Retrieve partnerships, client/vendor relationships, and licensing activity for up to 100 organizations at once, with AI-generated insights on each."},{"name":"List Management and Board","description":"Retrieve leadership teams, board members, and the Management factor of the Mosaic Score for up to 100 organizations at once."},{"name":"List Outlook","description":"Retrieve Mosaic Score, Commercial Maturity, and Exit Probability for up to 100 organizations at once."},{"name":"List Funding Windows","description":"Retrieve the estimated next-round funding window for up to 100 organizations at once, with the cohort each was compared against."},{"name":"List Revenue","description":"Retrieve reported and estimated revenue by calendar year for up to 100 organizations at once."},{"name":"Ask ChatCBI","description":"Ask ChatCBI a question in natural language and get an answer grounded in CB Insights data, with its sources and suggested follow-ups. Uses generative AI and can be wrong — verify anything that matters."},{"name":"Retrieve Context","description":"Retrieve the raw structured CB Insights data relevant to a question, for feeding your own model rather than reading a written answer. Uses generative AI and can be wrong — verify anything that matters."}],"triggers":[],"skills":[{"name":"enrich-account-firmographics","description":"Resolve a company to its CB Insights ID and pull firmographics onto the record. Use to fill in accounts before scoring, routing, or outreach.","content":"# Enrich Account Firmographics\\n\\nTurn a company name or domain into a complete CB Insights profile.\\n\\n## Steps\\n1. Run Look Up Organizations on the name or website to get the orgId. This call never charges credits, so resolve first and confirm the match before spending any.\\n2. Run Search Firmographics with that orgId to pull the summary, taxonomy, headcount, financials, and identifiers.\\n3. Merge the returned fields onto the record, keeping existing values where CB Insights returned nothing.\\n\\n## Output\\nReport the matched orgId and the fields filled. Flag a name that resolved to nothing or matched more than one plausible company."},{"name":"build-icp-target-list","description":"Search firmographics against an ideal customer profile and page the full result set into a list. Use for territory and campaign planning.","content":"# Build ICP Target List\\n\\nTurn an ICP description into a paged list of matching companies.\\n\\n## Steps\\n1. Translate the ICP into firmographics filters — marketNames or marketIds, sectorIds, countryIds, the headcount range, and the funding or valuation range.\\n2. Run Search Firmographics, sorting by mosaicOverall so the strongest companies lead.\\n3. Page forward by passing the returned nextPageToken until it comes back null.\\n4. Write the deduplicated companies to a table.\\n\\n## Output\\nReport totalHits, how many rows were retrieved, and the filters used. Note when totalHitsRelation is \\"gte\\", which means the true total exceeds 10,000."},{"name":"screen-exit-probability","description":"Read the outlook for a set of companies and rank them by two-year exit probability against their peer mean. Use for pipeline and portfolio prioritization.","content":"# Screen Exit Probability\\n\\nRank companies by how likely they are to exit in the next two years.\\n\\n## Steps\\n1. Run List Outlook for up to 100 orgIds at a time.\\n2. For each company read the IPO and M&A probabilities together with meanProbability and ratioToMean — the ratio matters more than the raw number, because it is peer-adjusted.\\n3. Note any company whose incompleteRoundType is set: a pending round zeroes every probability, so it is not a real low score.\\n4. Rank the remainder and write the screen to a table.\\n\\n## Output\\nReport the ranked companies with both exit types and the peer ratio. List separately the companies excluded for a pending or rumored round."},{"name":"track-funding-history","description":"Pull the funding rounds and cap table history of a company and summarize how its terms evolved. Use for diligence and deal prep.","content":"# Track Funding History\\n\\nAssemble what a company has raised and on what terms.\\n\\n## Steps\\n1. Resolve the company with Look Up Organizations, then run Get Organization Fundings.\\n2. Read the fundings array for round, date, amountInMillions, valuationInMillions, and investors.\\n3. Read capTableHistory for issuance and conversion prices, percentage owned, and the terms object — liquidation preference, participation rights, and anti-dilution provision.\\n4. Page with nextPageToken until it comes back null.\\n\\n## Output\\nSummarize the round-by-round progression, calling out valuation step-ups or downs and any unusual terms. Say plainly when a value is not published rather than reporting it as zero."},{"name":"generate-company-brief","description":"Generate a CB Insights Scouting Report and turn it into a readable brief. Use before a meeting, an investment, or a partnership conversation.","content":"# Generate Company Brief\\n\\nProduce a one-page brief on a private company.\\n\\n## Steps\\n1. Resolve the company with Look Up Organizations. Only active companies are eligible for a Scouting Report.\\n2. Run Get Scouting Report. Generation can take several minutes — expect the call to be slow rather than treating it as hung.\\n3. Use reportMarkdown when citations matter; reportJson omits the citation links.\\n4. Pair the report with orgInfo for headcount, funding, Mosaic score, and commercial maturity.\\n\\n## Output\\nReturn the brief with its citations intact. Note that the report is AI-generated and state which claims were not corroborated by the structured fields."},{"name":"map-competitor-strategy","description":"Read a competitor\'s strategy map and summarize where it is partnering, investing, and acquiring. Use for competitive monitoring.","content":"# Map Competitor Strategy\\n\\nRead a competitor\'s posture from who it is connected to.\\n\\n## Steps\\n1. Resolve the competitor with Look Up Organizations, then run Get Strategy Map.\\n2. Walk the categories array; within each, read every company and its connections — businessRelationships, investments, and acquisitions.\\n3. Group by category to see where the activity concentrates, and read the AI-generated insights attached to each connection.\\n\\n## Output\\nReport the categories ranked by connection count, naming the notable companies in each and whether the tie is a partnership, an investment, or an acquisition."},{"name":"prune-and-refresh-mirror","description":"Refresh a mirrored company table from CB Insights in bulk without exhausting credits. Use to keep a local copy current.","content":"# Prune and Refresh Mirror\\n\\nKeep a mirrored company table in step with CB Insights.\\n\\n## Steps\\n1. Batch the stored orgIds into groups of 100 — every list endpoint caps there.\\n2. Use the multi-organization operations (List Outlook, List Revenue, List Funding Windows) rather than the per-organization ones; one call covers a hundred records.\\n3. Note that an organization with no data is omitted from the response rather than returned empty — treat a missing orgId as \\"no data\\", not as an error.\\n4. Write the refreshed values back, leaving untouched any row the response did not cover.\\n\\n## Output\\nReport how many organizations were requested, how many came back with data, and which were omitted."}],"templates":[{"title":"CB Insights account enrichment","prompt":"Create a workflow that watches my accounts table for new company names, resolves each to a CB Insights organization ID with the free lookup, pulls firmographics and the Mosaic Score, and writes headcount, sector, funding stage, and score back to the row.","integrations":[{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights ICP company list","prompt":"Build a workflow that searches CB Insights firmographics for companies matching my ideal customer profile — market, headcount band, funding raised, and headquarters country — pages through every result, and writes the list to a table for the SDR team.","integrations":[{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights exit probability watchlist","prompt":"Create a scheduled workflow that reads the outlook for every company on my watchlist, flags any whose two-year IPO or M&A exit probability moved meaningfully against its peer mean, and posts the changes to Slack.","integrations":[{"id":"cbinsights","name":"CB Insights"},{"id":"slack","name":"Slack"}]},{"title":"CB Insights funding window alerts","prompt":"Build a workflow that checks the estimated funding window for each company in my pipeline every week and emails me the ones entering their window in the next 60 days, with the cohort rate and their last round.","integrations":[{"id":"cbinsights","name":"CB Insights"},{"id":"gmail","name":"Gmail"}]},{"title":"CB Insights scouting report brief","prompt":"Create an agent that takes a company name, resolves it in CB Insights, generates a Scouting Report, and turns the business model, market position, strengths, and opportunities into a one-page brief I can take into a meeting.","integrations":[{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights leadership tracker","prompt":"Build a workflow that pulls management and board data for my target accounts, extracts each executive with their title, education, and prior roles, and writes the buying committee to a table so reps know who to engage.","integrations":[{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights competitor strategy map","prompt":"Create a workflow that takes a competitor, pulls its CB Insights strategy map, and summarizes which categories it is investing in, partnering across, and acquiring into — then posts the summary to my strategy channel.","integrations":[{"id":"cbinsights","name":"CB Insights"},{"id":"slack","name":"Slack"}]},{"title":"CB Insights portfolio exit digest","prompt":"Build a scheduled workflow that reads portfolio exits for the investors I track, summarizes each exit with the company, round, and amount, and emails a weekly digest to the investment team.","integrations":[{"id":"cbinsights","name":"CB Insights"},{"id":"gmail","name":"Gmail"}]},{"title":"CB Insights market research agent","prompt":"Create an agent that answers private-market questions by asking ChatCBI, then verifies the claims against firmographics and funding data before returning an answer with its sources.","integrations":[{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights revenue growth screen","prompt":"Build a workflow that pulls revenue by year for my target list, computes year-over-year growth, ranks the companies by it, and writes the ranked screen to a table with the sources behind each figure.","integrations":[{"id":"cbinsights","name":"CB Insights"}]}]},{"id":"checkr","type":"checkr","slug":"checkr","name":"Checkr","description":"Run and manage background checks with Checkr","category":"HR","docsUrl":"https://docs.sim.ai/integrations/checkr","authType":"api-key","connections":[],"operations":[{"name":"List Candidates","description":"List candidates, optionally filtered by email, name, custom ID, adjudication, dates, geo, or program. Candidates with non-US work locations are not returned."},{"name":"Get Candidate","description":"Retrieve a candidate by ID, including their report and geo IDs."},{"name":"Create Candidate","description":"Create a candidate to screen. Only email is required when the candidate will be invited; ordering a report directly also needs name, date of birth, and the PII its package requires."},{"name":"Update Candidate","description":"Update a candidate. Once a report is ordered only empty fields can change, except email, phone, previous driver license, copy requested, custom ID, and geo IDs."},{"name":"Delete Candidate PII","description":"Request removal of a candidate\'s personally identifiable information. Fails if PII was already removed."},{"name":"Invite Candidate","description":"Invite a candidate to complete a background check through the Checkr-hosted apply flow. Checkr emails the candidate a link to provide their information and consent."},{"name":"List Invitations","description":"List invitations, optionally filtered by candidate or status."},{"name":"Get Invitation","description":"Retrieve an invitation by ID, including its status and invitation URL."},{"name":"Cancel Invitation","description":"Cancel a pending invitation so the candidate can no longer complete it."},{"name":"Order Report","description":"Order a background check report for a candidate using a package. Use only when you collect the candidate’s PII and consent yourself; otherwise create an invitation. Packages with international screenings must use invitations."},{"name":"Get Report","description":"Retrieve a report by ID, including its status, result, adjudication, and the IDs of each screening it ran."},{"name":"Update Report","description":"Upgrade a report to a different package or mark it as engaged. Provide a package, an adjudication, or both."},{"name":"Complete Report","description":"Complete a report now, canceling any pending or suspended screenings. Canceled screenings record a cancellation reason."},{"name":"Get Report ETA","description":"Retrieve the estimated completion date for a report."},{"name":"Get Report Checkpoints","description":"Retrieve checkpoint progress for an Enterprise Progressive report, including which checkpoint is waiting on a review action."},{"name":"Apply Report Review Action","description":"Continue or skip the remaining screenings on a report that is paused awaiting a review action."},{"name":"Get Report Tags","description":"List the tags on a report."},{"name":"Add Report Tag","description":"Add a tag to a report, keeping its existing tags."},{"name":"Set Report Tags","description":"Replace all tags on a report with the given list. Pass [] to remove every tag."},{"name":"Remove Report Tag","description":"Remove a tag from a report."},{"name":"List Adverse Items","description":"List the adverse items on a report that can be cited in an adverse action. The report must have a consider result and no active adverse action."},{"name":"List Assessments","description":"List the Assess results for a report, including the ruleset applied and which rule flagged each record. Requires Checkr Assess."},{"name":"List Verifications","description":"List the verifications on a report, such as requests for the candidate to confirm their SSN or upload an ID."},{"name":"Get Verification","description":"Retrieve a verification by ID."},{"name":"List Report Addresses","description":"List the address history found for a report."},{"name":"Get Screening","description":"Retrieve the results of one screening in a report, such as an SSN trace, county criminal search, or motor vehicle report. Get the screening ID from the report."},{"name":"Create Adverse Action","description":"Start the adverse action process on a report by sending the pre-adverse action notice. The report must have a consider result and no active adverse action."},{"name":"List Adverse Actions","description":"List the adverse actions for a report, optionally filtered by context."},{"name":"Get Adverse Action","description":"Retrieve an adverse action by ID, including its status and notice delivery state."},{"name":"Cancel Adverse Action","description":"Cancel an adverse action so the post-adverse action notice is not sent."},{"name":"List Packages","description":"List the background check packages on the account, with their slugs, prices, and included screenings."},{"name":"Get Package","description":"Retrieve a package by ID, including its slug, price, and screenings."},{"name":"List Geos","description":"List geos (work locations used for compliance), optionally filtered by name or state."},{"name":"Get Geo","description":"Retrieve a geo by ID."},{"name":"Create Geo","description":"Create a geo to group candidates by work location. A geo with the same name and state already existing returns an error."},{"name":"Update Geo","description":"Add a city to a geo. A geo’s city can only be set once."},{"name":"Delete Geo","description":"Delete a geo."},{"name":"List Nodes","description":"List the nodes in the account hierarchy. Hierarchy-enabled accounts need a node custom ID to order reports and invitations."},{"name":"Get Node","description":"Retrieve an account hierarchy node by its custom ID."},{"name":"List Programs","description":"List programs, which group packages and geos, optionally filtered by name."},{"name":"Get Program","description":"Retrieve a program by ID, including its package and geo IDs."},{"name":"List Counties","description":"List US counties for one or more states, with their FIPS codes. Use the county names in report self-disclosures."},{"name":"Schedule Recurring Check","description":"Schedule a recurring background check for a candidate, running a package every interval starting on a date."},{"name":"List Subscriptions","description":"List recurring check subscriptions, optionally filtered by candidate, status, or creation date."},{"name":"Get Subscription","description":"Retrieve a subscription by ID, including its schedule and next occurrence."},{"name":"Update Subscription","description":"Change the package, schedule, node, or work locations of a subscription."},{"name":"Cancel Subscription","description":"Cancel a subscription so no further recurring checks run."},{"name":"Create Continuous Check","description":"Enroll a candidate in continuous criminal or motor vehicle monitoring so new records trigger a report."},{"name":"List Continuous Checks","description":"List the continuous checks a candidate is enrolled in."},{"name":"Get Continuous Check","description":"Retrieve a continuous check by ID."},{"name":"Update Continuous Check","description":"Change the node or work locations of a continuous check."},{"name":"Cancel Continuous Check","description":"Cancel a continuous check to stop monitoring the candidate."},{"name":"List Candidate Documents","description":"List documents a candidate provided, such as driver licenses and consent forms. Download links expire after 15 minutes."},{"name":"Get Document","description":"Retrieve a report or candidate document by ID, including a download link valid for 15 minutes."},{"name":"Get Account","description":"Retrieve the authenticated Checkr account, including whether it is authorized to order checks and which screenings are available."},{"name":"List Users","description":"List the users on the Checkr account and their roles."}],"triggers":[{"id":"checkr_report_completed","name":"Checkr Report Completed","description":"Trigger workflow when a report is completed"},{"id":"checkr_report_created","name":"Checkr Report Created","description":"Trigger workflow when a report is created"},{"id":"checkr_report_updated","name":"Checkr Report Updated","description":"Trigger workflow when a report is updated, such as an ETA change or drug screening update"},{"id":"checkr_report_upgraded","name":"Checkr Report Upgraded","description":"Trigger workflow when a report is upgraded to another package"},{"id":"checkr_report_suspended","name":"Checkr Report Suspended","description":"Trigger workflow when a report is suspended awaiting candidate documentation"},{"id":"checkr_report_resumed","name":"Checkr Report Resumed","description":"Trigger workflow when a suspended report resumes"},{"id":"checkr_report_paused","name":"Checkr Report Paused","description":"Trigger workflow when a report pauses awaiting a review action"},{"id":"checkr_report_canceled","name":"Checkr Report Canceled","description":"Trigger workflow when a report is canceled"},{"id":"checkr_report_disputed","name":"Checkr Report Disputed","description":"Trigger workflow when a candidate disputes a report"},{"id":"checkr_report_dispute_completed","name":"Checkr Report Dispute Completed","description":"Trigger workflow when a report dispute is resolved"},{"id":"checkr_report_engaged","name":"Checkr Report Engaged","description":"Trigger workflow when a report is adjudicated as engaged"},{"id":"checkr_invitation_created","name":"Checkr Invitation Created","description":"Trigger workflow when an invitation is created"},{"id":"checkr_invitation_completed","name":"Checkr Invitation Completed","description":"Trigger workflow when a candidate completes an invitation"},{"id":"checkr_invitation_expired","name":"Checkr Invitation Expired","description":"Trigger workflow when an invitation expires"},{"id":"checkr_invitation_deleted","name":"Checkr Invitation Canceled","description":"Trigger workflow when an invitation is canceled"},{"id":"checkr_candidate_created","name":"Checkr Candidate Created","description":"Trigger workflow when a candidate is created"},{"id":"checkr_candidate_updated","name":"Checkr Candidate Updated","description":"Trigger workflow when a candidate is updated"},{"id":"checkr_adverse_action_created","name":"Checkr Adverse Action Created","description":"Trigger workflow when an adverse action is created"},{"id":"checkr_adverse_action_completed","name":"Checkr Adverse Action Completed","description":"Trigger workflow when the post-adverse action notice is sent"},{"id":"checkr_adverse_action_canceled","name":"Checkr Adverse Action Canceled","description":"Trigger workflow when an adverse action is canceled"},{"id":"checkr_adverse_action_notice_not_delivered","name":"Checkr Adverse Action Notice Not Delivered","description":"Trigger workflow when an adverse action notice cannot be delivered"},{"id":"checkr_verification_created","name":"Checkr Verification Created","description":"Trigger workflow when a candidate is asked to verify information or upload a document"},{"id":"checkr_verification_completed","name":"Checkr Verification Completed","description":"Trigger workflow when a candidate completes a verification"},{"id":"checkr_verification_processed","name":"Checkr Verification Processed","description":"Trigger workflow when a verification is processed and a decision is made"},{"id":"checkr_continuous_check_subscription_error","name":"Checkr Continuous Check Enrollment Error","description":"Trigger workflow when enrolling a candidate in Continuous MVR fails"},{"id":"checkr_continuous_check_confirmation_required","name":"Checkr Continuous Check Confirmation Required","description":"Trigger workflow when a candidate is unenrolled from Continuous MVR and must be re-enrolled"},{"id":"checkr_report_pre_adverse_action","name":"Checkr Report Pre-Adverse Action Sent","description":"Trigger workflow when the pre-adverse action notice for a report is sent"},{"id":"checkr_report_post_adverse_action","name":"Checkr Report Post-Adverse Action Sent","description":"Trigger workflow when the post-adverse action notice for a report is sent"},{"id":"checkr_adverse_action_paused","name":"Checkr Adverse Action Paused","description":"Trigger workflow when delivery of a post-adverse action notice is paused"},{"id":"checkr_adverse_action_resumed","name":"Checkr Adverse Action Resumed","description":"Trigger workflow when a paused adverse action resumes"},{"id":"checkr_webhook","name":"Checkr All Events","description":"Trigger workflow on any Checkr event"}],"skills":[{"name":"invite-candidate-to-background-check","description":"Create a Checkr candidate and send them a background check invitation for the right package. Use when a candidate is selected or receives an offer.","content":"# Invite Candidate to Background Check\\n\\nStart a Checkr background check for a selected candidate.\\n\\n## Steps\\n1. Search for an existing candidate by email with List Candidates to avoid duplicates.\\n2. If none exists, create the candidate with their email (and name if known).\\n3. List packages to confirm the package slug for the role, unless it was given.\\n4. Create an invitation for the candidate and package. For hierarchy-enabled accounts, include the node and work location.\\n\\n## Output\\nReport the candidate ID, invitation ID, package, invitation URL, and expiry date."},{"name":"summarize-background-check-report","description":"Read a completed Checkr report and summarize its result, adjudication, and the screenings that need attention. Use when a report.completed event arrives or a recruiter asks for status.","content":"# Summarize Background Check Report\\n\\nExplain a Checkr report in plain language for the hiring team.\\n\\n## Steps\\n1. Get the report by ID and note its status, result, package, and adjudication.\\n2. For each screening ID on the report, get the screening and note its status, result, and any records.\\n3. If Assess is enabled, list the report’s assessments and the rules that flagged records.\\n4. Keep PII such as SSN and date of birth out of the summary.\\n\\n## Output\\nA short summary: overall result, screenings that are clear, screenings that need review with the reason, and the recommended next step."},{"name":"check-background-check-status","description":"Report where a candidate’s Checkr background check stands, including invitation status and the report’s estimated completion. Use when a candidate or recruiter asks for an update.","content":"# Check Background Check Status\\n\\nGive an up-to-date status for a candidate’s background check.\\n\\n## Steps\\n1. Find the candidate by email or custom ID with List Candidates.\\n2. List the candidate’s invitations to see whether one is pending, completed, or expired.\\n3. For each report on the candidate, get the report and its ETA.\\n4. If a report is suspended, list its verifications to see what the candidate must provide.\\n\\n## Output\\nThe candidate, invitation status, report status and result, estimated completion date, and any action the candidate still needs to take."},{"name":"start-adverse-action","description":"Run the pre-adverse action step on a consider report by citing its adverse items. Use only after a human has reviewed the report and decided to proceed.","content":"# Start Adverse Action\\n\\nBegin the FCRA adverse action process on a report a reviewer decided not to move forward with.\\n\\n## Steps\\n1. Confirm the reviewer’s decision and the report ID.\\n2. Get the report and confirm its result is consider.\\n3. List the report’s adverse items and select the ones the reviewer cited.\\n4. Create the adverse action with those adverse item IDs, using the default post-notice timing unless told otherwise.\\n\\n## Output\\nThe adverse action ID, status, cited items, and when the post-adverse action notice will be sent."},{"name":"expired-invitation-recovery","description":"Find expired Checkr invitations and reissue them so candidates do not drop out. Use for recruiting operations clean-up.","content":"# Expired Invitation Recovery\\n\\nRecover candidates whose background check invitation lapsed.\\n\\n## Steps\\n1. List invitations with status expired.\\n2. For each, get the candidate and check that they do not already have a newer pending invitation or report.\\n3. Create a new invitation with the same package for candidates who still need one.\\n\\n## Output\\nA list of candidates reinvited, with new invitation IDs and URLs, and candidates skipped with the reason."},{"name":"continuous-monitoring-enrollment","description":"Enroll a hired candidate in Checkr continuous criminal or MVR monitoring. Use for drivers and roles that require ongoing screening.","content":"# Continuous Monitoring Enrollment\\n\\nKeep a hired worker under ongoing screening.\\n\\n## Steps\\n1. Confirm the candidate ID and whether criminal or MVR monitoring is required.\\n2. List the candidate’s continuous checks to avoid duplicate enrollment.\\n3. Create the continuous check, choosing the commercial MVR enrollment type for commercial drivers.\\n\\n## Output\\nThe continuous check ID, type, and candidate, or a note that the candidate was already enrolled."}],"templates":[{"title":"Background check on offer","prompt":"Build a workflow that runs when a candidate reaches the offer stage in Greenhouse, creates the candidate in Checkr with their email, sends a Checkr invitation for the role’s package, and posts the invitation link and status to the hiring channel in Slack.","integrations":[{"id":"checkr","name":"Checkr"},{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Checkr report completed alert","prompt":"Create a workflow triggered by a completed Checkr report that reads the report, summarizes the result and any screenings that need review, and notifies the recruiter in Slack with a clear or consider recommendation.","integrations":[{"id":"checkr","name":"Checkr"},{"id":"slack","name":"Slack"}]},{"title":"Consider report review queue","prompt":"Build a workflow that runs when a Checkr report completes with a consider result, pulls the report’s assessments and the records from each criminal screening, drafts an individualized assessment summary for the adjudicator, and logs the case to a review table.","integrations":[{"id":"checkr","name":"Checkr"}]},{"title":"Expired invitation follow-up","prompt":"Create a workflow triggered when a Checkr invitation expires that looks up the candidate, sends a friendly reminder email explaining the next steps, creates a fresh invitation for the same package, and records the follow-up in a tracking table.","integrations":[{"id":"checkr","name":"Checkr"},{"id":"gmail","name":"Gmail"}]},{"title":"Background check status digest","prompt":"Build a scheduled daily workflow that lists pending Checkr invitations, reads each invited candidate’s reports and their estimated completion dates, and sends the hiring team a digest of who is waiting, what is delayed, and which candidates need to act.","integrations":[{"id":"checkr","name":"Checkr"},{"id":"slack","name":"Slack"}]},{"title":"Clear report to onboarding","prompt":"Create a workflow that runs when a Checkr report completes with a clear result, engages the report, tags it as onboarded, and creates the new hire’s onboarding tasks in your project tracker with their start date.","integrations":[{"id":"checkr","name":"Checkr"},{"id":"asana","name":"Asana"}]},{"title":"Annual driver rescreening","prompt":"Build a workflow that reads a table of active drivers, creates a yearly Checkr subscription for each driver who does not have one, enrolls them in continuous MVR monitoring, and writes the subscription and continuous check IDs back to the table.","integrations":[{"id":"checkr","name":"Checkr"}]}]},{"id":"circleback","type":"circleback","slug":"circleback","name":"Circleback","description":"Read Circleback meetings, notes, transcripts, and action items","category":"AI","docsUrl":"https://docs.sim.ai/integrations/circleback","authType":"api-key","connections":[],"operations":[{"name":"List Meetings","description":"Lists meetings from Circleback with optional ownership, status, tag, and attendee filters."},{"name":"Get Meeting","description":"Gets a Circleback meeting by ID, including notes, attendees, action items, insights, and recording details."},{"name":"Search Meetings","description":"Searches Circleback meetings by name and content, with optional filters for specific meetings, tags, and people."},{"name":"Get Transcript","description":"Gets the full transcript for a Circleback meeting."},{"name":"Update Meeting","description":"Updates the name, notes, or private notes of a Circleback meeting. The API returns only the fields that were updated."},{"name":"Delete Meeting","description":"Deletes a Circleback meeting. Only the owner of the meeting can delete it. Returns the deleted meeting."},{"name":"List Action Items","description":"Lists action items across the authenticated user meetings, filtered by assignee, status, tags, and attendees. Defaults to incomplete action items assigned to the API key owner."},{"name":"Update Action Item","description":"Updates the title, description, status, or assignee of a Circleback action item. Returns the updated action item."},{"name":"Delete Action Item","description":"Deletes a Circleback action item. Returns the deleted action item."},{"name":"List Calendar Events","description":"Lists upcoming calendar events from the authenticated user connected calendars, with pagination and a configurable time window."},{"name":"List Companies","description":"Lists the companies whose people attend the authenticated user meetings, with optional tag filters."},{"name":"Get Company","description":"Gets a company by its domain from Circleback, including its people and external links."},{"name":"List People","description":"Lists the people who attend the authenticated user meetings, ordered by most recent meeting, with optional company and tag filters."},{"name":"Get Person","description":"Gets a person by their profile ID from Circleback, including their profile details and external links."},{"name":"List Tags","description":"Lists every tag available to the authenticated Circleback user."},{"name":"Create Tag","description":"Creates a new tag in Circleback. If a tag with the same name already exists, a conflict error is returned."},{"name":"Update Tag","description":"Updates the name or description of a Circleback tag."},{"name":"Delete Tag","description":"Permanently deletes a Circleback tag and removes it from every meeting it was applied to."},{"name":"Add Tag to Meetings","description":"Applies an existing Circleback tag to one or more meetings and returns the updated meetings."},{"name":"Remove Tag from Meetings","description":"Removes a Circleback tag from one or more meetings and returns the updated meetings."}],"triggers":[{"id":"circleback_meeting_completed","name":"Circleback Meeting Completed","description":"Trigger workflow when a meeting is processed and ready in Circleback"},{"id":"circleback_meeting_notes","name":"Circleback Meeting Notes Ready","description":"Trigger workflow when meeting notes and action items are ready"},{"id":"circleback_webhook","name":"Circleback Webhook","description":"Generic webhook trigger for all Circleback events"}],"skills":[{"name":"digest-meetings","description":"List recent Circleback meetings and produce a structured digest of notes, decisions, and action items.","content":"# Digest Meetings\\n\\nTurn recent Circleback meetings into a concise digest.\\n\\n## Steps\\n1. List meetings, optionally filtered by tags or attendees.\\n2. For each meeting, get the full meeting to read notes, action items, and insights.\\n3. Extract the meeting title, key decisions, takeaways, and action items with owners.\\n4. Keep each meeting summary short and uniformly structured.\\n\\n## Output\\nReturn a digest with one section per meeting: title, date, decisions, takeaways, and action items. Suitable for a team recap or daily summary."},{"name":"chase-action-items","description":"List open Circleback action items and group them by assignee for follow-up.","content":"# Chase Action Items\\n\\nBuild a follow-up list from open action items.\\n\\n## Steps\\n1. List action items with the assignee scope set to Anyone and the default incomplete status.\\n2. Group items by assignee, noting the source meeting for each.\\n3. Flag items whose source meeting is more than a week old.\\n\\n## Output\\nReturn a per-assignee list of open action items, each with the task, source meeting, and age. Ready to send as reminders."},{"name":"research-relationship","description":"Pull the meeting history, people, and notes Circleback holds for a company before an important call.","content":"# Research Relationship\\n\\nAssemble the relationship history with a company.\\n\\n## Steps\\n1. Get the company by domain to find its people and external links.\\n2. Search meetings restricted to those attendee profiles.\\n3. Get the most relevant meetings and read their notes and insights.\\n\\n## Output\\nReturn a brief with the people met, meeting timeline, open action items, and key discussion themes for the company."}],"templates":[{"title":"Circleback recap to Slack","prompt":"Build a workflow that triggers when a meeting is processed in Circleback, takes the notes and action items from the payload, and posts a clean recap to the relevant Slack channel.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"slack","name":"Slack"}]},{"title":"Circleback action-item tracker","prompt":"Create a workflow that triggers when a Circleback meeting is processed, reads the action items from the payload, and writes each one to a tasks table with the owner and due date.","integrations":[{"id":"circleback","name":"Circleback"}]},{"title":"Circleback notes to Notion","prompt":"Build a workflow that triggers when a meeting is processed in Circleback, pulls the notes, attendees, and transcript from the payload, and writes a structured meeting note to Notion with next steps.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"notion","name":"Notion"}]},{"title":"Circleback meeting prep brief","prompt":"Build a scheduled workflow that lists upcoming calendar events from Circleback each morning, pulls past meetings and notes for the same attendees, and posts a prep brief for each external meeting to Slack.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"slack","name":"Slack"}]},{"title":"Circleback action-item chaser","prompt":"Create a scheduled workflow that lists pending Circleback action items across the workspace each week, groups them by assignee, and sends each owner a summary of what is still open.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"slack","name":"Slack"}]},{"title":"Circleback CRM updater","prompt":"Build a workflow that runs after a Circleback sales meeting, gets the full meeting with notes and insights, summarizes it into a deal-ready update, and writes it to the matching HubSpot or Salesforce record using the attendee company domain.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"hubspot","name":"HubSpot"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Circleback customer-voice miner","prompt":"Create a workflow that searches Circleback meetings for a product or feature keyword, reads the matching transcripts, extracts notable customer quotes and pain points, and writes them to a tables-based research log.","integrations":[{"id":"circleback","name":"Circleback"}]},{"title":"Circleback weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists the past week of Circleback meetings, aggregates decisions, action items, and recurring themes, and posts a digest to the team Slack channel.","integrations":[{"id":"circleback","name":"Circleback"},{"id":"slack","name":"Slack"}]},{"title":"Circleback tag janitor","prompt":"Create a workflow that lists Circleback meetings without tags, classifies each meeting from its name and attendees, and applies the right existing tag so meetings stay organized.","integrations":[{"id":"circleback","name":"Circleback"}]}]},{"id":"managed_agent","type":"managed_agent","slug":"claude-managed-agents","name":"Claude Managed Agents","description":"Run a Claude Platform Managed Agent","category":"AI","docsUrl":"https://docs.sim.ai/integrations/managed_agent","authType":"api-key","connections":[],"operations":[{"name":"Run session (create, send, wait for reply)","description":"Open a Claude Platform Managed Agent session and return the assistant response as text."},{"name":"Create session","description":"Create a Claude Platform Managed Agent session and return its id without waiting for a reply."},{"name":"Send message","description":"Send a user message to an existing Claude Platform Managed Agent session."},{"name":"Get session","description":"Read a Managed Agent session: status, stop reason, token usage, metadata, and any tool calls awaiting approval."},{"name":"List events","description":"Read a Managed Agent session\'s event history and the agent\'s reply text."},{"name":"Update session","description":"Update a Managed Agent session\'s title or metadata."},{"name":"Interrupt session","description":"Stop a running Managed Agent session; it stays usable afterwards."},{"name":"Respond to tool confirmation","description":"Allow or deny the tool calls a Managed Agent session is waiting on before it can continue."},{"name":"Respond to custom tool","description":"Return the result of a custom tool a Managed Agent session is waiting on so it can continue."},{"name":"Archive session","description":"Archive a Managed Agent session, preserving its history. Not reversible."},{"name":"Delete session","description":"Permanently delete a Managed Agent session, its events, and its sandbox. Not reversible."}],"triggers":[],"skills":[{"name":"run-managed-agent-task","description":"Send one task to a Claude Platform Managed Agent and wait for its final answer. Use for a self-contained job where you only need the result, not the intermediate steps.","content":"# Run Managed Agent Task\\n\\nHand a Claude Platform Managed Agent a single task and return what it produced.\\n\\n## Steps\\n1. Choose the **Run session** operation — it creates a session, sends one message, waits for the agent to finish, and returns its text in one block.\\n2. Select the Claude Platform account, then pick the Agent and Environment from that workspace. The agent already carries its own model, system prompt, and tools — you supply the task, not the configuration.\\n3. Write the User message as a complete brief: the goal, the constraints, and what \\"done\\" looks like. The agent cannot ask a follow-up question mid-run, so anything you leave out it has to guess.\\n4. Attach what the task needs: credential vaults for any MCP servers the agent calls, files it should read, and a memory store if it should carry context from earlier sessions.\\n\\n## Output\\nReturn the agent\'s final text, plus the session id so the run can be traced later. Report the outcome as the agent stated it — if it says a step failed or was skipped, pass that through rather than summarizing it as success."},{"name":"resume-managed-agent-conversation","description":"Keep one Managed Agent session alive across separate workflow runs so follow-up turns retain earlier context. Use for chat threads, ticket conversations, and any multi-turn exchange.","content":"# Resume Managed Agent Conversation\\n\\nHold a conversation with a Managed Agent across runs instead of starting over each time.\\n\\n## Steps\\n1. On the first turn, use **Create session** — it opens the session and returns its id without waiting for a reply. Store that id somewhere durable (a table row keyed by the thread or ticket).\\n2. On every later turn, use **Send message** with the stored Session ID. The agent still has its earlier turns; do not re-send the history.\\n3. Use **Get session** when you need to know whether the agent is still working, is waiting on you, or has finished before you send the next message.\\n4. When the conversation ends, use **Archive session** to make it read-only, or **Delete session** to remove it and its history entirely.\\n\\n## Output\\nReturn the agent\'s reply for this turn and the session id you used. If the session turned out to be already terminated or archived, say so plainly rather than silently opening a new one — a fresh session loses every earlier turn."},{"name":"approve-managed-agent-tool-calls","description":"Answer the permission prompts a Managed Agent raises before running a gated tool. Use when the agent is configured to ask before acting and a human or policy decides each call.","content":"# Approve Managed Agent Tool Calls\\n\\nUnblock a session that has paused waiting for permission to run a tool.\\n\\n## Steps\\n1. Use **Get session** to see the session status and the tool calls currently waiting on a decision. A session sitting idle with pending calls is blocked until you answer.\\n2. For each pending call, decide allow or deny. Route it to a person when the action is hard to reverse — sending mail, deleting data, pushing to a shared branch.\\n3. Use **Respond to tool confirmation** with the tool use event IDs and the decision. Answer every pending call; one left unanswered keeps the session blocked.\\n4. On a deny, write a Deny reason saying what to do instead. The agent reads it and adjusts, rather than retrying the same call.\\n\\n## Output\\nReturn which calls were allowed and which were denied, with the reason for each denial, and confirm the session resumed. If it did not resume, report which calls are still pending instead of assuming the answers landed."},{"name":"answer-managed-agent-custom-tool","description":"Execute a custom tool a Managed Agent invoked and return the result to the session. Use when the agent calls a tool your own workflow implements rather than one the platform runs.","content":"# Answer Managed Agent Custom Tool\\n\\nRun a tool the agent asked for and hand back what it produced.\\n\\n## Steps\\n1. Use **Get session** or **List events** to find the custom tool call the agent is waiting on, and read the arguments it passed.\\n2. Do the work in your workflow — call the API, query the table, run the function. This is the point of a custom tool: the credential and the logic stay on your side, never inside the agent\'s sandbox.\\n3. Use **Respond to custom tool** with the custom tool use event ID and the result. Keep the result focused — the agent reads it directly, so return the fields it needs rather than a raw dump.\\n4. If the work failed, still respond, and mark it as an error with the reason. The agent can then try a different approach instead of waiting on a result that will never come.\\n\\n## Output\\nReturn what the tool did and what you sent back, and confirm the session resumed. Never fabricate a result to unblock a session — an invented answer propagates into everything the agent does next."},{"name":"audit-managed-agent-session","description":"Reconstruct what a Managed Agent actually did from its event history. Use for compliance review, debugging a bad run, or reporting cost and token usage per run.","content":"# Audit Managed Agent Session\\n\\nBuild an evidence trail for one session from the events it emitted.\\n\\n## Steps\\n1. Use **Get session** for the summary: status, title, metadata, and cumulative input and output tokens.\\n2. Use **List events** to read the history. Narrow with Event types when you only care about one kind — tool calls, messages, status changes — and raise Max events when the run was long enough that the default page truncates it.\\n3. Walk the events in order and pair each tool call with its result, so the record shows what the agent attempted and what came back, not just what it said afterwards.\\n4. Write the reconstructed trail wherever it needs to live — a table row per run, a file, a message to the reviewing channel.\\n\\n## Output\\nReturn the ordered list of what the agent did, the token totals, and the final status. Base every claim on an event you actually read; if the history was truncated, say where it stops rather than describing the run as complete."},{"name":"stop-runaway-managed-agent-session","description":"Halt a Managed Agent session that is working longer than it should and clean it up. Use for cost control and for cancelling work a user changed their mind about.","content":"# Stop Runaway Managed Agent Session\\n\\nStop work in progress without losing what the session already produced.\\n\\n## Steps\\n1. Use **Get session** to confirm the session is genuinely running rather than idle and waiting on you — a session blocked on a tool confirmation needs an answer, not an interrupt.\\n2. Use **Interrupt session** to stop it. The agent halts at a safe point and goes idle; it does not treat the interrupt as a message, so its history and outputs survive.\\n3. Send a follow-up message if you want it to continue differently. The session is still usable after an interrupt.\\n4. When you are finished with it, use **Archive session** to keep the record read-only, or **Delete session** to remove the session and its history for good. Deletion is not reversible.\\n\\n## Output\\nReturn why the session was stopped, what it had completed at that point, and whether you archived or deleted it. Prefer archive over delete when anyone may need the history later."},{"name":"give-managed-agent-persistent-memory","description":"Attach a memory store so an agent carries learnings between sessions. Use when repeated runs should build on earlier ones instead of starting cold.","content":"# Give Managed Agent Persistent Memory\\n\\nLet an agent remember across sessions rather than only within one.\\n\\n## Steps\\n1. Set the Environment type to cloud — memory stores and file attachments are cloud-only, and a self-hosted environment rejects them.\\n2. On **Run session** or **Create session**, select the Memory store the agent should mount. Choose read-only when the store is shared reference material the agent must not edit; choose read-write when it should record what it learns.\\n3. Write Memory instructions saying what lives in the store and when to consult it. The agent reads that description to decide whether the store is relevant, so describe the contents, not the mechanics.\\n4. Keep secrets out of the store. Memories are replayed verbatim into every later session that mounts it — put API keys and tokens in a credential vault instead.\\n\\n## Output\\nReturn the agent\'s result and note whether it read from or wrote to the store. If the agent reports that expected context was missing, say so rather than assuming the store was mounted correctly."}],"templates":[{"title":"Claude Managed Agents overnight refactor","prompt":"Build a workflow that runs nightly, opens a Claude Managed Agents session against a mounted repository, asks it to work through the migration backlog, and posts the branches it pushed to Slack in the morning.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"slack","name":"Slack"}]},{"title":"Claude Managed Agents PR reviewer","prompt":"Create a workflow that triggers on a new GitHub pull request, runs a Claude Managed Agents session over the diff, and posts the findings back as a review comment on the PR.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"github","name":"GitHub"}]},{"title":"Claude Managed Agents approval gate","prompt":"Build a workflow that creates a Claude Managed Agents session, polls it for tool calls waiting on permission, posts each one to Slack for a human decision, and sends the allow or deny answer back to the session so it keeps working.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"slack","name":"Slack"}]},{"title":"Claude Managed Agents research desk","prompt":"Create a workflow that takes a research question, runs a Claude Managed Agents session to gather and cross-check sources, and writes the findings plus every citation into a table.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Claude Managed Agents weekly report","prompt":"Build a scheduled workflow that runs a Claude Managed Agents session every Monday to compile last week’s metrics into a spreadsheet, then sends the finished file to the leadership list over Gmail.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"gmail","name":"Gmail"}]},{"title":"Claude Managed Agents support triage","prompt":"Create a workflow that opens a Claude Managed Agents session per incoming ticket, has it reproduce the issue and draft a reply, and files a Linear issue when it finds a real bug.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"linear","name":"Linear"}]},{"title":"Claude Managed Agents conversational assistant","prompt":"Build a workflow that creates a Claude Managed Agents session on the first Slack message in a thread, stores the session id, and sends every later reply in that thread to the same session so the agent keeps its context across runs.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"slack","name":"Slack"}]},{"title":"Claude Managed Agents run auditor","prompt":"Create a workflow that reads the event history of a finished Claude Managed Agents session, extracts every tool call and its result, and writes a per-run audit row into a table for compliance review.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Claude Managed Agents runaway stopper","prompt":"Build a scheduled workflow that checks long-running Claude Managed Agents sessions, interrupts any that have been working past a threshold, archives the ones that already finished, and posts what it stopped to Slack.","integrations":[{"id":"managed_agent","name":"Claude Managed Agents"},{"id":"slack","name":"Slack"}]}]},{"id":"clay","type":"clay","slug":"clay","name":"Clay","description":"Populate Clay workbook","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/clay","authType":"api-key","connections":[],"operations":[{"name":"Clay Populate","description":"Send structured JSON data to a Clay table webhook and return its response and HTTP metadata."}],"triggers":[],"skills":[{"name":"push-record-to-clay","description":"Send a single contact or account record to a Clay table via its populate webhook so Clay can enrich it. Use to hand a lead off to a Clay enrichment waterfall.","content":"# Push Record To Clay\\n\\nSend one record into a Clay table for enrichment.\\n\\n## Steps\\n1. Get the Clay table populate webhook URL (Clay shows it on the table when you add a \\"Webhook\\" source).\\n2. Build the record as a JSON object whose keys match the Clay table column names you want to populate (e.g. name, email, company, domain, linkedin_url).\\n3. If the table has webhook authentication enabled, supply the auth token; it is sent in the x-clay-webhook-auth header.\\n4. Populate the table with the record.\\n\\n## Output\\nReturn the webhook response and metadata (status, timestamp). Confirm the record was accepted. Note that enrichment runs asynchronously inside Clay, so the enriched columns appear there, not in the immediate response."},{"name":"bulk-load-list-into-clay","description":"Push many prospect or account rows from a table into a Clay workbook for enrichment. Use to seed a lead list or sync a CRM segment into Clay.","content":"# Bulk Load List Into Clay\\n\\nLoad a list of records into a Clay table.\\n\\n## Steps\\n1. Gather the source rows (e.g. from a Sim table or a CRM query).\\n2. Get the Clay table populate webhook URL and any auth token.\\n3. For each row, map your fields to the Clay column names and populate the table once per record. Keep the JSON keys consistent across all records so columns line up.\\n4. Send the records, pacing them if the list is large.\\n\\n## Output\\nReturn a count of records pushed and any that failed (with the error). Remind the user that Clay enriches the rows on its side, and suggest they verify the row count in the Clay table once ingestion completes."}],"templates":[{"title":"Apify lead-list builder","prompt":"Create a workflow that runs an Apify scraper on a target site, enriches each row with Clay, and writes the enriched lead list into HubSpot.","integrations":[{"id":"clay","name":"Clay"},{"id":"apify","name":"Apify"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Clay lead-list builder","prompt":"Build a workflow that reads a list of target prospects from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with role and intent signals through its own waterfall.","integrations":[{"id":"clay","name":"Clay"}]},{"title":"Clay CRM enricher","prompt":"Create a scheduled workflow that reads new HubSpot contacts and pushes each one to a Clay table via the populate webhook, so Clay runs its enrichment waterfall on role, seniority, and tech-stack signals.","integrations":[{"id":"clay","name":"Clay"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Clay account pusher","prompt":"Build a scheduled workflow that reads target accounts from a Sim table and pushes each one to a Clay table via the populate webhook, so Clay enriches them with hiring, funding, and tech-change signals through its waterfall.","integrations":[{"id":"clay","name":"Clay"}]},{"title":"Clay outbound personalizer","prompt":"Create a workflow that reads a prospect record from a Sim table — including the role and company signals already gathered — drafts a personalized first-touch email, queues it for review, and pushes the prospect to a Clay table via the populate webhook for further enrichment.","integrations":[{"id":"clay","name":"Clay"},{"id":"gmail","name":"Gmail"}]},{"title":"Clay TAM seeder","prompt":"Build a workflow that reads a seed account list from Salesforce and pushes each account to a Clay table via the populate webhook, so Clay runs its lookalike and enrichment waterfall to expand the TAM.","integrations":[{"id":"clay","name":"Clay"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Clay inbound lead router","prompt":"Create a workflow that scores each inbound HubSpot lead against the ICP using the fields already on the contact, routes high-fit leads to sales while parking the rest for nurture, and pushes every lead to a Clay table via the populate webhook for enrichment.","integrations":[{"id":"clay","name":"Clay"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Clay enrichment pusher","prompt":"Build a scheduled workflow that reads new rows from a leads table and pushes each record to a Clay table via the populate webhook, so Clay runs its enrichment waterfall and the data flows back into my outbound stack automatically.","integrations":[{"id":"clay","name":"Clay"}]},{"title":"Loops contact property enricher","prompt":"Create a scheduled workflow that reads a Sim table of contacts missing key custom properties, enriches each one using Clay or web research, updates the matching contact in Loops with the new properties, and tracks enrichment coverage in a table.","integrations":[{"id":"clay","name":"Clay"},{"id":"loops","name":"Loops"}]}]},{"id":"clerk","type":"clerk","slug":"clerk","name":"Clerk","description":"Manage users, organizations, and sessions in Clerk","category":"Security","docsUrl":"https://docs.sim.ai/integrations/clerk","authType":"none","connections":[],"operations":[{"name":"List Users","description":"List all users in your Clerk application with optional filtering and pagination"},{"name":"Get User","description":"Retrieve a single user by their ID from Clerk"},{"name":"Create User","description":"Create a new user in your Clerk application"},{"name":"Update User","description":"Update an existing user in your Clerk application"},{"name":"Delete User","description":"Delete a user from your Clerk application"},{"name":"Ban User","description":"Ban a user, preventing them from signing in"},{"name":"Unban User","description":"Remove a ban from a user, allowing them to sign in again"},{"name":"Lock User","description":"Lock a user account, blocking sign-in attempts"},{"name":"Unlock User","description":"Unlock a previously locked user account"},{"name":"Get User OAuth Token","description":"Retrieve a user\'s OAuth access token for a connected external provider (e.g. Google, GitHub, Microsoft) obtained via Clerk SSO"},{"name":"List Organizations","description":"List all organizations in your Clerk application with optional filtering"},{"name":"Get Organization","description":"Retrieve a single organization by ID or slug from Clerk"},{"name":"Create Organization","description":"Create a new organization in your Clerk application"},{"name":"Update Organization","description":"Update an existing organization in your Clerk application"},{"name":"Delete Organization","description":"Delete an organization from your Clerk application"},{"name":"List Organization Memberships","description":"List members of a Clerk organization with optional filtering and pagination"},{"name":"Add Organization Member","description":"Add a user as a member of a Clerk organization with a given role"},{"name":"Update Organization Membership","description":"Change a member\'s role within a Clerk organization"},{"name":"Remove Organization Member","description":"Remove a member from a Clerk organization"},{"name":"Create Organization Invitation","description":"Invite a user by email to join a Clerk organization with a given role"},{"name":"List Organization Invitations","description":"List pending and past invitations for a Clerk organization"},{"name":"List Sessions","description":"List sessions for a user or client in your Clerk application"},{"name":"Get Session","description":"Retrieve a single session by ID from Clerk"},{"name":"Revoke Session","description":"Revoke a session to immediately invalidate it"},{"name":"List Allowlist Identifiers","description":"List email/phone/web3-wallet identifiers on your Clerk instance allowlist"},{"name":"Create Allowlist Identifier","description":"Add an email, phone number, or web3 wallet to your Clerk instance allowlist"},{"name":"Delete Allowlist Identifier","description":"Remove an identifier from your Clerk instance allowlist"},{"name":"List Blocklist Identifiers","description":"List email/phone/web3-wallet identifiers on your Clerk instance blocklist"},{"name":"Create Blocklist Identifier","description":"Add an email, phone number, or web3 wallet to your Clerk instance blocklist to prevent sign-ups"},{"name":"Delete Blocklist Identifier","description":"Remove an identifier from your Clerk instance blocklist"},{"name":"List JWT Templates","description":"List custom JWT templates configured on your Clerk instance"},{"name":"Get JWT Template","description":"Retrieve a single custom JWT template by ID from Clerk"},{"name":"Create Actor Token","description":"Create an actor token to impersonate a user (God Mode / act-as-user), e.g. for support tooling"},{"name":"Revoke Actor Token","description":"Revoke an actor token before it is used or expires"}],"triggers":[{"id":"clerk_user_created","name":"Clerk User Created","description":"Trigger workflow when a Clerk user is created"},{"id":"clerk_user_updated","name":"Clerk User Updated","description":"Trigger workflow when a Clerk user is updated"},{"id":"clerk_user_deleted","name":"Clerk User Deleted","description":"Trigger workflow when a Clerk user is deleted"},{"id":"clerk_session_created","name":"Clerk Session Created","description":"Trigger workflow when a Clerk session is created"},{"id":"clerk_session_ended","name":"Clerk Session Ended","description":"Trigger workflow when a Clerk session ends"},{"id":"clerk_session_removed","name":"Clerk Session Removed","description":"Trigger workflow when a Clerk session is removed"},{"id":"clerk_session_revoked","name":"Clerk Session Revoked","description":"Trigger workflow when a Clerk session is revoked"},{"id":"clerk_organization_created","name":"Clerk Organization Created","description":"Trigger workflow when a Clerk organization is created"},{"id":"clerk_organization_updated","name":"Clerk Organization Updated","description":"Trigger workflow when a Clerk organization is updated"},{"id":"clerk_organization_deleted","name":"Clerk Organization Deleted","description":"Trigger workflow when a Clerk organization is deleted"},{"id":"clerk_organization_membership_created","name":"Clerk Organization Membership Created","description":"Trigger workflow when a Clerk organization membership is created"},{"id":"clerk_organization_membership_updated","name":"Clerk Organization Membership Updated","description":"Trigger workflow when a Clerk organization membership is updated"},{"id":"clerk_organization_membership_deleted","name":"Clerk Organization Membership Deleted","description":"Trigger workflow when a Clerk organization membership is deleted"},{"id":"clerk_webhook","name":"Clerk Webhook","description":"Trigger workflow on any Clerk webhook event"}],"skills":[{"name":"find-user","description":"Look up a Clerk user by email, username, or name and return their profile. Use to resolve a user before acting on their account or syncing them elsewhere.","content":"# Find User\\n\\nLocate a Clerk user account.\\n\\n## Steps\\n1. Use List Users with a Search Query (matches email, phone, username, or name), or the email/username/phone/external ID filters for an exact match.\\n2. If you already have the Clerk user id (user_...), use Get User instead for the full record.\\n3. Review the returned profile: id, primary email, name, externalId, and flags like banned, locked, and twoFactorEnabled.\\n\\n## Output\\nReturn the matched user id, primary email, name, and key status flags. If multiple users match, list the candidates with their emails so the right one can be confirmed; if none match, say so."},{"name":"provision-user","description":"Create or update a Clerk user with email, name, and metadata. Use to onboard a user or sync profile changes from another system into Clerk.","content":"# Provision User\\n\\nCreate or update a Clerk user.\\n\\n## Steps\\n1. To create, use Create User with at least an email address (and optionally phone, username, password, first/last name).\\n2. To set application roles or app data, pass Public Metadata (visible to the frontend) and Private Metadata (server-only) as JSON.\\n3. Set External ID to link the Clerk user to your own system id.\\n4. To modify an existing user, use Update User with the user id and only the fields that change.\\n\\n## Output\\nReturn the user id, primary email, and the metadata that was set. Confirm whether the user was created or updated. If a required field is missing or the email already exists, report it clearly."},{"name":"moderate-user-access","description":"Ban, unban, lock, or unlock a Clerk user to control their ability to sign in. Use for abuse response, suspicious-activity containment, or manual account recovery.","content":"# Moderate User Access\\n\\nControl whether a Clerk user can sign in.\\n\\n## Steps\\n1. Resolve the target user id first (see find-user) if you only have an email or name.\\n2. Use Ban User to immediately block all sign-in attempts (e.g. for confirmed abuse); use Unban User to lift it once resolved.\\n3. Use Lock User for a temporary, reversible hold (e.g. suspicious login pattern under review); use Unlock User to restore access.\\n4. For a full audit trail, use Audit User Sessions afterward to revoke any sessions that should not continue.\\n\\n## Output\\nReturn the user id and the resulting banned/locked flags after the action. State clearly which control was applied and why, so the moderation trail is auditable."},{"name":"audit-user-sessions","description":"List and inspect a Clerk user active sessions and revoke suspicious ones. Use for security review or forced sign-out.","content":"# Audit User Sessions\\n\\nReview and control Clerk sessions.\\n\\n## Steps\\n1. Use List Sessions filtered by user id and status (e.g. active) to see current sessions.\\n2. For a specific session, use Get Session to read its details: client, status, lastActiveAt.\\n3. Identify sessions that look risky (stale, unexpected client, or flagged by your own logic).\\n4. Use Revoke Session with the session id to force sign-out of any session that should not continue.\\n\\n## Output\\nReturn the list of sessions reviewed with status and last-active time, and the ids of any sessions revoked. Summarize the action taken so the security trail is clear."},{"name":"manage-organization","description":"Create or update a Clerk organization, manage its memberships, and invite new members. Use when provisioning a new team or tenant in a multi-tenant app, or when onboarding/offboarding members.","content":"# Manage Organization\\n\\nCreate, inspect, and staff a Clerk organization.\\n\\n## Steps\\n1. To create, use Create Organization with the organization name and the Creator User ID (that user becomes the admin); optionally set a slug and max members. Use Update Organization to rename, re-slug, or change membership limits later.\\n2. To inspect, use Get Organization by org id or slug, or List Organizations with a search query and include members count.\\n3. To staff the org, use Add Organization Member with an existing user id and role, or Create Organization Invitation to invite someone by email who does not have an account yet.\\n4. Use List Organization Memberships to see current members and their roles, Update Organization Membership to change a member\'s role, and Remove Organization Member to offboard someone.\\n5. Use List Organization Invitations to check on pending invites.\\n\\n## Output\\nReturn the organization id, name, slug, and member count. When adding or inviting a member, confirm the user id or email and the assigned role. When creating, confirm the admin user and echo the org id so it can be linked back to your billing or CRM record."}],"templates":[{"title":"Clerk new-signup pipeline","prompt":"Build a scheduled workflow that lists recent Clerk users, creates each new signup in HubSpot with the right lifecycle stage, and enrolls them in a Loops onboarding sequence.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"hubspot","name":"HubSpot"},{"id":"loops","name":"Loops"}]},{"title":"Clerk MFA enrollment chaser","prompt":"Create a scheduled workflow that finds Clerk users without MFA enrolled in 30 days, sends in-app prompts via Loops, and writes enrollment progress to a security dashboard.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"loops","name":"Loops"}]},{"title":"Clerk session anomaly watcher","prompt":"Build a scheduled workflow that lists recent Clerk sessions, flags unusual patterns — impossible travel, repeated login failures — and pings the security Slack channel on real threats.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"slack","name":"Slack"}]},{"title":"Clerk org-management automator","prompt":"Create a workflow that on a new enterprise plan via Stripe creates a Clerk organization, invites the admin by email, and writes the Clerk org ID back to the Stripe customer.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"stripe","name":"Stripe"}]},{"title":"Clerk inactive-user cleaner","prompt":"Build a scheduled workflow that finds Clerk users with no sign-ins in 180 days, sends a re-engagement email, and bans accounts that stay inactive after a grace period.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"gmail","name":"Gmail"}]},{"title":"Clerk access-review automator","prompt":"Create a scheduled quarterly workflow that lists Clerk organizations and their memberships, requires owner re-attestation, and writes the review trail to a compliance table.","integrations":[{"id":"clerk","name":"Clerk"}]},{"title":"Clerk user roster archiver","prompt":"Build a scheduled workflow that exports the full Clerk user and organization roster to S3 on a retention schedule, and writes the snapshot manifest to a compliance table.","integrations":[{"id":"clerk","name":"Clerk"},{"id":"s3","name":"S3"}]}]},{"id":"clickhouse","type":"clickhouse","slug":"clickhouse","name":"ClickHouse","description":"Connect to a ClickHouse database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/clickhouse","authType":"none","connections":[],"operations":[{"name":"Query (SELECT)","description":"Execute a SELECT query on a ClickHouse database"},{"name":"Execute Raw SQL","description":"Execute raw SQL (DDL, mutations, or queries) on a ClickHouse database"},{"name":"Insert Row","description":"Insert a row into a ClickHouse table"},{"name":"Insert Rows (Bulk)","description":"Insert multiple rows into a ClickHouse table"},{"name":"Update Data","description":"Update rows in a ClickHouse table via an ALTER TABLE ... UPDATE mutation"},{"name":"Delete Data","description":"Delete rows from a ClickHouse table via an ALTER TABLE ... DELETE mutation"},{"name":"List Databases","description":"List all databases on a ClickHouse server"},{"name":"List Tables","description":"List tables in the connected ClickHouse database"},{"name":"Describe Table","description":"Describe the columns of a ClickHouse table"},{"name":"Show Create Table","description":"Get the CREATE TABLE statement (DDL) for a ClickHouse table"},{"name":"Count Rows","description":"Count rows in a ClickHouse table, optionally filtered"},{"name":"Introspect Schema","description":"Introspect a ClickHouse database to retrieve table structures, columns, and engines"},{"name":"Create Database","description":"Create a new database on a ClickHouse server"},{"name":"Drop Database","description":"Drop a database from a ClickHouse server"},{"name":"Create Table","description":"Create a new MergeTree-family table in ClickHouse"},{"name":"Drop Table","description":"Drop a table from a ClickHouse database"},{"name":"Truncate Table","description":"Remove all rows from a ClickHouse table"},{"name":"Rename Table","description":"Rename a ClickHouse table"},{"name":"Optimize Table","description":"Trigger a merge of table parts via OPTIMIZE TABLE"},{"name":"List Partitions","description":"List active partitions for a ClickHouse table"},{"name":"Drop Partition","description":"Drop a partition from a ClickHouse table"},{"name":"List Mutations","description":"List mutations (async ALTER UPDATE/DELETE) for the connected database"},{"name":"List Running Queries","description":"List currently running queries on a ClickHouse server"},{"name":"Kill Query","description":"Kill a running query by its query ID"},{"name":"Table Stats","description":"Get row counts and on-disk size for tables in the connected database"},{"name":"List Clusters","description":"List configured clusters, shards, and replicas"}],"triggers":[],"skills":[{"name":"answer-question-with-sql","description":"Translate a plain-English analytics question into ClickHouse SQL, run it, and return the answer. Use for ad-hoc data questions over a ClickHouse table.","content":"# Answer Question With SQL\\n\\nTurn a natural-language question into a ClickHouse query and report the result.\\n\\n## Steps\\n1. If you do not know the schema, use Introspect Schema or Describe Table to learn the columns and types.\\n2. Write a ClickHouse SELECT using ClickHouse functions (toDate, uniqExact, quantile, etc.). Filter on primary/sorting keys and add a LIMIT for exploratory queries.\\n3. Run it with the Query (SELECT) operation against the connection (host, port, database, credentials).\\n4. Inspect the returned rows and row count.\\n\\n## Output\\nReturn the result as a small table plus a one-sentence answer to the original question. Include the SQL you ran so it is reproducible. If the query errors, report the message and adjust the SQL rather than guessing blindly."},{"name":"summarize-metrics","description":"Run aggregation queries against ClickHouse and summarize key metrics and trends. Use for a recurring metrics digest or dashboard refresh.","content":"# Summarize Metrics\\n\\nCompute and summarize metrics from ClickHouse.\\n\\n## Steps\\n1. Confirm the relevant table and time column with Describe Table if needed.\\n2. Write aggregation queries (e.g. daily uniqExact users, counts, quantiles over a time window) using Query (SELECT).\\n3. Run each query against the connection and collect the results.\\n4. Compare against the prior period to spot increases, drops, or anomalies.\\n\\n## Output\\nReturn a concise digest: the headline numbers, period-over-period change, and any notable anomalies. Keep it readable, lead with the most important metric, and note the time window covered."},{"name":"bulk-insert-events","description":"Insert a batch of rows into a ClickHouse table after mapping them to the right columns. Use to ingest event or record payloads into ClickHouse.","content":"# Bulk Insert Events\\n\\nLoad a batch of records into a ClickHouse table.\\n\\n## Steps\\n1. Use Describe Table to confirm the target column names and types.\\n2. Map each incoming payload to those columns, coercing types (e.g. timestamps to DateTime format, numbers to the right width).\\n3. Build a JSON array of row objects with consistent keys, then use Insert Rows (Bulk) against the table.\\n4. Verify with Count Rows or a small SELECT.\\n\\n## Output\\nReturn the number of rows inserted and any rows that were skipped or failed validation, with the reason. Confirm the new total row count so the caller knows ingestion succeeded."},{"name":"document-schema","description":"Introspect a ClickHouse database and produce readable documentation of its tables, columns, and engines. Use when onboarding to an unfamiliar ClickHouse instance or refreshing schema docs.","content":"# Document Schema\\n\\nInspect a ClickHouse database and describe its structure.\\n\\n## Steps\\n1. Use Introspect Schema to pull every table with its columns, types, and engine in one call. For a single table, use Describe Table or Show Create Table instead.\\n2. Group columns by table and note primary/sorting key membership and defaults.\\n3. Summarize each table: what it appears to store, its engine, key columns, and approximate row count.\\n\\n## Output\\nReturn a per-table summary (name, engine, key columns, row count) followed by a column reference. Keep it concise and skimmable; call out anything unusual such as missing ORDER BY keys or very wide tables."},{"name":"maintain-tables","description":"Keep ClickHouse tables healthy by inspecting parts, optimizing tables, and dropping stale partitions. Use for scheduled maintenance or when storage or part counts grow.","content":"# Maintain Tables\\n\\nRun routine ClickHouse table maintenance. Optimize is safe; dropping partitions is destructive and irreversible, so treat it with care.\\n\\n## Steps\\n1. Use Table Stats and List Partitions to see size on disk, part counts, and per-partition rows.\\n2. For tables with many small parts, run Optimize Table (optionally with Force Final Merge) to consolidate them.\\n3. Dropping partitions requires an explicit retention cutoff supplied by the caller — never infer or guess one. List the partitions of the intended table, select only those whose range ends strictly before that cutoff, and confirm each target\'s table and partition id before acting. Drop them one at a time with Drop Partition.\\n4. Re-check Table Stats to confirm the part count and size dropped.\\n\\n## Output\\nReport what was optimized or dropped, the before/after part count and size on disk, and any partitions intentionally retained. If no explicit cutoff was given, do not drop anything — optimize and report only. Never drop a partition unless it is clearly older than the cutoff and on the intended table."}],"templates":[{"title":"Natural-language ClickHouse query","prompt":"Build a workflow where I ask a question in plain English, an agent writes the matching ClickHouse SQL against my events table, runs the query, and returns the results formatted as a readable answer.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"Daily ClickHouse metrics digest","prompt":"Create a scheduled workflow that runs a set of ClickHouse aggregation queries each morning, summarizes the key trends and anomalies with an agent, and posts the digest to Slack.","integrations":[{"id":"clickhouse","name":"ClickHouse"},{"id":"slack","name":"Slack"}]},{"title":"Event ingestion to ClickHouse","prompt":"Build a workflow that takes incoming event payloads, maps them to the right columns with an agent, and bulk-inserts the rows into a ClickHouse table for analytics.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"Document a ClickHouse schema","prompt":"Build a workflow that introspects my ClickHouse database schema, then has an agent write clear documentation describing each table, its columns, types, and engine.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"Scheduled ClickHouse maintenance","prompt":"Create a scheduled workflow that runs OPTIMIZE TABLE on my high-write ClickHouse tables each night to merge parts, then reports the resulting part counts and storage size.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"ClickHouse partition cleanup","prompt":"Build a scheduled workflow that enforces a retention policy on my ClickHouse events table: take an explicit cutoff date as input, list the table partitions, select only the partitions on that exact table whose range ends strictly before the cutoff, and drop just those. Never infer the cutoff and never drop a partition that is not clearly past it.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"Alert on slow ClickHouse queries","prompt":"Create a scheduled workflow that lists ClickHouse running queries and posts a Slack alert for any whose elapsed time exceeds an explicit threshold I set, including the query_id, user, and elapsed time so a human can investigate and decide whether to intervene.","integrations":[{"id":"clickhouse","name":"ClickHouse"},{"id":"slack","name":"Slack"}]},{"title":"Provision a ClickHouse table from a spec","prompt":"Build a workflow where I describe the table I need in plain English, an agent designs the columns, engine, and ORDER BY key, and the workflow creates the ClickHouse table.","integrations":[{"id":"clickhouse","name":"ClickHouse"}]},{"title":"ClickHouse storage growth report","prompt":"Create a scheduled workflow that collects ClickHouse table stats (rows and size on disk) each week, has an agent summarize the largest tables and fastest growth, and posts the report to Slack.","integrations":[{"id":"clickhouse","name":"ClickHouse"},{"id":"slack","name":"Slack"}]}]},{"id":"clickup","type":"clickup","slug":"clickup","name":"ClickUp","description":"Manage ClickUp tasks, comments, hierarchy, and time entries","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/clickup","authType":"oauth","connections":[{"id":"clickup","kind":"oauth","label":"Connect with OAuth","providerId":"clickup","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/clickup","requiredScopes":[],"fields":[]},{"id":"clickup-service-account","kind":"service_account","providerId":"clickup-service-account","label":"Add API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/clickup-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"pk_...","secret":true,"hint":"ClickUp personal API tokens start with pk_."}]}],"operations":[{"name":"Create Task","description":"Create a new task in a ClickUp list"},{"name":"Get Task","description":"Retrieve a task from ClickUp by ID"},{"name":"Update Task","description":"Update an existing task in ClickUp"},{"name":"Delete Task","description":"Delete a task from ClickUp"},{"name":"Get Tasks","description":"List the tasks in a ClickUp list (100 tasks per page; increment page until an empty result to paginate)"},{"name":"Search Tasks","description":"Search tasks across a ClickUp workspace with filters for lists, folders, spaces, statuses, assignees, tags, and due dates (100 tasks per page; increment page until an empty result to paginate)"},{"name":"Create Comment","description":"Add a comment to a ClickUp task"},{"name":"Get Comments","description":"Retrieve comments on a ClickUp task, newest first (25 per page; paginate with start and startId)"},{"name":"Update Comment","description":"Update the content, assignee, or resolved state of a ClickUp task comment"},{"name":"Delete Comment","description":"Delete a comment from a ClickUp task"},{"name":"Upload Attachment","description":"Upload a file to a ClickUp task as an attachment"},{"name":"Add Tag to Task","description":"Add an existing space tag to a ClickUp task"},{"name":"Remove Tag from Task","description":"Remove a tag from a ClickUp task"},{"name":"Get Space Tags","description":"List the task tags available in a ClickUp space"},{"name":"Get Task Members","description":"List the workspace members who have explicit access to a ClickUp task"},{"name":"Get List Members","description":"List the workspace members who have explicit access to a ClickUp list"},{"name":"Get Custom Fields","description":"List the custom fields accessible in a ClickUp list"},{"name":"Set Custom Field Value","description":"Set the value of a custom field on a ClickUp task (the value shape depends on the field type)"},{"name":"Remove Custom Field Value","description":"Remove the value of a custom field from a ClickUp task (does not delete the field itself)"},{"name":"Create Checklist","description":"Add a new checklist to a ClickUp task"},{"name":"Update Checklist","description":"Rename or reorder a checklist on a ClickUp task"},{"name":"Delete Checklist","description":"Delete a checklist from a ClickUp task"},{"name":"Create Checklist Item","description":"Add an item to a checklist on a ClickUp task"},{"name":"Update Checklist Item","description":"Update a checklist item on a ClickUp task — rename, assign, resolve, or nest it"},{"name":"Delete Checklist Item","description":"Delete an item from a checklist on a ClickUp task"},{"name":"Get Time Entries","description":"List time entries in a ClickUp workspace within a date range (defaults to the last 30 days for the authenticated user)"},{"name":"Create Time Entry","description":"Create a manual time entry in a ClickUp workspace, optionally linked to a task"},{"name":"Update Time Entry","description":"Update a time entry in a ClickUp workspace — description, start/end times, task, or billable state"},{"name":"Delete Time Entry","description":"Delete a time entry from a ClickUp workspace"},{"name":"Start Timer","description":"Start a timer for the authenticated user in a ClickUp workspace"},{"name":"Stop Timer","description":"Stop the authenticated user\'s currently running timer in a ClickUp workspace"},{"name":"Get Running Timer","description":"Get the currently running time entry in a ClickUp workspace (null when no timer is running)"},{"name":"Get Workspaces","description":"List the ClickUp workspaces (teams) available to the connected account"},{"name":"Get Spaces","description":"List the spaces in a ClickUp workspace"},{"name":"Get Folders","description":"List the folders in a ClickUp space"},{"name":"Get Lists","description":"List the lists in a ClickUp folder, or the folderless lists in a space when a space ID is provided instead"},{"name":"Create Folder","description":"Create a new folder in a ClickUp space"},{"name":"Create List","description":"Create a new list in a ClickUp folder, or a folderless list in a space when a space ID is provided instead"}],"triggers":[{"id":"clickup_task_created","name":"ClickUp Task Created","description":"Trigger workflow when a task is created in ClickUp"},{"id":"clickup_task_updated","name":"ClickUp Task Updated","description":"Trigger workflow when a task is updated in ClickUp"},{"id":"clickup_task_deleted","name":"ClickUp Task Deleted","description":"Trigger workflow when a task is deleted in ClickUp"},{"id":"clickup_task_status_updated","name":"ClickUp Task Status Updated","description":"Trigger workflow when the status of a task changes in ClickUp"},{"id":"clickup_task_priority_updated","name":"ClickUp Task Priority Updated","description":"Trigger workflow when the priority of a task changes in ClickUp"},{"id":"clickup_task_assignee_updated","name":"ClickUp Task Assignee Updated","description":"Trigger workflow when the assignees of a task change in ClickUp"},{"id":"clickup_task_due_date_updated","name":"ClickUp Task Due Date Updated","description":"Trigger workflow when the due date of a task changes in ClickUp"},{"id":"clickup_task_tag_updated","name":"ClickUp Task Tag Updated","description":"Trigger workflow when the tags of a task change in ClickUp"},{"id":"clickup_task_moved","name":"ClickUp Task Moved","description":"Trigger workflow when a task is moved to a different list in ClickUp"},{"id":"clickup_task_comment_posted","name":"ClickUp Task Comment Posted","description":"Trigger workflow when a comment is posted on a task in ClickUp"},{"id":"clickup_task_comment_updated","name":"ClickUp Task Comment Updated","description":"Trigger workflow when a task comment is updated in ClickUp"},{"id":"clickup_task_time_estimate_updated","name":"ClickUp Task Time Estimate Updated","description":"Trigger workflow when the time estimate of a task changes in ClickUp"},{"id":"clickup_task_time_tracked_updated","name":"ClickUp Task Time Tracked Updated","description":"Trigger workflow when the tracked time of a task changes in ClickUp"},{"id":"clickup_list_created","name":"ClickUp List Created","description":"Trigger workflow when a list is created in ClickUp"},{"id":"clickup_list_updated","name":"ClickUp List Updated","description":"Trigger workflow when a list is updated in ClickUp"},{"id":"clickup_list_deleted","name":"ClickUp List Deleted","description":"Trigger workflow when a list is deleted in ClickUp"},{"id":"clickup_folder_created","name":"ClickUp Folder Created","description":"Trigger workflow when a folder is created in ClickUp"},{"id":"clickup_folder_updated","name":"ClickUp Folder Updated","description":"Trigger workflow when a folder is updated in ClickUp"},{"id":"clickup_folder_deleted","name":"ClickUp Folder Deleted","description":"Trigger workflow when a folder is deleted in ClickUp"},{"id":"clickup_space_created","name":"ClickUp Space Created","description":"Trigger workflow when a space is created in ClickUp"},{"id":"clickup_space_updated","name":"ClickUp Space Updated","description":"Trigger workflow when a space is updated in ClickUp"},{"id":"clickup_space_deleted","name":"ClickUp Space Deleted","description":"Trigger workflow when a space is deleted in ClickUp"},{"id":"clickup_goal_created","name":"ClickUp Goal Created","description":"Trigger workflow when a goal is created in ClickUp"},{"id":"clickup_goal_updated","name":"ClickUp Goal Updated","description":"Trigger workflow when a goal is updated in ClickUp"},{"id":"clickup_goal_deleted","name":"ClickUp Goal Deleted","description":"Trigger workflow when a goal is deleted in ClickUp"},{"id":"clickup_key_result_created","name":"ClickUp Key Result Created","description":"Trigger workflow when a key result is created in ClickUp"},{"id":"clickup_key_result_updated","name":"ClickUp Key Result Updated","description":"Trigger workflow when a key result is updated in ClickUp"},{"id":"clickup_key_result_deleted","name":"ClickUp Key Result Deleted","description":"Trigger workflow when a key result is deleted in ClickUp"},{"id":"clickup_webhook","name":"ClickUp Webhook","description":"Trigger workflow on any ClickUp event (subscribes to all events)"}],"skills":[{"name":"create-task-from-request","description":"Turn an incoming request or message into a well-formed ClickUp task in the right list with priority, assignees, and due date. Use for intake and ticket creation.","content":"# Create Task from Request\\n\\nConvert an incoming request into a structured ClickUp task.\\n\\n## Steps\\n1. Extract the work to be done, the target list, any assignees, a priority, and a due date.\\n2. If the list is referenced by name, walk the hierarchy (workspaces, spaces, folders, lists) to resolve its ID.\\n3. Create the task with a clear name, a description capturing the request details, and the extracted fields.\\n4. Add a comment with any links or source context if helpful.\\n\\n## Output\\nReport the created task name, its URL or ID, list, assignees, and due date."},{"name":"summarize-list-tasks","description":"Fetch the tasks in a ClickUp list and summarize status, overdue items, and who owns what. Use for standups and project status checks.","content":"# Summarize List Tasks\\n\\nProduce a status snapshot of a ClickUp list.\\n\\n## Steps\\n1. Resolve the list, then fetch its tasks (include closed tasks when a full picture is needed).\\n2. For each task capture name, assignees, status, priority, and due date.\\n3. Group into completed, in progress, and overdue or due soon.\\n4. Note any unassigned tasks or tasks with no due date.\\n\\n## Output\\nA concise status summary: counts per group, overdue tasks called out by name and owner, and any gaps to address."},{"name":"update-task-status","description":"Find a ClickUp task and update its fields — status, priority, due date — or add a progress comment. Use to keep tasks current from other systems.","content":"# Update Task Status\\n\\nKeep a ClickUp task in sync with the latest state.\\n\\n## Steps\\n1. Identify the target task by ID, or search the workspace to find it.\\n2. Read the current task to confirm it is the right one.\\n3. Update the relevant fields — status, priority, due date, or archive state.\\n4. Add a comment summarizing what changed and why.\\n\\n## Output\\nReport which fields changed and confirm the task ID. If no matching task was found, say so."}],"templates":[{"title":"ClickUp task intake","prompt":"Build a workflow that turns incoming Slack requests into ClickUp tasks in the right list with a clear name, description, priority, and due date, then replies in the thread with the task link.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"slack","name":"Slack"}]},{"title":"ClickUp standup digest","prompt":"Create a scheduled weekday workflow that pulls open ClickUp tasks for each list, groups them by assignee and status, and posts a morning standup summary to the team Slack channel.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"slack","name":"Slack"}]},{"title":"ClickUp overdue-task nudger","prompt":"Build a scheduled workflow that searches ClickUp for tasks past their due date, adds a comment asking for a status update, and emails each assignee a digest of their overdue work.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"gmail","name":"Gmail"}]},{"title":"ClickUp bug triager","prompt":"Create a workflow that reads newly reported bugs from a ClickUp list, classifies each by severity and component with an agent, sets the priority and tags accordingly, and opens a matching GitHub issue for engineering.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"github","name":"GitHub"}]},{"title":"ClickUp sprint retro writer","prompt":"Build a workflow that pulls the ClickUp tasks completed during a sprint, summarizes wins, blockers, and recurring themes with an agent, and shares a retro document with the team in Slack.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"slack","name":"Slack"}]},{"title":"ClickUp customer onboarding launcher","prompt":"Create a workflow that on a closed-won Salesforce opportunity creates a ClickUp onboarding task with the right assignees and due date, attaches the signed order form, and writes the task link back to the opportunity.","integrations":[{"id":"clickup","name":"ClickUp"},{"id":"salesforce","name":"Salesforce"}]},{"title":"ClickUp meeting action items","prompt":"Build a workflow that takes meeting notes, extracts action items with an agent, creates a ClickUp task for each with the right assignee and due date, and replies with a checklist of created tasks.","integrations":[{"id":"clickup","name":"ClickUp"}]}]},{"id":"cloudflare","type":"cloudflare","slug":"cloudflare","name":"Cloudflare","description":"Manage DNS, WAF, Zero Trust access, and edge infrastructure","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/cloudflare","authType":"api-key","connections":[],"operations":[{"name":"List Zones","description":"Lists one page of zones (domains) in the Cloudflare account."},{"name":"Get Zone Details","description":"Gets details for a specific zone (domain) by its ID."},{"name":"Create Zone","description":"Adds a new zone (domain) to the Cloudflare account."},{"name":"Delete Zone","description":"Deletes a zone (domain) from the Cloudflare account."},{"name":"List DNS Records","description":"Lists DNS records for a specific zone."},{"name":"Create DNS Record","description":"Creates a new DNS record for a zone."},{"name":"Update DNS Record","description":"Updates an existing DNS record for a zone."},{"name":"Delete DNS Record","description":"Deletes a DNS record from a zone."},{"name":"Get DNS Record","description":"Retrieves details for a specific DNS record in the zone."},{"name":"List Certificates","description":"Lists SSL/TLS certificate packs for a zone."},{"name":"Get Zone Settings","description":"Reads zone settings such as SSL mode, minimum TLS version, security level, and caching level. Cloudflare retired the endpoint that read every setting in one request, so each setting is read individually — name the ones you need to keep the read small. Defaults to ${DEFAULT_ZONE_SETTING_IDS.join(\', \')}."},{"name":"Update Zone Setting","description":"Updates a specific zone setting such as SSL mode, security level, cache level, or other configuration."},{"name":"Update Zone","description":"Edits a zone. Only one zone property can be changed at a time."},{"name":"DNS Analytics","description":"Gets DNS analytics report for a zone including query counts and trends."},{"name":"Purge Cache","description":"Purges cached content for a zone. Can purge everything or specific files/tags/hosts/prefixes."},{"name":"List Rulesets","description":"Lists every ruleset defined on a zone across all phases (WAF custom rules, managed rules, rate limiting, transform rules, and more). The list response deliberately omits the rules inside each ruleset — use \\"Get Ruleset\\" to read them. Requires an API token with Zone WAF Read (or another matching ruleset Read permission)."},{"name":"Get Ruleset","description":"Reads a single zone ruleset including every rule it contains, in evaluation order. Requires an API token with Zone WAF Read (or another matching ruleset Read permission)."},{"name":"Get Phase Entry Point Ruleset","description":"Reads the entry point ruleset for a phase on a zone, including all of its rules. This is how you find the ruleset ID you need before adding, updating, or deleting a rule — for example http_request_firewall_custom for WAF custom rules, http_request_firewall_managed for managed-ruleset deployments and overrides, or http_ratelimit for rate limiting rules. Requires an API token with Zone WAF Read (or another matching ruleset Read permission)."},{"name":"Create Ruleset","description":""},{"name":"Create Ruleset Rule","description":"Adds a rule to a zone ruleset. Use \\"Get Phase Entry Point Ruleset\\" first to find the ruleset ID for the phase you want (for example http_request_firewall_custom for a WAF custom rule, or http_request_firewall_managed with action \\"execute\\" to deploy a managed ruleset). The rule is appended to the end of the ruleset unless a position is given. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission)."},{"name":"Update Ruleset Rule","description":"Updates a rule in a zone ruleset. Cloudflare replaces the rule definition rather than merging it, so you must send every field you want the rule to keep — any field you omit is reset to its default. Read the current rule with \\"Get Ruleset\\" first. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission)."},{"name":"Delete Ruleset Rule","description":"Permanently deletes a rule from a zone ruleset. This takes effect immediately on live traffic and cannot be undone — deleting a WAF custom rule, a managed-ruleset deployment, or a rate limiting rule removes that protection from the zone. Also use this to delete rate limiting rules, which live in the http_ratelimit phase ruleset. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission)."},{"name":"List Managed Ruleset Overrides","description":"Lists the WAF managed rulesets deployed on a zone together with the overrides applied to each one. Cloudflare has no dedicated overrides endpoint — overrides live on the \\"execute\\" rules of the http_request_firewall_managed phase entry point ruleset, which this reads. Requires an API token with Zone WAF Read."},{"name":"Delete Ruleset","description":"Deletes all versions of an existing zone ruleset."},{"name":"Update Ruleset","description":"Updates the description and rules of a zone ruleset, creating a new version. Read the current rules with \\"Get Ruleset\\" before replacing the list. The rules array replaces the complete list: include every existing rule you want to keep; omitted rules are removed. Use \\"Create Ruleset Rule\\" to add a single rule without replacing the list."},{"name":"List Rate Limiting Rules","description":"Lists the rate limiting rules on a zone by reading the http_ratelimit phase entry point ruleset. This uses the current Rulesets-based rate limiting API; the legacy rate_limits endpoint is no longer available. The returned ruleset ID is what \\"Create Rate Limiting Rule\\", \\"Update Rate Limiting Rule\\", and \\"Delete Ruleset Rule\\" need. Requires an API token with Zone WAF Read."},{"name":"Create Rate Limiting Rule","description":"Creates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API (the legacy rate_limits endpoint is no longer available). Run \\"List Rate Limiting Rules\\" first to get the ruleset ID. Requires an API token with Zone WAF Edit."},{"name":"Update Rate Limiting Rule","description":"Updates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API. Cloudflare replaces the rule definition rather than merging it, so send the complete rule — every field you omit is reset. Run \\"List Rate Limiting Rules\\" first to read the current definition and get the ruleset ID. Requires an API token with Zone WAF Edit."},{"name":"List Access Applications","description":"Lists the Cloudflare Access (Zero Trust) applications protecting an account. Requires an API token with Account Access: Apps and Policies Read."},{"name":"Get Access Application","description":"Reads a single Cloudflare Access (Zero Trust) application, including its attached policies. Requires an API token with Account Access: Apps and Policies Read."},{"name":"Create Access Application","description":"Creates a Cloudflare Access (Zero Trust) application that puts an identity check in front of a hostname. Until at least one policy is attached the application denies everyone, so pair this with \\"Create Access Policy\\". Requires an API token with Account Access: Apps and Policies Edit."},{"name":"Update Access Application","description":"Updates a Cloudflare Access (Zero Trust) application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: send every field the application should keep, because an omitted field may revert to its default and widen or break access. Read the current configuration with \\"Get Access Application\\" first. Requires an API token with Account Access: Apps and Policies Edit."},{"name":"Delete Access Application","description":"Permanently deletes a Cloudflare Access (Zero Trust) application and every policy attached to it. The hostname it protected is immediately left without an Access identity check, so anyone who can reach it can reach the origin. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit."},{"name":"List Access Policies","description":"Lists the Cloudflare Access (Zero Trust) policies attached to an application, in precedence order. Requires an API token with Account Access: Apps and Policies Read."},{"name":"Create Access Policy","description":"Creates a Cloudflare Access (Zero Trust) policy on an application, deciding who may reach it. A policy takes effect on live traffic as soon as it is created — an allow policy with a broad include rule grants access immediately. Requires an API token with Account Access: Apps and Policies Edit."},{"name":"Update Access Policy","description":""},{"name":"Delete Access Policy","description":"Permanently deletes a Cloudflare Access (Zero Trust) policy from an application. This changes who can reach the application the moment it runs: removing an allow policy locks out everyone it covered, and removing a deny or require policy drops that restriction. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit."},{"name":"Get Access Policy","description":"Fetches a single Access policy configured for an application. Returns both exclusively owned and reusable policies used by the application."},{"name":"List Access Groups","description":"Lists the reusable Cloudflare Access (Zero Trust) groups in an account. Groups bundle identity rules that policies can reference by ID. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read."},{"name":"Create Access Group","description":"Creates a new Access group."},{"name":"Delete Access Group","description":"Deletes an Access group."},{"name":"Get Access Group","description":"Fetches a single Access group."},{"name":"Update Access Group","description":"Updates a configured Access group. Replaces the configuration; resend all values to retain."},{"name":"List Access Identity Providers","description":"Lists the identity providers configured for Cloudflare Access (Zero Trust) in an account, such as Okta, Entra ID, Google Workspace, or a one-time PIN. Use the returned IDs to restrict an application with allowed_idps. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read."},{"name":"List Access Service Tokens","description":"Lists the Cloudflare Access (Zero Trust) service tokens in an account, which let machines authenticate to Access-protected applications. Client secrets are never returned by this endpoint — only on creation. Requires an API token with Account Access: Service Tokens Read."},{"name":"Create Access Service Token","description":"Creates a Cloudflare Access (Zero Trust) service token so a machine can authenticate to Access-protected applications. This is the only response that ever contains the client secret — Cloudflare will not return it again, so capture it in the same run. Requires an API token with Account Access: Service Tokens Edit."},{"name":"Revoke Access Service Token","description":"Permanently deletes a Cloudflare Access (Zero Trust) service token, revoking it. Every machine or integration still presenting that client ID and secret is locked out of the Access-protected applications immediately, and the secret cannot be recovered. This cannot be undone. Requires an API token with Account Access: Service Tokens Edit."},{"name":"Get Access Service Token","description":"Fetches a single service token."},{"name":"Refresh Access Service Token","description":"Refreshes the expiration of a service token."},{"name":"Rotate Access Service Token","description":"Generates a new Client Secret. The previous secret expires immediately unless previous_client_secret_expires_at schedules a later expiration."},{"name":"Update Access Service Token","description":"Updates a configured service token. Replaces the configuration; resend all values to retain."},{"name":"List R2 Buckets","description":"Lists the R2 object storage buckets in an account. Requires an API token with Account Workers R2 Storage Read."},{"name":"Get R2 Bucket","description":"Reads the metadata of a single R2 object storage bucket. Requires an API token with Account Workers R2 Storage Read."},{"name":"Create R2 Bucket","description":"Creates an R2 object storage bucket in an account. The location hint and jurisdiction are fixed at creation and cannot be changed later. Requires an API token with Account Workers R2 Storage Edit."},{"name":"Delete R2 Bucket","description":"Permanently deletes an R2 object storage bucket. Cloudflare only deletes an empty bucket, and the deletion cannot be undone. Requires an API token with Account Workers R2 Storage Edit."},{"name":"List Worker Scripts","description":"Lists the Workers scripts deployed in an account. Requires an API token with Account Workers Scripts Read."},{"name":"Get Worker Script Settings","description":"Reads the deployment settings of a single Workers script — bindings, compatibility date and flags, limits, observability, placement, and tail consumers. The plain \\"get script\\" endpoint in the Cloudflare API returns raw JavaScript source rather than JSON, so this settings endpoint is the structured way to inspect one script. Requires an API token with Account Workers Scripts Read."},{"name":"Delete Worker Script","description":"Delete your worker. This call has no response body on a successful delete."},{"name":"List Worker Routes","description":"Lists the Workers routes on a zone, showing which URL patterns are handled by which Worker script. Unlike the Workers script endpoints, routes are zone-scoped. Requires an API token with Zone Workers Routes Read."},{"name":"Create Worker Route","description":"Creates a route that maps a URL pattern to a Worker."},{"name":"Delete Worker Route","description":"Deletes a Worker route."},{"name":"Get Worker Route","description":"Returns information about a Worker route, including URL pattern and Worker."},{"name":"Update Worker Route","description":"Replaces the URL pattern or Worker associated with a Worker route. Replaces the configuration; resend all values to retain."},{"name":"List Tunnels","description":"Lists the Cloudflare Tunnels (cloudflared) in an account, with their health status and active connections. Requires an API token with Account Cloudflare Tunnel Read."},{"name":"Get Tunnel","description":"Reads a single Cloudflare Tunnel (cloudflared), including its health status and active connector connections. Requires an API token with Account Cloudflare Tunnel Read."},{"name":"Get Tunnel Configuration","description":"Reads the configuration of a remotely-managed Cloudflare Tunnel — its ingress rules, origin request settings, and WARP routing. Only tunnels whose configuration source is \\"cloudflare\\" have a remote configuration; locally-managed tunnels keep it in their own config file. Requires an API token with Account Cloudflare Tunnel Read."},{"name":"Update Tunnel Configuration","description":"Replaces the configuration for a remotely managed Cloudflare Tunnel, including its ingress rules and origin request settings. Replaces the configuration; resend all values to retain."},{"name":"Create Tunnel","description":"Creates a remotely or locally managed Cloudflare Tunnel in an account. After creation, retrieve its token and run cloudflared to establish the connector connection."},{"name":"Delete Tunnel","description":"Permanently deletes a Cloudflare Tunnel from an account. The tunnel must have no active connections."},{"name":"Delete R2 Bucket CORS","description":"Delete the CORS policy for a bucket."},{"name":"Get R2 Bucket CORS","description":"Get the CORS policy for a bucket."},{"name":"Update R2 Bucket CORS","description":"Replaces the Cross-Origin Resource Sharing (CORS) rules for an R2 bucket. Rules specify which origins, methods, and headers are allowed for browser requests to objects in the bucket. Replaces the configuration; resend all values to retain."},{"name":"Get R2 Bucket Lifecycle","description":"Get object lifecycle rules for a bucket."},{"name":"Update R2 Bucket Lifecycle","description":"Replaces the object lifecycle rules for an R2 bucket. Rules match object-key prefixes and can expire objects, abort incomplete multipart uploads, or transition objects to Infrequent Access storage. Replaces the configuration; resend all values to retain."},{"name":"Get Tunnel Token","description":"Gets the connector token used to run a remotely managed Cloudflare Tunnel with cloudflared."},{"name":"Update Tunnel","description":"Updates the name or secret of an existing Cloudflare Tunnel."}],"triggers":[],"skills":[{"name":"audit-dns-records","description":"Pull all DNS records for a Cloudflare zone and report on misconfigurations, dangling records, and sensitive record changes.","content":"# Audit Cloudflare DNS Records\\n\\nExport and review the DNS configuration for a zone to catch misconfigurations and risky records.\\n\\n## Steps\\n1. Resolve the zone ID for the target domain.\\n2. List every DNS record (A, AAAA, CNAME, MX, TXT, NS) for the zone.\\n3. Flag records that point to deprovisioned hosts, wildcard CNAMEs, missing SPF/DMARC TXT records, and proxied vs. unproxied mismatches.\\n4. Group findings by record type and severity.\\n\\n## Output\\nA prioritized list of DNS issues with the record name, type, current value, and recommended fix."},{"name":"purge-cache","description":"Purge Cloudflare cache for specific URLs or an entire zone after a deploy, then confirm what was cleared.","content":"# Purge Cloudflare Cache\\n\\nClear cached content so visitors see the latest deploy.\\n\\n## Steps\\n1. Identify the affected zone and the paths or hostnames that changed.\\n2. Purge by specific files when possible; only purge everything for the zone if the change is global.\\n3. Confirm the purge succeeded and note the timestamp.\\n\\n## Output\\nA short confirmation listing the zone, the purged URLs (or \\"full zone\\"), and the purge time."},{"name":"check-ssl-and-zone-settings","description":"Inspect SSL certificate status and security settings for Cloudflare zones and report drift from a desired baseline.","content":"# Check SSL and Zone Settings\\n\\nVerify SSL/TLS posture and key security settings across zones.\\n\\n## Steps\\n1. List the target zones.\\n2. For each zone read SSL mode, certificate status/expiry, minimum TLS version, and security level.\\n3. Compare against the desired baseline (e.g. Full Strict, TLS 1.2+).\\n4. Flag expiring certs and any setting weaker than the baseline.\\n\\n## Output\\nA per-zone table of SSL status, settings, and any drift that needs remediation."},{"name":"provision-new-zone","description":"Onboard a new domain onto Cloudflare: create the zone, add starter DNS records, and return the nameservers to hand off for delegation.","content":"# Provision a New Cloudflare Zone\\n\\nStand up a new domain on Cloudflare so it can be pointed at Cloudflare nameservers.\\n\\n## Steps\\n1. Create the zone for the domain under the target account.\\n2. Add the initial DNS records the domain needs (A/AAAA for the apex, CNAME for www, MX/TXT for mail as required).\\n3. Read back the assigned Cloudflare name servers from the created zone.\\n4. Summarize the zone ID, initial records created, and the name servers the registrar needs to be updated to.\\n\\n## Output\\nThe new zone ID, the records created, and the name servers to hand off for delegation."},{"name":"setup-email-authentication-records","description":"Add or update the SPF, DKIM, and DMARC TXT records a zone needs to authenticate outbound email and improve deliverability.","content":"# Set Up Email Authentication Records\\n\\nEmail providers (Google Workspace, Microsoft 365, transactional senders) require SPF, DKIM, and DMARC TXT records to authenticate mail and avoid it being marked as spam.\\n\\n## Steps\\n1. Resolve the zone ID for the sending domain.\\n2. List existing TXT records to check for conflicting or duplicate SPF/DMARC entries.\\n3. Create or update the SPF TXT record (`v=spf1 ...`), the DKIM selector TXT record, and the DMARC TXT record (`_dmarc` name, `v=DMARC1; ...` policy) with the values the mail provider supplies.\\n4. Confirm each record was created with the correct name, type, and content.\\n\\n## Output\\nA confirmation of the SPF, DKIM, and DMARC records now in place, with their record IDs and TTLs."},{"name":"deploy-waf-custom-rule","description":"Add a WAF custom rule to a Cloudflare zone through the Rulesets engine, blocking or challenging traffic that matches a filter expression.","content":"# Deploy a WAF Custom Rule\\n\\nWAF custom rules live in the `http_request_firewall_custom` phase of the Rulesets engine, so the ruleset ID has to be resolved before a rule can be added.\\n\\n## Steps\\n1. Resolve the zone ID for the target domain.\\n2. Read the `http_request_firewall_custom` phase entry point ruleset for that zone to get its ruleset ID and current rules.\\n3. Write the filter expression for the traffic to act on (e.g. `(ip.src.country in {\\"GB\\" \\"FR\\"})` or `(http.request.uri.path matches \\"^/admin\\")`).\\n4. Create the rule in that ruleset with the chosen action — `block`, `managed_challenge`, `js_challenge`, `challenge`, `skip`, or `log`. Start with `log` to observe impact before enforcing.\\n5. Read the ruleset back and confirm the new rule appears in the intended evaluation order.\\n\\n## Output\\nThe ruleset ID, the new rule ID, its expression and action, and its position in the evaluation order.\\n\\n## Cautions\\nRules take effect on live traffic immediately. A broad expression with `block` can lock out legitimate users, so verify the expression in `log` mode first."},{"name":"rate-limit-an-api-endpoint","description":"Protect an API path from abuse with a Cloudflare rate limiting rule using the current Rulesets-based rate limiting API.","content":"# Rate Limit an API Endpoint\\n\\nRate limiting rules are rules in the `http_ratelimit` phase entry point ruleset. The legacy `rate_limits` endpoint is no longer the way to do this.\\n\\n## Steps\\n1. Resolve the zone ID for the domain serving the API.\\n2. List the existing rate limiting rules to get the `http_ratelimit` entry point ruleset ID and see what is already in place.\\n3. Decide the counting characteristics. `cf.colo.id` is mandatory. `ip.src` (per IP) and `cf.unique_visitor_id` (per visitor) are mutually exclusive - include at most one, and neither is required; a rule keyed on host, path, country, header or cookie alone is valid. Add `http.request.headers[\\"\\"]` to count per API key.\\n4. Pick a counting period (10, 60, 120, 300, 600, or 3600 seconds) and the request allowance for that period.\\n5. Create the rule with the matching expression (e.g. `(http.request.uri.path matches \\"^/api/\\")`), the counting configuration, and the mitigation action.\\n6. Read the rules back and confirm the new rule and its limit.\\n\\n## Output\\nThe ruleset ID, the new rule ID, the expression, and the effective limit (requests per period, characteristics, and mitigation timeout).\\n\\n## Cautions\\nThe rule applies to live traffic as soon as it is created. Size the allowance against real traffic before choosing `block` over `log` or `managed_challenge`."},{"name":"review-zero-trust-access","description":"Audit Cloudflare Access applications and their policies to find unprotected apps, over-broad rules, and bypass decisions.","content":"# Review Zero Trust Access\\n\\nAccess applications and policies are account-scoped. An application with no policy denies everyone; a broad `allow` policy lets in more than intended.\\n\\n## Steps\\n1. List the Access applications in the account.\\n2. For each application, list its policies in precedence order.\\n3. List the configured identity providers so `allowed_idps` values can be read as names rather than IDs.\\n4. Flag applications with no policies, `allow` policies whose include rules are a whole email domain or `everyone`, any `bypass` decision, and applications with no `allowed_idps` restriction.\\n5. Note session durations that are longer than the organization allows.\\n\\n## Output\\nA per-application summary of domain, type, identity providers, policy decisions and include rules, and the flagged findings ranked by risk."}],"templates":[{"title":"Cloudflare DNS change tracker","prompt":"Create a scheduled workflow that pulls every Cloudflare DNS record for my zones each hour, diffs the snapshot against the previous run, logs added, removed, and modified records to a table, and posts a Slack alert when sensitive records like MX or NS change.","integrations":[{"id":"cloudflare","name":"Cloudflare"},{"id":"slack","name":"Slack"}]},{"title":"Cloudflare cache purge on deploy","prompt":"Build a workflow that fires when a Vercel deployment succeeds on production, purges the Cloudflare cache for the affected hostnames, verifies the new content is being served, and posts a confirmation message to Slack with the purged paths.","integrations":[{"id":"cloudflare","name":"Cloudflare"},{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]},{"title":"Cloudflare SSL and zone check","prompt":"Create a scheduled weekly workflow that inspects every Cloudflare zone for SSL certificate status, security level, and zone settings drift, logs findings to a table, and opens Linear tickets for any zones that need attention.","integrations":[{"id":"cloudflare","name":"Cloudflare"},{"id":"linear","name":"Linear"}]},{"title":"Cloudflare DNS analytics digest","prompt":"Build a scheduled workflow that pulls Cloudflare DNS analytics for the top zones every Monday, identifies query spikes, anomalies, and surges in particular record types, and emails a written analysis to the platform team with traffic graphs and recommendations.","integrations":[{"id":"cloudflare","name":"Cloudflare"}]},{"title":"Cloudflare zone provisioning","prompt":"Create a workflow that accepts a domain name from a form, creates a new Cloudflare zone, sets opinionated default DNS records and zone settings, generates the nameserver instructions, and posts the setup summary to Slack so the team can finalize delegation.","integrations":[{"id":"cloudflare","name":"Cloudflare"},{"id":"slack","name":"Slack"}]},{"title":"Cloudflare DNS bulk importer","prompt":"Build a workflow that reads a table of DNS records — name, type, content, TTL — validates each row, creates or updates the matching record in Cloudflare, and writes results back to the table so DNS changes are versioned and reviewable.","integrations":[{"id":"cloudflare","name":"Cloudflare"}]},{"title":"Cloudflare zone policy enforcer","prompt":"Create a scheduled workflow that reads a baseline of required Cloudflare zone settings from a knowledge base, compares it against every zone weekly, automatically reverts unauthorized changes, and emails a compliance report to security leadership.","integrations":[{"id":"cloudflare","name":"Cloudflare"}]},{"title":"Cloudflare WAF and rate limit rollout","prompt":"Build a workflow that reads a table of WAF rules — expression, action, and rate limit — validates each row against the zone it targets, deploys it into the matching Cloudflare ruleset phase, and posts a Slack summary of every rule created, changed, or skipped.","integrations":[{"id":"cloudflare","name":"Cloudflare"},{"id":"slack","name":"Slack"}]},{"title":"Cloudflare Zero Trust access review","prompt":"Create a scheduled monthly workflow that lists every Cloudflare Access application and its policies, flags applications with no policy, overly broad email-domain rules, or bypass decisions, logs the findings to a table, and emails an access review to security leadership.","integrations":[{"id":"cloudflare","name":"Cloudflare"}]}]},{"id":"cloudformation","type":"cloudformation","slug":"cloudformation","name":"CloudFormation","description":"Manage and inspect AWS CloudFormation stacks, resources, and drift","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/cloudformation","authType":"none","connections":[],"operations":[{"name":"Describe Stacks","description":"List and describe CloudFormation stacks"},{"name":"Create Stack","description":"Create a new CloudFormation stack from a template"},{"name":"Update Stack","description":"Update an existing CloudFormation stack with a new or previous template"},{"name":"Delete Stack","description":"Delete a CloudFormation stack and its resources"},{"name":"Cancel Update Stack","description":"Cancel an in-progress stack update and roll back to the last known stable state"},{"name":"Create Change Set","description":"Preview the changes a stack create or update would make before applying them"},{"name":"Describe Change Set","description":"View the resource changes a change set would make and its execution status"},{"name":"Execute Change Set","description":"Apply a previously created and reviewed change set to its stack"},{"name":"List Stack Resources","description":"List all resources in a CloudFormation stack"},{"name":"Describe Stack Events","description":"Get the event history for a CloudFormation stack"},{"name":"Detect Stack Drift","description":"Initiate drift detection on a CloudFormation stack"},{"name":"Drift Detection Status","description":"Check the status of a stack drift detection operation"},{"name":"Get Template","description":"Retrieve the template body for a CloudFormation stack"},{"name":"Get Template Summary","description":"Get a summary of a template or deployed stack: resource types, required capabilities, and parameters, without full validation"},{"name":"Validate Template","description":"Validate a CloudFormation template for syntax and structural correctness"}],"triggers":[],"skills":[{"name":"detect-stack-drift","description":"Run drift detection on CloudFormation stacks and summarize resources whose live config no longer matches the template.","content":"# Detect CloudFormation Stack Drift\\n\\nFind resources that have been changed outside of CloudFormation.\\n\\n## Steps\\n1. List the target stacks (or accept a specific stack name).\\n2. Initiate drift detection for each stack and poll until detection completes.\\n3. Pull the drift results and isolate resources with status DRIFTED or DELETED.\\n4. For each drifted resource, summarize the property differences.\\n\\n## Output\\nA per-stack drift report listing each drifted resource, its type, and the specific properties that differ from the template."},{"name":"inventory-stacks","description":"List CloudFormation stacks with their status, region, and resources to build a single inventory of deployed infrastructure.","content":"# Inventory CloudFormation Stacks\\n\\nBuild a unified view of all deployed stacks.\\n\\n## Steps\\n1. List every stack and capture name, status, creation/update time, and region.\\n2. For each stack, describe its resources and count them by type.\\n3. Highlight stacks in failed or rollback states.\\n\\n## Output\\nA table of stacks with status, region, resource count, and any stacks needing attention."},{"name":"investigate-stack-failure","description":"Pull recent CloudFormation stack events to diagnose a failed create, update, or rollback and explain the root cause.","content":"# Investigate CloudFormation Stack Failure\\n\\nDiagnose why a stack operation failed.\\n\\n## Steps\\n1. Describe the target stack and confirm its current status.\\n2. Pull recent stack events, ordered newest first.\\n3. Find the first FAILED event and read its resource status reason.\\n4. Trace any dependent resource failures that cascaded from it.\\n\\n## Output\\nA plain-English root-cause summary naming the failing resource, the error reason, and a suggested fix."},{"name":"preview-stack-change","description":"Create a CloudFormation change set to preview what a stack update would do before applying it.","content":"# Preview a CloudFormation Stack Change\\n\\nSafely preview changes before they are applied to a live stack.\\n\\n## Steps\\n1. Create a change set against the target stack with the new template or parameters.\\n2. Describe the change set and list each resource action (Add, Modify, Remove) and whether it requires replacement.\\n3. Flag any replacement or deletion of stateful resources (databases, storage) for extra scrutiny.\\n4. Only execute the change set after the changes have been reviewed and approved.\\n\\n## Output\\nA list of proposed resource changes with the replacement risk for each, and confirmation of whether the change set was executed."}],"templates":[{"title":"CloudFormation drift detector","prompt":"Create a scheduled daily workflow that runs drift detection on every CloudFormation stack in my AWS account, waits for detection to complete, summarizes drifted resources, logs them to a table, and posts a Slack alert when any production stack drifts.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"slack","name":"Slack"}]},{"title":"CloudFormation stack inventory","prompt":"Build a scheduled weekly workflow that describes every CloudFormation stack, lists its resources, and writes a unified inventory of stacks, status, region, and resource counts into a tracking table so the platform team has a single source of truth.","integrations":[{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation template validator","prompt":"Create a workflow triggered when a CloudFormation template is changed in a GitHub pull request. Pull the template, validate it via the CloudFormation API, summarize any syntax or structural errors, and post the validation result as a PR comment to block merges on broken templates.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"github","name":"GitHub"}]},{"title":"CloudFormation failure investigator","prompt":"Build a scheduled workflow that polls CloudFormation stack events every few minutes, detects rollbacks and create-failed events, pulls the failure reason and recent events from the stack, summarizes the root cause, opens a Linear ticket with the diagnosis, and posts to the on-call Slack channel.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"CloudFormation template archive","prompt":"Create a scheduled workflow that retrieves the deployed template for every CloudFormation stack, stores each template as a versioned file in your files store, and updates a knowledge base so engineers can search infrastructure definitions in natural language.","integrations":[{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation change report","prompt":"Build a scheduled weekly workflow that pulls CloudFormation stack events, summarizes resource creates, updates, and deletes across the account, classifies risky changes, and writes a written change report file for platform leadership review.","integrations":[{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation pre-deploy drift gate","prompt":"Create a workflow that runs before a deploy, initiates drift detection on the target CloudFormation stack, polls until drift detection completes, and either approves the deploy or blocks it with a Slack alert explaining the drifted resources.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"slack","name":"Slack"}]},{"title":"CloudFormation change set approval","prompt":"Build a workflow that creates a CloudFormation change set for a stack update, describes the proposed resource changes, posts a summary to Slack for approval, and executes the change set only after an approver replies, otherwise deletes the change set.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"slack","name":"Slack"}]},{"title":"CloudFormation environment provisioner","prompt":"Create a workflow that takes an environment name and template parameters as input, creates a new CloudFormation stack for that environment, polls stack events until it reaches CREATE_COMPLETE or fails, and posts the stack outputs to Slack.","integrations":[{"id":"cloudformation","name":"CloudFormation"},{"id":"slack","name":"Slack"}]}]},{"id":"cloudtrail","type":"cloudtrail","slug":"cloudtrail","name":"CloudTrail","description":"Audit who did what in AWS with CloudTrail event history and Lake queries","category":"Security","docsUrl":"https://docs.sim.ai/integrations/cloudtrail","authType":"api-key","connections":[],"operations":[{"name":"Look Up Events","description":"Look up AWS CloudTrail management or Insights events from the last 90 days in a Region"},{"name":"Describe Trails","description":"Retrieve the full configuration of one or more CloudTrail trails in the current Region"},{"name":"Get Trail","description":"Retrieve the settings of a single CloudTrail trail by name or ARN"},{"name":"Get Trail Status","description":"Check whether a CloudTrail trail is logging and surface its most recent delivery errors"},{"name":"List Trails","description":"List the ARN, name, and home Region of every CloudTrail trail visible to the account"},{"name":"Get Event Selectors","description":"Read which management, data, and network activity events a CloudTrail trail is configured to log"},{"name":"Get Insight Selectors","description":"Read which CloudTrail Insights types are enabled on a trail or event data store"},{"name":"Start Lake Query","description":"Start a CloudTrail Lake SQL query over an event data store"},{"name":"Describe Lake Query","description":"Check the status, run time, and scan statistics of a CloudTrail Lake query"},{"name":"Get Lake Query Results","description":"Fetch a page of result rows from a finished CloudTrail Lake query"},{"name":"Cancel Lake Query","description":"Cancel a running CloudTrail Lake query"},{"name":"List Event Data Stores","description":"List the CloudTrail Lake event data stores in the account for the current Region"},{"name":"Get Event Data Store","description":"Retrieve the configuration of a single CloudTrail Lake event data store"},{"name":"List Tags","description":"List the tags on CloudTrail trails, event data stores, dashboards, or channels"}],"triggers":[],"skills":[{"name":"investigate-aws-actor","description":"Trace everything a specific AWS user, role, or access key did in the last 90 days using CloudTrail event history. Use for incident response and offboarding reviews.","content":"# Investigate AWS Actor\\n\\nBuild a timeline of what one principal did in AWS.\\n\\n## Steps\\n1. Choose the lookup attribute that matches what you were given: Username for an IAM user or role session, AccessKeyId for a credential.\\n2. Look up events for that value, setting the start and end time to the window under investigation. CloudTrail event history only covers the last 90 days.\\n3. Page through with the returned pagination token until no token comes back. Look up events is limited to 50 events per page and two requests per second per Region, so pace the paging.\\n4. Read the parsed cloudTrailEvent record on each event for the source IP, user agent, request parameters, and any error code.\\n5. Group the calls by service and by source IP, and call out any write action or permission change.\\n\\n## Output\\nA chronological timeline of the calls, plus a short summary naming the services touched, the source IPs used, and any failed authorization attempts."},{"name":"audit-trail-coverage","description":"Verify that CloudTrail trails exist, are logging, and are configured to capture the events an audit requires. Use for SOC 2 and ISO evidence gathering.","content":"# Audit Trail Coverage\\n\\nProve that AWS API activity is actually being recorded.\\n\\n## Steps\\n1. List trails to enumerate every trail visible to the account, noting each home Region.\\n2. Describe trails to read the full configuration, including whether each is multi-Region, an organization trail, and whether log file validation is enabled.\\n3. Get trail status for each trail and flag any where logging is stopped or a recent delivery error is present.\\n4. Get event selectors for each trail to confirm management events are recorded and check which data resources are covered.\\n5. Note that trails outside the current Region must be addressed by ARN.\\n\\n## Output\\nA per-trail coverage report: logging state, multi-Region and organization scope, log file validation, delivery errors, and any gap in management or data event coverage."},{"name":"run-lake-query","description":"Run a SQL query against a CloudTrail Lake event data store, wait for it to finish, and return the rows. Use for aggregate audit questions that span more than 90 days.","content":"# Run Lake Query\\n\\nAnswer an aggregate audit question with CloudTrail Lake.\\n\\n## Steps\\n1. List event data stores, or get one by ARN, to find the store ID to query and confirm its retention period.\\n2. Compose the SQL, naming the event data store ID in the FROM clause.\\n3. Start the query to obtain a query ID.\\n4. Poll describe query with that query ID until the status is FINISHED, FAILED, CANCELLED, or TIMED_OUT.\\n5. On FINISHED, fetch the query results with the same query ID, paging with the returned token until no token comes back.\\n6. Cancel the query if it is no longer needed while still RUNNING.\\n\\n## Output\\nThe result rows, plus the query ID, events matched, events scanned, and run time. On failure, surface the error message and the SQL that produced it."}],"templates":[{"title":"CloudTrail root login alerter","prompt":"Create a scheduled workflow that looks up AWS CloudTrail ConsoleLogin events every 15 minutes, flags any sign-in by the root user or a login without MFA, and posts the actor, source IP, and time to a Slack security channel.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"slack","name":"Slack"}]},{"title":"CloudTrail IAM change review","prompt":"Build a daily workflow that looks up AWS CloudTrail events from iam.amazonaws.com, summarizes every policy attach, role creation, and access key change with the principal who made it, and writes the review to a compliance table.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"iam","name":"AWS IAM"}]},{"title":"CloudTrail trail health monitor","prompt":"Create a scheduled workflow that lists every AWS CloudTrail trail, checks each trail status for logging stopped or recent delivery errors, and opens a PagerDuty incident when a trail stops recording.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"CloudTrail access key forensics","prompt":"Build a workflow that takes an AWS access key ID, looks up every CloudTrail event made with it in the last 90 days, groups the calls by service and source IP, and returns a timeline of what that credential did.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"slack","name":"Slack"}]},{"title":"CloudTrail Lake audit agent","prompt":"Build a Slack agent that turns natural-language audit questions into CloudTrail Lake SQL, starts the query, polls until it finishes, and returns the result rows with the SQL it ran for review.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"slack","name":"Slack"}]},{"title":"CloudTrail data-event coverage audit","prompt":"Create a weekly workflow that reads the event selectors of every AWS CloudTrail trail, reports which trails are missing management event logging or S3 data events, and writes the gaps to a compliance table.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"s3","name":"S3"}]},{"title":"CloudTrail offboarding evidence pack","prompt":"Build a workflow that, given a departing employee username, looks up all their AWS CloudTrail activity from the last 90 days, summarizes the resources they touched, and emails an evidence pack to the security team.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"gmail","name":"Gmail"}]},{"title":"CloudTrail Insights anomaly digest","prompt":"Create a daily workflow that looks up AWS CloudTrail Insights events, correlates each API call-rate or error-rate anomaly with the principals active at that time, and posts a digest to Slack.","integrations":[{"id":"cloudtrail","name":"CloudTrail"},{"id":"slack","name":"Slack"}]}]},{"id":"cloudwatch","type":"cloudwatch","slug":"cloudwatch","name":"CloudWatch","description":"Query and monitor AWS CloudWatch logs, metrics, and alarms","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/cloudwatch","authType":"none","connections":[],"operations":[{"name":"Query Logs (Insights)","description":"Run a CloudWatch Log Insights query against one or more log groups"},{"name":"Filter Log Events","description":"Search log events across all streams in a log group by filter pattern and time range, without writing a Log Insights query"},{"name":"Describe Log Groups","description":"List available CloudWatch log groups"},{"name":"Get Log Events","description":"Retrieve log events from a specific CloudWatch log stream"},{"name":"Describe Log Streams","description":"List log streams within a CloudWatch log group"},{"name":"Set Log Group Retention","description":"Set (or clear, for never-expire) the retention period for a CloudWatch log group"},{"name":"List Metrics","description":"List available CloudWatch metrics"},{"name":"Get Metric Statistics","description":"Get statistics for a CloudWatch metric over a time range"},{"name":"Publish Metric","description":"Publish a custom metric data point to CloudWatch"},{"name":"Describe Alarms","description":"List and filter CloudWatch alarms"},{"name":"Describe Alarm History","description":"Retrieve state-change and configuration history for CloudWatch alarms"},{"name":"Mute Alarm","description":"Create a CloudWatch alarm mute rule that suppresses alarms for a fixed duration"},{"name":"Unmute Alarm","description":"Delete a CloudWatch alarm mute rule, restoring alarm notifications"}],"triggers":[],"skills":[{"name":"investigate-error-spike","description":"Run a CloudWatch Logs Insights query to find and summarize error spikes in a log group over a time window.","content":"# Investigate CloudWatch Error Spike\\n\\nFind the cause of an error spike using Logs Insights.\\n\\n## Steps\\n1. Identify the relevant log group and the time window to investigate.\\n2. Run a Logs Insights query that filters for error or exception lines and aggregates by error type.\\n3. Pull representative sample log events for the top error groups.\\n4. Correlate timing with any recent deploys or traffic changes.\\n\\n## Output\\nA summary of the top error types, their counts, sample messages, and the likely cause."},{"name":"check-metric-health","description":"Pull CloudWatch metric statistics for a resource and report whether key metrics are within healthy ranges.","content":"# Check CloudWatch Metric Health\\n\\nReview key metrics for a resource against expected thresholds.\\n\\n## Steps\\n1. Identify the namespace, metric names, and dimensions for the resource (e.g. CPUUtilization, latency, error rate).\\n2. Get metric statistics over the chosen window with an appropriate period and statistic (Average, p99, Sum).\\n3. Compare values against healthy thresholds.\\n\\n## Output\\nA per-metric summary with the current value, trend, and whether it is within a healthy range."},{"name":"review-alarm-state","description":"List CloudWatch alarms, report which are in ALARM or INSUFFICIENT_DATA, and optionally mute noisy alarms.","content":"# Review CloudWatch Alarm State\\n\\nGet a snapshot of alarm health across the account.\\n\\n## Steps\\n1. Describe alarms and group them by state (OK, ALARM, INSUFFICIENT_DATA).\\n2. For alarms in ALARM, capture the metric, threshold, and reason.\\n3. If asked, mute alarms that are known-noisy during a maintenance window and note them.\\n\\n## Output\\nA list of alarms currently firing or missing data, with the metric and threshold for each."}],"templates":[{"title":"CloudWatch alarm digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of CloudWatch alarms by service and severity, identifies repeat offenders, and posts a digest to Slack.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"slack","name":"Slack"}]},{"title":"CloudWatch log triage","prompt":"Build a scheduled workflow that runs CloudWatch Logs Insights queries hourly for error patterns, clusters matches, writes top groups to a triage table, and pings the on-call engineer.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"CloudWatch cost-control alerts","prompt":"Create a scheduled workflow that pulls CloudWatch billing alarms daily, projects month-end spend by service, and posts an alert when projection exceeds budget thresholds.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"slack","name":"Slack"}]},{"title":"CloudWatch incident scribe","prompt":"Build a scheduled workflow that polls CloudWatch alarms every few minutes for any in ALARM state, captures the surrounding metrics and recent log excerpts, and writes a timeline file for the incident review.","integrations":[{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"CloudWatch SLO burn-rate watcher","prompt":"Create a workflow that monitors CloudWatch SLO burn rate every five minutes, classifies severity, and pages the on-call team via PagerDuty when burn exceeds fast-burn thresholds.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"CloudWatch metric archiver","prompt":"Build a scheduled workflow that exports CloudWatch metric snapshots into S3 long-term storage, preserving granularity for compliance, and writing a manifest table.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"s3","name":"S3"}]},{"title":"CloudWatch log error triager","prompt":"Create a workflow that runs a CloudWatch Logs Insights query against application log groups every few minutes, groups recurring error signatures with an agent, opens a Linear issue for any new error pattern, and posts a Slack alert.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline rollback brake","prompt":"Create a workflow that watches CloudWatch alarms after a deployment, and when an error-rate alarm fires while a CodePipeline execution is in progress, stops the execution with a reason and notifies the release channel.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"codepipeline","name":"CodePipeline"},{"id":"slack","name":"Slack"}]},{"title":"DynamoDB hot-partition watcher","prompt":"Build a scheduled workflow that pulls DynamoDB CloudWatch metrics, identifies hot partitions and throttled requests, and writes the report to a Slack channel with mitigation suggestions.","integrations":[{"id":"cloudwatch","name":"CloudWatch"},{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"slack","name":"Slack"}]}]},{"id":"coda","type":"coda","slug":"coda","name":"Coda","description":"Read and write Coda docs, pages, tables, and rows","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/coda","authType":"api-key","connections":[{"id":"coda-service-account","kind":"service_account","providerId":"coda-service-account","label":"Add API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/coda","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste a Coda API token","secret":true}]}],"operations":[{"name":"List Docs","description":"List Coda docs the user has opened, most recently used first, filtered by search, owner, publishing, stars, workspace, folder, or source doc"},{"name":"Get Doc","description":"Get metadata for a Coda doc, including its owner, workspace, folder, size, and publishing settings"},{"name":"Create Doc","description":"Create a Coda doc, optionally copying an existing doc and setting up its first page with Markdown, HTML, an embed, or a sync page. Requires Doc Maker access in the workspace."},{"name":"Update Doc","description":"Rename a Coda doc or change its icon. Renaming requires Doc Maker access in the workspace."},{"name":"Delete Doc","description":"Delete a Coda doc"},{"name":"Publish Doc","description":"Publish a Coda doc or update its publishing settings: URL slug, discoverability, categories, and interaction mode. The doc owner needs a Coda maker profile."},{"name":"Unpublish Doc","description":"Unpublish a Coda doc"},{"name":"List Doc Categories","description":"List the categories that can be applied to a published Coda doc"},{"name":"List Custom Domains","description":"List the custom domains connected to a published Coda doc and their setup status"},{"name":"Add Custom Domain","description":"Connect a custom domain to a published Coda doc. Requires a Coda plan with custom domains."},{"name":"Delete Custom Domain","description":"Remove a custom domain from a published Coda doc"},{"name":"Get Custom Domain Provider","description":"Look up the DNS provider (GoDaddy, Namecheap, Hover, Network Solutions, Google Domains, or Other) of a custom domain"},{"name":"List Permissions","description":"List who a Coda doc is shared with and their access levels"},{"name":"Share Doc","description":"Share a Coda doc with a user, group, domain, workspace, or anyone with the link. Sharing with an email sends a notification unless suppressed."},{"name":"Remove Permission","description":"Revoke a sharing permission on a Coda doc"},{"name":"Search Users and Groups","description":"Search for users and groups a Coda doc can be shared with (up to 20 of each). Returns nothing without a query."},{"name":"Get Sharing Metadata","description":"Check whether the connected user can share or copy a Coda doc, and whether they can share it with the workspace or organization"},{"name":"Get Sharing Settings","description":"Get the sharing settings of a Coda doc"},{"name":"Update Sharing Settings","description":"Update who can change permissions, copy, or request edit access on a Coda doc; unset settings are left unchanged"},{"name":"List Pages","description":"List the pages in a Coda doc, including their hierarchy"},{"name":"Get Page","description":"Get metadata for a page in a Coda doc"},{"name":"Create Page","description":"Create a page in a Coda doc, optionally as a subpage, with Markdown or HTML content, a full-page embed, or a sync page from another doc. The page is created asynchronously. Requires Doc Maker access."},{"name":"Update Page","description":"Update a Coda page: rename it, change its subtitle, icon, cover, or visibility, and append, prepend, or replace content with Markdown or HTML. Applied asynchronously."},{"name":"Delete Page","description":"Delete a page from a Coda doc. Applied asynchronously."},{"name":"Get Page Content","description":"Read the content of a Coda canvas page as plain-text lines with their styles (headings, paragraphs, lists, quotes, code) and element IDs"},{"name":"Delete Page Content","description":"Delete specific content elements from a Coda page, or all of its content when no element IDs are given. Applied asynchronously."},{"name":"Export Page","description":"Start exporting a Coda page as HTML or Markdown. Poll Get Page Export Status with the returned export ID for the download link."},{"name":"Get Page Export Status","description":"Check a Coda page export and get its download link once complete. Download links expire shortly after they are issued."},{"name":"List Tables","description":"List the tables and views in a Coda doc"},{"name":"Get Table","description":"Get details about a table or view in a Coda doc, including its row count, sorts, layout, and filter"},{"name":"List Columns","description":"List the columns of a Coda table with their IDs, formats, and formulas. Use column IDs when reading and writing rows."},{"name":"Get Column","description":"Get details about a column in a Coda table, including its full format settings"},{"name":"List Rows","description":"List rows in a Coda table or view, optionally filtered by a column value, sorted, or limited to rows changed since a sync token"},{"name":"Get Row","description":"Get a single row from a Coda table, including all of its cell values"},{"name":"Insert or Upsert Rows","description":"Insert rows into a Coda base table, or update matching rows when key columns are given. Only works on base tables, not views. Applied asynchronously."},{"name":"Update Row","description":"Update cell values in a row of a Coda table. Applied asynchronously."},{"name":"Delete Row","description":"Delete a row from a Coda table or view. Applied asynchronously."},{"name":"Delete Rows","description":"Delete multiple rows from a Coda table or view by ID. Applied asynchronously."},{"name":"Push Button","description":"Push a button column on a row of a Coda table, running its action. The button can perform any action in the doc."},{"name":"List Formulas","description":"List the named formulas in a Coda doc"},{"name":"Get Formula","description":"Get the current computed value of a named formula in a Coda doc"},{"name":"List Controls","description":"List the controls (sliders, selects, checkboxes, date pickers, buttons, etc.) in a Coda doc"},{"name":"Get Control","description":"Get the type and current value of a control in a Coda doc"},{"name":"Trigger Automation","description":"Trigger a webhook-invoked automation in a Coda doc, optionally passing a JSON payload the automation can read"},{"name":"List Folders","description":"List the Coda folders the user can access, optionally within one workspace"},{"name":"Get Folder","description":"Get details about a Coda folder"},{"name":"Create Folder","description":"Create a folder in a Coda workspace"},{"name":"Update Folder","description":"Rename a Coda folder or change its description. Coda can return the folder as it was before the change; read it again to confirm."},{"name":"Delete Folder","description":"Delete an empty Coda folder (it must contain no docs)"},{"name":"List Subfolders","description":"List the direct subfolders of a Coda folder. Subfolders you cannot access but manage the parent of are returned with only an ID and restricted visibility."},{"name":"List Workspace Members","description":"List the members of a Coda workspace with their roles and doc activity, requesting user first. The workspace must belong to an organization."},{"name":"Change User Role","description":"Change the workspace role of a Coda user. Requires Admin access in a workspace that belongs to an organization."},{"name":"List Workspace Role Activity","description":"Get monthly counts of active and inactive Admins, Doc Makers, and Editors in a workspace. The workspace must belong to an organization."},{"name":"List Doc Analytics","description":"Get per-day or cumulative analytics (views, copies, likes, sessions by device, AI credits) for Coda docs"},{"name":"List Page Analytics","description":"Get daily analytics (views, sessions, users, time viewed) for each page of a Coda doc. Only available for docs in Enterprise workspaces."},{"name":"Get Doc Analytics Summary","description":"Get the total number of sessions across the Coda docs the user can access"},{"name":"Get Analytics Last Updated","description":"Get the dates (Pacific time) Coda analytics were last refreshed, to know how current analytics data is"},{"name":"Resolve Browser Link","description":"Resolve a Coda browser URL (doc, page, table, row, etc.) into its resource type and ID for use in other Coda operations"},{"name":"Get Mutation Status","description":"Check whether a queued Coda change (row, page, publish, or automation request) has been applied. Status is kept for about a day."},{"name":"Get Current User","description":"Get the user and default workspace behind the connected Coda API token"}],"triggers":[],"skills":[{"name":"log-action-items-to-coda","description":"Turn meeting notes or a conversation into action items and add them as rows in a Coda tasks table.","content":"# Log Action Items to Coda\\n\\nCapture follow-ups from a meeting or thread in a Coda tasks table.\\n\\n## Steps\\n1. Extract each action item with its owner, due date, and a one-line description.\\n2. List the columns of the target Coda table to get the exact column IDs or names.\\n3. Insert one row per action item, mapping each field to its column. Use the task name as an upsert key when re-running on the same notes.\\n4. Keep the returned request ID and check the mutation status if you need to confirm the rows were written.\\n\\n## Output\\nThe number of rows added and the list of action items with their owners."},{"name":"answer-from-coda-table","description":"Answer a question using the rows of a Coda table, filtering by a column value when possible.","content":"# Answer From Coda Table\\n\\nUse a Coda table as the source of truth for a question.\\n\\n## Steps\\n1. If only a Coda link is given, resolve the browser link to get the doc and table IDs.\\n2. List the table columns to find the columns relevant to the question.\\n3. List rows with column names enabled, filtering on a single column value when the question names one.\\n4. Page through results with the page token until you have the rows you need.\\n5. Answer only from the returned values.\\n\\n## Output\\nA concise answer citing the row names and links used. Say so if no matching rows exist."},{"name":"write-status-update-page","description":"Draft a status update and prepend it to a Coda page as Markdown, keeping earlier updates below.","content":"# Write Status Update Page\\n\\nPublish a dated status update into an existing Coda page.\\n\\n## Steps\\n1. Gather the facts for the update (progress, risks, next steps) from the provided sources.\\n2. Write the update in Markdown with a dated heading and short bullet lists.\\n3. Update the Coda page with content mode set to prepend so the newest update is at the top.\\n4. Confirm the change with the returned request ID if needed.\\n\\n## Output\\nThe Markdown that was added and the page link."},{"name":"triage-coda-tracker-rows","description":"Review new rows in a Coda tracker table and update their status, priority, or owner columns.","content":"# Triage Coda Tracker Rows\\n\\nTriage incoming items (bugs, requests, tickets) stored in a Coda table.\\n\\n## Steps\\n1. List rows filtered to the untriaged status value.\\n2. For each row, decide priority and owner from its description.\\n3. Update each row with the triage fields using column names or IDs.\\n4. Push the row button column if the table uses a button to notify the owner.\\n\\n## Output\\nA table of triaged rows with the priority and owner assigned to each."},{"name":"audit-coda-doc-sharing","description":"Review who a Coda doc is shared with and flag public links or access outside the company domain.","content":"# Audit Coda Doc Sharing\\n\\nCheck a Coda doc for overly broad access.\\n\\n## Steps\\n1. List the permissions on the doc.\\n2. Flag any permission shared with anyone with the link, or with an email or domain outside the company domain.\\n3. Read the sharing settings to see whether editors can change permissions or viewers can copy the doc.\\n4. Remove a permission only when the user confirms it should be revoked.\\n\\n## Output\\nA list of risky permissions with the principal and access level, plus the current sharing settings."},{"name":"export-coda-page-markdown","description":"Export a Coda page as Markdown so its content can be summarized, archived, or synced elsewhere.","content":"# Export Coda Page as Markdown\\n\\nGet the full content of a Coda page as a Markdown file.\\n\\n## Steps\\n1. Start a page export with Markdown as the output format.\\n2. Check the export status with the returned export ID until the status is complete.\\n3. Use the download link right away; it expires shortly after it is issued.\\n4. If the export fails, read the page content directly as plain-text lines instead.\\n\\n## Output\\nThe download link or the page text, plus the page name."}],"templates":[{"title":"Coda meeting notes publisher","prompt":"Build a workflow that takes a meeting transcript, has an agent write a summary with decisions and action items, creates a Coda page for the meeting in the team doc, and inserts each action item as a row in the Coda tasks table with owner and due date.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda OKR progress report","prompt":"Create a scheduled workflow that reads the OKR table in a Coda doc every Friday, computes progress per objective from the key result rows, and appends a weekly progress summary to the OKR review page in Markdown.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda CRM lead upsert","prompt":"Build a workflow that receives new leads from a form webhook, has an agent normalize company and contact fields, and upserts each lead into a Coda CRM table keyed on email so repeat submissions update the existing row.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda bug tracker triage","prompt":"Create a workflow that lists new rows in a Coda bug tracker table, has an agent classify severity and suggest an owner for each bug, updates the rows with the triage fields, and posts the high-severity bugs to Slack.","integrations":[{"id":"coda","name":"Coda"},{"id":"slack","name":"Slack"}]},{"title":"Coda wiki to knowledge base","prompt":"Build a scheduled workflow that lists the pages of a Coda team wiki doc, reads each page as text, and syncs the content into a Sim knowledge base so agents can answer questions from the wiki.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda table to Sim table mirror","prompt":"Create a scheduled workflow that reads rows changed since the last run from a Coda table using its sync token and mirrors them into a Sim table for reporting and downstream agent runs.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda project status digest","prompt":"Build a scheduled workflow that reads the project tracker table in a Coda doc each morning, has an agent flag overdue and blocked projects, and emails a status digest to project leads with links to each row.","integrations":[{"id":"coda","name":"Coda"},{"id":"gmail","name":"Gmail"}]},{"title":"Coda doc access audit","prompt":"Create a scheduled workflow that lists the Coda docs in a workspace, reads the sharing permissions and sharing settings on each, and writes any docs shared with anyone or outside domains to an audit table for review.","integrations":[{"id":"coda","name":"Coda"}]},{"title":"Coda doc engagement report","prompt":"Build a scheduled workflow that pulls last week of Coda doc analytics, ranks docs by sessions and views, and posts the most and least used team docs to Slack so owners can archive stale docs.","integrations":[{"id":"coda","name":"Coda"},{"id":"slack","name":"Slack"}]}]},{"id":"codepipeline","type":"codepipeline","slug":"codepipeline","name":"CodePipeline","description":"Run, monitor, and approve AWS CodePipeline pipelines","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/codepipeline","authType":"api-key","connections":[],"operations":[{"name":"Start Execution","description":"Start a CodePipeline pipeline execution, optionally overriding pipeline variables"},{"name":"Get Pipeline State","description":"Get the current state of a CodePipeline pipeline, including stage and action status and pending approval tokens"},{"name":"Get Pipeline Structure","description":"Get the structure of a CodePipeline pipeline, including its stages, actions, and variables"},{"name":"List Pipelines","description":"List all CodePipeline pipelines in an AWS account and region"},{"name":"List Executions","description":"List recent executions of a CodePipeline pipeline with status and source revisions"},{"name":"List Action Executions","description":"List action-level execution history for a CodePipeline pipeline, including per-action status, timing, and error details"},{"name":"Get Execution","description":"Get details of a CodePipeline execution, including status, trigger, source revisions, and resolved variables"},{"name":"Stop Execution","description":"Stop a CodePipeline pipeline execution, either finishing in-progress actions or abandoning them"},{"name":"Retry Stage","description":"Retry the failed actions (or all actions) of a failed CodePipeline stage"},{"name":"Approve / Reject Approval","description":"Approve or reject a pending CodePipeline manual approval action. The approval token is available from Get Pipeline State on the pending approval action"},{"name":"Disable Stage Transition","description":"Prevent artifacts from transitioning into or out of a CodePipeline stage, freezing the pipeline at that point"},{"name":"Enable Stage Transition","description":"Re-enable artifacts transitioning into or out of a CodePipeline stage after it was disabled"}],"triggers":[],"skills":[{"name":"approve-pending-deployment","description":"Find a pending CodePipeline manual approval, summarize the change, and approve or reject it.","content":"# Approve Pending CodePipeline Deployment\\n\\nHandle a manual approval gate in a pipeline.\\n\\n## Steps\\n1. Get the pipeline state and locate the action awaiting approval (status InProgress on a manual approval action) and its approval token.\\n2. Pull the execution details for the stage to summarize what is being deployed (source revisions, trigger).\\n3. Submit the approval result with the token, the Approved or Rejected decision, and a summary explaining the decision.\\n\\n## Output\\nThe decision that was submitted, the approval summary, and the pipeline/stage/action it applied to."},{"name":"investigate-failed-pipeline","description":"Find the failing stage and action of a CodePipeline execution and report the error details.","content":"# Investigate Failed CodePipeline Execution\\n\\nDiagnose why a pipeline run failed.\\n\\n## Steps\\n1. List recent executions for the pipeline and identify the failed one (or use the provided execution ID).\\n2. Get the pipeline state and find the stage and action with a Failed status.\\n3. Capture the action error code, error message, and external execution URL, plus the source revisions that were being deployed.\\n4. If more history is needed than the current state shows, list action executions for the pipeline execution ID to see every action attempt with its status and error details.\\n\\n## Output\\nThe failing stage and action, the error details, the commit/revision involved, and a link to the external execution."},{"name":"freeze-pipeline-for-incident","description":"Disable a CodePipeline stage transition to freeze deployments during an incident, then re-enable it once resolved.","content":"# Freeze CodePipeline During an Incident\\n\\nStop new releases from reaching a stage without stopping an in-flight execution.\\n\\n## Steps\\n1. Disable the inbound (or outbound) transition on the affected stage with a reason describing the incident.\\n2. Confirm via the pipeline state or structure that the transition is disabled.\\n3. Once the incident is resolved, enable the transition again so releases resume flowing.\\n\\n## Output\\nThe stage and transition type that was disabled or re-enabled, and the reason recorded."},{"name":"trigger-pipeline-release","description":"Start a CodePipeline execution, optionally with variable overrides, and report the execution ID.","content":"# Trigger CodePipeline Release\\n\\nKick off a pipeline run.\\n\\n## Steps\\n1. Confirm the pipeline name (list pipelines if unsure).\\n2. Start the execution, passing any pipeline variable overrides (e.g. version or environment) and an idempotency token if retries are possible.\\n3. Optionally poll the pipeline state to confirm the execution entered the first stage.\\n\\n## Output\\nThe pipeline execution ID that was started and the variables it ran with."},{"name":"retry-failed-stage","description":"Retry the failed actions of a CodePipeline stage and confirm the stage re-entered execution.","content":"# Retry Failed CodePipeline Stage\\n\\nRe-run a failed stage without restarting the whole pipeline.\\n\\n## Steps\\n1. Get the pipeline state and identify the failed stage and the execution ID stuck in it.\\n2. Retry the stage with FAILED_ACTIONS mode (or ALL_ACTIONS if the whole stage should re-run).\\n3. Check the pipeline state again to confirm the stage is InProgress.\\n\\n## Output\\nThe stage that was retried, the retry mode used, and the current stage status."}],"templates":[{"title":"CodePipeline deploy approver","prompt":"Build a workflow that checks a CodePipeline pipeline for pending manual approvals, posts the change summary and source revisions to Slack, and approves or rejects the deployment based on the team lead reply.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline failure triage","prompt":"Create a scheduled workflow that polls CodePipeline executions every few minutes, and when one fails, pulls the pipeline state to find the failing stage and action error, opens a Linear issue, and alerts the on-call channel in Slack.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline release train","prompt":"Build a scheduled workflow that starts the release CodePipeline pipeline every weekday at 9am with the release version as a pipeline variable, then posts the execution ID and a link to Slack.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline deploy digest","prompt":"Create a scheduled daily workflow that lists executions across the team CodePipeline pipelines, summarizes successes, failures, and rollbacks with their source revisions, and posts a digest to Slack.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline flaky-stage retrier","prompt":"Build a scheduled workflow that finds failed CodePipeline executions, retries the failed stage once with failed-actions mode, and escalates to PagerDuty if the retry fails again.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"CodePipeline rollback brake","prompt":"Create a workflow that watches CloudWatch alarms after a deployment, and when an error-rate alarm fires while a CodePipeline execution is in progress, stops the execution with a reason and notifies the release channel.","integrations":[{"id":"codepipeline","name":"CodePipeline"},{"id":"cloudwatch","name":"CloudWatch"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline deployment audit log","prompt":"Build a scheduled workflow that records every CodePipeline execution — pipeline, status, trigger, source revisions, and timing — into a table for compliance and deployment-frequency reporting.","integrations":[{"id":"codepipeline","name":"CodePipeline"}]}]},{"id":"confluence","type":"confluence_v2","slug":"confluence","name":"Confluence","description":"Manage Confluence pages, comments, and attachments","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/confluence","authType":"oauth","connections":[{"id":"confluence","kind":"oauth","label":"Connect with OAuth","providerId":"confluence","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/confluence","requiredScopes":[{"id":"read:confluence-content.all","label":"Read all Confluence content"},{"id":"read:confluence-space.summary","label":"Read Confluence space information"},{"id":"read:space:confluence","label":"View Confluence spaces"},{"id":"write:confluence-content","label":"Create and edit Confluence pages, blog posts, and comments"},{"id":"write:confluence-space","label":"Manage Confluence spaces"},{"id":"write:confluence-file","label":"Upload files to Confluence"},{"id":"read:page:confluence","label":"View Confluence pages"},{"id":"write:page:confluence","label":"Create and update Confluence pages"},{"id":"read:comment:confluence","label":"View comments on Confluence pages"},{"id":"write:comment:confluence","label":"Create and update comments"},{"id":"delete:comment:confluence","label":"Delete comments from Confluence pages"},{"id":"delete:attachment:confluence","label":"Delete attachments from Confluence pages"},{"id":"delete:page:confluence","label":"Delete Confluence pages"},{"id":"read:label:confluence","label":"View labels on Confluence content"},{"id":"write:label:confluence","label":"Add and remove labels"},{"id":"read:attachment:confluence","label":"View attachments on Confluence pages"},{"id":"write:attachment:confluence","label":"Upload and manage attachments"},{"id":"search:confluence","label":"Search Confluence content"},{"id":"read:me","label":"Read profile information"},{"id":"offline_access","label":"Access account when not using the application"},{"id":"read:hierarchical-content:confluence","label":"View page hierarchy (children and ancestors)"},{"id":"read:content.metadata:confluence","label":"View content metadata (required for ancestors)"},{"id":"read:user:confluence","label":"View Confluence user profiles"},{"id":"read:confluence-user","label":"View Confluence user profiles (v1 API)"},{"id":"read:group:confluence","label":"View Confluence groups and memberships"},{"id":"read:task:confluence","label":"View Confluence inline tasks"},{"id":"write:task:confluence","label":"Update Confluence inline tasks"},{"id":"write:space:confluence","label":"Create and update Confluence spaces"},{"id":"delete:space:confluence","label":"Delete Confluence spaces"},{"id":"read:blogpost:confluence","label":"View Confluence blog posts"},{"id":"write:blogpost:confluence","label":"Create and update Confluence blog posts"},{"id":"delete:blogpost:confluence","label":"Delete Confluence blog posts"},{"id":"read:content.property:confluence","label":"View properties on Confluence content"},{"id":"write:content.property:confluence","label":"Create and manage content properties"},{"id":"read:space.property:confluence","label":"View Confluence space properties"},{"id":"write:space.property:confluence","label":"Create and manage space properties"},{"id":"read:space.permission:confluence","label":"View Confluence space permissions"}],"fields":[]},{"id":"atlassian-service-account","kind":"service_account","providerId":"atlassian-service-account","label":"Add service account","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/atlassian-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste the API token","secret":true},{"id":"domain","label":"Site domain","placeholder":"your-team.atlassian.net"}]}],"operations":[{"name":"Read Page","description":"Retrieve content from Confluence pages using the Confluence API."},{"name":"Create Page","description":"Create a new page in a Confluence space."},{"name":"Update Page","description":"Update a Confluence page using the Confluence API."},{"name":"Delete Page","description":"Delete a Confluence page. By default moves to trash; use purge=true to permanently delete."},{"name":"List Pages in Space","description":"List all pages within a specific Confluence space. Supports pagination and filtering by status."},{"name":"Get Page Children","description":"Get all child pages of a specific Confluence page. Useful for navigating page hierarchies."},{"name":"Get Page Ancestors","description":"Get the ancestor (parent) pages of a specific Confluence page. Returns the full hierarchy from the page up to the root."},{"name":"List Page Versions","description":"List all versions (revision history) of a Confluence page."},{"name":"Get Page Version","description":"Get details about a specific version of a Confluence page."},{"name":"List Page Properties","description":"List all custom properties (metadata) attached to a Confluence page."},{"name":"Create Page Property","description":"Create a new custom property (metadata) on a Confluence page."},{"name":"Delete Page Property","description":"Delete a content property from a Confluence page by its property ID."},{"name":"Search Content","description":"Search for content across Confluence pages, blog posts, and other content."},{"name":"Search in Space","description":"Search for content within a specific Confluence space. Optionally filter by text query and content type."},{"name":"List Blog Posts","description":"List all blog posts across all accessible Confluence spaces."},{"name":"Get Blog Post","description":"Get a specific Confluence blog post by ID, including its content."},{"name":"Create Blog Post","description":"Create a new blog post in a Confluence space."},{"name":"Update Blog Post","description":"Update an existing Confluence blog post title and/or content."},{"name":"Delete Blog Post","description":"Delete a Confluence blog post."},{"name":"List Blog Posts in Space","description":"List all blog posts within a specific Confluence space."},{"name":"Create Comment","description":"Add a comment to a Confluence page."},{"name":"List Comments","description":"List all comments on a Confluence page."},{"name":"Update Comment","description":"Update an existing comment on a Confluence page."},{"name":"Delete Comment","description":"Delete a comment from a Confluence page."},{"name":"Upload Attachment","description":"Upload a file as an attachment to a Confluence page."},{"name":"List Attachments","description":"List all attachments on a Confluence page."},{"name":"Delete Attachment","description":"Delete an attachment from a Confluence page (moves to trash)."},{"name":"List Labels","description":"List all labels on a Confluence page."},{"name":"Add Label","description":"Add a label to a Confluence page for organization and categorization."},{"name":"Delete Label","description":"Remove a label from a Confluence page."},{"name":"Get Pages by Label","description":"Retrieve all pages that have a specific label applied."},{"name":"List Space Labels","description":"List all labels associated with a Confluence space."},{"name":"Get Space","description":"Get details about a specific Confluence space."},{"name":"Create Space","description":"Create a new Confluence space."},{"name":"Update Space","description":"Update a Confluence space name or description."},{"name":"Delete Space","description":"Delete a Confluence space."},{"name":"List Spaces","description":"List all Confluence spaces accessible to the user."},{"name":"List Space Properties","description":"List properties on a Confluence space."},{"name":"Create Space Property","description":"Create a property on a Confluence space."},{"name":"Delete Space Property","description":"Delete a property from a Confluence space."},{"name":"List Space Permissions","description":"List permissions for a Confluence space."},{"name":"Get Page Descendants","description":"Get all descendants of a Confluence page recursively."},{"name":"List Tasks","description":"List inline tasks from Confluence. Optionally filter by page, space, assignee, or status."},{"name":"Get Task","description":"Get a specific Confluence inline task by ID."},{"name":"Update Task","description":"Update the status of a Confluence inline task (complete or incomplete)."},{"name":"Get User","description":"Get display name and profile info for a Confluence user by account ID."}],"triggers":[{"id":"confluence_page_created","name":"Confluence Page Created","description":"Trigger workflow when a new page is created in Confluence"},{"id":"confluence_page_updated","name":"Confluence Page Updated","description":"Trigger workflow when a page is updated in Confluence"},{"id":"confluence_page_removed","name":"Confluence Page Removed","description":"Trigger workflow when a page is removed or trashed in Confluence"},{"id":"confluence_page_moved","name":"Confluence Page Moved","description":"Trigger workflow when a page is moved in Confluence"},{"id":"confluence_page_restored","name":"Confluence Page Restored","description":"Trigger workflow when a page is restored from trash in Confluence"},{"id":"confluence_page_permissions_updated","name":"Confluence Page Permissions Updated","description":"Trigger workflow when page permissions are changed in Confluence"},{"id":"confluence_comment_created","name":"Confluence Comment Created","description":"Trigger workflow when a comment is created in Confluence"},{"id":"confluence_comment_removed","name":"Confluence Comment Removed","description":"Trigger workflow when a comment is removed in Confluence"},{"id":"confluence_comment_updated","name":"Confluence Comment Updated","description":"Trigger workflow when a comment is updated in Confluence"},{"id":"confluence_blog_created","name":"Confluence Blog Post Created","description":"Trigger workflow when a blog post is created in Confluence"},{"id":"confluence_blog_updated","name":"Confluence Blog Post Updated","description":"Trigger workflow when a blog post is updated in Confluence"},{"id":"confluence_blog_removed","name":"Confluence Blog Post Removed","description":"Trigger workflow when a blog post is removed in Confluence"},{"id":"confluence_blog_restored","name":"Confluence Blog Post Restored","description":"Trigger workflow when a blog post is restored from trash in Confluence"},{"id":"confluence_attachment_created","name":"Confluence Attachment Created","description":"Trigger workflow when an attachment is uploaded in Confluence"},{"id":"confluence_attachment_removed","name":"Confluence Attachment Removed","description":"Trigger workflow when an attachment is removed in Confluence"},{"id":"confluence_attachment_updated","name":"Confluence Attachment Updated","description":"Trigger workflow when an attachment is updated in Confluence"},{"id":"confluence_space_created","name":"Confluence Space Created","description":"Trigger workflow when a new space is created in Confluence"},{"id":"confluence_space_updated","name":"Confluence Space Updated","description":"Trigger workflow when a space is updated in Confluence"},{"id":"confluence_space_removed","name":"Confluence Space Removed","description":"Trigger workflow when a space is removed in Confluence"},{"id":"confluence_label_added","name":"Confluence Label Added","description":"Trigger workflow when a label is added to content in Confluence"},{"id":"confluence_label_removed","name":"Confluence Label Removed","description":"Trigger workflow when a label is removed from content in Confluence"},{"id":"confluence_user_created","name":"Confluence User Created","description":"Trigger workflow when a new user is added to Confluence"},{"id":"confluence_webhook","name":"Confluence Webhook (All Events)","description":"Trigger workflow on any Confluence webhook event"}],"skills":[{"name":"publish-meeting-notes","description":"Create a Confluence page with structured meeting notes including attendees, decisions, and action items in the right space.","content":"# Publish Meeting Notes to Confluence\\n\\nTurn raw meeting notes into a clean, structured Confluence page.\\n\\n## Steps\\n1. Confirm the target space and any parent page.\\n2. Structure the notes into sections: attendees, agenda, decisions, and action items with owners.\\n3. Create the page with a clear, dated title.\\n4. Return the page URL.\\n\\n## Output\\nA confirmation with the new page title and link, plus the list of action items captured."},{"name":"update-doc-page","description":"Read an existing Confluence page, apply updates, and save it back, respecting version control to avoid conflicts.","content":"# Update a Confluence Page\\n\\nSafely edit an existing documentation page.\\n\\n## Steps\\n1. Read the target page to get its current content and version number.\\n2. Apply the requested changes to the body, preserving existing structure and formatting.\\n3. Update the page, incrementing the version number by one to avoid optimistic-locking conflicts.\\n4. If the update fails on a version conflict, re-read and retry.\\n\\n## Output\\nA confirmation of the updated page with its new version number and link."},{"name":"search-knowledge","description":"Search Confluence content for a topic and summarize the most relevant pages with links for quick reference.","content":"# Search Confluence Knowledge\\n\\nFind and summarize documentation on a topic.\\n\\n## Steps\\n1. Search content using the topic keywords, optionally scoped to a space.\\n2. Read the top matching pages.\\n3. Summarize what each page covers and how it relates to the question.\\n\\n## Output\\nA short briefing answering the question, with links to the source pages cited."},{"name":"collect-page-feedback","description":"List and summarize comments on a Confluence page so you can triage feedback and open questions.","content":"# Collect Confluence Page Feedback\\n\\nGather and organize comments left on a page.\\n\\n## Steps\\n1. Read the target page to confirm its identity.\\n2. List all comments on the page.\\n3. Group comments into themes: questions, corrections, and approvals.\\n\\n## Output\\nA digest of comment themes with any unresolved questions flagged for follow-up."}],"templates":[{"title":"PagerDuty incident coordinator","prompt":"Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"},{"id":"pagerduty","name":"PagerDuty"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"Confluence knowledge base sync","prompt":"Create a knowledge base connected to my Confluence workspace so all wiki pages are automatically synced and searchable. Then build a scheduled workflow that identifies stale pages not updated in 90 days and sends a Slack reminder to page owners to review them.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"slack","name":"Slack"}]},{"title":"Confluence multi-source knowledge hub","prompt":"Create a knowledge base and connect it to Confluence, Notion, and Google Drive so all my company documentation is automatically synced, chunked, and embedded. Then deploy a Q&A agent that can answer questions across all sources with citations.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Confluence weekly contributor digest","prompt":"Build a scheduled workflow that aggregates the week’s new and updated Confluence pages, identifies top contributors, and posts a digest to the team Slack channel.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"slack","name":"Slack"}]},{"title":"Confluence space migration helper","prompt":"Create a workflow that takes a source Confluence space, copies pages into a target space with rewritten internal links, attachments, and labels, and writes a mapping table for redirects.","integrations":[{"id":"confluence","name":"Confluence"}]},{"title":"Confluence question router","prompt":"Build a workflow that watches a Confluence space for new questions, finds the right SME via labels, pings them on Slack, and updates the question page with a sourced answer once available.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"slack","name":"Slack"}]},{"title":"Confluence knowledge assistant","prompt":"Create a knowledge base synced from a Confluence space, then build a Slack agent that searches Confluence pages to answer team questions, cites the source page, and offers to create a new page when an answer is missing.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"slack","name":"Slack"}]},{"title":"Google Translate Confluence localization","prompt":"Create a workflow that watches Confluence pages tagged for localization, translates each into the target languages with Google Translate, and publishes localized copies.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Auto-generate Confluence pages from Jira sprints","prompt":"Build a workflow that runs at the end of each Jira sprint, pulls all completed and in-progress tickets, and automatically creates a structured Confluence documentation page so sprint reporting requires no manual effort.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"jira","name":"Jira"}]},{"title":"ServiceNow knowledge sync","prompt":"Build a scheduled workflow that pulls Confluence pages tagged for IT operations and creates or updates matching ServiceNow knowledge articles, mapping categories and authors so the knowledge base stays in sync without manual copy-paste.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"servicenow","name":"ServiceNow"}]},{"title":"SharePoint to Confluence migrator","prompt":"Build a workflow that imports SharePoint pages into Confluence under matching spaces, preserves attachments, and writes a mapping table so links can be redirected.","integrations":[{"id":"confluence","name":"Confluence"},{"id":"sharepoint","name":"SharePoint"}]}]},{"id":"context_dev","type":"context_dev","slug":"context-dev","name":"Context.dev","description":"Scrape, crawl, search, extract, and enrich web and brand data","category":"Search","docsUrl":"https://docs.sim.ai/integrations/context_dev","authType":"api-key","connections":[],"operations":[{"name":"Scrape Markdown","description":"Scrape any URL and return clean, LLM-ready markdown content."},{"name":"Scrape HTML","description":"Scrape any URL and return the raw HTML content of the page."},{"name":"Scrape Images","description":"Discover every image asset on a page, with optional dimension and type enrichment."},{"name":"Screenshot","description":"Capture a screenshot of any web page and store it as a downloadable image file."},{"name":"Crawl Website","description":"Crawl an entire website and return each discovered page as clean markdown."},{"name":"Map Sitemap","description":"Build a sitemap of a domain and return every discovered page URL."},{"name":"Web Search","description":"Search the web with natural language and optionally scrape results to markdown."},{"name":"Extract Structured Data","description":"Crawl a website and extract structured data matching a provided JSON schema."},{"name":"Extract Product","description":"Detect and extract structured product details from a single product page URL."},{"name":"Extract Products","description":"Extract the product catalog from a brand\'s website by domain (beta)."},{"name":"Scrape Fonts","description":"Extract the font families, usage stats, and font files used by a domain."},{"name":"Scrape Styleguide","description":"Extract a domain\'s design system: colors, typography, spacing, shadows, and UI components."},{"name":"Classify NAICS","description":"Classify a brand into NAICS industry codes from its domain or company name."},{"name":"Classify SIC","description":"Classify a brand into SIC industry codes from its domain or company name."},{"name":"Get Brand by Domain","description":"Retrieve brand data for a domain: logos, colors, backdrops, socials, address, and industry."},{"name":"Get Brand by Name","description":"Retrieve brand data by company name: logos, colors, socials, address, and industry."},{"name":"Get Brand by Email","description":"Retrieve brand data from a work email address. Free/disposable emails are rejected (422)."},{"name":"Get Brand by Ticker","description":"Retrieve brand data for a public company by its stock ticker symbol."},{"name":"Identify Transaction","description":"Identify the brand behind a raw bank/card transaction descriptor and return its brand data."}],"triggers":[],"skills":[],"templates":[{"title":"Context.dev knowledge-base builder","prompt":"Build a workflow that maps a documentation site with Context.dev, crawls each page to clean markdown, chunks and embeds the content, and upserts it into a knowledge base for an answering agent.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev competitor monitor","prompt":"Build a scheduled workflow that scrapes competitor pricing and changelog pages to markdown with Context.dev weekly, diffs against the prior snapshot, logs changes to a table, and posts notable updates to Slack.","integrations":[{"id":"context_dev","name":"Context.dev"},{"id":"slack","name":"Slack"}]},{"title":"Context.dev lead enrichment","prompt":"Create a workflow that takes a work email, uses Context.dev to retrieve brand data by email and classify the company into NAICS codes, and writes the enriched firmographics to a CRM record.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev structured data extractor","prompt":"Build a workflow that takes a website URL and a JSON schema, uses Context.dev Extract to pull structured fields across the site, and returns the validated records as JSON.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev research brief","prompt":"Create an agent that runs a Context.dev web search on a topic, scrapes the top results to markdown, and synthesizes a cited research brief saved as a file.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev design-system extractor","prompt":"Build a workflow that takes a domain, uses Context.dev to scrape its styleguide and fonts plus a homepage screenshot, and stores the design tokens and assets as files for a design handoff.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev transaction enrichment","prompt":"Create a workflow that takes raw bank transaction descriptors, uses Context.dev to identify the merchant brand behind each one, and appends the resolved company and logo to a table.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev product catalog importer","prompt":"Build a workflow that takes a brand domain, uses Context.dev to extract the brand\'s product catalog with pricing and features, and writes each product as a row in a table.","integrations":[{"id":"context_dev","name":"Context.dev"}]},{"title":"Context.dev site change watcher","prompt":"Build a scheduled workflow that maps a site sitemap with Context.dev, scrapes new or changed pages to markdown, summarizes the differences, and emails a digest.","integrations":[{"id":"context_dev","name":"Context.dev"},{"id":"gmail","name":"Gmail"}]}]},{"id":"convex","type":"convex","slug":"convex","name":"Convex","description":"Use Convex database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/convex","authType":"api-key","connections":[],"operations":[{"name":"Run Query","description":"Run a Convex query function and return its result"},{"name":"Run Mutation","description":"Run a Convex mutation function to write data and return its result"},{"name":"Run Action","description":"Run a Convex action function and return its result"},{"name":"Run Function","description":"Run any Convex function (query, mutation, or action) by path without specifying its type"},{"name":"List Tables","description":"List all tables in a Convex deployment along with their JSON schemas. Requires streaming export, available on Convex paid plans."},{"name":"List Documents","description":"List documents from a Convex table via a paginated snapshot. Pass the returned snapshot and page cursor back in to fetch the next page. Requires streaming export, available on Convex paid plans."},{"name":"Document Deltas","description":"List documents that changed after a snapshot or previous delta cursor. Deleted documents are returned with a _deleted flag. Requires streaming export, available on Convex paid plans."}],"triggers":[],"skills":[{"name":"run-convex-function","description":"Run a Convex query, mutation, or action with named arguments and use its result.","content":"# Run a Convex Function\\n\\nCall a function deployed to Convex and work with its return value.\\n\\n## Steps\\n1. Pick the operation that matches the function type: Run Query for reads, Run Mutation for writes, Run Action for side effects like calling external APIs.\\n2. Provide the Deployment URL (https://your-deployment.convex.cloud) and a deploy key from the dashboard Settings page.\\n3. Set Function Path in module:function form, for example messages:list or tasks/admin:reset.\\n4. Pass Function Arguments as a JSON object whose keys match the argument names the function declares, for example {\\"limit\\": 10}.\\n\\n## Output\\nThe function result is available as value, with any console output in logLines. Surface the fields downstream steps need."},{"name":"export-convex-table","description":"Page through a full Convex table snapshot with List Documents until hasMore is false.","content":"# Export a Convex Table\\n\\nRead every document in a table using snapshot pagination so the export is consistent.\\n\\n## Steps\\n1. Use the List Documents operation with the deployment URL, deploy key, and the table name (leave empty to export all tables).\\n2. On the first call leave Snapshot and Cursor empty; the response pins a snapshot timestamp.\\n3. While hasMore is true, call List Documents again passing back the returned snapshot and pageCursor values.\\n4. Collect the documents arrays from each page into your destination.\\n\\n## Output\\nA complete, point-in-time set of documents for the table, each including _id and _creationTime."},{"name":"sync-convex-changes","description":"Fetch only changed Convex documents since a snapshot using Document Deltas.","content":"# Sync Convex Changes Incrementally\\n\\nAfter an initial export, keep a downstream copy fresh by reading only what changed.\\n\\n## Steps\\n1. Run an initial export with List Documents and keep the final snapshot value.\\n2. On each sync run, call Document Deltas with that value as the Cursor (and optionally a table name).\\n3. While hasMore is true, keep calling Document Deltas with the returned cursor; persist the last cursor for the next run.\\n4. Apply each document by _id; documents with _deleted set to true should be removed downstream.\\n\\n## Output\\nThe changed documents since the stored cursor plus a new cursor to persist, giving reliable incremental sync when documents are applied idempotently by _id."}],"templates":[{"title":"Convex support ticket triage","prompt":"Build a workflow that runs a Convex query to fetch open support tickets, classifies each by urgency with an agent, writes the triage label back via a Convex mutation, and posts critical tickets to Slack.","integrations":[{"id":"convex","name":"Convex"},{"id":"slack","name":"Slack"}]},{"title":"Convex nightly backup to S3","prompt":"Create a scheduled workflow that runs each night, pages through every Convex table with List Documents, writes the exported JSON to S3 with date partitions, and records the run in an audit table.","integrations":[{"id":"convex","name":"Convex"},{"id":"s3","name":"S3"}]},{"title":"Convex change-data alerting","prompt":"Build a scheduled workflow that polls Convex Document Deltas for changed rows since the last run, filters for high-value records like fraud flags or large orders, and posts an alert with context to Slack.","integrations":[{"id":"convex","name":"Convex"},{"id":"slack","name":"Slack"}]},{"title":"Convex user onboarding automation","prompt":"Create a workflow that receives new-signup webhooks, runs a Convex mutation to provision the user record with defaults, and sends a personalized welcome email.","integrations":[{"id":"convex","name":"Convex"},{"id":"gmail","name":"Gmail"}]},{"title":"Convex daily metrics digest","prompt":"Create a scheduled daily workflow that runs Convex queries for new signups, active users, and key feature usage, summarizes the numbers with an agent, and posts a digest to Slack with day-over-day trend.","integrations":[{"id":"convex","name":"Convex"},{"id":"slack","name":"Slack"}]},{"title":"Convex search index sync","prompt":"Build a scheduled workflow that uses Convex Document Deltas to mirror changed documents into an Algolia index, removes deleted documents, and writes sync lag to a tables-based monitor.","integrations":[{"id":"convex","name":"Convex"},{"id":"algolia","name":"Algolia"}]},{"title":"Convex schema drift monitor","prompt":"Create a scheduled workflow that runs Convex List Tables, diffs the returned table schemas against the last snapshot stored in a table, and notifies the engineering channel when fields are added, removed, or change type.","integrations":[{"id":"convex","name":"Convex"},{"id":"slack","name":"Slack"}]}]},{"id":"crowdstrike","type":"crowdstrike","slug":"crowdstrike","name":"CrowdStrike","description":"Investigate and respond to CrowdStrike Falcon alerts, hosts, IOCs, and vulnerabilities","category":"Security","docsUrl":"https://docs.sim.ai/integrations/crowdstrike","authType":"api-key","connections":[],"operations":[{"name":"Query Alerts","description":"Search CrowdStrike Falcon alerts with a Falcon Query Language filter and return their composite IDs. Uses the current Alerts API (GET /alerts/queries/alerts/v2), which replaced the Detects API decommissioned on September 30, 2025. Requires the \\"Alerts: Read\\" API scope."},{"name":"Get Alert Details","description":"Get full CrowdStrike Falcon alert records for one or more composite alert IDs (POST /alerts/entities/alerts/v2). Requires the \\"Alerts: Read\\" API scope."},{"name":"Update Alerts","description":"Update CrowdStrike Falcon alerts by composite ID: change status, assign or unassign an analyst, add or remove tags, append a comment, or toggle visibility (PATCH /alerts/entities/alerts/v3). This modifies live alerts in the Falcon console. Requires the \\"Alerts: Write\\" API scope."},{"name":"Perform Host Action","description":"Act on CrowdStrike Falcon hosts (POST /devices/entities/devices-actions/v2). Actions: contain, lift_containment, hide_host, unhide_host, detection_suppress, detection_unsuppress. contain network-isolates the host so it can only reach the Falcon cloud; hide_host removes the host record from the console. Both are immediately disruptive. Up to 100 host IDs per call. Requires the \\"Hosts: Write\\" API scope."},{"name":"Query Host Groups","description":"Search CrowdStrike Falcon host groups with a Falcon Query Language filter and return their IDs (GET /devices/queries/host-groups/v1). Requires the \\"Host groups: Read\\" API scope."},{"name":"Get Host Group Details","description":"Get CrowdStrike Falcon host group records for one or more group IDs (GET /devices/entities/host-groups/v1). Requires the \\"Host groups: Read\\" API scope."},{"name":"Perform Host Group Action","description":"Add hosts to or remove hosts from a CrowdStrike Falcon static host group (POST /devices/entities/host-group-actions/v1). Group membership drives policy assignment, so changing it changes which policies apply to those hosts. Requires the \\"Host groups: Write\\" API scope."},{"name":"Query Indicators","description":"Search custom CrowdStrike Falcon indicators of compromise (IOCs) with a Falcon Query Language filter and return their IDs (GET /iocs/queries/indicators/v1). Requires the \\"IOC Management: Read\\" API scope."},{"name":"Get Indicator Details","description":"Get custom CrowdStrike Falcon indicator of compromise (IOC) records for one or more IOC IDs (GET /iocs/entities/indicators/v1). Requires the \\"IOC Management: Read\\" API scope."},{"name":"Create Indicators","description":"Create custom CrowdStrike Falcon indicators of compromise (POST /iocs/entities/indicators/v1). Each indicator can allow, detect, or block activity across the fleet, so a wrong value can suppress detections or break legitimate software. Requires the \\"IOC Management: Write\\" API scope."},{"name":"Update Indicators","description":"Update custom CrowdStrike Falcon indicators of compromise by ID (PATCH /iocs/entities/indicators/v1). DESTRUCTIVE: omitted fields may be cleared, so read each indicator with crowdstrike_get_indicator_details first and resend its full field set with your edits applied. Changing action or scope changes prevention behavior fleet-wide. type and value are immutable. Requires the \\"IOC Management: Write\\" API scope."},{"name":"Delete Indicators","description":"Permanently delete custom CrowdStrike Falcon indicators of compromise (DELETE /iocs/entities/indicators/v1). Cannot be undone; deleting a blocking indicator removes that protection from every host, and a broad filter can delete far more than intended. Supply an ID list or a filter, never both -- CrowdStrike lets a filter silently override the IDs, so this tool rejects that instead. Requires the \\"IOC Management: Write\\" API scope."},{"name":"Query Vulnerabilities","description":"Search CrowdStrike Falcon Spotlight vulnerabilities with a required Falcon Query Language filter and return their IDs (GET /spotlight/queries/vulnerabilities/v1). Requires the spotlight-vulnerabilities:read API scope, shown as \\"Vulnerabilities: Read\\" in the Falcon API client UI."},{"name":"Get Vulnerability Details","description":"Get CrowdStrike Falcon Spotlight vulnerability records for one or more vulnerability IDs, including CVE, affected host, application, and remediation details (GET /spotlight/entities/vulnerabilities/v2). Requires the spotlight-vulnerabilities:read API scope, shown as \\"Vulnerabilities: Read\\" in the Falcon API client UI."},{"name":"Init RTR Session","description":"Open a CrowdStrike Falcon Real Time Response session against a host so read-only commands can be run on it (POST /real-time-response/entities/sessions/v1). This connects a live remote shell to the endpoint. Requires the \\"Real time response: Read\\" API scope."},{"name":"Execute RTR Command","description":"Run a read-only Real Time Response command in an open CrowdStrike Falcon session (POST /real-time-response/entities/command/v1). baseCommand names the family only (cat, cd, clear, csrutil, env, eventlog, filehash, getsid, help, history, ifconfig, ipconfig, ls, mount, netstat, ps, reg, users); subcommands go in commandString. Host-modifying commands need the Active Responder or Admin endpoints. Requires the \\"Real time response: Read\\" API scope."},{"name":"Get RTR Command Status","description":"Get the status and output of a Real Time Response command by cloud request ID (GET /real-time-response/entities/command/v1). Long output is chunked across sequences, so increment the sequence ID to read the next chunk. Requires the \\"Real time response: Read\\" API scope."},{"name":"Delete RTR Session","description":"Close an open CrowdStrike Falcon Real Time Response session (DELETE /real-time-response/entities/sessions/v1). Requires the \\"Real time response: Read\\" API scope."},{"name":"Query Cases","description":"Search CrowdStrike Falcon Case Management cases with a Falcon Query Language filter and return their IDs (GET /cases/queries/cases/v1). Case Management supersedes the CrowdScore Incidents API, which CrowdStrike has removed from its published API spec. Requires the \\"Cases: Read\\" API scope."},{"name":"Get Case Details","description":"Get CrowdStrike Falcon Case Management case records for one or more case IDs (POST /cases/entities/cases/v2). Requires the \\"Cases: Read\\" API scope."},{"name":"Query Sensors","description":"Search CrowdStrike Identity Protection sensors -- the domain controllers Falcon Identity Protection monitors, not Falcon endpoint sensors -- and return their device IDs (GET /identity-protection/queries/devices/v1). Sort uses the dot form, for example status.desc. Requires the \\"Identity Protection Entities: Read\\" API scope, a separate entitlement from Hosts and Alerts."},{"name":"Get Sensor Details","description":"Get CrowdStrike Identity Protection sensor details for one or more device IDs (POST /identity-protection/entities/devices/GET/v1). These are the domain controllers Falcon Identity Protection monitors, not Falcon endpoint sensors. Requires the \\"Identity Protection Entities: Read\\" API scope."},{"name":"Get Sensor Aggregates","description":"Aggregate CrowdStrike Identity Protection sensors from a JSON aggregate query body (POST /identity-protection/aggregates/devices/GET/v1). These are the domain controllers Falcon Identity Protection monitors, not Falcon endpoint sensors. Requires the \\"Identity Protection Entities: Read\\" API scope."}],"triggers":[],"skills":[{"name":"triage-falcon-alerts","description":"Query CrowdStrike alerts, pull their details, and summarize severity, tactic, and affected host for SOC triage.","content":"# Triage CrowdStrike Alerts\\n\\nWork a queue of Falcon alerts down to a reviewed state.\\n\\n## Steps\\n1. Query alerts with an FQL filter for the status and severity you care about.\\n2. Pull alert details for the returned composite IDs.\\n3. Summarize each alert by severity, tactic, technique, and affected host.\\n4. Update the reviewed alerts with a new status and an audit comment.\\n\\n## Output\\nA triage summary per alert plus the list of alert IDs whose status was updated."},{"name":"contain-compromised-host","description":"Contain a CrowdStrike host and collect live evidence through a Real Time Response session.","content":"# Contain a Compromised Host\\n\\nIsolate a host and gather evidence before responders arrive.\\n\\n## Steps\\n1. Run the contain action against the target host ID.\\n2. Open a Real Time Response session on that host.\\n3. Run read-tier commands (ps, netstat, ls, filehash) and poll each cloud request ID for output.\\n4. Close the session when collection is done.\\n\\n## Output\\nConfirmation the host was contained, plus the captured command output for the incident record."},{"name":"manage-custom-indicators","description":"Create, update, search, and delete custom CrowdStrike indicators of compromise.","content":"# Manage Custom CrowdStrike Indicators\\n\\nKeep the custom IOC list current.\\n\\n## Steps\\n1. Query existing indicators with an FQL filter to see what is already covered.\\n2. Create new indicators with the intended action, platforms, and expiration.\\n3. Update severity, action, or expiration on indicators that need changing.\\n4. Delete indicators that are stale, scoping deletes by explicit IDs rather than a broad filter.\\n\\n## Output\\nThe indicator IDs created, updated, or deleted, plus any per-item errors CrowdStrike returned."},{"name":"prioritize-spotlight-vulnerabilities","description":"Query CrowdStrike Spotlight vulnerabilities and rank them by severity, exploit status, and affected host.","content":"# Prioritize Spotlight Vulnerabilities\\n\\nTurn the Spotlight backlog into a ranked remediation list.\\n\\n## Steps\\n1. Query vulnerabilities with an FQL filter (Spotlight requires one) for open findings.\\n2. Pull details for the returned IDs to get CVE data, host info, and remediations.\\n3. Rank by CVE severity and exploit status, then group by host or application.\\n\\n## Output\\nA prioritized remediation list naming each CVE, its affected hosts, and the recommended fix."},{"name":"audit-identity-sensors","description":"Query CrowdStrike Identity Protection sensors and report on coverage, status, and devices missing protection.","content":"# Audit CrowdStrike Identity Sensors\\n\\nReview Identity Protection sensor coverage across the fleet.\\n\\n## Steps\\n1. Query sensors, optionally filtered by status or hostname.\\n2. For sensors of interest, pull detailed attributes (version, last seen, assigned policy).\\n3. Flag sensors that are offline, stale, or out of policy.\\n\\n## Output\\nA coverage report listing healthy sensors, plus any that are offline, stale, or misconfigured for SOC review."},{"name":"summarize-sensor-aggregates","description":"Pull documented CrowdStrike sensor aggregates and summarize the fleet distribution by version, status, or platform.","content":"# Summarize CrowdStrike Sensor Aggregates\\n\\nBuild a high-level picture of the sensor fleet.\\n\\n## Steps\\n1. Request the documented sensor aggregates (e.g. counts by version, status, or platform).\\n2. Compute the distribution and identify outliers, such as a large share of outdated versions.\\n3. Compare against the expected baseline.\\n\\n## Output\\nA fleet summary with key counts and any segments that need attention (outdated, offline)."}],"templates":[{"title":"CrowdStrike alert triage","prompt":"Create a workflow that queries new high-severity CrowdStrike alerts, pulls their details, summarizes the tactic, technique, and affected host for each, posts the triage summary to Slack, and marks the reviewed alerts in progress.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"slack","name":"Slack"}]},{"title":"CrowdStrike host containment","prompt":"Create a workflow that takes a host ID, contains the host in CrowdStrike, opens a Real Time Response session to capture running processes and network connections, and posts the collected evidence to Slack for the on-call responder.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"slack","name":"Slack"}]},{"title":"CrowdStrike IOC sync","prompt":"Create a workflow that reads indicators of compromise from a table, creates them as custom CrowdStrike indicators with a blocking action and an expiration, and records the returned indicator IDs back to the table.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike vulnerability report","prompt":"Create a scheduled workflow that queries CrowdStrike Spotlight for open critical vulnerabilities, pulls the CVE and remediation details, groups them by host, and writes a prioritized remediation report for the platform team.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike case digest","prompt":"Create a scheduled workflow that queries open CrowdStrike Case Management cases, pulls each case status, severity, and assignee, and posts a daily standup digest to Slack.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"slack","name":"Slack"}]},{"title":"CrowdStrike sensor coverage gaps","prompt":"Create a scheduled workflow that queries CrowdStrike Identity Protection sensors, identifies devices reporting an unprotected or degraded status, opens a PagerDuty incident for critical gaps, and posts the list to Slack.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"CrowdStrike weekly sensor digest","prompt":"Create a scheduled weekly workflow that runs CrowdStrike sensor aggregate queries by status and OS version, summarizes coverage and unprotected counts, and writes a digest file for security leadership.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike + Okta coverage check","prompt":"Build a workflow that lists CrowdStrike Identity Protection sensors and cross-references them with Okta users and devices to find accounts active on endpoints that have no protected sensor, then writes the findings to a security table.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"okta","name":"Okta"}]},{"title":"CrowdStrike asset inventory","prompt":"Create a scheduled workflow that queries CrowdStrike Identity Protection sensors per device, identifies endpoints reporting an unprotected status, and writes the gap list to a compliance table.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike stale sensor finder","prompt":"Build a scheduled workflow that queries CrowdStrike sensors, flags devices whose last heartbeat is older than a threshold, and writes the stale-sensor list to a SOC investigation table for follow-up.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike coverage report doc","prompt":"Create a scheduled workflow that aggregates CrowdStrike sensor status, OS version, and policy assignment, and generates a coverage report doc in Google Docs for the security team.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"google_docs","name":"Google Docs"}]},{"title":"CrowdStrike policy drift watcher","prompt":"Build a scheduled workflow that queries CrowdStrike Identity Protection sensors, compares each device’s assigned IdP policy against the expected baseline, and writes mismatches to a SOC review queue.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"Elasticsearch security event correlator","prompt":"Create a workflow that pulls Elasticsearch security events, correlates them across sources, and opens a CrowdStrike or PagerDuty incident on a confirmed pattern.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"elasticsearch","name":"Elasticsearch"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Okta compromised-account responder","prompt":"Create a workflow triggered by a CrowdStrike detection on a user that suspends the matching Okta account, resets their password, and pings the security Slack channel with the action taken.","integrations":[{"id":"crowdstrike","name":"CrowdStrike"},{"id":"okta","name":"Okta"},{"id":"slack","name":"Slack"}]}]},{"id":"crunchbase","type":"crunchbase","slug":"crunchbase","name":"Crunchbase","description":"Search and look up companies, people, funding rounds, and acquisitions","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/crunchbase","authType":"api-key","connections":[],"operations":[{"name":"Search Organizations","description":"Search Crunchbase companies, investors, and schools with filter predicates on funding, headcount, location, category, and rank."},{"name":"Get Organization","description":"Look up a single Crunchbase organization by permalink or UUID, returning the requested fields and related cards."},{"name":"Search People","description":"Search Crunchbase people — founders, executives, and investors — with filter predicates on job title, organization, location, and rank."},{"name":"Get Person","description":"Look up a single Crunchbase person by permalink or UUID, returning the requested fields and related cards."},{"name":"Search Funding Rounds","description":"Search Crunchbase funding rounds with filter predicates on announced date, investment type, amount raised, and investors."},{"name":"Get Funding Round","description":"Look up a single Crunchbase funding round by permalink or UUID, returning the requested fields and related cards."},{"name":"Search Acquisitions","description":"Search Crunchbase acquisitions with filter predicates on announced date, price, acquisition type, and the companies involved."},{"name":"Get Acquisition","description":"Look up a single Crunchbase acquisition by permalink or UUID, returning the requested fields and related cards."},{"name":"Search Any Collection","description":"Search any Crunchbase collection — events, jobs, ipos, funds, investments, press references, layoffs, insights, predictions, and more — with filter predicates."},{"name":"Get Any Entity","description":"Look up a single entity in any Crunchbase collection — events, jobs, ipos, funds, investments, press references, insights, predictions, and more — by permalink or UUID."},{"name":"Get Entity Card","description":"Page through one related-entity card of a Crunchbase entity — an investor\'s investments, a company\'s founders, a round\'s investors — past the 100-item cap an inline card request returns."},{"name":"Autocomplete","description":"Suggest Crunchbase entities matching a typed query, returning the permalinks and UUIDs the lookup and search operations take."},{"name":"List Deleted Entities","description":"List entities Crunchbase has deleted, so a mirrored copy can be pruned in step with the source."},{"name":"Get Fields Metadata","description":"List the field ids, types, and descriptions each Crunchbase collection publishes, which is how the field_ids and query predicates of the other operations are discovered."}],"triggers":[],"skills":[{"name":"enrich-company-record","description":"Resolve a company name or domain to its Crunchbase organization and pull firmographics onto the record. Use to fill in accounts before scoring or routing.","content":"# Enrich Company Record\\n\\nTurn a company name into a complete Crunchbase organization record.\\n\\n## Steps\\n1. Run Autocomplete on the company name, constrained to the organizations collection, and take the permalink of the best match.\\n2. Look up the organization with the fields the record needs — short_description, website_url, location_identifiers, categories, founded_on, num_employees_enum, operating_status.\\n3. When the record needs the leadership team, add the founders card.\\n4. Merge the returned fields onto the record, keeping existing values where Crunchbase returned nothing.\\n\\n## Output\\nReport the matched permalink and the fields filled. Flag a name that autocompleted to nothing or matched more than one plausible company."},{"name":"build-target-account-list","description":"Search Crunchbase organizations against an ideal customer profile and page the full result set into a list. Use for territory and campaign planning.","content":"# Build Target Account List\\n\\nTurn an ICP description into a paged list of matching companies.\\n\\n## Steps\\n1. Translate the ICP into search predicates — categories with `includes`, location_identifiers with `includes`, num_employees_enum with `includes`, founded_on with `between`.\\n2. Run Search Organizations with the columns the list needs and an order clause on rank_org.\\n3. Page forward by passing the returned nextAfterId as After ID until a page comes back short.\\n4. Write the deduplicated companies to a table.\\n\\n## Output\\nReport the total match count, how many rows were retrieved, and the predicates used. Note when paging stopped early."},{"name":"track-funding-rounds","description":"Find funding rounds announced in a window and report the company, stage, amount, and investors. Use for daily or weekly funding alerts.","content":"# Track Funding Rounds\\n\\nSurface new funding in a market and summarize each round.\\n\\n## Steps\\n1. Search Funding Rounds with an `announced_on` `gte` predicate for the window, plus any category or amount filters.\\n2. Request announced_on, investment_type, money_raised, funded_organization_identifier, investor_identifiers, and lead_investor_identifiers.\\n3. Order by announced_on descending so the newest rounds lead.\\n4. Summarize each round as company, stage, amount raised, and lead investors.\\n\\n## Output\\nReport the rounds found in the window. State the window explicitly, and say so plainly when nothing was announced."},{"name":"map-investor-portfolio","description":"Page an investor\'s participated investments and summarize their stage, sector, and check-size focus. Use for diligence and investor research.","content":"# Map Investor Portfolio\\n\\nAssemble what an investor actually backs from their investment card.\\n\\n## Steps\\n1. Autocomplete the investor name against the organizations or people collection to get a permalink.\\n2. Read the participated_investments card with Get Entity Card, requesting the announced date, amount, and funded organization.\\n3. Page forward with the returned nextAfterId until the card is exhausted — an inline card request stops at 100 items.\\n4. Group the investments by stage, sector, and year to describe the pattern.\\n\\n## Output\\nReport the number of investments read, the stage and sector concentration, and the typical check size. Say when the portfolio was truncated by a license limit."},{"name":"monitor-acquisitions","description":"Search acquisitions announced in a window and summarize acquirer, target, price, and terms. Use for competitive and market monitoring.","content":"# Monitor Acquisitions\\n\\nWatch consolidation in a market.\\n\\n## Steps\\n1. Search Acquisitions with an `announced_on` `gte` predicate for the window.\\n2. Request acquiree_identifier, acquirer_identifier, announced_on, price, acquisition_type, status, and terms.\\n3. Order by announced_on descending.\\n4. Summarize each deal, calling out an undisclosed price rather than reporting it as zero.\\n\\n## Output\\nReport each deal as acquirer, target, price, and status. Note deals whose price Crunchbase does not publish."},{"name":"discover-collection-fields","description":"List the fields a Crunchbase collection publishes before writing a search. Use when a predicate or column name is uncertain.","content":"# Discover Collection Fields\\n\\nGround a search in the fields the license actually exposes.\\n\\n## Steps\\n1. Run Get Fields Metadata for the collections in question.\\n2. Read the returned CSV for the field ids, their types, and their descriptions.\\n3. Pick the columns for `field_ids` and the filterable fields for the query predicates.\\n4. Run the search with those exact ids.\\n\\n## Output\\nReport the fields chosen and why. Say explicitly when a field the request assumed does not exist on that collection or under this license."},{"name":"prune-deleted-entities","description":"Read the Crunchbase deleted-entity feed and remove the matching rows from a mirrored copy. Use to keep a local mirror in step with the source.","content":"# Prune Deleted Entities\\n\\nKeep a mirrored copy from drifting away from Crunchbase.\\n\\n## Steps\\n1. Run List Deleted Entities for the collections being mirrored, ordering by deletion time ascending.\\n2. Page forward with the returned nextAfterId, keeping the last cursor as the watermark for the next run.\\n3. Match each deleted uuid against the mirrored rows.\\n4. Delete or tombstone the matches, leaving unmatched deletions alone.\\n\\n## Output\\nReport how many deletions were read, how many matched local rows, and the cursor to resume from."}],"templates":[{"title":"Crunchbase funding round watcher","prompt":"Build a workflow that runs every morning, searches Crunchbase for funding rounds announced in the last day in my target categories, and posts each round — company, stage, amount raised, and lead investors — to a Slack channel.","integrations":[{"id":"crunchbase","name":"Crunchbase"},{"id":"slack","name":"Slack"}]},{"title":"Crunchbase account enrichment","prompt":"Create a workflow that watches my accounts table for new company names, autocompletes each one against Crunchbase to resolve its permalink, looks up the organization, and writes headcount, headquarters, categories, and founding date back to the row.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase ICP company list","prompt":"Build a workflow that searches Crunchbase organizations matching my ideal customer profile — category, headcount band, and headquarters region — pages through every result, and writes the company list to a table for the SDR team.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase investor portfolio brief","prompt":"Create an agent that takes an investor name, looks them up in Crunchbase, pages through their participated investments card, and writes a brief covering stage focus, check size, and the sectors they back most.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase founder finder","prompt":"Build a workflow that takes a list of target companies, looks each one up in Crunchbase with the founders card, and writes every founder with their title and LinkedIn to a table so I can start outreach.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase acquisition digest","prompt":"Create a scheduled workflow that searches Crunchbase for acquisitions announced this week in my industry, summarizes each deal — acquirer, target, price, and terms — and emails the digest to the strategy team every Friday.","integrations":[{"id":"crunchbase","name":"Crunchbase"},{"id":"gmail","name":"Gmail"}]},{"title":"Crunchbase competitor tracker","prompt":"Build a workflow that takes my competitor list, looks each company up in Crunchbase, compares headcount, operating status, and latest funding against what I stored last month, and alerts me in Slack when anything changed.","integrations":[{"id":"crunchbase","name":"Crunchbase"},{"id":"slack","name":"Slack"}]},{"title":"Crunchbase inbound lead qualifier","prompt":"Create a workflow that runs when a demo request comes in, resolves the submitted company against Crunchbase, looks up its headcount, funding stage, and category, and routes the lead to the enterprise or self-serve queue based on what it finds.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase mirror pruner","prompt":"Build a nightly workflow that reads the Crunchbase deleted-entity feed for organizations and people, matches each deletion against my mirrored companies table, and removes or tombstones the rows that no longer exist upstream.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase query builder","prompt":"Create an agent that lists the fields a Crunchbase collection publishes, turns a plain-English request like \\"European fintechs that raised a Series B last quarter\\" into the matching search predicates, runs the search, and returns the results.","integrations":[{"id":"crunchbase","name":"Crunchbase"}]}]},{"id":"cursor","type":"cursor_v2","slug":"cursor","name":"Cursor","description":"Launch and manage Cursor cloud agents to work on GitHub repositories","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/cursor","authType":"api-key","connections":[],"operations":[{"name":"Launch Agent","description":"Start a new cloud agent to work on a GitHub repository with the given instructions."},{"name":"Add Follow-up","description":"Add a follow-up instruction to an existing cloud agent."},{"name":"Get Agent Status","description":"Retrieve the current status and results of a cloud agent."},{"name":"Get Conversation","description":"Retrieve the conversation history of a cloud agent, including all user prompts and assistant responses."},{"name":"List Agents","description":"List all cloud agents for the authenticated user with optional pagination."},{"name":"Stop Agent","description":"Stop a running cloud agent. This pauses the agent without deleting it."},{"name":"Delete Agent","description":"Permanently delete a cloud agent. This action cannot be undone."},{"name":"List Artifacts","description":"List generated artifact files for a cloud agent."},{"name":"Download Artifact","description":"Download a generated artifact file from a cloud agent."},{"name":"List Models","description":"List the models available for launching cloud agents."},{"name":"List Repositories","description":"List the GitHub repositories accessible to the authenticated user."},{"name":"Get API Key Info","description":"Retrieve details about the API key currently in use."}],"triggers":[],"skills":[{"name":"launch-coding-agent","description":"Launch a Cursor cloud agent on a GitHub repository with a clear task prompt and report the agent id and starting status.","content":"# Launch a Cursor Coding Agent\\n\\nKick off an autonomous Cursor agent to work on a repo.\\n\\n## Steps\\n1. Confirm the target repository and the task to perform.\\n2. Write a precise prompt: what to change, constraints, and acceptance criteria.\\n3. Launch the agent with the chosen model and repository.\\n4. Capture the agent id and initial status.\\n\\n## Output\\nA confirmation with the agent id, repository, and the task prompt it was given."},{"name":"track-agent-progress","description":"Poll a Cursor agent for status and conversation updates and summarize what it has done so far.","content":"# Track Cursor Agent Progress\\n\\nMonitor a running Cursor agent.\\n\\n## Steps\\n1. Get the agent status for the given agent id.\\n2. Pull the conversation to see the latest actions and reasoning.\\n3. If the agent is finished, list its artifacts; if blocked, identify why.\\n\\n## Output\\nA status summary describing progress, current state, and any blockers or produced artifacts."},{"name":"send-agent-followup","description":"Send a follow-up instruction to an in-progress Cursor agent to refine or redirect its work.","content":"# Send a Cursor Agent Follow-up\\n\\nGuide an active agent with additional instructions.\\n\\n## Steps\\n1. Confirm the agent id and review its recent conversation.\\n2. Compose a clear follow-up message addressing what to change or add.\\n3. Add the follow-up to the agent.\\n4. Note that the agent has resumed work.\\n\\n## Output\\nA confirmation that the follow-up was delivered, with the instruction sent."}],"templates":[{"title":"Cursor cloud agent launcher","prompt":"Build a workflow that takes a feature description and a GitHub repository, launches a Cursor cloud agent with structured instructions, polls until the agent finishes, captures the generated pull request link, and posts a summary to Slack so the team can review.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"slack","name":"Slack"}]},{"title":"Cursor issue-to-PR pipeline","prompt":"Create a workflow that fires when a GitHub issue is labeled \\"auto-fix\\", crafts a precise prompt from the issue description, launches a Cursor cloud agent on the repository, monitors progress, and comments on the issue with the resulting pull request and conversation summary.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"github","name":"GitHub"}]},{"title":"Cursor agent fleet monitor","prompt":"Build a scheduled workflow that runs every fifteen minutes, lists all active Cursor cloud agents, logs status, runtime, and repository to a tracking table, and posts a daily Slack summary of completed, failing, and long-running agents.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"slack","name":"Slack"}]},{"title":"Cursor test-fix delegator","prompt":"Build a workflow triggered by a failing GitHub Actions test run that extracts the failing test name and error, launches a targeted Cursor cloud agent to fix only that test, downloads the artifact diff when ready, and replies on the failed run with the proposed patch.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"github","name":"GitHub"}]},{"title":"Cursor refactor follow-up loop","prompt":"Create a workflow that picks up review comments on a Cursor-authored pull request, formulates each comment as a follow-up instruction, sends them to the originating Cursor cloud agent, and waits for the updated diff before re-requesting review.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"github","name":"GitHub"}]},{"title":"Cursor agent conversation archiver","prompt":"Build a scheduled daily workflow that lists completed Cursor cloud agents, fetches each conversation history, stores the transcripts and produced artifacts as files, and updates a tracking table with prompts, durations, and outcomes for retrospective analysis.","integrations":[{"id":"cursor","name":"Cursor"}]},{"title":"Cursor stuck-agent cleaner","prompt":"Create a scheduled workflow that runs hourly, lists Cursor cloud agents, detects agents stuck in the same state longer than a configurable threshold, stops or deletes them based on rules, and posts a Slack report of the cleanup actions taken.","integrations":[{"id":"cursor","name":"Cursor"},{"id":"slack","name":"Slack"}]}]},{"id":"dagster","type":"dagster","slug":"dagster","name":"Dagster","description":"Orchestrate data pipelines and manage job runs with Dagster","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/dagster","authType":"api-key","connections":[],"operations":[{"name":"Launch Run","description":"Launch a job run on a Dagster instance."},{"name":"Get Run","description":"Get the status and details of a Dagster run by its ID."},{"name":"Get Run Logs","description":"Fetch execution event logs for a Dagster run."},{"name":"List Runs","description":"List Dagster runs with optional filters by job name, status, and creation-time range, plus cursor pagination."},{"name":"List Jobs","description":"List all jobs across repositories in a Dagster instance."},{"name":"Reexecute Run","description":"Reexecute an existing Dagster run, optionally resuming only from failed steps."},{"name":"Terminate Run","description":"Terminate an in-progress Dagster run."},{"name":"Delete Run","description":"Permanently delete a Dagster run record."},{"name":"List Schedules","description":"List all schedules in a Dagster repository, optionally filtered by status."},{"name":"Start Schedule","description":"Enable (start) a schedule in a Dagster repository."},{"name":"Stop Schedule","description":"Disable (stop) a running schedule in Dagster."},{"name":"List Sensors","description":"List all sensors in a Dagster repository, optionally filtered by status."},{"name":"Start Sensor","description":"Enable (start) a sensor in a Dagster repository."},{"name":"Stop Sensor","description":"Disable (stop) a running sensor in Dagster."},{"name":"List Assets","description":"List assets tracked by a Dagster instance, optionally filtered by key prefix."},{"name":"Get Asset","description":"Get an asset definition and its latest materialization by asset key."},{"name":"Materialize Assets","description":"Materialize selected assets by launching their asset job with an asset selection."},{"name":"Report Asset Materialization","description":"Report an external (runless) materialization or observation for an asset."},{"name":"Wipe Asset","description":"DESTRUCTIVE: permanently wipes ALL materialization history (every partition) for an asset. This cannot be undone."}],"triggers":[],"skills":[{"name":"launch-pipeline-run","description":"Launch a Dagster job run with the right config and report the run id and starting status.","content":"# Launch a Dagster Pipeline Run\\n\\nKick off a data pipeline job.\\n\\n## Steps\\n1. List jobs to confirm the target job name.\\n2. Assemble the run config (partitions, tags, resources) for the run.\\n3. Launch the run and capture the run id.\\n4. Confirm the run entered the queue or started.\\n\\n## Output\\nA confirmation with the run id, job name, and initial status."},{"name":"monitor-failed-runs","description":"List recent Dagster runs, surface failures, and pull logs to diagnose why a run failed.","content":"# Monitor Failed Dagster Runs\\n\\nFind and diagnose pipeline failures.\\n\\n## Steps\\n1. List recent runs and filter to those in a failed state.\\n2. For each failed run, get the run details and pull its logs.\\n3. Identify the failing step/op and the error message.\\n4. Decide whether a re-execute of the failed steps is appropriate.\\n\\n## Output\\nA per-run failure summary with the failing op, error, and a recommendation (retry or investigate)."},{"name":"reexecute-failed-run","description":"Re-execute a failed Dagster run from the point of failure and confirm the new run started.","content":"# Re-execute a Failed Dagster Run\\n\\nRetry a pipeline from where it broke.\\n\\n## Steps\\n1. Get the failed run to confirm its id and failure point.\\n2. Re-execute the run, scoping to the failed and downstream steps when supported.\\n3. Capture the new run id and status.\\n\\n## Output\\nA confirmation with the original run id, the new run id, and the re-execution scope."},{"name":"manage-schedules","description":"List Dagster schedules and sensors and start or stop them to control automated pipeline execution.","content":"# Manage Dagster Schedules\\n\\nControl which automated triggers are running.\\n\\n## Steps\\n1. List schedules and sensors with their current running state.\\n2. Identify the schedule or sensor to change.\\n3. Start or stop it as requested.\\n4. Confirm the new state.\\n\\n## Output\\nA confirmation of which schedules/sensors were started or stopped and their resulting state."}],"templates":[{"title":"Dagster pipeline status digest","prompt":"Create a scheduled daily workflow that pulls Dagster run statuses for the previous day, identifies failed and skipped runs, and posts a digest with links to the worst offenders in Slack.","integrations":[{"id":"dagster","name":"Dagster"},{"id":"slack","name":"Slack"}]},{"title":"Dagster asset freshness watcher","prompt":"Build a scheduled workflow that polls Dagster assets, checks each critical asset’s latest materialization timestamp against a freshness threshold, alerts when an asset becomes stale, and opens a Linear ticket for the data-platform team.","integrations":[{"id":"dagster","name":"Dagster"},{"id":"linear","name":"Linear"}]},{"title":"Dagster job kickoff orchestrator","prompt":"Create a workflow that triggers a Dagster job with run parameters when an upstream condition is satisfied, polls until completion, and writes the run outcome to a control table.","integrations":[{"id":"dagster","name":"Dagster"}]},{"title":"Dagster cost dashboard","prompt":"Build a scheduled weekly workflow that pulls Dagster run durations, calculates compute cost per pipeline, and writes a weekly cost dashboard to a finance review file.","integrations":[{"id":"dagster","name":"Dagster"}]},{"title":"Dagster lineage map","prompt":"Create a workflow that exports Dagster asset lineage into a graph database for cross-pipeline impact analysis when an upstream source schema changes.","integrations":[{"id":"dagster","name":"Dagster"},{"id":"neo4j","name":"Neo4j"}]},{"title":"Dagster sensor health watcher","prompt":"Build a scheduled workflow that lists Dagster sensors, checks their tick history, and alerts Slack when a sensor stops emitting ticks unexpectedly.","integrations":[{"id":"dagster","name":"Dagster"},{"id":"slack","name":"Slack"}]},{"title":"Dagster + Databricks coordinator","prompt":"Create a workflow that orchestrates a Dagster job that triggers a Databricks notebook, waits for completion, captures outputs, and writes the unified run history to a tracking table.","integrations":[{"id":"dagster","name":"Dagster"},{"id":"databricks","name":"Databricks"}]}]},{"id":"databricks","type":"databricks","slug":"databricks","name":"Databricks","description":"Run SQL, manage jobs, and ask Genie agents on Databricks","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/databricks","authType":"api-key","connections":[],"operations":[{"name":"Execute SQL","description":"Execute a SQL statement against a Databricks SQL warehouse and return results inline. Supports parameterized queries and Unity Catalog."},{"name":"Get Statement","description":"Poll a SQL statement by its ID to retrieve status and results. Use this after Execute SQL when a query runs longer than the wait timeout."},{"name":"Get Statement Chunk","description":"Retrieve one chunk of an INLINE SQL result using nextChunkIndex from Execute SQL or Get Statement."},{"name":"Cancel Statement","description":"Request cancellation of an executing SQL statement; poll Get Statement to confirm its final status."},{"name":"List Jobs","description":"List all jobs in a Databricks workspace with optional filtering by name."},{"name":"Get Job","description":"Get the full definition and settings of a single Databricks job by its job ID."},{"name":"Create Job","description":"Create a Databricks job with tasks, scheduling, execution identity, and notifications."},{"name":"Update Job","description":"Merge selected settings into a Databricks job and optionally remove settings or tasks."},{"name":"Reset Job","description":"Replace all settings of a Databricks job."},{"name":"Delete Job","description":"Delete a Databricks job and cancel its active runs."},{"name":"Run Job","description":"Trigger an existing Databricks job to run immediately with optional job-level or notebook parameters."},{"name":"Submit Run","description":"Submit a one-time task run without creating a saved job."},{"name":"List Runs","description":"List job runs in a Databricks workspace with optional filtering by job, status, and time range."},{"name":"Get Run","description":"Get the status, timing, and details of a Databricks job run by its run ID."},{"name":"Get Run Output","description":"Get the output of a completed Databricks job run, including notebook results, error messages, and logs. For multi-task jobs, use the task run ID (not the parent run ID)."},{"name":"Repair Run","description":"Rerun failed or selected tasks within an existing Databricks run."},{"name":"Cancel Run","description":"Cancel a running or pending Databricks job run. Cancellation is asynchronous; poll the run status to confirm termination."},{"name":"Cancel All Runs","description":"Request cancellation of active runs of a job or queued runs in the workspace."},{"name":"Delete Run","description":"Delete a completed Databricks job run."},{"name":"List Clusters","description":"List a page of clusters in a Databricks workspace including their state, configuration, and resource details."},{"name":"Get Cluster","description":"Get the state, configuration, and resource details of a single Databricks cluster by its cluster ID."},{"name":"Create Cluster","description":"Create a compute cluster with runtime, sizing, policy, and cloud-specific settings."},{"name":"Edit Cluster","description":"Replace a compute cluster configuration; a running cluster restarts to apply the changes."},{"name":"Start Cluster","description":"Start a terminated all-purpose compute cluster."},{"name":"Restart Cluster","description":"Restart a running compute cluster."},{"name":"Resize Cluster","description":"Change the fixed worker count or autoscaling range of a running cluster."},{"name":"Terminate Cluster","description":"Terminate a compute cluster while retaining its configuration for a later restart."},{"name":"Delete Cluster","description":"Permanently delete a compute cluster and its configuration."},{"name":"List Warehouses","description":"List a page of SQL warehouses in a Databricks workspace including their size, state, and type. Use this to discover the warehouse ID needed for Execute SQL."},{"name":"Get Warehouse","description":"Get the configuration, state, and scaling settings of a SQL warehouse."},{"name":"Create Warehouse","description":"Create a SQL warehouse with sizing, autoscaling, and serverless settings."},{"name":"Edit Warehouse","description":"Update a SQL warehouse configuration."},{"name":"Start Warehouse","description":"Start a stopped SQL warehouse."},{"name":"Stop Warehouse","description":"Stop a running SQL warehouse."},{"name":"Delete Warehouse","description":"Delete a SQL warehouse."},{"name":"List Genie Spaces","description":"List the Genie spaces (Genie agents) you can access. Use this to find the space ID needed to ask Genie a question."},{"name":"Get Genie Space","description":"Get a Genie space\'s title, description, and SQL warehouse, optionally with its full configuration export (tables, instructions, sample questions)."},{"name":"Create Genie Space","description":"Create a Genie space from its serialized configuration and a SQL warehouse."},{"name":"Update Genie Space","description":"Update a Genie space, optionally protecting the change with its current ETag."},{"name":"Trash Genie Space","description":"Move a Genie space to the trash."},{"name":"Ask Genie","description":"Ask a Databricks Genie space a question in natural language and wait for the answer. Starts a new conversation, or continues an existing one when a conversation ID is given. Returns the text answer, the SQL Genie generated, and the query result rows."},{"name":"Get Genie Message","description":"Get a Genie message\'s status and answer, including the generated SQL, visualizations, and suggested follow-up questions."},{"name":"List Genie Messages","description":"List the messages in a Genie conversation with their answers and generated SQL, for example to replay a conversation history."},{"name":"Get Genie Query Result","description":"Get the rows returned by the SQL query Genie generated for a message. Available once the message is EXECUTING_QUERY or COMPLETED."},{"name":"Execute Genie Query","description":"Re-run the SQL query Genie generated for a message. Use this when the message\'s query result has expired (status QUERY_RESULT_EXPIRED). If the returned status is PENDING or RUNNING, fetch the rows afterwards with Get Genie Query Result."},{"name":"Download Genie Visualization","description":"Download a chart Genie generated as a PNG image, for example to post it to Slack. The message must be COMPLETED and asked with visualization enabled. Not supported on Private Link workspaces."},{"name":"Send Genie Feedback","description":"Rate a Genie answer as positive or negative, with an optional comment. Space authors use this feedback to improve the space\'s instructions."},{"name":"Delete Genie Message","description":"Delete a message from a Genie conversation."},{"name":"List Genie Conversations","description":"List conversations in a Genie space, including whether each is a chat-mode or agent-mode conversation. By default only your own conversations are returned."},{"name":"Delete Genie Conversation","description":"Delete a Genie conversation you no longer need."},{"name":"Ask Genie Agent","description":"Ask a Genie agent a question in agent mode, where Genie plans multi-step research, runs several SQL queries, and writes a report with citations. Waits for the final report. Starts a new agent-mode conversation, or continues one when a conversation ID is given. Agent mode is in preview and must be enabled on the workspace."},{"name":"List Genie Agent Items","description":"List an agent-mode conversation\'s full history in order: questions, reasoning, SQL calls, query results, and reports. Agent mode is in preview and must be enabled on the workspace."},{"name":"Cancel Genie Agent Response","description":"Cancel an in-flight Genie agent response using the response ID returned by the agent stream."}],"triggers":[],"skills":[{"name":"repair-failed-tasks","description":"Repair the failed portion of a multi-task job without rerunning successful independent tasks.","content":"# Repair Failed Databricks Tasks\\n\\nRecover a failed job run.\\n\\n## Steps\\n1. Get the run with repair history enabled and inspect each failed task.\\n2. Retrieve output using the failing task run ID to diagnose the cause.\\n3. After correcting the cause, repair selected task keys or all failed tasks, optionally including dependents.\\n4. Supply the latest repair ID for subsequent repairs and poll the run for completion.\\n\\n## Output\\nThe repair ID, affected task keys, and final run status."},{"name":"configure-warehouse-scaling","description":"Inspect and adjust SQL warehouse size, cluster limits, and automatic stopping.","content":"# Configure SQL Warehouse Scaling\\n\\nApply the requested warehouse capacity settings.\\n\\n## Steps\\n1. Get the warehouse and inspect its current size, cluster limits, and state.\\n2. Confirm the desired size, minimum and maximum cluster counts, and idle stopping policy.\\n3. Edit the warehouse with the requested settings.\\n4. Get the warehouse again to report the applied configuration.\\n\\n## Output\\nThe warehouse ID and its updated capacity and automatic stopping settings."},{"name":"run-sql-query","description":"Execute a SQL query against a Databricks SQL warehouse and return the results in a clean, summarized form.","content":"# Run a Databricks SQL Query\\n\\nQuery a table or view and summarize the result.\\n\\n## Steps\\n1. Confirm the SQL warehouse and the query to run.\\n2. Execute the SQL statement and wait for it to complete.\\n3. Capture the returned rows and column schema; follow nextChunkIndex with Get Statement Chunk when more rows are needed.\\n4. Summarize key findings (counts, totals, notable values).\\n\\n## Output\\nThe query results plus a short plain-English summary of what they show."},{"name":"trigger-job-run","description":"Trigger a Databricks job, capture the run id, and confirm it started successfully.","content":"# Trigger a Databricks Job\\n\\nKick off a job and confirm it launched.\\n\\n## Steps\\n1. List jobs to confirm the target job id and name.\\n2. Run the job with any required parameters.\\n3. Capture the run id, then get the run to read its starting state.\\n\\n## Output\\nA confirmation with the job name, run id, and initial status."},{"name":"monitor-job-run","description":"Check the status of a Databricks job run, pull its output, and diagnose failures.","content":"# Monitor a Databricks Job Run\\n\\nTrack a job run to completion and report results.\\n\\n## Steps\\n1. Get the run for the given run id and read its lifecycle and result state.\\n2. If still running, report progress; if finished, pull the run output.\\n3. On failure, capture the error and the failing task.\\n\\n## Output\\nA run summary with final state, key output, and (on failure) the error and failing task."},{"name":"ask-genie","description":"Ask a Databricks Genie space a data question and report the answer, result rows, and generated SQL.","content":"# Ask Databricks Genie\\n\\nAnswer a business question from governed data through Genie.\\n\\n## Steps\\n1. If the Genie space is unknown, list Genie spaces and pick the one whose title and description fit the question.\\n2. Ask Genie the question, passing the conversation ID when this is a follow-up.\\n3. If Genie asked a clarifying follow-up question instead of answering, surface it to the user.\\n4. Otherwise capture the answer, the result rows, and the SQL Genie ran.\\n\\n## Output\\nThe answer in plain English, a compact table of the key rows, the SQL, and the conversation ID for follow-ups."},{"name":"research-with-genie-agent","description":"Run a multi-step Databricks Genie agent-mode investigation and summarize its report.","content":"# Research with a Genie Agent\\n\\nUse Genie agent mode for open-ended questions that need several queries.\\n\\n## Steps\\n1. Ask the Genie agent the research question, continuing the conversation ID for follow-ups.\\n2. Read the final report and the SQL queries the agent ran.\\n3. List the conversation items if the reasoning or intermediate results are needed.\\n\\n## Output\\nThe report summary, the key findings, and the queries behind them."}],"templates":[{"title":"Dagster + Databricks coordinator","prompt":"Create a workflow that orchestrates a Dagster job that triggers a Databricks notebook, waits for completion, captures outputs, and writes the unified run history to a tracking table.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"dagster","name":"Dagster"}]},{"title":"Databricks job runner","prompt":"Build a scheduled workflow that triggers a Databricks job daily, polls until completion, writes the run status and metrics to a control table, and pages on failure.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Databricks cluster cost guard","prompt":"Create a scheduled workflow that lists Databricks clusters hourly, flags clusters that are running while idle, and posts a Slack alert with the candidates to shut down so the platform team can reclaim spend.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks notebook scheduler","prompt":"Build a workflow that runs a parameterized Databricks notebook, captures the outputs as files, and posts the result to a chosen Slack channel for review.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks ML feature freshness","prompt":"Create a scheduled workflow that runs SQL against Databricks feature tables to check the latest update timestamp per feature, alerts when a critical feature has stale data, and writes the alert details to a tracking table.","integrations":[{"id":"databricks","name":"Databricks"}]},{"title":"Databricks model evaluator","prompt":"Build a workflow that runs a Databricks ML model evaluation job on the latest data, captures the metrics, writes results to a model-registry table, and pings Slack on regression.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks Delta Lake compactor","prompt":"Create a scheduled workflow that runs OPTIMIZE and VACUUM on Databricks Delta Lake tables weekly, captures the size and performance delta, and writes a maintenance report.","integrations":[{"id":"databricks","name":"Databricks"}]},{"title":"Databricks job failure watcher","prompt":"Build a workflow that lists recent Databricks job runs every 15 minutes, detects failed runs, pulls the run output and error for an agent to summarize the likely cause, and posts an actionable Slack alert with a link to the run.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks Genie Slack analyst","prompt":"Build an agent that answers data questions asked in a Slack channel with Databricks Genie. It keeps one Genie conversation per Slack thread in a table so follow-up questions keep their context, then replies in the thread with the answer, a short table of the result rows, and the SQL Genie ran.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks Genie space router","prompt":"Create an agent that lists the Databricks Genie spaces I can access, picks the space whose title and description best fit each incoming question, asks that Genie space, and posts the answer to Slack with which space answered it.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]},{"title":"Databricks Genie KPI digest","prompt":"Build a scheduled workflow that asks a Databricks Genie agent every Monday for a research report on last week\'s key business metrics and what drove them, then posts the report and the SQL behind it to a Slack channel.","integrations":[{"id":"databricks","name":"Databricks"},{"id":"slack","name":"Slack"}]}]},{"id":"datadog","type":"datadog","slug":"datadog","name":"Datadog","description":"Monitor infrastructure, applications, and logs with Datadog","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/datadog","authType":"api-key","connections":[],"operations":[{"name":"Submit Metrics","description":"Submit custom metrics to Datadog. Use for tracking application performance, business metrics, or custom monitoring data."},{"name":"Query Timeseries","description":"Query metric timeseries data from Datadog. Use for analyzing trends, creating reports, or retrieving metric values."},{"name":"Create Event","description":"Post an event to the Datadog event stream. Use for deployment notifications, alerts, or any significant occurrences."},{"name":"Create Monitor","description":"Create a new monitor/alert in Datadog. Monitors can track metrics, service checks, events, and more."},{"name":"Get Monitor","description":"Retrieve details of a specific monitor by ID."},{"name":"List Monitors","description":"List all monitors in Datadog with optional filtering by name, tags, or state."},{"name":"Mute Monitor","description":"Mute a monitor to temporarily suppress its notifications. Use Unmute Monitor to reverse it, or schedule a downtime instead when you want a planned, auditable maintenance window."},{"name":"Unmute Monitor","description":"Unmute a monitor so it resumes sending notifications. Reverses Mute Monitor, either for one scope or for every scope at once."},{"name":"Query Logs","description":"Search and retrieve logs from Datadog. Use for troubleshooting, analysis, or monitoring."},{"name":"Send Logs","description":"Send log entries to Datadog for centralized logging and analysis."},{"name":"Create Downtime","description":"Schedule a downtime to suppress monitor notifications during maintenance windows."},{"name":"List Downtimes","description":"List all scheduled downtimes in Datadog."},{"name":"Cancel Downtime","description":"Cancel a scheduled downtime."},{"name":"List Incidents","description":"List incidents for the organization. Requires the Incident Management `incident_read` permission; the Incidents API is in public beta."},{"name":"Get Incident","description":"Get the details of a single incident by ID. Requires the Incident Management `incident_read` permission; the Incidents API is in public beta."},{"name":"Create Incident","description":"Declare a new incident. Requires the Incident Management `incident_write` permission; the Incidents API is in public beta."},{"name":"Update Incident","description":"Partially update an existing incident. Requires the Incident Management `incident_write` permission; the Incidents API is in public beta."},{"name":"Add Incident Todo","description":"Add a follow-up task (todo) to an incident. Requires the Incident Management `incident_write` permission; the Incidents API is in public beta."},{"name":"List SLOs","description":"List service level objectives, optionally filtered by IDs, name, tags, or underlying metrics query."},{"name":"Get SLO","description":"Get the configuration of a single service level objective by ID."},{"name":"Create SLO","description":"Create a service level objective from a metric query, monitors, or a time-slice condition."},{"name":"Update SLO","description":"Update a service level objective. Reads the current SLO first and applies only the fields you supply, so anything left blank keeps its stored value."},{"name":"Delete SLO","description":"Permanently delete a service level objective. Datadog returns a conflict when the SLO is still referenced by a dashboard."},{"name":"Get SLO History","description":"Get an SLO’s history over a time window, including the overall SLI value and remaining error budget."},{"name":"List Dashboards","description":"List custom created or cloned dashboards. Datadog preset dashboards are not returned."},{"name":"Get Dashboard","description":"Get the full definition of a dashboard, including its widgets."},{"name":"Create Dashboard","description":"Create a dashboard from a title, layout type, and widget definitions."},{"name":"Delete Dashboard","description":"Delete a dashboard by ID."},{"name":"List Synthetic Tests","description":"List all Synthetic tests (API, browser, and mobile) with their current status."},{"name":"Get Synthetic Test","description":"Get the configuration of a Synthetic test by public ID. Browser test steps are not included by this type-agnostic endpoint."},{"name":"Get Synthetic Test Results","description":"Get the latest result summaries (up to the last 150 runs) for a Synthetic API test."},{"name":"Get Browser Synthetic Test Results","description":"Get the latest result summaries (up to the last 150 runs) for a Synthetic browser test, including step counts and errors."},{"name":"Trigger Synthetic Tests","description":"Trigger an immediate run of one or more Synthetic tests by public ID."},{"name":"Pause Or Start Synthetic Test","description":"Pause or resume a Synthetic test by setting its status to \\"paused\\" or \\"live\\"."},{"name":"List Security Signals","description":"Search Cloud SIEM security signals by query and time range. Requires the `security_monitoring_signals_read` permission."},{"name":"Get Security Signal","description":"Get the details of a single Cloud SIEM security signal. Requires the `security_monitoring_signals_read` permission."},{"name":"Update Security Signal State","description":"Change the triage state of a Cloud SIEM security signal to open, under_review, or archived. Requires the `security_monitoring_signals_write` permission."},{"name":"Assign Security Signal","description":"Assign a Cloud SIEM security signal to a Datadog user by UUID. Requires the `security_monitoring_signals_write` permission."},{"name":"List Security Rules","description":"List Cloud SIEM detection rules. Requires the `security_monitoring_rules_read` permission."},{"name":"Search Spans","description":"Search indexed APM spans using the span query syntax, with cursor pagination."},{"name":"List Services","description":"List service definitions from the Datadog Service Catalog. Requires the `apm_service_catalog_read` permission."}],"triggers":[],"skills":[{"name":"triage-firing-monitors","description":"List Datadog monitors, surface those in alert or warn state, and summarize what is firing and why.","content":"# Triage Firing Datadog Monitors\\n\\nGet a clear picture of what is alerting right now.\\n\\n## Steps\\n1. List monitors and filter to those in Alert or Warn states.\\n2. For each, get the monitor details: query, threshold, and current value.\\n3. Group by service or tag to find common root causes.\\n\\n## Output\\nA prioritized list of firing monitors with the metric, threshold, and likely affected service."},{"name":"investigate-logs","description":"Query Datadog logs for a service and time window to find errors and summarize patterns.","content":"# Investigate Datadog Logs\\n\\nSearch logs to diagnose an issue.\\n\\n## Steps\\n1. Confirm the service, environment, and time window.\\n2. Query logs filtering for error/critical status and the relevant service tag.\\n3. Aggregate by error message or type to find the dominant patterns.\\n4. Pull sample log lines for the top patterns.\\n\\n## Output\\nA summary of the top error patterns with counts and sample log lines."},{"name":"analyze-metric-trend","description":"Query a Datadog timeseries metric over a window and report the trend, anomalies, and current value.","content":"# Analyze a Datadog Metric Trend\\n\\nUnderstand how a metric is behaving over time.\\n\\n## Steps\\n1. Confirm the metric query and the time window.\\n2. Query the timeseries and compute the trend (rising, flat, falling).\\n3. Identify spikes, dips, or anomalies and when they occurred.\\n\\n## Output\\nA short analysis with the current value, overall trend, and any notable anomalies with timestamps."},{"name":"schedule-maintenance-downtime","description":"Create a Datadog downtime to mute monitors during a maintenance window, then confirm the scope and timing.","content":"# Schedule Datadog Maintenance Downtime\\n\\nSuppress alerts during planned maintenance.\\n\\n## Steps\\n1. Confirm the scope (tags/monitors) and the start and end times.\\n2. Create the downtime with that scope and window.\\n3. Verify it was created by listing active downtimes.\\n\\n## Output\\nA confirmation of the downtime with its scope, start/end time, and id."}],"templates":[{"title":"PagerDuty incident coordinator","prompt":"Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"},{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"Datadog infra health report","prompt":"Create a scheduled daily workflow that queries Datadog for key infrastructure metrics — error rates, latency percentiles, CPU and memory usage — logs them to a table for trend tracking, and sends a morning Slack report highlighting any anomalies or degradations.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"Datadog alert-to-Linear bridge","prompt":"Build a scheduled workflow that polls Datadog monitors for any in an alerting state, classifies severity, creates a Linear ticket for non-paging issues with full context, and posts a Slack notification linking both.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Datadog SLO weekly review","prompt":"Create a scheduled weekly workflow that queries Datadog timeseries for the key reliability metrics behind each service SLO, computes error budget burn, and writes a narrative review file for the SRE team to discuss in the weekly meeting.","integrations":[{"id":"datadog","name":"Datadog"}]},{"title":"Datadog cost optimizer","prompt":"Build a scheduled workflow that queries Datadog estimated-usage timeseries for the top custom metrics by volume, writes optimization recommendations to a finance review file, and pings the platform team.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"Datadog monitor config backup","prompt":"Create a scheduled workflow that lists every Datadog monitor nightly, fetches each monitor’s full configuration, exports the definitions as JSON to S3 with version history, and writes a manifest to a tracking table for restore drills.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"s3","name":"S3"}]},{"title":"Datadog deploy guardrail","prompt":"Build a workflow triggered after a deploy that creates a Datadog event marker, queries error-rate and latency timeseries over the next few minutes, and pages the team via PagerDuty if the metrics breach the rollback threshold.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Datadog SLO weekly report","prompt":"Create a scheduled weekly workflow that queries Datadog timeseries for key service SLOs, lists which monitors fired during the week, writes the SLO compliance numbers to a table, and emails an availability summary to the on-call leads.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"gmail","name":"Gmail"}]},{"title":"LaunchDarkly flag-flip safety gate","prompt":"Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"LaunchDarkly targeted rollout assistant","prompt":"Build a workflow that takes a LaunchDarkly flag and a rollout plan, advances the rollout percentage on a schedule while watching health metrics, pausing on degradation.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"launchdarkly","name":"LaunchDarkly"}]},{"title":"SQS alert enricher","prompt":"Create a workflow triggered by PagerDuty or Datadog alerts that classifies severity, decorates the payload with runbook context, and pushes the enriched alert to an Amazon SQS queue so multiple downstream notifiers and ticketing systems can consume it independently.","integrations":[{"id":"datadog","name":"Datadog"},{"id":"sqs","name":"Amazon SQS"},{"id":"pagerduty","name":"PagerDuty"}]}]},{"id":"datagma","type":"datagma","slug":"datagma","name":"Datagma","description":"Find verified B2B emails, mobile phones, and enrich person or company profiles","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/datagma","authType":"api-key","connections":[],"operations":[{"name":"Find Email","description":"Find a verified work email from a person\'s full name and company. Uses 1 credit when a verified email is found."},{"name":"Enrich Person","description":"Enrich a person\'s profile using their email, LinkedIn URL, or full name and company. Returns job title, company, location, and social data. Uses 2 credits per match; add 30 credits when a phone number is found."},{"name":"Enrich Company","description":"Enrich a company profile using a domain, company name, or SIREN number (France). Returns size, industry, revenue, and description. Uses 2 credits per match."},{"name":"Find Phone","description":"Find a mobile phone number from a person\'s LinkedIn URL. Optionally supply an email to improve match accuracy. Uses 30 credits when a number is found."},{"name":"Get Remaining Credits","description":"Check remaining credit balance on a Datagma account. Free — no credits consumed."}],"triggers":[],"skills":[],"templates":[]},{"id":"daytona","type":"daytona","slug":"daytona","name":"Daytona","description":"Run code and commands in secure cloud sandboxes","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/daytona","authType":"api-key","connections":[],"operations":[{"name":"Create Sandbox","description":"Create a new Daytona sandbox for running AI-generated code in isolation"},{"name":"Run Code","description":"Run Python, JavaScript, or TypeScript code inside a Daytona sandbox"},{"name":"Execute Command","description":"Execute a shell command inside a Daytona sandbox"},{"name":"Upload File","description":"Upload a file to a Daytona sandbox"},{"name":"Download File","description":"Download a file from a Daytona sandbox"},{"name":"List Files","description":"List files in a directory of a Daytona sandbox"},{"name":"Git Clone","description":"Clone a Git repository into a Daytona sandbox"},{"name":"List Sandboxes","description":"List Daytona sandboxes in the organization"},{"name":"Get Sandbox","description":"Get details of a Daytona sandbox"},{"name":"Start Sandbox","description":"Start a stopped Daytona sandbox"},{"name":"Stop Sandbox","description":"Stop a running Daytona sandbox"},{"name":"Delete Sandbox","description":"Delete a Daytona sandbox"}],"triggers":[],"skills":[{"name":"run-code-in-sandbox","description":"Run Python, JavaScript, or TypeScript in an isolated Daytona sandbox and return the output. Use as a safe code interpreter for computation, parsing, or data wrangling.","content":"# Run Code In Sandbox\\n\\nExecute code safely in an isolated Daytona sandbox.\\n\\n## Steps\\n1. Create a sandbox with the Create Sandbox operation (or reuse an existing sandbox ID), setting an auto-stop interval so it cleans up after itself.\\n2. Use Run Code with the language set to python, javascript, or typescript. Print the values you need to stdout — the printed output is what comes back.\\n3. Check the exit code: 0 means success; on failure, read the result output for the error, fix the code, and rerun.\\n4. Delete the sandbox with Delete Sandbox when the work is finished if it was created just for this task.\\n\\n## Output\\nReturn the printed result and the exit code. If the run produced chart artifacts, mention them. On repeated failures, return the last error output instead of fabricating a result."},{"name":"analyze-data-file","description":"Upload a data file into a Daytona sandbox, analyze it with Python, and download any generated results. Use for CSV/JSON analysis that needs real computation.","content":"# Analyze Data File\\n\\nProcess a workflow file with real code in a sandbox.\\n\\n## Steps\\n1. Create a sandbox (or reuse one) and note its ID.\\n2. Use Upload File to place the data file at a known path, e.g. /home/daytona/data.csv. A trailing slash on the destination uploads into that directory under the original file name.\\n3. Use Run Code with Python to read the file from that path, compute the analysis, print a summary, and write any derived files (reports, charts) to known paths.\\n4. Use Download File to pull each derived file back into the workflow, and List Files to discover outputs if paths are dynamic.\\n5. Delete the sandbox when finished.\\n\\n## Output\\nReturn the printed analysis summary and the downloaded result files. Name the exact sandbox paths used so the run can be reproduced."},{"name":"clone-repo-and-run-checks","description":"Clone a Git repository into a Daytona sandbox and run install, build, or test commands. Use for CI-style checks, repo health monitoring, or validating changes.","content":"# Clone Repo And Run Checks\\n\\nRun repository checks in an isolated environment.\\n\\n## Steps\\n1. Create a sandbox sized for the job (set CPU and memory in advanced options for heavy builds).\\n2. Use Git Clone with the repository URL and a clone path like /home/daytona/repo. Pass a branch for non-default branches, and a username plus token for private repositories.\\n3. Use Execute Command from the clone path (set the working directory) to run installs, builds, or tests. Raise the timeout for long commands — the default is 10 seconds.\\n4. Inspect each exit code and capture the output of failing commands.\\n5. Delete the sandbox when the checks complete.\\n\\n## Output\\nReturn pass/fail per command with exit codes, and include the failing output verbatim when something breaks."},{"name":"manage-sandbox-fleet","description":"List, stop, and delete Daytona sandboxes to control cost and tidy up environments. Use for scheduled cleanup or auditing what is currently running.","content":"# Manage Sandbox Fleet\\n\\nAudit and clean up sandboxes in the organization.\\n\\n## Steps\\n1. Use List Sandboxes to enumerate sandboxes; filter by name prefix or labels, and page with the cursor when there are many.\\n2. Inspect each sandbox state and timestamps to find ones idle or running longer than expected.\\n3. Stop Sandbox for environments worth keeping but not actively used; Delete Sandbox for disposable ones (e.g. labeled temporary).\\n4. When creating sandboxes elsewhere, set auto-stop and auto-delete intervals so cleanup happens automatically.\\n\\n## Output\\nReturn a summary of sandboxes found, which were stopped or deleted and why, and any that were left running with their states."}],"templates":[{"title":"Daytona code interpreter","prompt":"Build a workflow where an agent answers data questions by writing Python, creating a Daytona sandbox, running the code in it, and replying with the computed result and any printed output.","integrations":[{"id":"daytona","name":"Daytona"}]},{"title":"Daytona PR test runner","prompt":"Create a workflow triggered by a GitHub pull request that creates a Daytona sandbox, clones the repository at the PR branch, runs the test suite with an execute command, and posts the pass/fail summary back to the PR.","integrations":[{"id":"daytona","name":"Daytona"},{"id":"github","name":"GitHub"}]},{"title":"Daytona CSV analysis","prompt":"Build a workflow that takes an uploaded CSV file, uploads it into a Daytona sandbox, runs a Python analysis script over it, downloads the generated report file, and shares the findings in Slack.","integrations":[{"id":"daytona","name":"Daytona"},{"id":"slack","name":"Slack"}]},{"title":"Daytona scheduled script runner","prompt":"Create a scheduled daily workflow that spins up a Daytona sandbox, runs a maintenance script with an execute command, writes the output to a results table, and deletes the sandbox when finished.","integrations":[{"id":"daytona","name":"Daytona"}]},{"title":"Daytona sandbox janitor","prompt":"Build a scheduled weekly workflow that lists all Daytona sandboxes, stops any that have been running longer than expected, deletes sandboxes labeled as temporary, and posts a cleanup summary to Slack.","integrations":[{"id":"daytona","name":"Daytona"},{"id":"slack","name":"Slack"}]},{"title":"Daytona generated-code validator","prompt":"Create a workflow where an agent generates code from a user request, runs it in a Daytona sandbox, inspects the exit code and output, fixes errors and reruns until the code passes, then returns the validated code.","integrations":[{"id":"daytona","name":"Daytona"}]},{"title":"Daytona repo health check","prompt":"Build a scheduled workflow that creates a Daytona sandbox, clones the main branch of a repository, runs install and build commands, records any failures in a table, and alerts the engineering channel when the build breaks.","integrations":[{"id":"daytona","name":"Daytona"},{"id":"slack","name":"Slack"}]},{"title":"Daytona file transformer","prompt":"Create a workflow that receives a document from a form, uploads it to a Daytona sandbox, runs a conversion script on it, downloads the transformed file, and emails it back to the requester.","integrations":[{"id":"daytona","name":"Daytona"},{"id":"gmail","name":"Gmail"}]}]},{"id":"devin","type":"devin","slug":"devin","name":"Devin","description":"Autonomous AI software engineer","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/devin","authType":"api-key","connections":[],"operations":[{"name":"Create Session","description":"Create a new Devin session with a prompt. Devin will autonomously work on the task described in the prompt."},{"name":"Get Session","description":"Retrieve details of an existing Devin session including status, tags, pull requests, and structured output."},{"name":"List Sessions","description":"List Devin sessions in the organization. Returns up to 100 sessions by default."},{"name":"Send Message","description":"Send a message to a Devin session. If the session is suspended, it will be automatically resumed. Returns the updated session state."},{"name":"List Session Messages","description":"List the messages exchanged in a Devin session, including messages from both the user and Devin."},{"name":"List Session Attachments","description":"List the files uploaded to or produced by a Devin session."},{"name":"Get Session Tags","description":"Retrieve the tags currently applied to a Devin session."},{"name":"Append Session Tags","description":"Add tags to a Devin session without removing existing tags (max 50 tags total)."},{"name":"Replace Session Tags","description":"Replace all tags on a Devin session with a new set of tags (max 50 tags)."},{"name":"Archive Session","description":"Archive a Devin session. Archived sessions can still be viewed but cannot be modified or resumed."},{"name":"Terminate Session","description":"Terminate a Devin session. Optionally archive the session instead of permanently terminating it."}],"triggers":[],"skills":[{"name":"start-engineering-session","description":"Create a Devin session with a clear engineering task prompt and report the session id and link.","content":"# Start a Devin Engineering Session\\n\\nKick off an autonomous engineering task with Devin.\\n\\n## Steps\\n1. Confirm the repository and the task to perform.\\n2. Write a precise prompt: the goal, constraints, and acceptance criteria.\\n3. Create the session, optionally tagging it for tracking.\\n4. Capture the session id and URL.\\n\\n## Output\\nA confirmation with the session id, link, and the task prompt Devin was given."},{"name":"check-session-progress","description":"Get a Devin session status and recent messages and summarize what it has accomplished or where it is blocked.","content":"# Check Devin Session Progress\\n\\nMonitor a running Devin session.\\n\\n## Steps\\n1. Get the session for the given session id and read its status.\\n2. List recent session messages to see Devin actions and reasoning.\\n3. Determine whether it is making progress, finished, or blocked needing input.\\n\\n## Output\\nA status summary describing progress, current state, and any questions Devin is waiting on."},{"name":"guide-session","description":"Send a message to an active Devin session to answer a question or redirect its work.","content":"# Guide a Devin Session\\n\\nUnblock or steer an active session.\\n\\n## Steps\\n1. Confirm the session id and review the latest messages.\\n2. Compose a clear reply: answer the open question or give new direction.\\n3. Send the message to the session.\\n4. Confirm Devin has resumed.\\n\\n## Output\\nA confirmation that the message was sent, with the guidance provided."}],"templates":[{"title":"Devin session launcher","prompt":"Build a workflow that accepts a coding task description, creates a new Devin session with rich context, polls the session until it produces a pull request or hits a blocker, and posts the session link and status to Slack.","integrations":[{"id":"devin","name":"Devin"},{"id":"slack","name":"Slack"}]},{"title":"Devin bug-fix dispatcher","prompt":"Create a workflow that watches for new critical errors, packages the stack trace and reproduction steps into a Devin prompt, creates a session, and updates a Linear ticket with the Devin session link and any pull requests it opens.","integrations":[{"id":"devin","name":"Devin"},{"id":"linear","name":"Linear"}]},{"title":"Devin session monitor","prompt":"Build a scheduled workflow that runs every ten minutes, lists Devin sessions for your organization, tracks status changes, logs sessions, pull requests, and tags to a table, and sends a Slack alert when any session has been stuck for more than two hours.","integrations":[{"id":"devin","name":"Devin"},{"id":"slack","name":"Slack"}]},{"title":"Devin progress nudger","prompt":"Build a workflow that runs every hour against active Devin sessions, detects sessions that are suspended or awaiting input, sends a targeted follow-up message via the Devin API to unblock progress, and notifies the requester if a session needs human intervention.","integrations":[{"id":"devin","name":"Devin"},{"id":"slack","name":"Slack"}]},{"title":"Devin documentation gap closer","prompt":"Create a workflow that scans a knowledge base of docs against the latest repo state, finds undocumented public APIs, opens a Devin session for each gap with a prompt to write documentation, and stores the produced markdown back into the knowledge base.","integrations":[{"id":"devin","name":"Devin"}]},{"title":"Devin retrospective report","prompt":"Build a scheduled weekly workflow that lists Devin sessions completed in the past week, summarizes outcomes, pull requests merged, time-to-completion, and recurring failure modes, and writes a retrospective report file shared with engineering leadership.","integrations":[{"id":"devin","name":"Devin"}]},{"title":"Devin issue-to-PR runner","prompt":"Create a workflow triggered when a Linear issue is labeled ready-for-devin that creates a Devin session with the issue context, monitors the session to completion, and comments the resulting pull request link back on the Linear issue.","integrations":[{"id":"devin","name":"Devin"},{"id":"linear","name":"Linear"}]},{"title":"Linear ticket to Devin pipeline","prompt":"Create a workflow that fires when a Linear ticket gets the \\"devin\\" label, transforms the ticket description, acceptance criteria, and linked context into a Devin prompt, creates a session, and posts the session link plus an estimated completion window back on the ticket.","integrations":[{"id":"devin","name":"Devin"},{"id":"linear","name":"Linear"}]}]},{"id":"discord","type":"discord","slug":"discord","name":"Discord","description":"Interact with Discord","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/discord","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send a message to a Discord channel"},{"name":"Get Channel Messages","description":"Retrieve messages from a Discord channel"},{"name":"Get Server Information","description":"Retrieve information about a Discord server (guild)"},{"name":"Get User Information","description":"Retrieve information about a Discord user"},{"name":"Edit Message","description":"Edit an existing message in a Discord channel"},{"name":"Delete Message","description":"Delete a message from a Discord channel"},{"name":"Bulk Delete Messages","description":"Delete 2-100 messages from a Discord channel in a single request"},{"name":"Add Reaction","description":"Add a reaction emoji to a Discord message"},{"name":"Remove Reaction","description":"Remove a reaction from a Discord message"},{"name":"Pin Message","description":"Pin a message in a Discord channel"},{"name":"Unpin Message","description":"Unpin a message in a Discord channel"},{"name":"Get Pinned Messages","description":"Retrieve all pinned messages in a Discord channel"},{"name":"Create Thread","description":"Create a thread in a Discord channel"},{"name":"Join Thread","description":"Join a thread in Discord"},{"name":"Leave Thread","description":"Leave a thread in Discord"},{"name":"Archive Thread","description":"Archive or unarchive a thread in Discord"},{"name":"Create Channel","description":"Create a new channel in a Discord server"},{"name":"Update Channel","description":"Update a Discord channel"},{"name":"Delete Channel","description":"Delete a Discord channel"},{"name":"Get Channel","description":"Get information about a Discord channel"},{"name":"List Channels","description":"List all channels in a Discord server"},{"name":"Create Role","description":"Create a new role in a Discord server"},{"name":"Update Role","description":"Update a role in a Discord server"},{"name":"Delete Role","description":"Delete a role from a Discord server"},{"name":"Assign Role","description":"Assign a role to a member in a Discord server"},{"name":"Remove Role","description":"Remove a role from a member in a Discord server"},{"name":"List Roles","description":"List all roles in a Discord server"},{"name":"Kick Member","description":"Kick a member from a Discord server"},{"name":"Ban Member","description":"Ban a member from a Discord server"},{"name":"Unban Member","description":"Unban a member from a Discord server"},{"name":"Get Member","description":"Get information about a member in a Discord server"},{"name":"Update Member","description":"Update a member in a Discord server (e.g., change nickname)"},{"name":"Create Invite","description":"Create an invite link for a Discord channel"},{"name":"Get Invite","description":"Get information about a Discord invite"},{"name":"Delete Invite","description":"Delete a Discord invite"},{"name":"Create Webhook","description":"Create a webhook in a Discord channel"},{"name":"Execute Webhook","description":"Execute a Discord webhook to send a message"},{"name":"Get Webhook","description":"Get information about a Discord webhook"},{"name":"Delete Webhook","description":"Delete a Discord webhook"}],"triggers":[],"skills":[{"name":"post-announcement","description":"Post a formatted announcement message to a Discord channel and optionally pin it.","content":"# Post a Discord Announcement\\n\\nShare an announcement with a community channel.\\n\\n## Steps\\n1. Confirm the target channel and the announcement content.\\n2. Format the message clearly, using mentions or roles only if requested.\\n3. Send the message to the channel.\\n4. If it is important, pin the message.\\n\\n## Output\\nA confirmation with the channel, message link or id, and whether it was pinned."},{"name":"summarize-channel-activity","description":"Read recent Discord channel messages and produce a summary of discussions, questions, and decisions.","content":"# Summarize Discord Channel Activity\\n\\nCatch up on what happened in a channel.\\n\\n## Steps\\n1. Confirm the channel and how many recent messages to review.\\n2. Get the channel messages.\\n3. Group the conversation into themes: announcements, questions, and decisions.\\n4. Flag unanswered questions that need a reply.\\n\\n## Output\\nA concise digest of the discussion with unanswered questions called out."},{"name":"open-discussion-thread","description":"Create a Discord thread for a topic and post a kickoff message to organize community discussion.","content":"# Open a Discord Discussion Thread\\n\\nSpin up a focused thread for a topic.\\n\\n## Steps\\n1. Confirm the parent channel and the thread topic.\\n2. Create the thread with a clear name.\\n3. Post a kickoff message framing the discussion and any prompts.\\n\\n## Output\\nA confirmation with the thread name, link or id, and the kickoff message posted."},{"name":"collect-reactions-feedback","description":"Post a poll-style message in Discord, add reaction options, and read back the tally as feedback.","content":"# Collect Discord Reaction Feedback\\n\\nRun a lightweight reaction poll.\\n\\n## Steps\\n1. Confirm the channel, the question, and the reaction options.\\n2. Send the poll message.\\n3. Add each reaction option to the message.\\n4. After the polling window, read the message to tally the reaction counts.\\n\\n## Output\\nThe poll question with the reaction tally and which option leads."}],"templates":[{"title":"Discord community manager","prompt":"Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.","integrations":[{"id":"discord","name":"Discord"},{"id":"google_docs","name":"Google Docs"},{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"Discord support deflector","prompt":"Build a scheduled workflow that polls help channels in Discord for new questions, searches a knowledge base for an answer, and posts a sourced reply in-thread; escalates to a human when confidence is low.","integrations":[{"id":"discord","name":"Discord"}]},{"title":"Discord weekly community digest","prompt":"Create a scheduled weekly workflow that summarizes Discord activity — top threads, helpful members, new questions — and posts the digest to the announcements channel and Slack.","integrations":[{"id":"discord","name":"Discord"},{"id":"slack","name":"Slack"}]},{"title":"Discord onboarding tracker","prompt":"Build a scheduled workflow that polls a Discord server for recently joined members, opens a private onboarding thread for each new member with relevant links, and tracks completion of starter tasks in a table.","integrations":[{"id":"discord","name":"Discord"}]},{"title":"Discord moderation triage","prompt":"Create a scheduled workflow that polls Discord channels for new messages, classifies community-guideline violations with an agent, auto-warns the user on minor issues, and pings moderators in a private channel for severe cases.","integrations":[{"id":"discord","name":"Discord"}]},{"title":"Discord feature request collector","prompt":"Build a scheduled workflow that polls a Discord feedback channel for new posts, classifies them as bugs vs feature requests, opens Linear tickets for actionable items, and replies in-thread with the ticket link.","integrations":[{"id":"discord","name":"Discord"},{"id":"linear","name":"Linear"}]},{"title":"Discord event reminder","prompt":"Create a scheduled workflow that reads upcoming Luma or Google Calendar events, posts a reminder in the matching Discord channel 24 hours before, and pings RSVP attendees by role.","integrations":[{"id":"discord","name":"Discord"},{"id":"luma","name":"Luma"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Luma + Discord community sync","prompt":"Create a scheduled workflow that pulls the Luma event guest list and adds each new registrant to the matching Discord community channel with the right role for event access.","integrations":[{"id":"discord","name":"Discord"},{"id":"luma","name":"Luma"}]}]},{"id":"docusign","type":"docusign","slug":"docusign","name":"DocuSign","description":"Send documents for e-signature via DocuSign","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/docusign","authType":"oauth","connections":[{"id":"docusign","kind":"oauth","label":"Connect with OAuth","providerId":"docusign","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/docusign","requiredScopes":[{"id":"signature","label":"Send, track, and manage envelopes with the eSignature API"},{"id":"extended","label":"Keep access active by extending the refresh token lifetime"}],"fields":[]}],"operations":[{"name":"Send Envelope","description":"Create and send a DocuSign envelope with a document for e-signature"},{"name":"Send from Template","description":"Create and send a DocuSign envelope using a pre-built template"},{"name":"Get Envelope","description":"Get the details and status of a DocuSign envelope"},{"name":"List Envelopes","description":"List envelopes from your DocuSign account with optional filters"},{"name":"Void Envelope","description":"Void (cancel) a sent DocuSign envelope that has not yet been completed"},{"name":"Download Document","description":"Download a signed document from a completed DocuSign envelope"},{"name":"List Templates","description":"List available templates in your DocuSign account"},{"name":"List Recipients","description":"Get the recipient status details for a DocuSign envelope"}],"triggers":[],"skills":[{"name":"send-contract-for-signature","description":"Send a document to one or more signers for e-signature, using a DocuSign template or an uploaded file.","content":"# Send Contract for Signature\\n\\nSend a document out for e-signature through DocuSign and confirm it was delivered.\\n\\n## Steps\\n1. Determine whether to send from a template (preferred for standard agreements) or from an uploaded document. If a template is named, use List Templates to resolve its ID.\\n2. For a template, call Send from Template with the template ID and a template-roles JSON array mapping each role name to a signer name and email. For an ad-hoc document, call Send Envelope with the email subject, signer name, signer email, and the document file.\\n3. Add any CC recipients and set the email subject to something the signer will recognize.\\n4. Send immediately unless asked to save as a draft.\\n\\n## Output\\nReport the envelope ID and status. List each signer and CC recipient with their email so the requester can confirm the right people were addressed."},{"name":"track-pending-envelopes","description":"List envelopes awaiting signature, identify ones stalled past a threshold, and surface who still needs to sign.","content":"# Track Pending Envelopes\\n\\nFind DocuSign envelopes that are sent but not yet completed so stalled signatures can be chased.\\n\\n## Steps\\n1. Call List Envelopes filtered to sent and delivered status over a recent date window.\\n2. For each envelope, use List Recipients to see which signers have signed and which are still outstanding.\\n3. Compute how long each envelope has been waiting and flag any past the requested threshold (default 48 hours).\\n\\n## Output\\nReturn a table of stalled envelopes: envelope ID, subject, days waiting, and the outstanding signer name and email. Sort by longest waiting first."},{"name":"archive-completed-documents","description":"Find completed envelopes, download the signed PDFs, and extract key metadata for archiving.","content":"# Archive Completed Documents\\n\\nCollect signed documents once an envelope is complete and capture their metadata.\\n\\n## Steps\\n1. Call List Envelopes filtered to completed status over the requested date window.\\n2. For each completed envelope, call Download Document with \\"combined\\" to get the full signed PDF.\\n3. Record the envelope ID, subject, completed date, and signer list for each document.\\n\\n## Output\\nReturn each completed envelope with its downloaded file, signers, and completed date. Note any envelope where the download failed so it can be retried."},{"name":"void-stale-envelope","description":"Void an envelope that should no longer be signed and record the reason.","content":"# Void Stale Envelope\\n\\nCancel a DocuSign envelope that is no longer valid — wrong recipient, superseded terms, or expired offer.\\n\\n## Steps\\n1. Confirm the envelope ID. If only a subject or signer is known, use List Envelopes to resolve it, and verify it is not already completed.\\n2. Call Get Envelope to confirm the current status is still voidable (created, sent, or delivered).\\n3. Call Void Envelope with a clear void reason describing why it is being cancelled.\\n\\n## Output\\nConfirm the envelope ID, its new voided status, and the recorded reason. If the envelope was already completed or voided, report that instead of attempting to void it."}],"templates":[{"title":"Agiloft DocuSign bridge","prompt":"Create a scheduled workflow that searches Agiloft for contracts marked ready-to-sign, creates a DocuSign envelope from the template, sends it, and writes the envelope ID back to Agiloft.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"agiloft","name":"Agiloft"}]},{"title":"Brandfetch contract personalizer","prompt":"Build a workflow that pulls Brandfetch assets for the counterparty on a DocuSign envelope, embeds the right logo in the cover sheet, and sends.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"brandfetch","name":"Brandfetch"}]},{"title":"DocuSign envelope sender","prompt":"Build a workflow that takes a deal from Salesforce above a threshold, pre-fills a DocuSign envelope from a template, sends it, and writes the envelope ID back to the opportunity.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"salesforce","name":"Salesforce"}]},{"title":"DocuSign chase reminder","prompt":"Create a scheduled workflow that lists DocuSign envelopes pending signature for over 48 hours, notifies the owning rep in Slack to nudge each signer, and escalates with a flagged message after 7 days.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"slack","name":"Slack"}]},{"title":"DocuSign completed contract archiver","prompt":"Build a scheduled workflow that polls DocuSign for completed envelopes, downloads the signed PDF, saves it to a Google Drive contracts folder, and writes the metadata into a contracts table.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"google_drive","name":"Google Drive"}]},{"title":"DocuSign clause analyzer","prompt":"Create a workflow that processes signed DocuSign contracts, extracts payment terms, liability caps, and renewal dates, writes them to a table, and flags non-standard clauses for legal review.","integrations":[{"id":"docusign","name":"DocuSign"}]},{"title":"DocuSign renewal tracker","prompt":"Build a scheduled workflow that reads a DocuSign contracts table, finds renewals due in the next 60 days, and creates a renewal-prep task in Salesforce for each.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"salesforce","name":"Salesforce"}]},{"title":"DocuSign stalled envelope resolver","prompt":"Create a scheduled workflow that lists in-flight DocuSign envelopes, checks each envelope’s recipients for signers who have left the company, voids the affected envelopes, and posts the list to Slack so a rep can resend from the right template.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"slack","name":"Slack"}]},{"title":"DocuSign signature analytics digest","prompt":"Build a scheduled weekly workflow that pulls DocuSign envelope analytics — time-to-sign, completion rate, drop-off — and posts a digest to the sales ops Slack channel.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"slack","name":"Slack"}]},{"title":"Dropbox + DocuSign signed-doc archiver","prompt":"Build a scheduled workflow that polls DocuSign for completed envelopes, downloads each signed PDF, saves it to a Dropbox compliance folder, and writes the audit record to a contracts table.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"dropbox","name":"Dropbox"}]},{"title":"LaTeX offer letter generator","prompt":"Create a workflow that takes candidate details from a form, fills a LaTeX offer letter template, compiles it to PDF, and sends it for e-signature.","integrations":[{"id":"docusign","name":"DocuSign"},{"id":"latex","name":"LaTeX"}]}]},{"id":"downdetector","type":"downdetector","slug":"downdetector","name":"Downdetector","description":"Monitor outages and service status with Downdetector","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/downdetector","authType":"api-key","connections":[],"operations":[{"name":"Search Companies","description":"Search Downdetector for monitored companies by name, slug, country, or category. Returns matching companies with their ids and slugs, which you can use with the other Downdetector operations."},{"name":"Get Company","description":"Get details for a Downdetector company by id, including its current status, 24h report statistics, baseline, and available problem indicators."},{"name":"Get Company Status","description":"Get the current detected status for a Downdetector company. Returns \\"success\\" (no problems), \\"warning\\", or \\"danger\\" (likely outage)."},{"name":"Get Company Baseline","description":"Get the current baseline report value for a Downdetector company. This is the expected average number of reports for the current period, used to judge whether current reports are abnormal."},{"name":"Get Company Last 15 Minutes","description":"Get the number of outage reports for a Downdetector company over the last 15 minutes."},{"name":"Get Company Indicators","description":"Get the problem indicators (e.g. \\"App crashing\\", \\"Login\\", \\"Server connection\\") reported for a Downdetector company over a time period, with the report counts and percentages for each."},{"name":"Get Reports","description":"Get the number of outage reports over time for one or more company slugs, bucketed by interval. Useful for plotting report trends or detecting spikes. Defaults to the last 24 hours."},{"name":"Get Company Incidents","description":"Get the list of incidents (outages) for a Downdetector company. Defaults to the last 24 hours unless a date range is provided."},{"name":"Get Company Attribution","description":"Get the incident attribution for a Downdetector company while it is in an outage state — whether the issue is internal (isolated) or external (a dependency), the estimated user impact, and the related incident. Requires Incident Attribution access."},{"name":"Get Company Events","description":"Get the published events (such as detected outages) for a Downdetector company, including the measured vs expected report volume for each event."},{"name":"Get Site Companies","description":"List the companies monitored on a Downdetector site, including each company’s current status. Useful for discovering the companies available on a regional status page."},{"name":"Get Provider","description":"Get details for a Downdetector provider (ISP or network operator) by id, such as its name and Downdetector id."},{"name":"List Incidents","description":"List all incidents (outages) across every company that were active in the chosen time period, or in the last 24 hours if no date range is provided."},{"name":"List Categories","description":"List all Downdetector categories (e.g. \\"Telecom\\", \\"Gaming\\", \\"Social Media\\"). Use the returned category id to filter company searches."},{"name":"List Sites","description":"List all available Downdetector sites (regional status-page domains). Each site groups the companies monitored for a given country/region."}],"triggers":[],"skills":[{"name":"check-service-outage","description":"Look up a service on Downdetector and report whether it is currently experiencing an outage.","content":"# Check Service Outage\\n\\nDetermine whether a given service is currently down according to Downdetector.\\n\\n## Steps\\n1. Search companies by name to resolve the service to a company id.\\n2. Get the company status (success / warning / danger).\\n3. If the status is warning or danger, pull the company indicators to see what users are reporting.\\n\\n## Output\\nA short verdict: is the service up, degraded, or down, and the top reported problems if any."},{"name":"monitor-vendor-outages","description":"Continuously watch a set of critical vendors on Downdetector and alert when any goes into an outage state.","content":"# Monitor Vendor Outages\\n\\nKeep an eye on your critical vendors and surface outages as they happen.\\n\\n## Steps\\n1. For each vendor, resolve its company id via company search.\\n2. Get the current status for each company on a schedule.\\n3. Flag any company whose status is \\"danger\\" and summarize the impact.\\n\\n## Output\\nA list of vendors currently in an outage state, ready to drive an alert."},{"name":"log-service-incidents","description":"Pull Downdetector incidents for a service and record them in a structured incident log.","content":"# Log Service Incidents\\n\\nMaintain a running log of Downdetector incidents for the services you depend on.\\n\\n## Steps\\n1. Resolve the service to a company id.\\n2. Fetch the company incidents for the desired time window.\\n3. Record each incident (start, resolved, peak user impact, total reports) into a table, skipping ones already logged.\\n\\n## Output\\nAn incident log table with one row per outage and its key metrics."},{"name":"detect-report-spikes","description":"Compare recent Downdetector report volume against a company\'s baseline to detect abnormal spikes.","content":"# Detect Report Spikes\\n\\nDetect when outage reports for a service spike above normal levels.\\n\\n## Steps\\n1. Resolve the service to a company slug and id.\\n2. Get the recent reports bucketed by interval.\\n3. Get the current baseline and compare the latest bucket against it.\\n\\n## Output\\nWhether reports are abnormally elevated, with the current count and the baseline for context."}],"templates":[{"title":"Downdetector outage alerter","prompt":"Build a scheduled workflow that checks the Downdetector status of my critical vendors every 15 minutes and posts a Slack alert whenever any of them flips to a \\"danger\\" (outage) status.","integrations":[{"id":"downdetector","name":"Downdetector"},{"id":"slack","name":"Slack"}]},{"title":"Downdetector incident logger","prompt":"Create a scheduled workflow that pulls active Downdetector incidents for my key services hourly and appends new incidents to a tables-based incident log with start time, peak user impact, and total reports.","integrations":[{"id":"downdetector","name":"Downdetector"}]},{"title":"Downdetector report-spike watcher","prompt":"Build a scheduled workflow that fetches the last hour of Downdetector reports for a company slug, compares the latest bucket against the company baseline, and emails me when reports spike well above baseline.","integrations":[{"id":"downdetector","name":"Downdetector"},{"id":"gmail","name":"Gmail"}]},{"title":"Downdetector root-cause summarizer","prompt":"Create a workflow that, given a company id, pulls the current Downdetector status and top problem indicators and has an agent summarize what users are most likely experiencing right now.","integrations":[{"id":"downdetector","name":"Downdetector"}]},{"title":"Downdetector vendor status digest","prompt":"Build a scheduled daily workflow that searches Downdetector for each of my vendors, reads their current status and 24h report stats, writes a status digest table, and posts a Slack summary.","integrations":[{"id":"downdetector","name":"Downdetector"},{"id":"slack","name":"Slack"}]},{"title":"Downdetector support deflection","prompt":"Create a workflow triggered when a support ticket arrives that checks the Downdetector status of the affected service and, if there is a confirmed outage, replies to the customer that the issue is a known provider outage.","integrations":[{"id":"downdetector","name":"Downdetector"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Downdetector competitor outage tracker","prompt":"Build a scheduled workflow that lists all active Downdetector incidents across a category, filters to my competitors, and logs their outages to a table so the team can track reliability over time.","integrations":[{"id":"downdetector","name":"Downdetector"}]}]},{"id":"dropbox","type":"dropbox_v2","slug":"dropbox","name":"Dropbox","description":"Upload, download, share, and manage files in Dropbox","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/dropbox","authType":"oauth","connections":[{"id":"dropbox","kind":"oauth","label":"Connect with OAuth","providerId":"dropbox","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/dropbox","requiredScopes":[{"id":"account_info.read","label":"View Dropbox account information"},{"id":"files.metadata.read","label":"View file and folder names, sizes, and dates"},{"id":"files.metadata.write","label":"Modify file and folder metadata"},{"id":"files.content.read","label":"Download and read Dropbox files"},{"id":"files.content.write","label":"Upload, copy, move, and delete files in Dropbox"},{"id":"sharing.read","label":"View shared files and folders"},{"id":"sharing.write","label":"Share files and folders with others"}],"fields":[]}],"operations":[{"name":"Upload File","description":"Upload a file to Dropbox"},{"name":"Download File","description":"Download a file from Dropbox with metadata and content"},{"name":"List Folder","description":"List the contents of a folder in Dropbox"},{"name":"Create Folder","description":"Create a new folder in Dropbox"},{"name":"Delete File/Folder","description":"Delete a file or folder in Dropbox (moves to trash)"},{"name":"Copy File/Folder","description":"Copy a file or folder in Dropbox"},{"name":"Move File/Folder","description":"Move or rename a file or folder in Dropbox"},{"name":"Get Metadata","description":"Get metadata for a file or folder in Dropbox"},{"name":"Create Shared Link","description":"Create a shareable link for a file or folder in Dropbox"},{"name":"List Shared Links","description":"List shared links for a path, or for the entire account if no path is given"},{"name":"Search Files","description":"Search for files and folders in Dropbox"},{"name":"List Revisions","description":"List the revision history for a file in Dropbox (files only, not folders)"},{"name":"Restore File","description":"Restore a specific revision of a file to the given path"}],"triggers":[],"skills":[{"name":"upload-file-to-dropbox","description":"Upload a file to a specific Dropbox path and optionally generate a shareable link.","content":"# Upload File to Dropbox\\n\\nSave a file into Dropbox at a chosen location and optionally share it.\\n\\n## Steps\\n1. Determine the destination path, including the filename and extension (e.g., /reports/q3-summary.pdf).\\n2. Call Upload File with the file and destination path. Use overwrite mode only if replacing an existing file; otherwise use add and enable auto-rename to avoid clobbering.\\n3. If a shareable link is requested, call Create Shared Link on the uploaded path with the requested visibility (public, team-only, or password-protected).\\n\\n## Output\\nReport the final stored path (after any auto-rename) and, if created, the shared link URL."},{"name":"find-files-in-dropbox","description":"Search Dropbox for files by query, extension, or folder, and return matching paths.","content":"# Find Files in Dropbox\\n\\nLocate files in Dropbox matching a search term or filter.\\n\\n## Steps\\n1. Use Search Files with the query term. Scope to a folder path when the location is known, and pass file extensions (e.g., pdf,xlsx) to narrow results.\\n2. If browsing a known folder instead of searching, use List Folder with the folder path; enable recursive listing to include subfolders.\\n3. For any candidate match, use Get Metadata to confirm size, type, and last-modified time before acting on it.\\n\\n## Output\\nReturn the matching files as a list of path, name, size, and last-modified. If nothing matches, say so and suggest a broader query."},{"name":"organize-dropbox-folder","description":"List a folder and move, copy, or delete files to reorganize Dropbox contents.","content":"# Organize Dropbox Folder\\n\\nReorganize files in Dropbox by moving them into the right folders.\\n\\n## Steps\\n1. Call List Folder on the source path to enumerate the files to process.\\n2. Decide each file destination based on the requested rules (by type, date, campaign, or naming pattern). Create target folders with Create Folder if they do not exist.\\n3. Use Move File/Folder to relocate each file, or Copy File/Folder when the original must stay in place. Enable auto-rename to avoid conflicts.\\n\\n## Output\\nReturn a summary of every file moved or copied with its old and new path, and flag any operation that failed."},{"name":"share-dropbox-link","description":"Create a shared link for a Dropbox file or folder with controlled visibility and expiration.","content":"# Share Dropbox Link\\n\\nGenerate a shareable link for an existing Dropbox item with the right access controls.\\n\\n## Steps\\n1. Confirm the exact path of the file or folder. Use Get Metadata to verify it exists.\\n2. Call Create Shared Link with the path and the requested visibility — public for anyone, team-only for internal sharing, or password-protected with a supplied password.\\n3. Set an expiration date if the link should not be permanent.\\n\\n## Output\\nReturn the shared link URL, its visibility setting, and the expiration date if one was applied."},{"name":"recover-dropbox-file-version","description":"Recover an earlier version of a Dropbox file after an unwanted overwrite or edit.","content":"# Recover Dropbox File Version\\n\\nRoll a file back to an earlier saved revision.\\n\\n## Steps\\n1. Call List Revisions on the file path to see prior versions, each with a revision identifier and modification time.\\n2. Identify the revision to recover based on its timestamp or size.\\n3. Call Restore File with the file path and the chosen revision identifier. This saves that revision as the new current version — it does not delete history.\\n\\n## Output\\nReturn the restored file metadata, including its path and the revision that was restored."}],"templates":[{"title":"Dropbox to knowledge base","prompt":"Build a scheduled workflow that lists a Dropbox folder, downloads documents added since the last run, extracts and chunks their text, and upserts the chunks into a knowledge base for agent retrieval.","integrations":[{"id":"dropbox","name":"Dropbox"}]},{"title":"Dropbox shared-link auditor","prompt":"Create a scheduled workflow that lists Dropbox shared links, identifies links shared with external users or marked public, and writes a security review report to a table.","integrations":[{"id":"dropbox","name":"Dropbox"}]},{"title":"Dropbox vendor-invoice intake","prompt":"Build a scheduled workflow that lists a Dropbox vendor folder for invoice PDFs added since the last run, extracts vendor and amount with an agent, writes the row to a payables table, and pings finance on Slack.","integrations":[{"id":"dropbox","name":"Dropbox"},{"id":"slack","name":"Slack"}]},{"title":"Dropbox creative asset organizer","prompt":"Create a scheduled workflow that lists a Dropbox creative-assets folder, classifies files added since the last run by campaign and type, moves them into the right subfolder, and updates a tables-based asset index.","integrations":[{"id":"dropbox","name":"Dropbox"}]},{"title":"Dropbox retention sweeper","prompt":"Build a scheduled workflow that finds Dropbox files older than the retention policy, archives them to long-term storage, and writes the cleanup record to an audit table.","integrations":[{"id":"dropbox","name":"Dropbox"}]},{"title":"Dropbox to Notion publisher","prompt":"Create a scheduled workflow that lists Dropbox markdown files added since the last run, converts each to a Notion page in the right database, and writes a link back to the source file metadata.","integrations":[{"id":"dropbox","name":"Dropbox"},{"id":"notion","name":"Notion"}]},{"title":"Dropbox + DocuSign signed-doc archiver","prompt":"Build a scheduled workflow that polls DocuSign for completed envelopes, downloads each signed PDF, saves it to a Dropbox compliance folder, and writes the audit record to a contracts table.","integrations":[{"id":"dropbox","name":"Dropbox"},{"id":"docusign","name":"DocuSign"}]}]},{"id":"dropcontact","type":"dropcontact","slug":"dropcontact","name":"Dropcontact","description":"Enrich B2B contacts with verified email, phone, and company data","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/dropcontact","authType":"api-key","connections":[],"operations":[{"name":"Enrich Contact","description":"Enrich a contact with verified B2B email, phone, company data, and LinkedIn info via Dropcontact. Submits an async enrichment request, then makes up to 24 polls, waiting five seconds before each attempt. Dropcontact charges 1 credit for successful email enrichment or for checking an email supplied for verification. Provide at least one of: email, first_name+last_name+company, full_name+company, or linkedin URL."}],"triggers":[],"skills":[],"templates":[]},{"id":"dspy","type":"dspy","slug":"dspy","name":"DSPy","description":"Run predictions using self-hosted DSPy programs","category":"AI","docsUrl":"https://docs.sim.ai/integrations/dspy","authType":"api-key","connections":[],"operations":[{"name":"Predict","description":"Run a prediction using a self-hosted DSPy program endpoint"},{"name":"Chain of Thought","description":"Run a Chain of Thought prediction using a self-hosted DSPy ChainOfThought program endpoint"},{"name":"ReAct Agent","description":"Run a ReAct agent using a self-hosted DSPy ReAct program endpoint for multi-step reasoning and action"}],"triggers":[],"skills":[{"name":"run-dspy-prediction","description":"Call a self-hosted DSPy Predict program to get a structured output from an input.","content":"# Run DSPy Prediction\\n\\nSend input to a self-hosted DSPy Predict program and return its structured answer.\\n\\n## Steps\\n1. Confirm the DSPy server base URL and, if required, the API key.\\n2. Choose the Predict operation and supply the input text. Set the input field name only if the program signature expects something other than the default.\\n3. Pass any extra signature fields as an additional-inputs JSON object.\\n\\n## Output\\nReturn the program answer and any structured fields it produced. If the server returns a non-success status, surface the status and the raw output for debugging."},{"name":"reason-with-chain-of-thought","description":"Use a DSPy Chain of Thought program to answer a question with explicit reasoning.","content":"# Reason with Chain of Thought\\n\\nAnswer a question through a self-hosted DSPy Chain of Thought program that exposes its reasoning.\\n\\n## Steps\\n1. Confirm the DSPy server base URL and API key if needed.\\n2. Choose the Chain of Thought operation and supply the question. Add any background as context.\\n3. Run the program and capture both the answer and the reasoning trace.\\n\\n## Output\\nReturn the final answer plus the reasoning rationale so the requester can audit how the conclusion was reached."},{"name":"run-dspy-react-agent","description":"Run a DSPy ReAct agent on a task that requires multi-step tool use, and capture its trajectory.","content":"# Run DSPy ReAct Agent\\n\\nExecute a task with a self-hosted DSPy ReAct agent that interleaves reasoning and actions.\\n\\n## Steps\\n1. Confirm the DSPy server base URL and API key if needed.\\n2. Choose the ReAct operation and describe the task clearly. Set a max-iterations cap to bound how many reasoning-action cycles run.\\n3. Provide any needed context, then execute the agent.\\n\\n## Output\\nReturn the final answer and the step-by-step trajectory (thoughts, actions, observations). If the agent hit the iteration cap without finishing, note that and summarize the last state."}],"templates":[{"title":"DSPy structured extraction","prompt":"Build a workflow that reads raw records from a table, runs a DSPy predict program on your self-hosted server to extract structured fields from each, and writes the typed results back to the table.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"DSPy evaluation harness","prompt":"Create a workflow that runs a DSPy program against a labeled evals table, computes accuracy, F1, and per-class breakdowns, and writes the metrics to a reporting table for tracking over iterations.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"DSPy A/B program selector","prompt":"Create a scheduled workflow that runs two DSPy program endpoints against the same eval set nightly, scores each on accuracy, and writes the head-to-head comparison and recommended winner to a table.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"DSPy production traffic replay","prompt":"Build a workflow that periodically replays sample production traces through a DSPy program, captures divergences, and writes regression analysis to a tracking file.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"DSPy + LangSmith trace harness","prompt":"Create a workflow that runs a DSPy program over an eval set, logs each prediction as a LangSmith trace for evaluation, captures the quality delta against the previous run, and writes the comparison to engineering Slack.","integrations":[{"id":"dspy","name":"DSPy"},{"id":"langsmith","name":"LangSmith"},{"id":"slack","name":"Slack"}]},{"title":"DSPy ticket classifier","prompt":"Build a workflow that runs new support tickets through a DSPy predict signature to classify category, urgency, and sentiment with structured outputs, then routes each ticket to the right queue and writes the labels back to the ticket.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"DSPy reasoning research agent","prompt":"Create a workflow that takes a research question, uses DSPy chain-of-thought to break it into sub-questions, runs DSPy ReAct with web search to gather evidence, and writes a structured, cited answer to a file.","integrations":[{"id":"dspy","name":"DSPy"}]},{"title":"Perplexity + DSPy structured-output evaluator","prompt":"Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.","integrations":[{"id":"dspy","name":"DSPy"},{"id":"perplexity","name":"Perplexity"},{"id":"huggingface","name":"Hugging Face"},{"id":"mistral_parse","name":"Mistral Parser"}]}]},{"id":"dub","type":"dub_v2","slug":"dub","name":"Dub","description":"Link management with Dub","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/dub","authType":"api-key","connections":[],"operations":[{"name":"Create Link","description":"Create a new short link with Dub. Supports custom domains, slugs, UTM parameters, and more."},{"name":"Upsert Link","description":"Create or update a short link by its URL. If a link with the same URL already exists, update it. Otherwise, create a new link."},{"name":"Get Link","description":"Retrieve information about a short link by its link ID, external ID, or domain + key combination."},{"name":"Update Link","description":"Update an existing short link\'s destination URL, domain, slug, link-preview title and description, UTM parameters, and other supported settings."},{"name":"Delete Link","description":"Delete a short link by its link ID or external ID (prefixed with ext_)."},{"name":"List Links","description":"Retrieve a paginated list of short links for the authenticated workspace. Supports filtering by domain, search query, tags, and sorting."},{"name":"Count Links","description":"Retrieve the number of short links for the authenticated workspace, optionally filtered and grouped by domain, tag, user, or folder."},{"name":"Bulk Create Links","description":"Create up to 100 short links in a single request. Returns the created links alongside any per-link errors."},{"name":"Bulk Update Links","description":"Apply the same set of field updates to up to 100 links at once, selected by link IDs or external IDs."},{"name":"Bulk Delete Links","description":"Delete up to 100 short links in a single request by their link IDs. Non-existing IDs are ignored."},{"name":"Get Analytics","description":"Retrieve analytics for links including clicks, leads, and sales. Supports filtering by link, time range, and grouping by various dimensions."},{"name":"List Events","description":"Retrieve a paginated stream of individual click, lead, and sale events for links, with filtering by link, time range, and location."},{"name":"Get QR Code","description":"Generate a customizable QR code (PNG) for a short link, with control over size, error correction, colors, and margin."},{"name":"List Domains","description":"Retrieve the custom domains registered in the workspace, so links can be created against the right domain."},{"name":"List Tags","description":"Retrieve the tags defined in the workspace, so the right tag IDs can be assigned to links."},{"name":"Create Tag","description":"Create a new tag in the workspace for organizing and filtering short links."},{"name":"List Folders","description":"Retrieve the folders defined in the workspace, so the right folder ID can be used to organize links."}],"triggers":[],"skills":[{"name":"create-tracked-short-link","description":"Create a Dub short link for a destination URL with UTM parameters and an optional custom slug.","content":"# Create Tracked Short Link\\n\\nTurn a long destination URL into a branded, trackable Dub short link.\\n\\n## Steps\\n1. Take the destination URL and any campaign metadata (source, medium, campaign name).\\n2. Call Create Link with the URL. Set the UTM source, medium, and campaign fields so clicks attribute correctly, and set a custom slug when a memorable link is wanted.\\n3. Add a custom domain, title, or tag IDs if the request specifies them.\\n\\n## Output\\nReturn the full short link URL, its slug, the destination, and the QR code URL. Confirm which UTM parameters were applied."},{"name":"report-link-analytics","description":"Pull Dub click, lead, and sales analytics for a link or campaign over a time window.","content":"# Report Link Analytics\\n\\nSummarize how a Dub short link or campaign is performing.\\n\\n## Steps\\n1. Choose the Get Analytics operation. Set the event type (clicks, leads, sales, or composite) the request cares about.\\n2. Scope to a specific link via link ID or external ID, or to a domain for a whole campaign. Set the interval (e.g., 7d, 30d) or explicit start and end dates.\\n3. Set group-by to break results down by country, device, referrer, or top links when a breakdown is asked for; otherwise use count for totals.\\n\\n## Output\\nReport the headline metrics (clicks, leads, sales, revenue) and, when grouped, the top segments. Call out notable winners and decliners versus the prior period when comparison data is available."},{"name":"batch-create-campaign-links","description":"Upsert a Dub short link for each row in a list of destinations with consistent UTM tagging.","content":"# Batch Create Campaign Links\\n\\nGenerate consistent tracked links for many destinations at once.\\n\\n## Steps\\n1. For each destination URL in the list, build the UTM parameters and slug from the row data so tagging is uniform across the batch.\\n2. Use Upsert Link (keyed on external ID or slug) so re-runs refresh rather than duplicate existing links.\\n3. Collect the resulting short link for each row.\\n\\n## Output\\nReturn a table mapping each destination to its short link and external ID. Report how many links were created versus refreshed, and flag any rows that failed."},{"name":"audit-existing-links","description":"List Dub links and check each destination for broken or stale URLs to flag for cleanup.","content":"# Audit Existing Links\\n\\nReview existing Dub links to catch broken or outdated destinations.\\n\\n## Steps\\n1. Call List Links, optionally filtered by domain or tag IDs, paginating until all links are retrieved.\\n2. For each link, inspect the destination URL and check it for 4xx or 5xx responses or obviously stale targets.\\n3. Note links with low or zero clicks over a long period as candidates for archiving.\\n\\n## Output\\nReturn a remediation list: short link, destination, detected issue (broken, redirecting, stale), and a suggested action. Sort broken links first."}],"templates":[{"title":"Dub short link factory","prompt":"Build a workflow that takes a destination URL and campaign metadata, creates a tracked short link in Dub with UTM parameters and a custom slug, stores the link in a table, and returns it to the caller for use in outreach and marketing.","integrations":[{"id":"dub","name":"Dub"}]},{"title":"Dub campaign link batcher","prompt":"Create a workflow that reads a table of campaign destinations, upserts a Dub short link for each row with consistent UTM tags, writes the resulting short URL back into the table, and posts a Slack confirmation summarizing how many links were created or refreshed.","integrations":[{"id":"dub","name":"Dub"},{"id":"slack","name":"Slack"}]},{"title":"Dub analytics digest","prompt":"Build a scheduled weekly workflow that pulls Dub link analytics — clicks, leads, sales, and top referrers — for active campaigns, writes a narrative summary highlighting winners and decliners, and delivers the digest to Slack with deep links into the Dub dashboard.","integrations":[{"id":"dub","name":"Dub"},{"id":"slack","name":"Slack"}]},{"title":"Dub link hygiene auditor","prompt":"Create a scheduled monthly workflow that lists all Dub links, checks each destination for 4xx and 5xx responses, flags broken links in a table, and emails the marketing team a remediation list so dead campaign links never go live.","integrations":[{"id":"dub","name":"Dub"}]},{"title":"Dub outbound link personalizer","prompt":"Build a workflow that reads a leads table, generates a per-lead Dub short link with the lead identifier in UTM and metadata, attaches the personalized link to the outreach email body, and tracks delivery in the table.","integrations":[{"id":"dub","name":"Dub"},{"id":"gmail","name":"Gmail"}]},{"title":"Dub release announcement linker","prompt":"Create a workflow triggered by a GitHub release that creates a Dub short link for the release notes URL, posts the short link to the marketing Slack channel, and stores the mapping of release tag to short link in a tracking table.","integrations":[{"id":"dub","name":"Dub"},{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]},{"title":"Dub top-converting links report","prompt":"Build a scheduled monthly workflow that pulls Dub analytics grouped by link, ranks top performers by leads and sales, identifies underperformers, writes a narrative report file with recommendations, and shares it with marketing leadership.","integrations":[{"id":"dub","name":"Dub"}]}]},{"id":"duckduckgo","type":"duckduckgo","slug":"duckduckgo","name":"DuckDuckGo","description":"Search with DuckDuckGo","category":"Search","docsUrl":"https://docs.sim.ai/integrations/duckduckgo","authType":"none","connections":[],"operations":[{"name":"DuckDuckGo Search","description":"Search the web using DuckDuckGo Instant Answers API. Returns instant answers, abstracts, and related topics for your query. Free to use without an API key."}],"triggers":[],"skills":[{"name":"answer-with-duckduckgo","description":"Search DuckDuckGo for a quick instant answer or abstract on a topic and return it with its source.","content":"# Answer with DuckDuckGo\\n\\nGet a fast, privacy-preserving answer to a factual question using DuckDuckGo Instant Answers.\\n\\n## Steps\\n1. Form a concise query from the question. Enable Remove HTML so returned text is clean.\\n2. Run the search and read the instant answer, abstract, and abstract source.\\n3. If the result is a disambiguation page rather than a direct answer, refine the query to be more specific and search again.\\n\\n## Output\\nReturn the answer or abstract text along with the source name and URL so the claim is attributable. If no instant answer exists, say so and surface the related topics instead."},{"name":"gather-related-topics","description":"Use DuckDuckGo to collect related topics and external links around a subject for research.","content":"# Gather Related Topics\\n\\nBuild a quick research starting point on a subject using DuckDuckGo.\\n\\n## Steps\\n1. Search the subject with Remove HTML enabled.\\n2. Collect the heading, abstract, related topics, and any external link results.\\n3. Group the related topics into themes and pick the most authoritative links to explore further.\\n\\n## Output\\nReturn the abstract summary plus a list of related topics and external links, each with its URL, organized by theme."},{"name":"validate-claim-online","description":"Check a stated claim against DuckDuckGo results to confirm or flag it as unsupported.","content":"# Validate Claim Online\\n\\nVerify whether a claim is supported by public web sources via DuckDuckGo.\\n\\n## Steps\\n1. Turn the claim into a focused search query and run it with Remove HTML enabled.\\n2. Compare the instant answer, abstract, and source against the claim.\\n3. Decide whether the result supports, contradicts, or is silent on the claim.\\n\\n## Output\\nReturn a verdict — supported, contradicted, or unverified — with the source name and URL. If unverified, recommend a more targeted query or a dedicated source."}],"templates":[{"title":"DuckDuckGo private research agent","prompt":"Build an agent that runs DuckDuckGo searches for queries that need privacy preservation, returns answers with citations, and saves the findings to a knowledge base.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"DuckDuckGo daily digest","prompt":"Create a scheduled daily workflow that queries DuckDuckGo for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"},{"id":"slack","name":"Slack"}]},{"title":"DuckDuckGo competitor watcher","prompt":"Build a scheduled workflow that runs DuckDuckGo searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"DuckDuckGo agent fallback","prompt":"Create an agent that uses Perplexity for primary search and falls back to DuckDuckGo on rate-limit errors so research workflows remain reliable.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"},{"id":"perplexity","name":"Perplexity"}]},{"title":"DuckDuckGo legal-research helper","prompt":"Build a workflow that uses DuckDuckGo to find precedents and analyses for legal questions, summarizes with citations, and writes a research file for review.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"DuckDuckGo open-web validator","prompt":"Create a workflow that validates claims in an agent draft by searching DuckDuckGo for supporting sources, flagging claims without strong citations.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"DuckDuckGo enrichment researcher","prompt":"Build a workflow that uses DuckDuckGo to research prospect or company context where standard enrichment is missing, and writes the findings back to the CRM record.","integrations":[{"id":"duckduckgo","name":"DuckDuckGo"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"dynatrace","type":"dynatrace","slug":"dynatrace","name":"Dynatrace","description":"Manage Dynatrace problems, metrics, entities, logs, SLOs, settings, and security","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/dynatrace","authType":"api-key","connections":[],"operations":[{"name":"List Problems","description":"List Davis-detected problems in a Dynatrace environment, filtered by timeframe, problem selector, or entity selector."},{"name":"Get Problem","description":"Get the full details of a single Dynatrace problem, including root cause, affected entities, and optionally its evidence and impact analysis."},{"name":"Close Problem","description":"Close a Dynatrace problem and record the closing comment."},{"name":"List Problem Comments","description":"List the comments recorded on a Dynatrace problem."},{"name":"Add Problem Comment","description":"Add a comment to a Dynatrace problem."},{"name":"Query Metrics","description":"Read metric data points from Dynatrace using a metric selector, with optional entity and management-zone scoping."},{"name":"List Metrics","description":"Discover the metrics available in a Dynatrace environment, filtered by metric selector, free text, or metadata."},{"name":"Get Metric Descriptor","description":"Get the descriptor of a single Dynatrace metric — its unit, dimensions, supported aggregations, and transformations."},{"name":"Ingest Metrics","description":"Push custom metric data points into Dynatrace using the metric line protocol, one data point per line."},{"name":"List Entities","description":"List monitored entities — hosts, services, applications, Kubernetes workloads — matching an entity selector."},{"name":"Get Entity","description":"Get the properties, tags, management zones, and relationships of a single monitored entity."},{"name":"List Entity Types","description":"List the monitored entity types available in the environment, with the properties and relationships each supports. Use it to build valid entity selectors."},{"name":"List Events","description":"List events — deployments, availability changes, alerts, custom annotations — in a Dynatrace environment."},{"name":"Get Event","description":"Get the full details of a single Dynatrace event."},{"name":"Ingest Event","description":"Push an event into Dynatrace — a deployment marker, custom annotation, or custom alert — attached to the entities matched by an entity selector."},{"name":"Search Logs","description":"Search log records in Dynatrace by query and timeframe, for troubleshooting and incident analysis."},{"name":"Ingest Logs","description":"Push log events into Dynatrace. Accepts a single log event object or an array of them."},{"name":"List SLOs","description":"List service-level objectives with their current attainment, error budget, and burn rate."},{"name":"Get SLO","description":"Get a single service-level objective with its evaluated attainment, error budget, and burn rate."},{"name":"List Security Problems","description":"List vulnerabilities detected by Dynatrace Application Security, filtered by risk level, status, CVE, or technology."},{"name":"Get Security Problem","description":"Get a single vulnerability with its description, remediation guidance, affected entities, and risk assessment."},{"name":"Mute Security Problem","description":"Mute a single Dynatrace vulnerability with a reason, for triaging false positives or accepted risk."},{"name":"Unmute Security Problem","description":"Unmute a single Dynatrace vulnerability, returning it to the active triage queue."},{"name":"Mute Security Problems (Bulk)","description":"Mute several Dynatrace vulnerabilities at once with a shared reason, for bulk triage."},{"name":"Unmute Security Problems (Bulk)","description":"Unmute several Dynatrace vulnerabilities at once, returning them to active triage."},{"name":"List Remediation Items","description":"List the remediation items of a third-party vulnerability — the components to upgrade, their affected entities, and their mute state."},{"name":"List Attacks","description":"List runtime attacks Dynatrace Application Protection detected — injection attempts, their source, and whether they were blocked."},{"name":"Get Attack","description":"Get a single attack with its entry point, payload, attacker, and the vulnerability it exploited."},{"name":"List Tags","description":"List the custom tags applied to the monitored entities an entity selector matches."},{"name":"Add Tags","description":"Add custom tags to every monitored entity an entity selector matches. Tags drive selectors, management zones, and alerting."},{"name":"Delete Tag","description":"Remove a custom tag from every monitored entity an entity selector matches. Deletes one key-value pair, or every tag with the key."},{"name":"List Settings Schemas","description":"List the settings schemas available in the environment. Use it to find the schema ID for a configuration type such as builtin:alerting.profile."},{"name":"List Settings Objects","description":"List settings objects — the configuration behind maintenance windows, alerting profiles, management zones, and anomaly detection."},{"name":"Get Settings Object","description":"Get a single settings object with its value and its update token. Read it before updating so the token can guard against a concurrent change."},{"name":"Create Settings Object","description":"Create a settings object — a maintenance window, alerting profile, management zone, or any other schema-backed configuration."},{"name":"Update Settings Object","description":"Update an existing settings object. Pass the update token from Get Settings Object to fail rather than overwrite a concurrent change."},{"name":"Delete Settings Object","description":"Delete a settings object. Dynatrace cannot undo this."},{"name":"List Synthetic Monitors","description":"List synthetic monitors and their IDs. Use it to find the monitor IDs to feed into an on-demand execution."},{"name":"Execute Synthetic Monitors","description":"Trigger an on-demand batch execution of synthetic monitors, for gating a deploy on a smoke test. Returns a batch ID to poll."},{"name":"Get Synthetic Batch","description":"Get the status and failures of an on-demand synthetic batch execution. Poll it after triggering to gate a deploy on the result."},{"name":"Get Problem Comment","description":"Get a single comment on a Dynatrace problem."},{"name":"Update Problem Comment","description":"Replace the text of an existing comment on a Dynatrace problem."},{"name":"Delete Problem Comment","description":"Delete a comment from a Dynatrace problem."},{"name":"Create SLO","description":"Create a service-level objective from a metric expression, target, and evaluation timeframe."},{"name":"Update SLO","description":"Update an existing service-level objective. Every field is replaced, so send the complete definition."},{"name":"Delete SLO","description":"Delete a service-level objective."},{"name":"Get Audit Logs","description":"Read the Dynatrace audit log — who changed which configuration, when, and whether it succeeded."}],"triggers":[],"skills":[{"name":"triage-open-problems","description":"Pull open Dynatrace problems, attach root cause and impact context, and rank them for on-call.","content":"# Triage Open Problems\\n\\nBuild a prioritized picture of what is currently broken.\\n\\n## Steps\\n1. List problems with a selector of `status(\\"open\\")` over the relevant timeframe.\\n2. For each problem, get its details with the `evidenceDetails` and `impactAnalysis` fields so the root cause entity and estimated affected users are included.\\n3. Get the root cause entity to read its type, tags, and management zones.\\n4. Rank by impact level, severity level, and estimated affected users.\\n\\n## Output\\nReturn a ranked list: display ID, title, severity, impact, root cause entity, affected entity count, and how long the problem has been open."},{"name":"correlate-deploy-with-metrics","description":"Mark a deploy in Dynatrace and compare service metrics before and after it.","content":"# Correlate Deploy With Metrics\\n\\nMake a release visible in Dynatrace and prove whether it moved the numbers.\\n\\n## Steps\\n1. Ingest a `CUSTOM_DEPLOYMENT` event with the version and pipeline as properties, scoped to the service with an entity selector.\\n2. Query the service response time and error rate metrics for the window before the deploy.\\n3. Query the same metrics for the window after the deploy.\\n4. Compare the two and state whether the release regressed either metric.\\n\\n## Output\\nReturn the deploy event correlation ID plus a before/after table of each metric, with the percentage change and a regression verdict."},{"name":"review-slo-health","description":"Report SLO attainment, remaining error budget, and burn rate.","content":"# Review SLO Health\\n\\nProduce an SLO scorecard for a service review or weekly report.\\n\\n## Steps\\n1. List SLOs with evaluation enabled so the calculated values are populated.\\n2. Filter to the ones that are failing or warning, and to any with a FAST burn rate.\\n3. For each flagged SLO, get its details to read the estimated time to consume the error budget.\\n4. Group results by management zone or service.\\n\\n## Output\\nReturn each SLO with its target, current attainment, remaining error budget, burn rate type, and time to exhaustion. Flag the ones that will breach before the period ends."},{"name":"investigate-entity","description":"Assemble the full picture of one host or service: properties, metrics, events, and logs.","content":"# Investigate Entity\\n\\nGather everything Dynatrace knows about a single entity.\\n\\n## Steps\\n1. Get the entity by ID, or list entities with a selector to find it by name or tag.\\n2. Query its key metrics over the incident window using an entity selector scoped to its ID.\\n3. List events for the same entity and window to find deploys, restarts, or configuration changes.\\n4. Search logs filtered to the entity to pull the errors around the same time.\\n\\n## Output\\nReturn the entity properties and tags, a metric summary over the window, the timeline of events, and the top recurring log errors."},{"name":"audit-vulnerabilities","description":"Inventory open Dynatrace vulnerabilities by risk, exposure, and affected service.","content":"# Audit Vulnerabilities\\n\\nTurn Application Security findings into a remediation queue, then act on it.\\n\\n## Steps\\n1. List security problems with `status(\\"OPEN\\")` and request the `riskAssessment` and `globalCounts` fields.\\n2. Sort by risk score and separate the publicly exposed ones with reachable data assets — those are the ones to fix first.\\n3. Get the details of each high-priority finding to read its description, remediation guidance, and vulnerable components.\\n4. List the remediation items of a third-party finding to see which components to upgrade and which entities each covers.\\n5. Mute the findings that do not apply, with a reason — FALSE_POSITIVE, CONFIGURATION_NOT_AFFECTED, or VULNERABLE_CODE_NOT_IN_USE — so the queue reflects real work. Use the bulk mute when triaging many at once.\\n\\n## Output\\nReturn a remediation queue: CVE, risk level and score, exposure, affected services, vulnerable component version, and the recommended fix. List separately what was muted and why."},{"name":"open-maintenance-window","description":"Create a Dynatrace maintenance window as a settings object so a deploy does not raise problems.","content":"# Open Maintenance Window\\n\\nSuppress alerting for a planned change, then clean up after it.\\n\\n## Steps\\n1. List settings schemas and find the maintenance window schema (`builtin:alerting.maintenance-window`).\\n2. List existing settings objects for that schema to copy the shape of a working window — the `value` is schema-defined, so mirroring a real one beats guessing.\\n3. Create a settings object with the window scope, the suppression type, and the schedule covering the change.\\n4. Run the deploy, then delete the settings object — or let the schedule close it.\\n\\n## Output\\nReturn the created object ID and the window it covers, so a later step can delete it. Note whether the window suppresses alerting entirely or only problem creation."},{"name":"gate-deploy-on-synthetic","description":"Run Dynatrace synthetic monitors on demand after a deploy and decide from the batch result.","content":"# Gate Deploy On Synthetic\\n\\nProve a release works before letting it stand.\\n\\n## Steps\\n1. List synthetic monitors and pick the smoke tests covering the deployed service — the list returns the monitor IDs the execution needs.\\n2. Ingest a `CUSTOM_DEPLOYMENT` event so the release is visible on the timeline.\\n3. Execute the monitors on demand, attaching the release version as batch metadata.\\n4. Poll the batch until its status leaves RUNNING, then read the failed executions.\\n5. Roll back or alert when the batch reports failures.\\n\\n## Output\\nReturn the batch ID, its final status, the executed and failed counts, and the failure message of each failed execution. State plainly whether the deploy passed."},{"name":"tag-entities-from-workflow","description":"Apply or remove Dynatrace entity tags so selectors and zones stay accurate.","content":"# Tag Entities From Workflow\\n\\nKeep entity tags in step with what the workflow just learned.\\n\\n## Steps\\n1. List entities with a selector describing the set to change, and confirm it matches what you expect before writing.\\n2. Read the current tags on those entities so the change is additive rather than a surprise.\\n3. Add the tags, each with a key and an optional value. The response reports how many entities matched.\\n4. Delete tags that no longer apply, either one key-value pair or every value of a key.\\n\\n## Output\\nReturn the applied or removed tags and the matched entity count. Flag the case where the selector matched zero entities — that usually means the selector is wrong, not that the work is done."}],"templates":[{"title":"Dynatrace problem triage","prompt":"Build a scheduled workflow that polls Dynatrace every five minutes for open problems, pulls the root cause entity and recent logs for each one, summarizes the likely cause with an agent, and posts the enriched problem to Slack and PagerDuty.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Dynatrace deploy marker","prompt":"Create a workflow that runs when a GitHub release is published and ingests a CUSTOM_DEPLOYMENT event into Dynatrace with the version, commit, and service entity selector, so metric changes can be correlated with the deploy.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"github","name":"GitHub"}]},{"title":"Dynatrace SLO burn-rate watch","prompt":"Build a scheduled hourly workflow that reads Dynatrace SLOs, flags any with a fast error-budget burn rate, and opens a Linear issue with the SLO name, remaining budget, and time to exhaustion.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"linear","name":"Linear"}]},{"title":"Dynatrace vulnerability digest","prompt":"Create a scheduled daily workflow that lists open critical and high Dynatrace security problems, groups them by affected service and CVE, writes them to a Sim table, and posts a remediation digest to the security channel in Slack.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"slack","name":"Slack"}]},{"title":"Dynatrace capacity report","prompt":"Build a scheduled weekly workflow that queries Dynatrace host CPU, memory, and disk metrics per management zone, ranks the most saturated hosts, and writes a capacity planning report to a Sim table.","integrations":[{"id":"dynatrace","name":"Dynatrace"}]},{"title":"Dynatrace log error triage","prompt":"Create a scheduled workflow that searches Dynatrace logs for new error patterns in the last fifteen minutes, clusters them by message shape with an agent, and posts only the previously unseen clusters to Slack.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"slack","name":"Slack"}]},{"title":"Dynatrace auto-close on recovery","prompt":"Build a scheduled workflow that checks Dynatrace problems whose entities have returned to a healthy metric baseline, closes them with an explanatory comment, and records what was closed in a Sim table for review.","integrations":[{"id":"dynatrace","name":"Dynatrace"}]},{"title":"Dynatrace config audit","prompt":"Create a scheduled weekly workflow that reads the Dynatrace audit log for configuration changes, highlights changes made outside business hours or by service accounts, and emails a compliance summary to the platform team.","integrations":[{"id":"dynatrace","name":"Dynatrace"},{"id":"gmail","name":"Gmail"}]}]},{"id":"elasticsearch","type":"elasticsearch","slug":"elasticsearch","name":"Elasticsearch","description":"Search, index, and manage data in Elasticsearch","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/elasticsearch","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search documents in Elasticsearch using Query DSL. Returns matching documents with scores and metadata."},{"name":"Index Document","description":"Index (create or update) a document in Elasticsearch."},{"name":"Get Document","description":"Retrieve a document by ID from Elasticsearch."},{"name":"Update Document","description":"Partially update a document in Elasticsearch using doc merge."},{"name":"Delete Document","description":"Delete a document from Elasticsearch by ID."},{"name":"Bulk Operations","description":"Perform multiple index, create, delete, or update operations in a single request for high performance."},{"name":"Count Documents","description":"Count documents matching a query in Elasticsearch."},{"name":"Create Index","description":"Create a new index with optional settings and mappings."},{"name":"Delete Index","description":"Delete an index and all its documents. This operation is irreversible."},{"name":"Get Index Info","description":"Retrieve index information including settings, mappings, and aliases."},{"name":"List Indices","description":"List all indices in the Elasticsearch cluster with their health, status, and statistics."},{"name":"Cluster Health","description":"Get the health status of the Elasticsearch cluster."},{"name":"Cluster Stats","description":"Get Elasticsearch cluster health, node counts, and index statistics."}],"triggers":[],"skills":[{"name":"search-elasticsearch-index","description":"Run a query against an Elasticsearch index and return the matching documents.","content":"# Search Elasticsearch Index\\n\\nQuery an index and return the relevant documents.\\n\\n## Steps\\n1. Confirm the connection details (host or cloud ID and auth) and the target index name.\\n2. Choose the Search operation and build the query DSL — match for full-text, term for exact values, range for numeric or date bounds, and bool to combine clauses.\\n3. Set size and offset for paging, add a sort spec when ordering matters, and use source includes/excludes to trim returned fields.\\n\\n## Output\\nReturn the matching hits with their _id, _score, and relevant _source fields, plus the total count and query time. If nothing matched, report zero hits and suggest loosening the query."},{"name":"index-document","description":"Add or update a document in an Elasticsearch index.","content":"# Index Document\\n\\nWrite a document into an Elasticsearch index so it becomes searchable.\\n\\n## Steps\\n1. Confirm the connection details and target index.\\n2. Build the document as a JSON object with appropriate field types. Choose the Index Document operation; supply a document ID to upsert a known record, or omit it to let Elasticsearch auto-generate one.\\n3. To change only specific fields of an existing document, use Update Document with a partial document and the document ID instead.\\n4. Set the refresh policy to immediate or wait-for when the write must be searchable right away.\\n\\n## Output\\nReturn the resulting _id, _version, and the operation result (created or updated)."},{"name":"bulk-load-documents","description":"Index, update, or delete many Elasticsearch documents in a single bulk request.","content":"# Bulk Load Documents\\n\\nApply many document operations to Elasticsearch efficiently in one call.\\n\\n## Steps\\n1. Confirm the connection details and target index.\\n2. Assemble the operations as NDJSON: an action line (index, create, update, or delete) followed by the document line where required.\\n3. Run the Bulk Operations call and set a refresh policy if the data must be immediately searchable.\\n\\n## Output\\nReport whether any errors occurred and summarize the per-item results — how many succeeded versus failed and the reason for any failures."},{"name":"check-cluster-health","description":"Report Elasticsearch cluster health and key index statistics.","content":"# Check Cluster Health\\n\\nAssess the health of an Elasticsearch deployment.\\n\\n## Steps\\n1. Confirm the connection details.\\n2. Call Cluster Health to get the overall status (green, yellow, red) and node count. Optionally wait for a target status.\\n3. Use List Indices and Get Index Info to spot oversized, unassigned, or unhealthy indices, and Cluster Stats for storage and shard totals.\\n\\n## Output\\nReport the cluster status, number of nodes, and any indices that look problematic. If status is yellow or red, explain the likely cause (e.g., unassigned replicas) and what to check next."}],"templates":[{"title":"Elasticsearch log triage","prompt":"Build a scheduled workflow that runs saved Elasticsearch queries hourly for error patterns, clusters the matches, writes the top groups to a triage table, and pings on-call.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Elasticsearch security event correlator","prompt":"Create a workflow that pulls Elasticsearch security events, correlates them across sources, and opens a CrowdStrike or PagerDuty incident on a confirmed pattern.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"},{"id":"crowdstrike","name":"CrowdStrike"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Elasticsearch index lifecycle audit","prompt":"Build a scheduled weekly workflow that audits Elasticsearch indices against retention policies, identifies over-retained data, and writes the cleanup plan to a Slack approval thread.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"},{"id":"slack","name":"Slack"}]},{"title":"Elasticsearch search-as-a-service connector","prompt":"Create a workflow that exposes a saved Elasticsearch query as an internal search endpoint, normalizes results into a standard shape, and writes usage telemetry to a table.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"Elasticsearch + knowledge base hybrid","prompt":"Build a workflow that combines Elasticsearch keyword search with a vector knowledge base, fuses results with reciprocal-rank fusion, and answers user questions with grounded citations.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"Elasticsearch slow-query digest","prompt":"Create a scheduled daily workflow that aggregates Elasticsearch slow-log entries, clusters the top offenders, and posts a digest to the platform Slack channel with recommended fixes.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"},{"id":"slack","name":"Slack"}]},{"title":"Elasticsearch + LangSmith retrieval evaluator","prompt":"Create a workflow that uses LangSmith to evaluate retrieval quality from Elasticsearch versus a vector knowledge base, writes the head-to-head scores to a table.","integrations":[{"id":"elasticsearch","name":"Elasticsearch"},{"id":"langsmith","name":"LangSmith"}]}]},{"id":"elevenlabs","type":"elevenlabs","slug":"elevenlabs","name":"ElevenLabs","description":"Generate and transform audio with ElevenLabs","category":"AI","docsUrl":"https://docs.sim.ai/integrations/elevenlabs","authType":"api-key","connections":[],"operations":[{"name":"Text to Speech","description":"Convert text to speech using ElevenLabs voices"},{"name":"Sound Effects","description":"Generate a sound effect from a text prompt using ElevenLabs"},{"name":"Speech to Speech","description":"Convert audio into a chosen ElevenLabs voice while preserving content and emotion"},{"name":"Audio Isolation","description":"Remove background noise from an audio file, isolating the speech using ElevenLabs"},{"name":"List Voices","description":"List the voices available in your ElevenLabs account"},{"name":"Get Voice","description":"Get metadata and settings for a specific ElevenLabs voice"},{"name":"Get Voice Settings","description":"Get the configured settings for a specific ElevenLabs voice"},{"name":"Edit Voice Settings","description":"Update the settings for a specific ElevenLabs voice"},{"name":"List Models","description":"List the models available in ElevenLabs"},{"name":"Get User Info","description":"Get account and subscription information for the ElevenLabs user"}],"triggers":[],"skills":[{"name":"narrate-text-to-speech","description":"Convert a block of text into natural-sounding speech audio with a chosen ElevenLabs voice.","content":"# Narrate Text to Speech\\n\\nGenerate spoken audio from text using ElevenLabs.\\n\\n## Steps\\n1. Take the text to narrate and confirm the target voice ID (ask for one if not provided).\\n2. Pick a model — use a multilingual model for non-English or mixed-language text, or a turbo/flash model when low latency matters.\\n3. For consistent delivery, set stability higher; for more expressive variation, set it lower. Raise similarity boost to stay closer to the reference voice.\\n\\n## Output\\nReturn the generated audio file and its URL. Confirm the voice and model used so the requester can adjust if the delivery is not right."},{"name":"narrate-article-as-audio","description":"Turn a long article or blog post into a podcast-style audio narration.","content":"# Narrate Article as Audio\\n\\nProduce a listenable audio version of written content.\\n\\n## Steps\\n1. Clean the source text — strip markdown, navigation, and boilerplate so only the readable prose remains. Expand abbreviations the voice should speak in full.\\n2. Choose a voice ID suited to the content and a high-quality multilingual model for natural delivery.\\n3. Convert the cleaned text to speech, keeping stability moderate so the narration sounds engaging but consistent.\\n\\n## Output\\nReturn the audio file and a player-ready URL, along with the voice used. If the text is very long, note any truncation and suggest splitting it into parts."},{"name":"generate-voice-prompt","description":"Generate a short branded voice clip such as an IVR prompt, greeting, or notification.","content":"# Generate Voice Prompt\\n\\nCreate a short, polished voice clip for things like phone menus, greetings, or alerts.\\n\\n## Steps\\n1. Take the exact script for the prompt. Keep it concise and confirm pronunciation of any names or numbers.\\n2. Select a consistent brand voice ID so every prompt sounds the same.\\n3. Set stability high for a steady, professional delivery and convert the script to speech.\\n\\n## Output\\nReturn the audio file and its URL. When generating a set of prompts, list each clip with its script so they can be wired into the phone tree or app."}],"templates":[{"title":"ElevenLabs blog-to-podcast","prompt":"Build a workflow that takes a blog post, narrates it with an ElevenLabs voice, saves the audio file, and posts a player-ready link to the marketing Slack channel.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"slack","name":"Slack"}]},{"title":"ElevenLabs voice greeting generator","prompt":"Create a workflow that reads a table of new enterprise customers, generates a personalized ElevenLabs voice greeting with their account manager voice, and emails the audio file to the customer on day one.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"gmail","name":"Gmail"}]},{"title":"ElevenLabs IVR builder","prompt":"Build a workflow that generates branded ElevenLabs voice prompts from a tables-driven script, saves each clip as a file, and lists the bundle so it can be wired into the phone tree.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"ElevenLabs + Pulse meeting voice digest","prompt":"Build a workflow that takes Pulse meeting insights, narrates them with an ElevenLabs voice, and emails the audio digest to the team for asynchronous review.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"pulse","name":"Pulse"},{"id":"gmail","name":"Gmail"}]},{"title":"ElevenLabs daily voice digest","prompt":"Build a scheduled daily workflow that generates an ElevenLabs voice digest of the day’s key metrics, saves the audio, and Slacks the player link to leadership.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"slack","name":"Slack"}]},{"title":"ElevenLabs release-notes narrator","prompt":"Create a workflow that takes new product release notes, rewrites them into a natural spoken script with an agent, generates narration with ElevenLabs text-to-speech, and saves the audio file ready to share as a what\'s-new update.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"ElevenLabs voicemail responder","prompt":"Build a workflow that on a new inbound message drafts a short personalized reply with an agent, converts it to speech with ElevenLabs in a chosen voice, and saves the audio so it can be sent as a voice note to the customer.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"Extend + ElevenLabs spoken-summary","prompt":"Build a workflow that uses Extend to pull structured data from a document, then narrates the summary with ElevenLabs, producing an audio briefing for stakeholders.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"extend","name":"Extend"}]},{"title":"YouTube video audio brief","prompt":"Build a workflow that takes a YouTube URL, pulls the video details and top comments, summarizes them with an agent, narrates the summary with ElevenLabs, and saves the audio file for distribution.","integrations":[{"id":"elevenlabs","name":"ElevenLabs"},{"id":"youtube","name":"YouTube"}]}]},{"id":"emailbison","type":"emailbison","slug":"email-bison","name":"Email Bison","description":"Manage Email Bison leads, campaigns, replies, and tags","category":"Email","docsUrl":"https://docs.sim.ai/integrations/emailbison","authType":"api-key","connections":[],"operations":[{"name":"List Leads","description":"Retrieves leads from Email Bison with optional search and tag filters."},{"name":"Get Lead","description":"Retrieves a lead by Email Bison lead ID or email address."},{"name":"Create Lead","description":"Creates a single lead in Email Bison."},{"name":"Update Lead","description":"Updates an existing Email Bison lead. Fields omitted from a PUT update may be cleared by Email Bison."},{"name":"List Campaigns","description":"Retrieves Email Bison campaigns."},{"name":"Create Campaign","description":"Creates a new Email Bison campaign."},{"name":"Update Campaign","description":"Updates Email Bison campaign settings."},{"name":"Update Campaign Status","description":"Pauses, resumes, or archives an Email Bison campaign."},{"name":"Attach Leads to Campaign","description":"Adds existing Email Bison leads to a campaign."},{"name":"List Replies","description":"Retrieves Email Bison replies with optional status, folder, campaign, sender, lead, and tag filters."},{"name":"List Tags","description":"Retrieves all Email Bison tags for the authenticated workspace."},{"name":"Create Tag","description":"Creates a new Email Bison tag."},{"name":"Attach Tags to Leads","description":"Attaches Email Bison tags to one or more leads."}],"triggers":[{"id":"emailbison_email_sent","name":"Email Bison Email Sent","description":"Trigger when a campaign email is sent in Email Bison"},{"id":"emailbison_lead_first_contacted","name":"Email Bison Contact First Emailed","description":"Trigger when a contact receives their first campaign email in Email Bison"},{"id":"emailbison_lead_replied","name":"Email Bison Contact Replied","description":"Trigger when a campaign lead replies in Email Bison"},{"id":"emailbison_lead_interested","name":"Email Bison Contact Interested","description":"Trigger when a reply is marked interested in Email Bison"},{"id":"emailbison_lead_unsubscribed","name":"Email Bison Contact Unsubscribed","description":"Trigger when a contact unsubscribes in Email Bison"},{"id":"emailbison_untracked_reply_received","name":"Email Bison Untracked Reply Received","description":"Trigger when Email Bison receives a reply not tied to a scheduled campaign email"},{"id":"emailbison_email_opened","name":"Email Bison Email Opened","description":"Trigger when an Email Bison campaign email is opened"},{"id":"emailbison_email_bounced","name":"Email Bison Email Bounced","description":"Trigger when an Email Bison campaign email bounces"},{"id":"emailbison_email_account_added","name":"Email Bison Email Account Added","description":"Trigger when a sender email account is added to Email Bison"},{"id":"emailbison_email_account_removed","name":"Email Bison Email Account Removed","description":"Trigger when a sender email account is removed from Email Bison"},{"id":"emailbison_email_account_disconnected","name":"Email Bison Email Account Disconnected","description":"Trigger when a sender email account disconnects in Email Bison"},{"id":"emailbison_email_account_reconnected","name":"Email Bison Email Account Reconnected","description":"Trigger when a sender email account reconnects in Email Bison"},{"id":"emailbison_manual_email_sent","name":"Email Bison Manual Email Sent","description":"Trigger when a manual email is sent in Email Bison"},{"id":"emailbison_tag_attached","name":"Email Bison Tag Attached","description":"Trigger when a custom tag is attached to a taggable in Email Bison"},{"id":"emailbison_tag_removed","name":"Email Bison Tag Removed","description":"Trigger when a custom tag is removed from a taggable in Email Bison"},{"id":"emailbison_warmup_disabled_receiving_bounces","name":"Email Bison Warmup Disabled Receiving Bounces","description":"Trigger when warmup is disabled for a sender email receiving too many bounces"},{"id":"emailbison_warmup_disabled_causing_bounces","name":"Email Bison Warmup Disabled Causing Bounces","description":"Trigger when warmup is disabled for a sender email causing too many bounces"}],"skills":[{"name":"add-leads-to-campaign","description":"Create leads in Email Bison and attach them to an outbound campaign with personalization variables.","content":"# Add Leads to Campaign\\n\\nLoad prospects into Email Bison and enroll them in a campaign.\\n\\n## Steps\\n1. Confirm the instance URL and target campaign. If only a campaign name is known, use List Campaigns to resolve its ID.\\n2. For each prospect, call Create Lead with first name, last name, email, and any title or company. Pass personalization fields as a custom-variables JSON array (e.g., linkedin_url, first_line).\\n3. Collect the new lead IDs and call Attach Leads to Campaign with the campaign ID and those IDs.\\n\\n## Output\\nReport how many leads were created and attached, list any duplicates or invalid emails that were skipped, and confirm the campaign they were added to."},{"name":"triage-campaign-replies","description":"Pull recent Email Bison replies, classify each by intent, and tag the lead accordingly.","content":"# Triage Campaign Replies\\n\\nProcess inbound replies to outbound campaigns and route them.\\n\\n## Steps\\n1. Call List Replies, optionally scoped to a campaign, sender email, or the inbox folder, and filter to unread when only new replies matter.\\n2. Classify each reply as interested, not interested, objection, out-of-office, or auto-reply based on its content.\\n3. Resolve or create the matching tag with List Tags / Create Tag, then call Attach Tags to Leads to label the lead by intent.\\n\\n## Output\\nReturn each reply with its lead, classification, and the tag applied. Highlight interested replies so a rep can follow up first."},{"name":"manage-campaign-status","description":"Pause, resume, or archive an Email Bison campaign and adjust its sending settings.","content":"# Manage Campaign Status\\n\\nControl whether an Email Bison campaign is actively sending and tune its limits.\\n\\n## Steps\\n1. Confirm the campaign ID (resolve via List Campaigns if only a name is given).\\n2. Call Update Campaign Status with pause, resume, or archive as requested.\\n3. To adjust throughput or behavior, call Update Campaign to change max emails per day, max new leads per day, sequence prioritization, or tracking settings.\\n\\n## Output\\nConfirm the campaign new status and any sending settings that changed. Note the prior values so the change can be reverted if needed."},{"name":"report-campaign-performance","description":"Summarize Email Bison campaign performance — sends, opens, replies, and positive reply rate.","content":"# Report Campaign Performance\\n\\nProduce a performance snapshot across Email Bison campaigns.\\n\\n## Steps\\n1. Call List Campaigns to get the active campaigns and their stats.\\n2. For reply-level detail, call List Replies per campaign and tally interested versus total to compute positive reply rate.\\n3. Rank campaigns by reply rate and identify top and bottom performers.\\n\\n## Output\\nReturn a digest: per-campaign sends, opens, replies, and positive reply rate, with the best and worst performers called out and a one-line takeaway for each."}],"templates":[{"title":"Brandfetch outbound enricher","prompt":"Create a workflow that enriches outbound prospect data with Brandfetch logos and brand metadata, and writes the enriched contact record to Email Bison for personalization.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"brandfetch","name":"Brandfetch"}]},{"title":"Email Bison campaign launcher","prompt":"Build a workflow that takes a target persona and offer, drafts a multi-step Email Bison campaign with personalized variables, creates the campaign and attaches the matching leads, and launches it once a human approves.","integrations":[{"id":"emailbison","name":"Email Bison"}]},{"title":"Email Bison reply triage","prompt":"Create a workflow that pulls new Email Bison replies on a schedule, classifies each as interested, not interested, objection, or out-of-office, applies the matching tag to the lead, and pings the rep in Slack for hot replies.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"slack","name":"Slack"}]},{"title":"Email Bison + Apollo lead feeder","prompt":"Build a workflow that runs an Apollo search for an ICP, enriches each prospect, creates the lead in Email Bison with personalization variables, and attaches the leads to the matching active campaign.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"apollo","name":"Apollo"}]},{"title":"Email Bison tag automator","prompt":"Create a workflow that reads Email Bison replies and activity, and applies tags to leads based on engagement signals — opened, clicked, replied positively, bounced — so segmentation stays current for follow-up campaigns.","integrations":[{"id":"emailbison","name":"Email Bison"}]},{"title":"Email Bison weekly outbound digest","prompt":"Build a scheduled weekly workflow that pulls Email Bison campaign performance — sends, opens, replies, positive reply rate — generates a digest with the top campaigns and bottom performers, and posts it to a Slack sales channel.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"slack","name":"Slack"}]},{"title":"Email Bison + HubSpot sync","prompt":"Create a workflow that mirrors Email Bison lead status and reply outcomes into the matching HubSpot contact, logs each campaign step as an engagement, and creates a HubSpot task for sales when a lead replies positively.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Email Bison bounce cleanup","prompt":"Build a scheduled workflow that finds Email Bison leads with hard bounces, tags them for suppression, updates the lead in Email Bison, and writes a cleanup report so deliverability stays healthy.","integrations":[{"id":"emailbison","name":"Email Bison"}]},{"title":"Enrich + Email Bison sender","prompt":"Create a workflow that runs Enrich on prospects then drafts and sends a personalized Email Bison sequence based on the enriched fields.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"enrich","name":"Enrich"}]},{"title":"Hunter + Email Bison outbound","prompt":"Build a workflow that uses Hunter to find prospect emails, validates each, and pushes valid prospects into an active Email Bison campaign.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"hunter","name":"Hunter.io"}]},{"title":"PDL + Email Bison outbound","prompt":"Build a workflow that runs People Data Labs on prospects, drafts a personalized first-touch email based on enrichment fields, and sends via Email Bison.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"Prospeo + Email Bison outbound","prompt":"Create a workflow that uses Prospeo to find and verify prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"prospeo","name":"Prospeo"}]},{"title":"Sixtyfour outbound briefer","prompt":"Build a workflow that runs Sixtyfour on a prospect, generates a tailored outreach brief with hooks, and queues it for the rep to send via Email Bison.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Wiza + Email Bison outbound","prompt":"Create a workflow that uses Wiza to find and reveal verified prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.","integrations":[{"id":"emailbison","name":"Email Bison"},{"id":"wiza","name":"Wiza"}]}]},{"id":"embeddings","type":"embeddings","slug":"embeddings","name":"Embeddings","description":"Generate embeddings","category":"AI","docsUrl":"https://docs.sim.ai/integrations/embeddings","authType":"api-key","connections":[],"operations":[{"name":"OpenAI Embeddings","description":"Generate embeddings from text using OpenAI\'s embedding models"},{"name":"OpenRouter Embeddings","description":"Generate embeddings through OpenRouter"},{"name":"Gemini Embeddings","description":"Generate embeddings from text using Google\'s Gemini embedding models"},{"name":"Cohere Embeddings","description":"Generate embeddings from text using Cohere\'s embedding models"},{"name":"Mistral Embeddings","description":"Generate embeddings from text using Mistral\'s embedding models"},{"name":"Ollama Embeddings","description":"Generate embeddings on a self-hosted Ollama server"}],"triggers":[],"skills":[{"name":"embed-text","description":"Generate an embedding vector for a piece of text to use in semantic search or similarity.","content":"# Embed Text\\n\\nConvert text into an embedding vector.\\n\\n## Steps\\n1. Take the input text. If it is long, ensure it fits the model context; otherwise chunk it first.\\n2. Choose a provider and model — text-embedding-3-small for cost-efficient general use, gemini-embedding-001 for the highest retrieval quality, embed-v4.0 for multilingual work, or codestral-embed for code. Keep the model consistent with any existing vectors it will be compared against.\\n3. Set the task type to Query or Document when the model supports it, so the vector is conditioned for how it will be used.\\n4. Generate the embedding.\\n\\n## Output\\nReturn the embedding vector, the provider and model used, the dimensionality, and token usage. Vectors are only comparable when they come from the same model at the same dimensionality."},{"name":"embed-documents-for-retrieval","description":"Chunk and embed a set of documents so they can be upserted into a vector store for retrieval.","content":"# Embed Documents for Retrieval\\n\\nPrepare documents for semantic retrieval by chunking and embedding them.\\n\\n## Steps\\n1. Split each document into reasonably sized chunks with light overlap so context is preserved.\\n2. Embed each chunk with a single consistent model, using the Document task type where the model supports it.\\n3. Pair each vector with its source metadata (document ID, chunk index, title) ready for upsert into the vector store.\\n\\n## Output\\nReturn the embeddings with their associated metadata, the model used, and the dimensionality. Report how many chunks were produced and flag any chunk that failed to embed."},{"name":"find-semantic-duplicates","description":"Embed items and compare vectors by cosine similarity to flag near-duplicate content.","content":"# Find Semantic Duplicates\\n\\nDetect items that mean the same thing even when worded differently.\\n\\n## Steps\\n1. Embed each candidate item with the same model and dimensionality used for the existing set.\\n2. Compare each new vector against existing vectors using cosine similarity.\\n3. Flag pairs above a similarity threshold (e.g. 0.9) as likely duplicates; treat lower scores as distinct.\\n\\n## Output\\nReturn the flagged duplicate pairs with their similarity scores, sorted highest first, so they can be merged or deduplicated."}],"templates":[{"title":"Document embedding pipeline","prompt":"Build a workflow that watches a files folder, chunks each new document, generates embeddings, and upserts vectors into Pinecone with rich metadata for retrieval.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Knowledge base re-embedder","prompt":"Create a scheduled workflow that finds documents whose embeddings are stale, regenerates them, and re-upserts the vectors into Pinecone so retrieval stays current.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Semantic duplicate detector","prompt":"Build a workflow that reads new rows from a table, generates an embedding for each, compares them against existing rows by cosine similarity, and flags near-duplicates in an evaluation table.","integrations":[{"id":"embeddings","name":"Embeddings"}]},{"title":"Product catalog semantic search","prompt":"Create a workflow that embeds each product description from a table, upserts the vectors into Pinecone, and lets an incoming query return the closest matching products by similarity.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Semantic ticket deduplication","prompt":"Build a workflow that embeds each new support ticket, searches a Pinecone index of past tickets for near-duplicates, and links the new ticket to the matching thread instead of opening a fresh one.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"FAQ semantic router","prompt":"Create a workflow that embeds an incoming question, compares it against embedded FAQ entries to find the closest match, and returns the canned answer when similarity is high or escalates to an agent when it is not.","integrations":[{"id":"embeddings","name":"Embeddings"}]},{"title":"Embedding-based content clustering","prompt":"Build a scheduled workflow that pulls recent feedback from a table, generates embeddings for each entry, clusters them by semantic similarity, and writes the themed groups with representative quotes back to a summary table.","integrations":[{"id":"embeddings","name":"Embeddings"}]},{"title":"MongoDB to vector enrichment","prompt":"Build a scheduled workflow that polls a MongoDB collection for new documents, generates OpenAI embeddings, and upserts them into Pinecone with the source document ID for retrieval.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"mongodb","name":"MongoDB"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone reindex pipeline","prompt":"Build a scheduled workflow that regenerates embeddings with OpenAI for new or changed source documents and upserts the vectors into a Pinecone index so retrieval stays current.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone semantic search agent","prompt":"Create an agent that takes a natural-language query, embeds it with OpenAI, retrieves top-k matches from Pinecone, and answers with cited passages plus a confidence score.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone duplicate detector","prompt":"Create a workflow that reads a table of candidate records, embeds each with OpenAI, searches a Pinecone index for matches above a similarity threshold, and writes the near-duplicates to a cleanup queue.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone FAQ deflection bot","prompt":"Create a workflow that embeds an incoming question with OpenAI, searches a Pinecone index of FAQ entries for the closest match, and returns the answer when similarity is high or escalates when it is not.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone support knowledge retriever","prompt":"Build a workflow that fetches each new Zendesk ticket, embeds the question with OpenAI, queries a Pinecone index of resolved tickets and docs, and drafts a suggested reply citing the most relevant matches for the agent to approve.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"pinecone","name":"Pinecone"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Qdrant document ingestion","prompt":"Build a workflow that watches a Google Drive folder for new docs, chunks each, generates embeddings, and upserts the vectors into a Qdrant collection with rich metadata.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"qdrant","name":"Qdrant"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Qdrant support-answer retriever","prompt":"Build a workflow that embeds each new Zendesk ticket with OpenAI, runs a filtered Qdrant search scoped to the customer’s product, and drafts a cited reply from the closest matching resolved tickets for the agent to approve.","integrations":[{"id":"embeddings","name":"Embeddings"},{"id":"qdrant","name":"Qdrant"},{"id":"zendesk","name":"Zendesk"}]}]},{"id":"enrich","type":"enrich","slug":"enrich","name":"Enrich","description":"B2B data enrichment and LinkedIn intelligence with Enrich.so","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/enrich","authType":"api-key","connections":[],"operations":[{"name":"Email to Profile","description":"Retrieve detailed LinkedIn profile information using an email address including work history, education, and skills."},{"name":"Email to Person (Lite)","description":"Retrieve basic LinkedIn profile information from an email address. A lighter version with essential data only."},{"name":"LinkedIn Profile Enrichment","description":"Enrich a LinkedIn profile URL with detailed information including positions, education, and social metrics."},{"name":"Find Email","description":"Find a person\'s work email address using their full name and company domain."},{"name":"LinkedIn to Work Email","description":"Find a work email address from a LinkedIn profile URL."},{"name":"LinkedIn to Personal Email","description":"Find personal email address from a LinkedIn profile URL."},{"name":"Phone Finder (LinkedIn)","description":"Find a phone number from a LinkedIn profile URL."},{"name":"Email to Phone","description":"Find a phone number associated with an email address."},{"name":"Verify Email","description":"Verify an email address for deliverability, including catch-all detection and provider identification."},{"name":"Disposable Email Check","description":"Check if an email address is from a disposable or temporary email provider. Returns a score and validation details."},{"name":"Email to IP","description":"Discover an IP address associated with an email address."},{"name":"IP to Company","description":"Identify a company from an IP address with detailed firmographic information."},{"name":"Company Lookup","description":"Look up company information by name or domain, including funding, location, and social profiles."},{"name":"Company Funding & Traffic","description":"Retrieve company funding history, traffic metrics, and executive information by domain."},{"name":"Company Revenue","description":"Retrieve company revenue data, CEO information, and competitive analysis by domain."},{"name":"Search People","description":"Search for professionals by various criteria including name, title, skills, education, and company."},{"name":"Search Company","description":"Search for companies by various criteria including name, industry, location, and size."},{"name":"Search Company Employees","description":"Search for employees within specific companies by location and job title."},{"name":"Search Similar Companies","description":"Find companies similar to a given company by LinkedIn URL with filters for location and size."},{"name":"Sales Pointer (People)","description":"Advanced people search with complex filters for location, company size, seniority, experience, and more."},{"name":"Search Jobs","description":"Search LinkedIn job postings by keywords with filters for location, job type, workplace type, experience level, and company."},{"name":"Search Posts","description":"Search LinkedIn posts by keywords with date filtering."},{"name":"Get Post Details","description":"Get detailed information about a LinkedIn post by URL."},{"name":"Search Post Reactions","description":"Get reactions on a LinkedIn post with filtering by reaction type."},{"name":"Search Post Reactions (by URL)","description":"Get reactions on a LinkedIn post by its URL, filtered by reaction type."},{"name":"Search Post Comments","description":"Get comments on a LinkedIn post."},{"name":"Search Post Comments (by URL)","description":"Get comments on a LinkedIn post by its URL."},{"name":"Search People Activities","description":"Get a person\'s LinkedIn activities (posts, comments, or articles) by profile ID."},{"name":"Search Company Activities","description":"Get a company\'s LinkedIn activities (posts, comments, or articles) by company ID."},{"name":"Reverse Hash Lookup","description":"Convert an MD5 email hash back to the original email address and display name."},{"name":"Search Logo","description":"Get a company logo image URL by domain."},{"name":"Check Credits","description":"Check your Enrich API credit usage and remaining balance."}],"triggers":[],"skills":[{"name":"enrich-contact-from-email","description":"Enrich a person from their email address — name, role, company, social profiles, and more.","content":"# Enrich Contact from Email\\n\\nTurn an email address into a full contact profile using Enrich.so.\\n\\n## Steps\\n1. Take the email address. Choose Email to Profile for a full enrichment, or Email to Person (Lite) for a fast, cheaper lookup.\\n2. Enable fresh-data fetch when up-to-date info matters more than speed.\\n3. Read back name, current title, company, location, and any LinkedIn or social URLs.\\n\\n## Output\\nReturn the enriched fields in a clean object. Note which fields could not be resolved so downstream steps know what is missing, and report remaining credits if relevant."},{"name":"find-and-verify-work-email","description":"Find a prospect work email from a name and company or LinkedIn URL, then verify deliverability.","content":"# Find and Verify Work Email\\n\\nLocate a reliable work email for a prospect and confirm it is safe to send to.\\n\\n## Steps\\n1. If you have a name and company domain, use Find Email. If you have a LinkedIn profile URL, use LinkedIn to Work Email instead.\\n2. Run Verify Email on the returned address to check deliverability, and Disposable Email Check to rule out throwaway domains.\\n3. If the work email cannot be found, optionally fall back to LinkedIn to Personal Email when appropriate.\\n\\n## Output\\nReturn the discovered email, its verification status (valid, risky, invalid), and whether it is disposable. Recommend whether the address is safe to add to outreach."},{"name":"enrich-company-firmographics","description":"Look up firmographic data for a company — size, industry, funding, revenue, and traffic.","content":"# Enrich Company Firmographics\\n\\nBuild a firmographic profile for a target account using Enrich.so.\\n\\n## Steps\\n1. Identify the company by name or domain. Use Company Lookup for core firmographics.\\n2. Add Company Funding & Traffic and Company Revenue for deeper financial signals when account scoring needs them.\\n3. If you only have a visitor IP, use IP to Company first to resolve the organization.\\n\\n## Output\\nReturn a consolidated account brief: company name, domain, industry, employee count, funding, revenue, and traffic. Flag any data points that could not be resolved."},{"name":"search-prospects","description":"Search Enrich.so for people or companies matching an ideal-customer-profile filter.","content":"# Search Prospects\\n\\nFind people or companies that match a target profile.\\n\\n## Steps\\n1. For people, use Search People with filters like job title, industry, location, and skills. For companies, use Search Company with industry, location, and employee-size bounds.\\n2. To pull contacts at known accounts, use Search Company Employees with the company IDs and target job titles.\\n3. Page through results using the page and page-size parameters until you have enough matches.\\n\\n## Output\\nReturn the matching people or companies with their key identifying fields and any profile URLs, plus a count of total matches. Suggest tighter filters if too many or too few results come back."}],"templates":[{"title":"Enrich CRM hydrator","prompt":"Build a workflow that watches new Salesforce leads, enriches each with Enrich.so contact data, and writes role, company size, and email to the lead record.","integrations":[{"id":"enrich","name":"Enrich"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Enrich list cleaner","prompt":"Create a workflow that runs an outreach list through Enrich, removes invalid emails and disqualified roles, and writes the clean list to a sender table.","integrations":[{"id":"enrich","name":"Enrich"}]},{"title":"Enrich bulk-account researcher","prompt":"Build a workflow that takes a list of target accounts, enriches each with Enrich firmographic data, and writes a tables-based account brief for the sales team.","integrations":[{"id":"enrich","name":"Enrich"}]},{"title":"Enrich + Email Bison sender","prompt":"Create a workflow that runs Enrich on prospects then drafts and sends a personalized Email Bison sequence based on the enriched fields.","integrations":[{"id":"enrich","name":"Enrich"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Enrich event-attendee researcher","prompt":"Build a workflow that takes the Luma event attendee list, enriches each via Enrich, and writes a per-attendee research brief for the sales team.","integrations":[{"id":"enrich","name":"Enrich"},{"id":"luma","name":"Luma"}]},{"title":"Enrich CRM gap-filler","prompt":"Create a scheduled workflow that finds HubSpot contacts missing key fields, runs Enrich, and fills in the gaps so reporting is complete.","integrations":[{"id":"enrich","name":"Enrich"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Enrich LinkedIn role validator","prompt":"Build a scheduled workflow that reads HubSpot contacts with a LinkedIn profile URL, re-enriches each with Enrich, flags outdated roles, and updates the contact record with the current title.","integrations":[{"id":"enrich","name":"Enrich"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"enrow","type":"enrow","slug":"enrow","name":"Enrow","description":"Find and verify B2B email addresses","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/enrow","authType":"api-key","connections":[],"operations":[{"name":"Find Email","description":"Find a verified B2B email address from a full name and company domain or name. Uses the Enrow async finder — submits a search and polls until the result is ready. Costs 1 credit per valid email found. (https://docs.enrow.io/api-reference/email-finder/find-single)"},{"name":"Verify Email","description":"Verify the deliverability of an email address using the Enrow async verifier. Submits a verification request and polls until the result is ready. Costs 0.25 credits per verification. (https://docs.enrow.io/api-reference/email-verifier/verify-single)"}],"triggers":[],"skills":[],"templates":[]},{"id":"exa","type":"exa","slug":"exa","name":"Exa","description":"Search with Exa AI","category":"Search","docsUrl":"https://docs.sim.ai/integrations/exa","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search the web using Exa AI. Returns relevant search results with titles, URLs, and text snippets."},{"name":"Get Contents","description":"Retrieve the contents of webpages using Exa AI. Returns the title, text content, and optional summaries for each URL."},{"name":"Answer","description":"Get an AI-generated answer to a question with citations from the web using Exa AI."},{"name":"Agent","description":"Run a deep research task with Exa Agent. Handles multi-step list building, enrichment, and research, returning a written answer with field-level citations and optional structured output."},{"name":"Find Similar Links","description":"Find webpages similar to a given URL using Exa AI. Deprecated by Exa in favor of Search — prefer Search for new workflows."}],"triggers":[],"skills":[{"name":"search-the-web-with-exa","description":"Run an Exa search to find high-quality web sources on a topic.","content":"# Search the Web with Exa\\n\\nFind authoritative web pages on a topic using Exa AI search.\\n\\n## Steps\\n1. Use the Search operation with a clear query. Pick the search type — auto lets Exa decide, instant and fast favor latency, and deep, deep-lite, or deep-reasoning spend more time for harder questions.\\n2. Narrow results with include/exclude domains, a category filter (company, publication, news, personal site, financial report, people), and published-date bounds for recency.\\n3. Enable include-text or include-summary so each result comes back with usable content rather than just a link. Set max content age to control how fresh the crawled content must be.\\n4. To get a synthesized answer instead of a result list, supply an output schema and read structuredOutput.\\n\\n## Output\\nReturn the top results with title, URL, published date, and the text or summary. Note which filters were applied so the search can be tightened or broadened."},{"name":"answer-question-with-citations","description":"Use Exa Answer to get a direct, sourced answer to a factual question.","content":"# Answer Question with Citations\\n\\nGet a grounded answer to a question with supporting sources via Exa.\\n\\n## Steps\\n1. Use the Answer operation and pass the question in natural language.\\n2. Enable include-source-text when you want each citation to carry its full page text, not just the URL.\\n3. Supply an output schema when you need the answer as structured fields rather than prose.\\n4. Review the citations to confirm the answer is well-supported before relying on it.\\n\\n## Output\\nReturn the answer plus its citations (titles and URLs). If the citations are weak or conflicting, say so and recommend a follow-up search."},{"name":"extract-page-contents","description":"Use Exa Get Contents to pull clean text and summaries from a set of URLs.","content":"# Extract Page Contents\\n\\nRetrieve readable content from specific web pages using Exa.\\n\\n## Steps\\n1. Use the Get Contents operation with the target URLs (comma-separated), or pass result IDs carried over from a previous Exa search.\\n2. Enable include-text for full content, and supply a summary query to get a focused summary tailored to what you need.\\n3. To pull deeper context from a site, set a subpage count and target keywords (e.g., docs, pricing, about).\\n4. Set max content age to 0 when the page must be crawled live rather than served from cache.\\n\\n## Output\\nReturn each URL with its extracted text or summary and any highlights. Check statuses and flag any URL that could not be crawled."},{"name":"run-deep-research-with-exa","description":"Use the Exa Agent operation for multi-step research, list building, and enrichment.","content":"# Run Deep Research with Exa\\n\\nAnswer a question that needs many searches and cross-referencing, using the Exa Agent operation.\\n\\n## Steps\\n1. Use the Agent operation and write the query as a full instruction, not a keyword phrase — say what to find and what to report.\\n2. Pick an effort level: minimal or low for quick lookups, medium for normal research, high or xhigh for exhaustive list building. Auto lets Exa choose.\\n3. Supply an output schema when you need rows or fields back rather than prose; the result arrives in the structured output alongside field-level citations.\\n4. To ask a follow-up against the same research, pass the previous run ID.\\n\\n## Output\\nReturn the agent text answer, the structured result when a schema was used, and the grounding citations. Agent runs take longer than a search — expect seconds to minutes depending on effort."}],"templates":[{"title":"Exa company intel agent","prompt":"Build an agent that takes a company name, uses the Exa Agent operation to find recent product updates, funding news, and competitor mentions, and writes a one-page intel brief.","integrations":[{"id":"exa","name":"Exa"}]},{"title":"Exa knowledge crawler","prompt":"Build a workflow that uses Exa to find authoritative URLs on a topic, scrapes each one, chunks the content, and upserts it into a knowledge base so the agent can answer with citations.","integrations":[{"id":"exa","name":"Exa"}]},{"title":"Exa deep research agent","prompt":"Build an agent that uses Exa deep search to find authoritative sources on a topic, scrapes them, and produces a structured research brief with citations.","integrations":[{"id":"exa","name":"Exa"}]},{"title":"Exa similar-page finder","prompt":"Create a workflow that takes a URL, runs an Exa search to find related authoritative sources, and writes the discovery list to a research table.","integrations":[{"id":"exa","name":"Exa"}]},{"title":"Exa daily research digest","prompt":"Build a scheduled workflow that runs Exa searches on tracked topics each morning, summarizes top hits with citations, and emails the user a research digest.","integrations":[{"id":"exa","name":"Exa"},{"id":"gmail","name":"Gmail"}]},{"title":"Exa investment research helper","prompt":"Create an agent that uses the Exa Agent operation to deep-research a ticker, finds recent material developments, summarizes with citations, and writes the brief to a finance research file.","integrations":[{"id":"exa","name":"Exa"}]},{"title":"Exa competitor news monitor","prompt":"Build a scheduled daily workflow that runs Exa search for fresh news about my competitors, gets the page contents and finds similar coverage, summarizes the notable moves with citations, and posts a digest to the team Slack channel.","integrations":[{"id":"exa","name":"Exa"},{"id":"slack","name":"Slack"}]},{"title":"Firecrawl + Exa research stack","prompt":"Create an agent that uses Exa to find authoritative URLs on a topic, scrapes each with Firecrawl, and produces a structured research brief with citations.","integrations":[{"id":"exa","name":"Exa"},{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Perplexity multi-source research","prompt":"Create an agent that triangulates a topic across Perplexity, Exa, and Tavily, deduplicates findings, and produces a consensus brief with confidence scores per claim.","integrations":[{"id":"exa","name":"Exa"},{"id":"perplexity","name":"Perplexity"},{"id":"tavily","name":"Tavily"}]}]},{"id":"extend","type":"extend_v2","slug":"extend","name":"Extend","description":"Parse and extract content from documents","category":"AI","docsUrl":"https://docs.sim.ai/integrations/extend","authType":"api-key","connections":[],"operations":[{"name":"Extend Document Parser","description":"Parse and extract content from documents using Extend AI"}],"triggers":[],"skills":[{"name":"extract-invoice-fields","description":"Parse an uploaded invoice with Extend and return structured vendor, line item, and total fields.","content":"# Extract Invoice Fields\\n\\nUse Extend to turn an invoice PDF or image into structured, validated data.\\n\\n## Steps\\n1. Take the uploaded invoice document (file upload or URL).\\n2. Run the Extend parser to produce structured chunks and blocks.\\n3. Pull the key fields: vendor name, invoice number, invoice date, due date, line items (description, quantity, unit price), subtotal, tax, and total.\\n4. Validate that totals add up and that required fields are present; flag any that are missing or inconsistent.\\n\\n## Output\\nReturn a clean JSON object with the extracted fields plus a list of any validation warnings. Note the page count and credits used so cost can be tracked."},{"name":"parse-document-to-markdown","description":"Convert a scanned or complex document into clean, LLM-ready markdown using Extend.","content":"# Parse Document to Markdown\\n\\nUse Extend to convert any supported document (PDF, image, or Office file) into clean markdown an agent can reason over.\\n\\n## Steps\\n1. Take the source document and choose a chunking strategy (page, section, or document) based on how the content will be consumed.\\n2. Run the Extend parser with markdown output.\\n3. Stitch the returned chunks into a single ordered markdown document, preserving headings, tables, and lists.\\n\\n## Output\\nReturn the full markdown text plus the page count. If the document was chunked, also return the per-chunk markdown so downstream steps can process sections independently."},{"name":"classify-and-route-document","description":"Parse an uploaded document with Extend, identify its type, and route it to the right downstream handler.","content":"# Classify and Route Document\\n\\nUse Extend to read an incoming document and decide where it should go.\\n\\n## Steps\\n1. Run the Extend parser on the uploaded document to get its text content.\\n2. Inspect the parsed content to classify the document type (e.g. invoice, contract, claim form, purchase order, KYC document).\\n3. Pull the few identifying fields needed for routing (such as document type, reference number, and amount).\\n4. Decide the destination queue, table, or channel based on the classification and any thresholds.\\n\\n## Output\\nReturn the detected document type, the routing decision, and the extracted routing fields. Note any document that could not be confidently classified for manual review."}],"templates":[{"title":"Extend structured-data extractor","prompt":"Build a workflow that runs uploaded forms through Extend to pull labelled fields, writes the structured rows to a table, and notifies Slack on missing required fields.","integrations":[{"id":"extend","name":"Extend"},{"id":"slack","name":"Slack"}]},{"title":"Extend insurance claim ingester","prompt":"Create a workflow that uses Extend to ingest claim forms, extracts policy number, claim amount, and incident details to structured rows, and routes high-value claims to a Slack adjuster channel.","integrations":[{"id":"extend","name":"Extend"},{"id":"slack","name":"Slack"}]},{"title":"Extend purchase-order extractor","prompt":"Create a workflow that processes inbound PO PDFs with Extend, writes vendor, SKU, quantity, and total to an orders table, and pings Slack when a PO exceeds the approval threshold.","integrations":[{"id":"extend","name":"Extend"},{"id":"slack","name":"Slack"}]},{"title":"Extend + ElevenLabs spoken-summary","prompt":"Build a workflow that uses Extend to pull structured data from a document, then narrates the summary with ElevenLabs, producing an audio briefing for stakeholders.","integrations":[{"id":"extend","name":"Extend"},{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"Extend KYC pipeline","prompt":"Build a workflow that runs Extend on uploaded KYC documents, validates extracted fields against a compliance rule set, and writes outcomes to a verification table.","integrations":[{"id":"extend","name":"Extend"}]},{"title":"Extend invoice processor","prompt":"Create a workflow that parses uploaded vendor invoices with Extend, extracts line items, totals, and due dates, validates against the matching purchase order, and writes approved invoices to an accounts-payable table for payment.","integrations":[{"id":"extend","name":"Extend"}]},{"title":"Extend contract data extractor","prompt":"Build a workflow that runs Extend on uploaded contracts to pull parties, term dates, renewal clauses, and obligations, summarizes the key risks with an agent, and logs the structured fields to a contracts table for the legal team.","integrations":[{"id":"extend","name":"Extend"}]},{"title":"Textract + Extend pipeline composer","prompt":"Build a workflow that uses AWS Textract for layout-aware OCR and Extend for structured field extraction, fusing outputs into clean records for downstream automations.","integrations":[{"id":"extend","name":"Extend"},{"id":"textract","name":"AWS Textract"}]}]},{"id":"fathom","type":"fathom","slug":"fathom","name":"Fathom","description":"Access meeting recordings, transcripts, and summaries","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/fathom","authType":"api-key","connections":[],"operations":[{"name":"List Meetings","description":"List recent meetings recorded by the user or shared to their team."},{"name":"List Meeting Types","description":"List meeting types configured in your Fathom organization."},{"name":"Get Summary","description":"Get the call summary for a specific meeting recording."},{"name":"Get Transcript","description":"Get the full transcript for a specific meeting recording."},{"name":"List Team Members","description":"List team members in your Fathom organization."},{"name":"List Teams","description":"List teams in your Fathom organization."}],"triggers":[{"id":"fathom_new_meeting","name":"Fathom New Meeting Content","description":"Trigger workflow when new meeting content is ready in Fathom"},{"id":"fathom_webhook","name":"Fathom Webhook","description":"Generic webhook trigger for all Fathom events"}],"skills":[{"name":"summarize-recent-meetings","description":"List recent Fathom meetings and produce a concise digest of decisions, owners, and action items.","content":"# Summarize Recent Meetings\\n\\nUse Fathom to pull recent meetings and turn them into a readable digest.\\n\\n## Steps\\n1. List Fathom meetings, filtering by a date range (createdAfter / createdBefore) and optionally by team or recorder.\\n2. Request summaries and action items in the response so each meeting comes back with its recap.\\n3. Across the meetings, group the key decisions, commitments, and open action items by topic or owner.\\n\\n## Output\\nReturn a digest with one short section per meeting (title, date, attendees, key points) followed by a consolidated action-item list with owners. Use the pagination cursor to cover the full range if there are many meetings."},{"name":"extract-meeting-action-items","description":"Pull a specific Fathom meeting summary and extract a clean list of action items with owners.","content":"# Extract Meeting Action Items\\n\\nUse Fathom to turn a single meeting into a tracked task list.\\n\\n## Steps\\n1. Get the meeting summary for the given recording ID.\\n2. Identify every commitment or next step mentioned, with the responsible owner and any stated due date.\\n3. If owners are unclear, fall back to the transcript to find who made each commitment.\\n\\n## Output\\nReturn a structured list of action items, each with the task description, owner, and due date (or null). Include a one-line meeting recap at the top for context."},{"name":"log-sales-call-to-crm","description":"Pull a Fathom call summary and CRM matches, then format a CRM-ready note with next steps.","content":"# Log Sales Call to CRM\\n\\nUse Fathom to capture a sales call and prepare it for the CRM.\\n\\n## Steps\\n1. Get the summary for the meeting recording ID, including CRM matches so the linked contact or deal is known.\\n2. Extract the customer pain points, objections, commitments, and agreed next steps.\\n3. Format a concise call note suitable for logging against the matched CRM record.\\n\\n## Output\\nReturn the matched CRM contact or deal identifier, a formatted call note, and a list of follow-up next steps with owners and dates so they can be written into the CRM."}],"templates":[{"title":"Amplitude + Fathom unified analytics","prompt":"Build a scheduled workflow that joins Amplitude product analytics with Fathom web analytics, writes a unified active-user and engagement report, and surfaces anomalies.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"amplitude","name":"Amplitude"}]},{"title":"Fathom meeting recap to Slack","prompt":"Build a workflow that triggers when a Fathom meeting completes, pulls the summary and action items, and posts a recap to the relevant Slack channel.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"slack","name":"Slack"}]},{"title":"Fathom transcript to Notion notes","prompt":"Create a workflow that triggers on a new Fathom meeting, pulls the transcript and summary, and writes a structured meeting note to Notion with attendees and next steps.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"notion","name":"Notion"}]},{"title":"Fathom weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists Fathom meetings from the past week, summarizes the key decisions and commitments across calls with an agent, and emails the digest to the team.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"gmail","name":"Gmail"}]},{"title":"Fathom CRM call logger","prompt":"Build a workflow that triggers when a Fathom meeting ends, pulls the summary and CRM matches, and logs the call notes and next steps to the matched HubSpot contact.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Fathom action-item tracker","prompt":"Create a workflow that triggers on a new Fathom meeting, extracts action items from the summary with an agent, and writes each one to a tasks table with owner and due date.","integrations":[{"id":"fathom","name":"Fathom"}]},{"title":"Fathom meeting archive","prompt":"Build a workflow that triggers on a completed Fathom meeting, pulls the full transcript and summary, and saves a formatted recap file to the shared meeting archive.","integrations":[{"id":"fathom","name":"Fathom"}]},{"title":"Fathom sales-call action items","prompt":"Create a workflow that after a Fathom meeting pulls the summary and transcript, extracts the customer commitments and next steps with an agent, creates follow-up tasks in the CRM, and emails a recap to the attendees.","integrations":[{"id":"fathom","name":"Fathom"},{"id":"gmail","name":"Gmail"}]}]},{"id":"findymail","type":"findymail","slug":"findymail","name":"Findymail","description":"Find and verify B2B emails, phones, employees, and company data","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/findymail","authType":"api-key","connections":[],"operations":[{"name":"Find Email From Name","description":"Find someone\'s email from their name and a company domain or company name. Uses one finder credit when a verified email is found."},{"name":"Find Email From LinkedIn","description":"Find someone\'s email from a LinkedIn profile URL or username. Uses one finder credit when a verified email is found."},{"name":"Find Emails By Domain","description":"Find verified contacts at a given domain matching one or more target roles (max 3 roles). Limited to 5 concurrent synchronous requests."},{"name":"Verify Email","description":"Verifies the deliverability of an email address. Uses one verifier credit."},{"name":"Reverse Email Lookup","description":"Find a business profile from an email address. Uses 1 finder credit if a profile is found, 2 credits if returning full profile data."},{"name":"Get Company Info","description":"Retrieve company information from a LinkedIn URL, domain, or company name. Uses 1 finder credit per successful response."},{"name":"Find Employees","description":"Find employees at a company by website and target job titles. Uses 1 credit per found contact. Does not return email addresses."},{"name":"Find Phone","description":"Find someone\'s phone number from a LinkedIn profile URL. Uses 10 finder credits if a phone is found. EU citizens are excluded for legal reasons."},{"name":"Search Technologies","description":"Search the technology catalog by name. Returns up to 25 technologies. Free endpoint, rate limited to 10 requests per minute."},{"name":"Lookup Technologies By Domain","description":"Get the technology stack for a company by domain. Optionally filter by technology names. 1 finder credit if technologies are found, free otherwise."},{"name":"Get Remaining Credits","description":"Retrieve the remaining finder and verifier credits for the authenticated account."}],"triggers":[],"skills":[{"name":"find-verified-email","description":"Find a prospect verified work email from their name and company, or from a LinkedIn URL.","content":"# Find Verified Email\\n\\nUse Findymail to discover a deliverable work email for a prospect.\\n\\n## Steps\\n1. If you have a name plus company domain, use Find Email From Name. If you have a LinkedIn profile URL, use Find Email From LinkedIn.\\n2. Findymail verifies the email at discovery time, so the returned address is already checked for deliverability.\\n3. Capture the contact name, email, and domain from the response.\\n\\n## Output\\nReturn the verified email, the matched contact name, and the source company domain. If no email was found, say so clearly rather than guessing an address."},{"name":"verify-email-list","description":"Run a list of email addresses through Findymail verification and split into deliverable and undeliverable.","content":"# Verify Email List\\n\\nUse Findymail to clean an email list before an outbound send.\\n\\n## Steps\\n1. For each email address, run Verify Email.\\n2. Read the verified flag and the detected provider for each result.\\n3. Partition the list into deliverable addresses and undeliverable ones.\\n\\n## Output\\nReturn two lists: deliverable emails (with provider) and undeliverable emails. Include a short summary count so the caller knows how many were removed."},{"name":"map-company-team","description":"Given a company domain, find employees by job title and enrich the company profile into a team map.","content":"# Map Company Team\\n\\nUse Findymail to build an org map for a target account.\\n\\n## Steps\\n1. Use Get Company Info on the domain to pull industry, size, and description.\\n2. Use Find Employees with the company website and a list of target job titles to pull matching people.\\n3. Optionally find each contact verified email or phone for the highest-priority roles.\\n\\n## Output\\nReturn the company profile plus a list of employees (name, job title, LinkedIn URL, and email where available), grouped by function so the account team can see the buying committee."},{"name":"enrich-from-email","description":"Reverse-lookup an email address with Findymail to recover the full LinkedIn profile and current company.","content":"# Enrich From Email\\n\\nUse Findymail to turn a bare email address into a full contact record.\\n\\n## Steps\\n1. Run Reverse Email Lookup on the email, requesting the full profile.\\n2. Pull the full name, headline, job title, location, current company, and profile details.\\n3. Optionally call Get Company Info on the recovered company domain for firmographics.\\n\\n## Output\\nReturn a structured contact record: name, title, company, location, LinkedIn URL, and the original email. Note any fields the lookup could not resolve."}],"templates":[{"title":"Findymail email finder","prompt":"Build a workflow that takes a prospect name and company domain from a table, runs Findymail to find the verified work email, and writes the deliverable contact back to the row.","integrations":[{"id":"findymail","name":"Findymail"}]},{"title":"Findymail LinkedIn enricher","prompt":"Create a workflow that takes a list of LinkedIn profile URLs, finds the matching verified work email via Findymail, and writes the enriched contacts into a research table.","integrations":[{"id":"findymail","name":"Findymail"}]},{"title":"Findymail email verifier","prompt":"Build a workflow that runs a list of email addresses through Findymail verification, removes undeliverable addresses, and writes a clean list for outbound sends.","integrations":[{"id":"findymail","name":"Findymail"}]},{"title":"Findymail company team mapper","prompt":"Create a workflow that takes a target company domain, uses Findymail to find employees by job title and enrich company data, and writes the org map into a tables-based account base.","integrations":[{"id":"findymail","name":"Findymail"}]},{"title":"Findymail CRM gap-filler","prompt":"Build a scheduled workflow that finds HubSpot contacts missing verified emails, looks them up with Findymail, verifies each, and updates the contact record.","integrations":[{"id":"findymail","name":"Findymail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Findymail LinkedIn list builder","prompt":"Create a workflow that reads a list of LinkedIn profile URLs from a table, finds and verifies each prospect\'s work email and phone with Findymail, enriches their company, and writes a clean, ready-to-contact prospect table.","integrations":[{"id":"findymail","name":"Findymail"}]},{"title":"Findymail domain prospecting","prompt":"Build a workflow that takes a target company domain, uses Findymail to find employees and their verified emails by role, validates each address, and pushes the qualified contacts into the outbound sequence.","integrations":[{"id":"findymail","name":"Findymail"}]}]},{"id":"firecrawl","type":"firecrawl","slug":"firecrawl","name":"Firecrawl","description":"Scrape, search, crawl, map, and extract web data","category":"Search","docsUrl":"https://docs.sim.ai/integrations/firecrawl","authType":"api-key","connections":[],"operations":[{"name":"Scrape","description":"Convert web pages to Markdown or HTML, including SEO metadata, Open Graph tags, and page information."},{"name":"Batch Scrape","description":"Scrape multiple URLs in a single batch job and retrieve structured content from each page."},{"name":"Batch Scrape Status","description":"Check the status and retrieve results of a previously started Firecrawl batch scrape job by its job ID."},{"name":"Search","description":"Search for information on the web using Firecrawl"},{"name":"Crawl","description":"Crawl entire websites and extract structured content from all accessible pages"},{"name":"Crawl Status","description":"Check the status and retrieve results of a previously started Firecrawl crawl job by its job ID."},{"name":"Cancel Crawl","description":"Cancel an in-progress Firecrawl crawl job by its job ID."},{"name":"Map","description":"Get a complete list of URLs from any website quickly and reliably. Useful for discovering all pages on a site without crawling them."},{"name":"Extract","description":"Extract structured data from web pages using natural language prompts and JSON Schema."},{"name":"Extract Status","description":"Check the status and retrieve results of a previously started Firecrawl extract job by its job ID."},{"name":"Agent","description":"Autonomous web data extraction agent. Searches and gathers information based on natural language prompts without requiring specific URLs."},{"name":"Parse Document","description":"Parse uploaded documents (PDF, DOCX, HTML, etc.) into clean markdown using Firecrawl. Supports .html, .htm, .pdf, .docx, .doc, .odt, .rtf, .xlsx, .xls."},{"name":"Credit Usage","description":"Retrieve the remaining and allocated Firecrawl credits for the team."},{"name":"Enrich Contact or Company","description":"Find work emails, phone numbers, LinkedIn profiles, company domains, and company information through Firecrawl Alexandria. Uses FullEnrich for contact lookups and People Data Labs for company, name-based profile, and single-part-name contact lookups. Provider terms must be enabled in Firecrawl. People Data Labs has a 50,000-record annual team limit."}],"triggers":[],"skills":[{"name":"scrape-page-to-markdown","description":"Scrape a single URL with Firecrawl and return clean main-content markdown for an agent to read.","content":"# Scrape Page to Markdown\\n\\nUse Firecrawl to fetch a web page as clean, LLM-ready markdown.\\n\\n## Steps\\n1. Use the Scrape operation on the target URL.\\n2. Enable Only Main Content to strip navigation, ads, and footers; set a Wait For delay if the page renders content with JavaScript.\\n3. Return the markdown output and capture page metadata (title, description).\\n\\n## Output\\nReturn the page markdown plus key metadata. If the page failed to load or returned empty content, report that instead of fabricating text."},{"name":"extract-structured-data","description":"Pull structured fields from one or more URLs using Firecrawl Extract with a prompt or schema.","content":"# Extract Structured Data\\n\\nUse Firecrawl to extract specific fields from web pages.\\n\\n## Steps\\n1. Use the Extract operation with the list of target URLs.\\n2. Provide a clear extraction prompt describing exactly what to pull (for example product name, price, and description).\\n3. Run the extraction and read the structured data from the response.\\n\\n## Output\\nReturn the extracted records as structured JSON. List the source URLs and flag any URL that yielded no data."},{"name":"crawl-site","description":"Crawl an entire site or section with Firecrawl and return the page content for indexing or analysis.","content":"# Crawl Site\\n\\nUse Firecrawl to traverse a site and collect its pages.\\n\\n## Steps\\n1. Use the Crawl operation on the root URL, setting a sensible page Limit to control cost.\\n2. Enable Only Main Content so each page comes back as clean markdown.\\n3. Collect the crawled pages and their URLs from the response.\\n\\n## Output\\nReturn the list of crawled pages with their URL and markdown content, plus the total page count. This output is ready to chunk and embed into a knowledge base."},{"name":"research-with-search","description":"Run a web search with Firecrawl, then scrape the top results into a cited research brief.","content":"# Research With Search\\n\\nUse Firecrawl to gather and synthesize web sources on a topic.\\n\\n## Steps\\n1. Use the Search operation with the research query and a result Limit.\\n2. For the most relevant results, use Scrape to pull the full page markdown.\\n3. Synthesize the findings into a brief, attributing each claim to its source URL.\\n\\n## Output\\nReturn a structured research brief with key findings and a Sources list of the URLs used. Keep claims grounded in the scraped content."}],"templates":[{"title":"Firecrawl keyword brief generator","prompt":"Build a workflow that takes a target keyword, uses Firecrawl to scrape the top 10 ranking pages, analyzes their content structure and subtopics, then generates a detailed content brief with outline, word count target, questions to answer, and internal linking suggestions.","integrations":[{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Firecrawl competitor change tracker","prompt":"Build a scheduled workflow that scrapes competitor websites, pricing pages, and changelog pages weekly using Firecrawl, compares against previous snapshots, summarizes any changes, logs them to a tracking table, and sends a Slack alert for major updates.","integrations":[{"id":"firecrawl","name":"Firecrawl"},{"id":"slack","name":"Slack"}]},{"title":"Firecrawl competitor site monitor","prompt":"Build a scheduled workflow that uses Firecrawl to scrape competitor pricing, product, and changelog pages weekly, diffs against the prior snapshot, and posts changes to Slack.","integrations":[{"id":"firecrawl","name":"Firecrawl"},{"id":"slack","name":"Slack"}]},{"title":"Firecrawl SEO content brief","prompt":"Create a workflow that takes a target keyword, scrapes the top-10 ranking pages with Firecrawl, analyzes structure and subtopics, and writes a content brief file.","integrations":[{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Firecrawl knowledge-base builder","prompt":"Build a workflow that crawls a documentation site with Firecrawl, chunks and embeds the pages, and upserts them into a knowledge base for an answering agent.","integrations":[{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Firecrawl + Exa research stack","prompt":"Create an agent that uses Exa to find authoritative URLs on a topic, scrapes each with Firecrawl, and produces a structured research brief with citations.","integrations":[{"id":"firecrawl","name":"Firecrawl"},{"id":"exa","name":"Exa"}]},{"title":"Firecrawl product-launch detector","prompt":"Build a scheduled workflow that crawls competitor blogs and product pages with Firecrawl daily, classifies posts as product launches, and posts notable launches to Slack.","integrations":[{"id":"firecrawl","name":"Firecrawl"},{"id":"slack","name":"Slack"}]},{"title":"Obsidian web clipper","prompt":"Build a workflow that accepts a URL from a form, scrapes the page with Firecrawl, summarizes with an agent, and writes the clip as a new Obsidian note with source metadata.","integrations":[{"id":"firecrawl","name":"Firecrawl"},{"id":"obsidian","name":"Obsidian"}]}]},{"id":"fireflies","type":"fireflies_v2","slug":"fireflies","name":"Fireflies","description":"Interact with Fireflies.ai meeting transcripts and recordings","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/fireflies","authType":"api-key","connections":[],"operations":[{"name":"List Transcripts","description":"List meeting transcripts from Fireflies.ai with optional filtering"},{"name":"Get Transcript","description":"Get a single transcript with full details including summary, action items, and analytics"},{"name":"Get User","description":"Get user information from Fireflies.ai. Returns current user if no ID specified."},{"name":"List Users","description":"List all users within your Fireflies.ai team"},{"name":"Upload Audio","description":"Upload an audio file URL to Fireflies.ai for transcription"},{"name":"Delete Transcript","description":"Delete a transcript from Fireflies.ai"},{"name":"Add Bot to Live Meeting","description":"Add the Fireflies.ai bot to an ongoing meeting to record and transcribe"},{"name":"Create Bite","description":"Create a soundbite/highlight from a specific time range in a transcript"},{"name":"List Bites","description":"List soundbites/highlights from Fireflies.ai"},{"name":"List Contacts","description":"List all contacts from your Fireflies.ai meetings"}],"triggers":[{"id":"fireflies_transcription_complete","name":"Fireflies Transcription Complete","description":"Trigger workflow when a Fireflies meeting transcription is complete"}],"skills":[{"name":"summarize-meeting-transcript","description":"Fetch a Fireflies transcript and produce a structured recap with decisions, action items, and owners.","content":"# Summarize Meeting Transcript\\n\\nUse Fireflies to turn a recorded meeting into a clean recap.\\n\\n## Steps\\n1. Get the transcript for the given transcript ID (or pick the latest from List Transcripts).\\n2. Read the sentences and any provided summary to identify the main topics discussed.\\n3. Extract key decisions, action items with owners, and notable questions or risks.\\n\\n## Output\\nReturn a structured recap: a short overview, a bulleted list of decisions, and an action-item table (task, owner, due date). Keep it grounded in the transcript content."},{"name":"extract-action-items","description":"Pull a Fireflies transcript and extract a clean list of action items with owners and due dates.","content":"# Extract Action Items\\n\\nUse Fireflies to capture follow-ups from a meeting.\\n\\n## Steps\\n1. Get the transcript for the meeting by its transcript ID.\\n2. Scan the sentences for commitments, assignments, and next steps.\\n3. Attribute each item to the speaker who owns it and capture any stated deadline.\\n\\n## Output\\nReturn a list of action items, each with the task, owner, and due date (or null). Add a one-line meeting summary at the top for context."},{"name":"create-meeting-soundbite","description":"Create a Fireflies soundbite (bite) clipping a key moment from a transcript for sharing.","content":"# Create Meeting Soundbite\\n\\nUse Fireflies to clip and share a highlight from a recorded meeting.\\n\\n## Steps\\n1. Get the transcript and find the start and end timestamps of the moment to clip.\\n2. Use Create Bite with the transcript ID and the chosen time range.\\n3. Confirm the bite was created and capture its identifier or link.\\n\\n## Output\\nReturn the soundbite identifier or shareable link plus a short caption describing the clipped moment."}],"templates":[{"title":"Attio call-summary updater","prompt":"Create a workflow that runs after a Fireflies sales call, summarizes the transcript into a deal-ready summary, and updates the matching Attio deal record.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"attio","name":"Attio"}]},{"title":"Fireflies meeting recap to Slack","prompt":"Build a workflow that runs when a Fireflies recording finishes, pulls the transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"slack","name":"Slack"}]},{"title":"Fireflies CRM updater","prompt":"Create a workflow that runs after a Fireflies sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Fireflies action-item ticket creator","prompt":"Build a workflow that extracts action items from a Fireflies meeting transcript, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"linear","name":"Linear"},{"id":"asana","name":"Asana"}]},{"title":"Fireflies customer-quote miner","prompt":"Create a workflow that processes Fireflies transcripts for customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.","integrations":[{"id":"fireflies","name":"Fireflies"}]},{"title":"Fireflies talk-ratio coach","prompt":"Build a scheduled weekly workflow that pulls Fireflies sales-call analytics per rep — talk ratio, longest monologue, question rate — and posts a coaching digest to managers.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"slack","name":"Slack"}]},{"title":"Fireflies + Notion meeting notes","prompt":"Create a workflow that watches Fireflies recordings, generates a polished meeting-notes page in Notion under the right team space, and links the recording.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"notion","name":"Notion"}]},{"title":"Fireflies competitor-mention tracker","prompt":"Build a workflow that scans Fireflies sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts notable patterns to Slack weekly.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"slack","name":"Slack"}]},{"title":"Word meeting-notes writer","prompt":"Build a workflow that takes a Fireflies meeting transcript, summarizes the decisions and action items, and creates a formatted Word document in the team OneDrive folder.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"onedrive","name":"OneDrive"}]},{"title":"Pipedrive call-summary updater","prompt":"Build a workflow that runs after a Fireflies sales call, summarizes the transcript, and updates the matching Pipedrive deal with the call summary and next steps.","integrations":[{"id":"fireflies","name":"Fireflies"},{"id":"pipedrive","name":"Pipedrive"}]}]},{"id":"fivetran","type":"fivetran","slug":"fivetran","name":"Fivetran","description":"Manage Fivetran connections, syncs, and transformations","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/fivetran","authType":"oauth","connections":[{"id":"fivetran-service-account","kind":"service_account","providerId":"fivetran-service-account","label":"Add API key","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/fivetran","fields":[{"id":"clientId","label":"API key","placeholder":"Paste the API key","secret":true,"hint":"In Fivetran, click your username, then API Key > Generate API key. The key acts with your Fivetran permissions."},{"id":"clientSecret","label":"API secret","placeholder":"Paste the API secret","secret":true}]}],"operations":[{"name":"List Connections","description":"List Fivetran connections with their sync state, schedule, and last success or failure, optionally filtered by group or schema name."},{"name":"Get Connection","description":"Get a Fivetran connection, including its setup, sync, and update state, open tasks and warnings, and schedule."},{"name":"Create Connection","description":"Create a Fivetran connection in a group. The config object holds the connector-specific settings and the destination naming: schema for most connectors, schema_prefix for databases, or schema and table for file connectors."},{"name":"Update Connection","description":"Update a Fivetran connection: pause or resume it, change its sync frequency or schedule, or update its configuration."},{"name":"Pause Connection","description":""},{"name":"Resume Connection","description":""},{"name":"Delete Connection","description":"Delete a Fivetran connection. This cannot be undone."},{"name":"Sync Connection","description":"Start an incremental sync of a Fivetran connection now, without changing its schedule."},{"name":"Re-sync Connection","description":"Run a full historical re-sync of a Fivetran connection, or only of the tables listed in scope. Fivetran returns 409 if a running sync cannot finish first."},{"name":"Re-sync Tables","description":"Run a historical re-sync of specific tables in a Fivetran connection without changing its schedule."},{"name":"Run Connection Setup Tests","description":"Run the setup tests of a Fivetran connection without changing its configuration, and return each test result."},{"name":"Get Sync History","description":"List the recent syncs of a Fivetran connection with their outcome, failure reason, and data volume per stage. The time window is at most 7 days and defaults to the last hour."},{"name":"Get Connection Warnings","description":"List the active warnings on a Fivetran connection, grouped by destination table."},{"name":"Get Schema Config","description":"Get the schemas, tables, and columns a Fivetran connection syncs, and whether each is enabled."},{"name":"Reload Schema","description":"Reload the schema config of a Fivetran connection from its source to pick up new schemas, tables, and columns. Large sources can take a long time."},{"name":"Update Table Sync","description":"Enable or disable syncing of one table in a Fivetran connection, and optionally change its sync mode."},{"name":"Update Schema Sync","description":"Enable or disable syncing of one schema in a Fivetran connection, optionally changing several of its tables at once."},{"name":"Update Schema Config","description":"Update how a Fivetran connection handles new schemas, tables, and columns, and enable or disable schemas and tables in one call."},{"name":"Create Connect Card","description":"Generate a Connect Card link that lets someone authorize and finish setting up a Fivetran connection in a Fivetran-hosted form."},{"name":"List Groups","description":"List the groups in the Fivetran account. Each group pairs with one destination, so the group ID is also the destination ID."},{"name":"Get Group","description":"Get a Fivetran group by ID."},{"name":"Create Group","description":"Create a Fivetran group. Each group holds one destination, so create the group first, then its destination."},{"name":"List Destinations","description":"List the destinations in the Fivetran account, such as Databricks or Snowflake, with their region and setup status."},{"name":"Get Destination","description":"Get a Fivetran destination with its region, time zone, and setup status."},{"name":"Create Destination","description":"Create the destination for a Fivetran group, such as a Databricks workspace. The config object holds the destination-specific connection settings."},{"name":"Run Destination Setup Tests","description":"Run the setup tests of a Fivetran destination, such as a Databricks workspace, and return each test result."},{"name":"List Transformations","description":"List Fivetran transformations (dbt Core and Quickstart) with their status, schedule, and last run times."},{"name":"Get Transformation","description":"Get a Fivetran transformation with its status, schedule, and output models."},{"name":"Run Transformation","description":"Start a run of a Fivetran transformation now."},{"name":"Cancel Transformation","description":"Cancel a running Fivetran transformation."},{"name":"Get Account Info","description":"Get the Fivetran account and the user or system key that the API key belongs to."},{"name":"List Users","description":"List the users and service accounts in the Fivetran account with their role, status, and last login, for access reviews."},{"name":"List Connector Types","description":"List the source connector types available in Fivetran, with the service ID to use when creating a connection."},{"name":"Get Connector Type","description":"Get the configuration and authorization fields a Fivetran connector type takes, to build the config for Create Connection."}],"triggers":[{"id":"fivetran_sync_end","name":"Fivetran Sync Ended","description":"Trigger workflow when a connection sync finishes, succeeds, fails, or is rescheduled"},{"id":"fivetran_sync_start","name":"Fivetran Sync Started","description":"Trigger workflow when a connection starts syncing"},{"id":"fivetran_connection_failure","name":"Fivetran Connection Failed","description":"Trigger workflow when Fivetran fails to connect to a source"},{"id":"fivetran_connection_successful","name":"Fivetran Connection Succeeded","description":"Trigger workflow when Fivetran connects to a source successfully"},{"id":"fivetran_create_connector","name":"Fivetran Connection Created","description":"Trigger workflow when a connection is created"},{"id":"fivetran_edit_connector","name":"Fivetran Connection Edited","description":"Trigger workflow when connection credentials, sync frequency, or other settings change"},{"id":"fivetran_pause_connector","name":"Fivetran Connection Paused","description":"Trigger workflow when a connection is paused, by a user or automatically"},{"id":"fivetran_resume_connector","name":"Fivetran Connection Resumed","description":"Trigger workflow when a connection is resumed"},{"id":"fivetran_delete_connector","name":"Fivetran Connection Deleted","description":"Trigger workflow when a connection is deleted"},{"id":"fivetran_force_update_connector","name":"Fivetran Manual Sync Triggered","description":"Trigger workflow when someone triggers a manual sync of a connection"},{"id":"fivetran_resync_connector","name":"Fivetran Connection Re-sync Triggered","description":"Trigger workflow when a historical re-sync of a connection is triggered"},{"id":"fivetran_resync_table","name":"Fivetran Table Re-sync Triggered","description":"Trigger workflow when a historical re-sync of a table is triggered"},{"id":"fivetran_transformation_start","name":"Fivetran Transformation Started","description":"Trigger workflow when a transformation run starts"},{"id":"fivetran_transformation_succeeded","name":"Fivetran Transformation Succeeded","description":"Trigger workflow when a transformation run succeeds"},{"id":"fivetran_transformation_failed","name":"Fivetran Transformation Failed","description":"Trigger workflow when a transformation run fails"},{"id":"fivetran_webhook","name":"Fivetran All Events","description":"Trigger workflow on any Fivetran sync, connection, or transformation event"}],"skills":[{"name":"diagnose-failed-fivetran-sync","description":"Explain why a Fivetran connection is failing and what to do about it. Use when a sync_end event reports a failure or someone asks why data is stale.","content":"# Diagnose a Failed Fivetran Sync\\n\\nFind the cause of a failing or delayed Fivetran connection.\\n\\n## Steps\\n1. Get the connection and read its status: setupState, syncState, updateState, and any tasks or warnings.\\n2. Get the sync history for the last 24 hours and note failed syncs and their reasons.\\n3. Get the connection warnings to see table-level problems.\\n4. If setupState is broken, run the connection setup tests and report the failing test.\\n\\n## Output\\nThe connection, when it last succeeded, the failure reason, and the concrete fix (for example reconnect credentials, grant permissions, or re-sync a table)."},{"name":"pipeline-health-report","description":"Summarize the health of every Fivetran connection in an account or group. Use for daily data-platform reviews.","content":"# Pipeline Health Report\\n\\nReport which Fivetran pipelines are healthy and which need attention.\\n\\n## Steps\\n1. List connections, following nextCursor until every page is read, optionally filtered by group.\\n2. For each connection, note paused, setupState, syncState, updateState, succeededAt, and failedAt.\\n3. For connections that are broken, delayed, or failed after their last success, read their warnings.\\n\\n## Output\\nA table of connections needing attention with the reason, followed by a count of healthy connections."},{"name":"resync-fivetran-tables","description":"Re-sync specific tables or a whole Fivetran connection after a data issue. Use when data in the destination is missing or wrong.","content":"# Re-sync Fivetran Tables\\n\\nReload historical data for the affected tables only.\\n\\n## Steps\\n1. Read the connection schema config and confirm the schema and table names exactly as stored (they are case-sensitive).\\n2. Re-sync just those tables with Re-sync Tables, passing a map of schema to table names.\\n3. Only re-sync the whole connection when the issue spans most tables, since a full re-sync can take a long time.\\n\\n## Output\\nWhat was re-synced, and a note to check sync history once the historical sync finishes."},{"name":"onboard-fivetran-source","description":"Create a new Fivetran connection and hand the owner a Connect Card link to authorize it. Use when a team requests a new data source.","content":"# Onboard a Fivetran Source\\n\\nSet up a new source without sharing source credentials with the data team.\\n\\n## Steps\\n1. Find the connector type ID with List Connector Types.\\n2. Find the destination group with List Groups.\\n3. Create the connection paused, with a config that sets the destination schema name.\\n4. Create a Connect Card for the connection with a redirect URL, and send the link to the source owner.\\n\\n## Output\\nThe connection ID, schema name, and Connect Card link."},{"name":"audit-fivetran-access","description":"Review who can use the Fivetran account and which identities hold API keys. Use for periodic security access reviews.","content":"# Audit Fivetran Access\\n\\nCheck Fivetran users and service accounts for stale or risky access.\\n\\n## Steps\\n1. List users, following nextCursor through every page.\\n2. Flag suspended users that still have API keys, service accounts with API keys, and users whose last login is more than 90 days old.\\n3. Note each flagged identity’s role.\\n\\n## Output\\nA list of flagged identities with the reason and suggested action, and a count of identities reviewed."}],"templates":[{"title":"Failed sync triage","prompt":"Build a workflow triggered when a Fivetran sync ends with a failure that reads the connection, its active warnings, and the last day of sync history, has an agent explain the likely cause and fix, and posts the summary to the data team in Slack.","integrations":[{"id":"fivetran","name":"Fivetran"},{"id":"slack","name":"Slack"}]},{"title":"Security log ingestion monitor","prompt":"Create a scheduled workflow that lists the Fivetran connections feeding security logs from sources like Okta into Databricks, flags any that are paused, broken, or delayed, and opens a Jira ticket for each one so the SIEM pipeline never silently goes stale.","integrations":[{"id":"fivetran","name":"Fivetran"},{"id":"jira","name":"Jira"}]},{"title":"Run dbt after a sync","prompt":"Build a workflow that runs when a Fivetran sync finishes successfully and starts the matching Fivetran transformation, then reports when the transformation succeeds or fails.","integrations":[{"id":"fivetran","name":"Fivetran"}]},{"title":"Daily pipeline health digest","prompt":"Create a scheduled daily workflow that lists every Fivetran connection, collects its sync history and data volumes for the last day, and emails the data team a digest of failures, delays, and the largest loads.","integrations":[{"id":"fivetran","name":"Fivetran"},{"id":"gmail","name":"Gmail"}]},{"title":"Connection change audit log","prompt":"Build a workflow triggered by Fivetran connection created, edited, paused, resumed, and deleted events that records who changed what and when in a table, for a change-management audit trail.","integrations":[{"id":"fivetran","name":"Fivetran"}]},{"title":"Fivetran access review","prompt":"Create a scheduled monthly workflow that lists Fivetran users and service accounts, flags suspended accounts that still have API keys and users who have not logged in for 90 days, and writes the review to a table for the security team.","integrations":[{"id":"fivetran","name":"Fivetran"}]},{"title":"Self-serve source onboarding","prompt":"Build a workflow that takes a requested source type and team, creates a paused Fivetran connection in the right group, generates a Connect Card link, and sends it to the requester in Slack so they can authorize the source themselves.","integrations":[{"id":"fivetran","name":"Fivetran"},{"id":"slack","name":"Slack"}]}]},{"id":"flint","type":"flint","slug":"flint","name":"Flint","description":"Run background agent tasks on your Flint sites","category":"Marketing","docsUrl":"https://docs.sim.ai/integrations/flint","authType":"api-key","connections":[],"operations":[{"name":"Create Task","description":"Start a background Flint agent task that modifies a site from a natural-language prompt."},{"name":"Generate Pages","description":"Start a background Flint agent task that generates up to 10 pages from a template page."},{"name":"Get Task","description":"Get the status and results of a background Flint agent task."}],"triggers":[],"skills":[{"name":"run-flint-site-update","description":"Start a Flint agent task from a prompt and track it to completion.","content":"# Run a Flint Site Update\\n\\nModify a Flint site with a natural-language prompt.\\n\\n## Steps\\n1. Choose the Create Task operation.\\n2. Enter the Site ID and write a clear Prompt describing the change (for example \\"Add a new About page with a team section\\").\\n3. Optionally enable Publish on Completion to push the change live automatically.\\n4. Save the returned taskId, then poll with the Get Task operation until status is completed or failed.\\n\\n## Output\\nReturn the task status and, when completed, the created/modified pages with their preview, edit, and published URLs."},{"name":"generate-pages-from-template","description":"Generate up to 10 Flint pages from a template page in one task.","content":"# Generate Pages from a Template\\n\\nCreate a batch of pages that share a template layout.\\n\\n## Steps\\n1. Choose the Generate Pages operation.\\n2. Enter the Site ID and the Template Page Slug of the existing template (for example /case-studies/template).\\n3. Provide the Pages JSON array with 1-10 items, each containing targetPageSlug and context.\\n4. Poll the task with Get Task until it completes.\\n\\n## Output\\nReturn the list of created pages with their slugs and preview, edit, and published URLs."},{"name":"check-flint-task-status","description":"Check whether a Flint agent task is running, completed, or failed.","content":"# Check a Flint Task\\n\\nLook up the state and results of a background task.\\n\\n## Steps\\n1. Choose the Get Task operation.\\n2. Enter the Task ID returned when the task was created.\\n3. Branch on the returned status: running means keep polling, completed exposes pagesCreated/pagesModified/pagesDeleted, failed exposes errorMessage.\\n\\n## Output\\nReturn the task status plus page URLs on success or the error message on failure."}],"templates":[{"title":"Flint programmatic SEO pages","prompt":"Build a workflow that reads a table of target keywords and customer data, then uses Flint to generate a landing page for each row from a template page, publishing them automatically.","integrations":[{"id":"flint","name":"Flint"}]},{"title":"Flint case-study generator","prompt":"Create a workflow triggered when a deal is marked closed-won that pulls the customer details, drafts case-study context with an agent, and uses Flint to generate a case-study page from the template.","integrations":[{"id":"flint","name":"Flint"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Flint site update from Slack","prompt":"Build a workflow triggered by a Slack message in the #website channel that turns the request into a Flint agent task prompt, starts the task, and replies in the thread with the task ID.","integrations":[{"id":"flint","name":"Flint"},{"id":"slack","name":"Slack"}]},{"title":"Flint task status monitor","prompt":"Create a scheduled workflow that reads pending Flint task IDs from a table, checks each task status with Flint, writes preview and published URLs back to the row when completed, and flags failures.","integrations":[{"id":"flint","name":"Flint"}]},{"title":"Flint changelog page publisher","prompt":"Build a workflow triggered when a new release is tagged in GitHub that summarizes the changes with an agent and starts a Flint task to add the release notes to the changelog page, publishing on completion.","integrations":[{"id":"flint","name":"Flint"},{"id":"github","name":"GitHub"}]},{"title":"Flint failed-task alerts","prompt":"Create a workflow that checks a Flint task status and, when the task has failed, posts the task ID and error message to a Slack channel so the team can rerun it.","integrations":[{"id":"flint","name":"Flint"},{"id":"slack","name":"Slack"}]},{"title":"Flint location pages from a spreadsheet","prompt":"Build a workflow that reads city and service data from Google Sheets and uses Flint to generate a local landing page per city from a template, then writes each published URL back to the sheet.","integrations":[{"id":"flint","name":"Flint"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Flint content refresh agent","prompt":"Create a scheduled workflow that reviews outdated pages listed in a table, drafts updated copy instructions with an agent, and starts a Flint task per page to refresh the content without publishing until reviewed.","integrations":[{"id":"flint","name":"Flint"}]}]},{"id":"gamma","type":"gamma","slug":"gamma","name":"Gamma","description":"Generate presentations, documents, and webpages with AI","category":"Marketing","docsUrl":"https://docs.sim.ai/integrations/gamma","authType":"api-key","connections":[],"operations":[{"name":"Generate","description":"Generate a new Gamma presentation, document, webpage, or social post from text input."},{"name":"Generate from Template","description":"Generate a new Gamma by adapting an existing template with a prompt."},{"name":"Check Status","description":"Check the status of a Gamma generation job. Returns the gamma URL when completed, or error details if failed."},{"name":"List Themes","description":"List available themes in your Gamma workspace. Returns theme IDs, names, and keywords for styling."},{"name":"List Folders","description":"List available folders in your Gamma workspace. Returns folder IDs and names for organizing generated content."}],"triggers":[],"skills":[{"name":"generate-presentation","description":"Generate a polished presentation deck from a topic or outline using Gamma.","content":"# Generate Presentation\\n\\nUse Gamma to turn a topic or outline into a finished presentation.\\n\\n## Steps\\n1. Gather the source content: a topic, a brief, or a structured outline of the points to cover.\\n2. Call Gamma to generate a presentation, choosing the number of cards and a theme that fits the audience.\\n3. Request an export format (such as PDF or PPTX) if a downloadable file is needed.\\n\\n## Output\\nReturn the link to the generated Gamma and, if requested, the export file URL. Summarize the deck structure (titles per card) so the requester can review before sharing."},{"name":"generate-document","description":"Generate a structured document or webpage from input text using Gamma.","content":"# Generate Document\\n\\nUse Gamma to produce a formatted document or webpage from raw input.\\n\\n## Steps\\n1. Provide the input text and choose the output format (document or webpage).\\n2. Call Gamma to generate the content, setting a theme and the desired length or number of cards.\\n3. Capture the resulting Gamma URL and any export URL.\\n\\n## Output\\nReturn the generated Gamma link plus a short outline of the sections it produced. Include the export file URL if one was requested."},{"name":"personalize-deck-from-template","description":"Adapt an existing Gamma template into a prospect or client-specific deck with Generate from Template.","content":"# Personalize Deck From Template\\n\\nUse Gamma to scale on-brand, personalized decks from a proven template.\\n\\n## Steps\\n1. Identify the template gamma ID to adapt (a master pitch or proposal deck) and collect the recipient details and the angle to tailor for.\\n2. Use Generate from Template with that template gamma ID and a prompt that retargets the audience, swaps in the recipient name and use case, and adjusts emphasis (for example highlight compliance for a healthcare buyer). The template structure is preserved by default.\\n3. Request an export (PDF or PPTX) if a downloadable file is needed.\\n\\n## Output\\nReturn the generated Gamma link and any export URL. Note the recipient it was generated for so it can be attached to the right CRM record or email."},{"name":"check-generation-status","description":"Poll a Gamma generation job by its generation ID and return the final deck link once ready.","content":"# Check Generation Status\\n\\nGamma generation is asynchronous, so use this to wait for a deck to finish.\\n\\n## Steps\\n1. Take the generation ID returned when the deck was requested.\\n2. Use Check Status to read the current status of the job.\\n3. Repeat until the status is completed (or failed), respecting a sensible polling interval.\\n\\n## Output\\nReturn the final status and, on success, the Gamma URL and any export URL. On failure, return the error details so the caller can retry or adjust the request."}],"templates":[{"title":"Brandfetch deck personalizer","prompt":"Build a workflow that on a new opportunity pulls the prospect’s brand assets from Brandfetch, generates a personalized pitch deck with their logo and colors, and attaches it.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"brandfetch","name":"Brandfetch"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Gamma deck from doc","prompt":"Build a workflow that takes a Google Docs source, generates a Gamma deck from the structure and bullet points, and emails the deck link to the author for polish.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"google_docs","name":"Google Docs"},{"id":"gmail","name":"Gmail"}]},{"title":"Gamma customer-story builder","prompt":"Create a workflow that takes a customer-story brief, generates a Gamma deck with the challenge, solution, results, and pull quote, and shares the link with the marketing team in Slack.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"slack","name":"Slack"}]},{"title":"Gamma weekly all-hands deck","prompt":"Build a scheduled weekly workflow that pulls KPIs from tables, generates a Gamma all-hands deck with the latest numbers, and posts the link to the leadership Slack channel.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"slack","name":"Slack"}]},{"title":"Gamma onboarding training","prompt":"Create a workflow that generates a Gamma onboarding training deck from a knowledge base topic, including interactive quizzes at the end, and shares it with the new hire.","integrations":[{"id":"gamma","name":"Gamma"}]},{"title":"Gamma sales pitch personalizer","prompt":"Build a workflow triggered by a Salesforce opportunity that generates a Gamma sales pitch deck personalized to the account, embeds the deck link in the opportunity, and notifies the rep.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Gamma weekly content carousel","prompt":"Create a scheduled workflow that turns the week’s top blog posts into a multi-slide Gamma carousel, then queues the export for X and LinkedIn posting.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"x","name":"X"},{"id":"linkedin","name":"LinkedIn"}]},{"title":"Gamma RFP responder","prompt":"Build a workflow that takes an inbound RFP, generates a Gamma response deck using a knowledge base of past proposals, and attaches the deck link to the linked HubSpot deal.","integrations":[{"id":"gamma","name":"Gamma"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"github","type":"github_v2","slug":"github","name":"GitHub","description":"Interact with GitHub or trigger workflows from GitHub events","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/github","authType":"api-key","connections":[],"operations":[{"name":"Get PR details","description":"Fetch PR details including diff and files changed"},{"name":"Create PR comment","description":"Create comments on GitHub PRs"},{"name":"Get repository info","description":"Read GitHub repository metadata, including stars, forks, issues, and primary language. Requires a GitHub token with access to the repository."},{"name":"Get latest commit","description":"Retrieve the latest commit from a GitHub repository"},{"name":"Create issue comment","description":"Create a comment on a GitHub issue"},{"name":"List issue comments","description":"List all comments on a GitHub issue"},{"name":"Update comment","description":"Update an existing comment on a GitHub issue or pull request"},{"name":"Delete comment","description":"Delete a comment on a GitHub issue or pull request"},{"name":"List PR comments","description":"List all review comments on a GitHub pull request"},{"name":"Create pull request","description":"Create a new pull request in a GitHub repository"},{"name":"Update pull request","description":"Update an existing pull request in a GitHub repository"},{"name":"Merge pull request","description":"Merge a pull request in a GitHub repository"},{"name":"List pull requests","description":"List pull requests in a GitHub repository"},{"name":"Get PR files","description":"Get the list of files changed in a pull request"},{"name":"Close pull request","description":"Close a pull request in a GitHub repository"},{"name":"Request PR reviewers","description":"Request reviewers for a pull request"},{"name":"Create PR review","description":"Submit a review for a pull request. Use APPROVE, REQUEST_CHANGES, or COMMENT. A body is required for REQUEST_CHANGES and COMMENT reviews."},{"name":"Get file content","description":"Get the content of a file from a GitHub repository. Supports files up to 1MB. Content is returned decoded and human-readable."},{"name":"Create file","description":"Create a new file in a GitHub repository. The file content will be automatically Base64 encoded. Supports files up to 1MB."},{"name":"Update file","description":"Update an existing file in a GitHub repository. Requires the file SHA. Content will be automatically Base64 encoded. Supports files up to 1MB."},{"name":"Delete file","description":"Delete a file from a GitHub repository. Requires the file SHA. This operation cannot be undone through the API."},{"name":"Get directory tree","description":"Get the contents of a directory in a GitHub repository. Returns a list of files and subdirectories. Use empty path or omit to get root directory contents."},{"name":"Get README","description":"Get the preferred README for a GitHub repository, with its content decoded to plain text."},{"name":"List tags","description":"List tags for a GitHub repository. Returns tag names with their commit SHA and download URLs."},{"name":"List branches","description":"List all branches in a GitHub repository. Optionally filter by protected status and control pagination."},{"name":"Get branch","description":"Get detailed information about a specific branch in a GitHub repository, including commit details and protection status."},{"name":"Create branch","description":"Create a new branch in a GitHub repository by creating a git reference pointing to a specific commit SHA."},{"name":"Delete branch","description":"Delete a branch from a GitHub repository by removing its git reference. Protected branches cannot be deleted."},{"name":"Get branch protection","description":"Get the branch protection rules for a specific branch, including status checks, review requirements, and restrictions."},{"name":"Update branch protection","description":"Update branch protection rules for a specific branch, including status checks, review requirements, admin enforcement, and push restrictions."},{"name":"Create issue","description":"Create a new issue in a GitHub repository"},{"name":"Update issue","description":"Update an existing issue in a GitHub repository"},{"name":"List issues","description":"List issues in a GitHub repository. Note: This includes pull requests as PRs are considered issues in GitHub"},{"name":"Get issue","description":"Get detailed information about a specific issue in a GitHub repository"},{"name":"Close issue","description":"Close an issue in a GitHub repository"},{"name":"Add issue labels","description":"Add labels to an issue in a GitHub repository"},{"name":"Remove issue label","description":"Remove a label from an issue in a GitHub repository"},{"name":"Add issue assignees","description":"Add assignees to an issue in a GitHub repository"},{"name":"Create release","description":"Create a new release for a GitHub repository. Specify tag name, target commit, title, description, and whether it should be a draft or prerelease."},{"name":"Update release","description":"Update an existing GitHub release. Modify tag name, target commit, title, description, draft status, or prerelease status."},{"name":"List releases","description":"List all releases for a GitHub repository. Returns release information including tags, names, and download URLs."},{"name":"Get release","description":"Get detailed information about a specific GitHub release by ID. Returns release metadata including assets and download URLs."},{"name":"Get latest release","description":"Get the latest published, non-draft, non-prerelease release for a GitHub repository. Returns release metadata including assets and download URLs."},{"name":"Delete release","description":"Delete a GitHub release by ID. This permanently removes the release but does not delete the associated Git tag."},{"name":"List workflows","description":"List all workflows in a GitHub repository. Returns workflow details including ID, name, path, state, and badge URL."},{"name":"Get workflow","description":"Get details of a specific GitHub Actions workflow by ID or filename. Returns workflow information including name, path, state, and badge URL."},{"name":"Trigger workflow","description":"Trigger a workflow dispatch event for a GitHub Actions workflow. The workflow must have a workflow_dispatch trigger configured. Returns 204 No Content on success."},{"name":"List workflow runs","description":"List workflow runs for a repository, or for a single workflow when a workflow ID or filename is given. Supports filtering by actor, branch, event, and status. Returns run details including status, conclusion, and links."},{"name":"Get workflow run","description":"Get detailed information about a specific workflow run by ID. Returns status, conclusion, timing, and links to the run."},{"name":"Cancel workflow run","description":"Cancel a workflow run. Returns 202 Accepted if cancellation is initiated, or 409 Conflict if the run cannot be cancelled (already completed)."},{"name":"Rerun workflow","description":"Rerun a workflow run. Optionally enable debug logging for the rerun. Returns 201 Created on success."},{"name":"List projects","description":"List GitHub Projects V2 for an organization or user. Returns up to 20 projects with their details including ID, title, number, URL, and status."},{"name":"Get project","description":"Get detailed information about a specific GitHub Project V2 by its number. Returns project details including ID, title, description, URL, and status."},{"name":"Create project","description":"Create a new GitHub Project V2. Requires the owner Node ID (not login name). Returns the created project with ID, title, and URL."},{"name":"Update project","description":"Update an existing GitHub Project V2. Can update title, description, visibility (public), or status (closed). Requires the project Node ID."},{"name":"Delete project","description":"Delete a GitHub Project V2. This action is permanent and cannot be undone. Requires the project Node ID."},{"name":"Search code","description":"Search for code across GitHub repositories. Use qualifiers like repo:owner/name, language:js, path:src, extension:py"},{"name":"Search commits","description":"Search for commits across GitHub. Use qualifiers like repo:owner/name, author:user, committer:user, author-date:>2023-01-01"},{"name":"Search issues","description":"Search for issues and pull requests across GitHub. Use qualifiers like repo:owner/name, is:issue, is:pr, state:open, label:bug, author:user"},{"name":"Search repositories","description":"Search for repositories across GitHub. Use qualifiers like language:python, stars:>1000, topic:react, user:owner, org:name"},{"name":"Search users","description":"Search for users and organizations on GitHub. Use qualifiers like type:user, type:org, followers:>1000, repos:>10, location:city"},{"name":"List commits","description":"List commits in a repository with optional filtering by SHA, path, author, committer, or date range"},{"name":"Get commit","description":"Get detailed information about a specific commit including files changed and stats"},{"name":"Compare commits","description":"Compare two commits or branches to see the diff, commits between them, and changed files"},{"name":"Create gist","description":"Create a new gist with one or more files"},{"name":"Get gist","description":"Get a gist by ID including its file contents"},{"name":"List gists","description":"List gists for a user or the authenticated user"},{"name":"Update gist","description":"Update a gist description or files. To delete a file, set its value to null in files object"},{"name":"Delete gist","description":"Delete a gist by ID"},{"name":"Fork gist","description":"Fork a gist to create your own copy"},{"name":"Star gist","description":"Star a gist"},{"name":"Unstar gist","description":"Unstar a gist"},{"name":"Fork repository","description":"Fork a repository to your account or an organization"},{"name":"List forks","description":"List forks of a repository"},{"name":"Create milestone","description":"Create a milestone in a repository"},{"name":"Get milestone","description":"Get a specific milestone by number"},{"name":"List milestones","description":"List milestones in a repository"},{"name":"Update milestone","description":"Update a milestone in a repository"},{"name":"Delete milestone","description":"Delete a milestone from a repository"},{"name":"Add issue reaction","description":"Add a reaction to an issue"},{"name":"Remove issue reaction","description":"Remove a reaction from an issue"},{"name":"Add comment reaction","description":"Add a reaction to an issue comment"},{"name":"Remove comment reaction","description":"Remove a reaction from an issue comment"},{"name":"Star repository","description":"Star a repository"},{"name":"Unstar repository","description":"Remove star from a repository"},{"name":"Check if starred","description":"Check if you have starred a repository"},{"name":"List stargazers","description":"List users who have starred a repository"}],"triggers":[{"id":"github_issue_opened","name":"GitHub Issue Opened","description":"Trigger workflow when a new issue is opened in a GitHub repository"},{"id":"github_issue_closed","name":"GitHub Issue Closed","description":"Trigger workflow when an issue is closed in a GitHub repository"},{"id":"github_issue_comment","name":"GitHub Issue Comment","description":"Trigger workflow when a comment is added to an issue (not pull requests)"},{"id":"github_pr_opened","name":"GitHub PR Opened","description":"Trigger workflow when a new pull request is opened in a GitHub repository"},{"id":"github_pr_closed","name":"GitHub PR Closed","description":"Trigger workflow when a pull request is closed without being merged (e.g., abandoned) in a GitHub repository"},{"id":"github_pr_merged","name":"GitHub PR Merged","description":"Trigger workflow when a pull request is successfully merged in a GitHub repository"},{"id":"github_pr_comment","name":"GitHub PR Comment","description":"Trigger workflow when a comment is added to a pull request in a GitHub repository"},{"id":"github_pr_reviewed","name":"GitHub PR Reviewed","description":"Trigger workflow when a pull request review is submitted, edited, or dismissed in a GitHub repository"},{"id":"github_push","name":"GitHub Push","description":"Trigger workflow when code is pushed to a repository"},{"id":"github_release_published","name":"GitHub Release Published","description":"Trigger workflow when a new release is published in a GitHub repository"},{"id":"github_workflow_run","name":"GitHub Actions Workflow Run","description":"Trigger workflow when a GitHub Actions workflow run is requested, in progress, or completed"}],"skills":[{"name":"review-pull-request","description":"Fetch a GitHub PR, its changed files, and diff, then post a structured review comment.","content":"# Review Pull Request\\n\\nUse GitHub to read a pull request and leave a useful review.\\n\\n## Steps\\n1. Get PR details for the given owner, repo, and PR number to read the title, description, and status.\\n2. Get the PR files to see the changed paths and diffs.\\n3. Assess the changes for correctness, missing tests, and risky edits.\\n4. Post a PR comment summarizing the review with specific, actionable feedback.\\n\\n## Output\\nConfirm the comment was posted and return a short summary of the findings: what looks good, what needs changes, and any blocking concerns."},{"name":"triage-new-issue","description":"Read a GitHub issue, classify it, apply labels, and assign it to the right owner.","content":"# Triage New Issue\\n\\nUse GitHub to triage an incoming issue.\\n\\n## Steps\\n1. Get the issue by owner, repo, and issue number to read its title and body.\\n2. Classify it (bug, feature, question, docs) and judge its severity.\\n3. Add the appropriate labels with Add issue labels.\\n4. Assign the issue to the relevant owner with Add issue assignees.\\n\\n## Output\\nReturn the applied labels, the assignee, and a one-line triage summary. If the issue lacks reproduction details, note what information is missing."},{"name":"summarize-repo-activity","description":"Pull recent GitHub PRs, commits, and issues for a repo and produce a concise activity digest.","content":"# Summarize Repo Activity\\n\\nUse GitHub to build a status digest for a repository.\\n\\n## Steps\\n1. List open pull requests and recent issues for the owner and repo.\\n2. Get the latest commit to anchor the digest in time.\\n3. Group activity into in-progress work, newly opened items, and anything stalled or awaiting review.\\n\\n## Output\\nReturn a digest with three sections: open PRs (title, author, status), notable issues, and the latest commit. Keep it short enough to drop into a standup or Slack channel."},{"name":"open-pull-request-with-changes","description":"Create a branch, commit a file change, and open a GitHub pull request for review.","content":"# Open Pull Request With Changes\\n\\nUse GitHub to land a change as a reviewable PR.\\n\\n## Steps\\n1. Create a new branch off the default branch with Create branch.\\n2. Create or update the target file on that branch with Create file or Update file, including a clear commit message.\\n3. Open a pull request from the new branch with Create pull request, writing a descriptive title and body.\\n4. Optionally request reviewers with Request PR reviewers.\\n\\n## Output\\nReturn the new PR number and URL, the branch name, and the files changed so the requester can track it to merge."}],"templates":[{"title":"AppConfig bootstrap from GitHub","prompt":"Build a workflow triggered when a config file changes in a GitHub pull request that creates a new hosted AWS AppConfig configuration version from the file contents and deploys it to a staging environment for validation.","integrations":[{"id":"github","name":"GitHub"},{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"Asana bug intake triager","prompt":"Build a workflow that searches Asana for newly created tasks in the bug project, classifies each by severity and component with an agent, adds a triage comment, and creates a matching GitHub issue for engineering pickup.","integrations":[{"id":"github","name":"GitHub"},{"id":"asana","name":"Asana"}]},{"title":"ClickUp bug triager","prompt":"Create a workflow that reads newly reported bugs from a ClickUp list, classifies each by severity and component with an agent, sets the priority and tags accordingly, and opens a matching GitHub issue for engineering.","integrations":[{"id":"github","name":"GitHub"},{"id":"clickup","name":"ClickUp"}]},{"title":"CloudFormation template validator","prompt":"Create a workflow triggered when a CloudFormation template is changed in a GitHub pull request. Pull the template, validate it via the CloudFormation API, summarize any syntax or structural errors, and post the validation result as a PR comment to block merges on broken templates.","integrations":[{"id":"github","name":"GitHub"},{"id":"cloudformation","name":"CloudFormation"}]},{"title":"Cursor issue-to-PR pipeline","prompt":"Create a workflow that fires when a GitHub issue is labeled \\"auto-fix\\", crafts a precise prompt from the issue description, launches a Cursor cloud agent on the repository, monitors progress, and comments on the issue with the resulting pull request and conversation summary.","integrations":[{"id":"github","name":"GitHub"},{"id":"cursor","name":"Cursor"}]},{"title":"Cursor test-fix delegator","prompt":"Build a workflow triggered by a failing GitHub Actions test run that extracts the failing test name and error, launches a targeted Cursor cloud agent to fix only that test, downloads the artifact diff when ready, and replies on the failed run with the proposed patch.","integrations":[{"id":"github","name":"GitHub"},{"id":"cursor","name":"Cursor"}]},{"title":"Cursor refactor follow-up loop","prompt":"Create a workflow that picks up review comments on a Cursor-authored pull request, formulates each comment as a follow-up instruction, sends them to the originating Cursor cloud agent, and waits for the updated diff before re-requesting review.","integrations":[{"id":"github","name":"GitHub"},{"id":"cursor","name":"Cursor"}]},{"title":"Daytona PR test runner","prompt":"Create a workflow triggered by a GitHub pull request that creates a Daytona sandbox, clones the repository at the PR branch, runs the test suite with an execute command, and posts the pass/fail summary back to the PR.","integrations":[{"id":"github","name":"GitHub"},{"id":"daytona","name":"Daytona"}]},{"title":"Dub release announcement linker","prompt":"Create a workflow triggered by a GitHub release that creates a Dub short link for the release notes URL, posts the short link to the marketing Slack channel, and stores the mapping of release tag to short link in a tracking table.","integrations":[{"id":"github","name":"GitHub"},{"id":"dub","name":"Dub"},{"id":"slack","name":"Slack"}]},{"title":"Dynatrace deploy marker","prompt":"Create a workflow that runs when a GitHub release is published and ingests a CUSTOM_DEPLOYMENT event into Dynatrace with the version, commit, and service entity selector, so metric changes can be correlated with the deploy.","integrations":[{"id":"github","name":"GitHub"},{"id":"dynatrace","name":"Dynatrace"}]},{"title":"Flint changelog page publisher","prompt":"Build a workflow triggered when a new release is tagged in GitHub that summarizes the changes with an agent and starts a Flint task to add the release notes to the changelog page, publishing on completion.","integrations":[{"id":"github","name":"GitHub"},{"id":"flint","name":"Flint"}]},{"title":"GitHub PR review assistant","prompt":"Create a knowledge base connected to my GitHub repo so it stays synced with my style guide and coding standards. Then build a workflow that reviews new pull requests against it, checks for common issues and security vulnerabilities, and posts a review comment with specific suggestions.","integrations":[{"id":"github","name":"GitHub"}]},{"title":"GitHub changelog generator","prompt":"Build a scheduled workflow that runs every Friday, pulls all merged PRs from GitHub for the week, categorizes changes as features, fixes, or improvements, and generates a user-facing changelog document with clear descriptions.","integrations":[{"id":"github","name":"GitHub"}]},{"title":"GitHub docs auto-updater","prompt":"Create a knowledge base connected to my GitHub repository so code and docs stay synced. Then build a scheduled weekly workflow that detects API changes, compares them against the knowledge base to find outdated documentation, and either updates Notion pages directly or creates Linear tickets for the needed changes.","integrations":[{"id":"github","name":"GitHub"},{"id":"notion","name":"Notion"},{"id":"linear","name":"Linear"}]},{"title":"GitHub repository search","prompt":"Create a knowledge base connected to my GitHub repository so all source files, READMEs, and pull request descriptions are automatically synced and searchable. Then build an agent I can ask things like \\"where do we handle Stripe webhooks?\\" or \\"what changed in the auth module last month?\\" and get answers with file and PR citations.","integrations":[{"id":"github","name":"GitHub"}]},{"title":"GitHub release notes drafter","prompt":"Build a workflow triggered when a GitHub release tag is created. Pull every merged pull request and commit since the previous tag, group them by feature, fix, and chore, draft customer-facing release notes, and post the draft as a comment on the release for final approval.","integrations":[{"id":"github","name":"GitHub"}]},{"title":"GitHub weekly team digest","prompt":"Build a scheduled workflow that runs every Friday, pulls the week\'s GitHub commits, closed Linear issues, and key Slack conversations, then emails a formatted weekly summary to the team.","integrations":[{"id":"github","name":"GitHub"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Link GitHub pull requests to Jira tickets","prompt":"Build a workflow that monitors GitHub pull requests and automatically transitions linked Jira issues when PRs are opened or merged, keeping your project board accurate without any manual updates.","integrations":[{"id":"github","name":"GitHub"},{"id":"jira","name":"Jira"}]},{"title":"Sync GitHub events with Linear issues","prompt":"Build a workflow that creates Linear issues from GitHub pull requests and commits, and automatically updates their status when a PR is merged.","integrations":[{"id":"github","name":"GitHub"},{"id":"linear","name":"Linear"}]},{"title":"Get GitHub activity alerts in Slack","prompt":"Create an agent that watches GitHub for new pull requests, commits, issues, or deployments and posts formatted Slack notifications so your engineering team never misses a critical event.","integrations":[{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]},{"title":"PageSpeed pre-deploy gate","prompt":"Build a workflow triggered by a Vercel preview deployment that runs Google PageSpeed Insights against the preview URL, posts the scores as a GitHub PR comment, and fails the check if scores drop below threshold.","integrations":[{"id":"github","name":"GitHub"},{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"vercel","name":"Vercel"}]},{"title":"Greenhouse candidate enricher","prompt":"Create a workflow that watches for new Greenhouse candidates, enriches each profile with LinkedIn background, GitHub activity, and public writing, and writes a structured research summary to a recruiting table for recruiters to review.","integrations":[{"id":"github","name":"GitHub"},{"id":"greenhouse","name":"Greenhouse"},{"id":"linkedin","name":"LinkedIn"}]},{"title":"Greptile PR review context","prompt":"Build a workflow that takes a pull request, asks Greptile how the changed code interacts with the rest of the repository, and writes a review comment summarizing impact and risks with cited files.","integrations":[{"id":"github","name":"GitHub"},{"id":"greptile","name":"Greptile"}]},{"title":"Infisical CI sync","prompt":"Build a workflow that mirrors Infisical secrets into GitHub Actions environments for CI deploys, keeping the secret store as the single source of truth.","integrations":[{"id":"github","name":"GitHub"},{"id":"infisical","name":"Infisical"}]},{"title":"Logfire release regression check","prompt":"Create a workflow that fires after each deploy, waits for a soak period, then searches Logfire for new exception types in the production environment that were not present before the release, and comments the diff on the GitHub pull request that shipped it.","integrations":[{"id":"github","name":"GitHub"},{"id":"logfire","name":"Logfire"}]},{"title":"LogRocket release tagging on deploy","prompt":"Build a workflow that runs after a GitHub deployment succeeds, registers the deployed version as a LogRocket release so stack traces decode against it, and posts the tagged version to the release channel in Slack.","integrations":[{"id":"github","name":"GitHub"},{"id":"logrocket","name":"LogRocket"},{"id":"slack","name":"Slack"}]},{"title":"Claude Managed Agents PR reviewer","prompt":"Create a workflow that triggers on a new GitHub pull request, runs a Claude Managed Agents session over the diff, and posts the findings back as a review comment on the PR.","integrations":[{"id":"github","name":"GitHub"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Microsoft Teams daily brief","prompt":"Build a scheduled workflow that pulls updates from your project tools — GitHub commits, Jira ticket status changes, and calendar events — and posts a formatted daily brief to your Microsoft Teams channel each morning.","integrations":[{"id":"github","name":"GitHub"},{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"jira","name":"Jira"}]},{"title":"Mintlify release-notes publisher","prompt":"Build a workflow that reads merged pull requests from GitHub, has an agent draft release notes, creates a Mintlify agent job to add them to the changelog, and triggers a docs deployment once the pull request merges.","integrations":[{"id":"github","name":"GitHub"},{"id":"mintlify","name":"Mintlify"}]},{"title":"Mintlify preview deployment on PR","prompt":"Create a workflow that triggers a Mintlify preview deployment for a Git branch, polls the deployment status until it succeeds or fails, and comments the preview URL on the GitHub pull request.","integrations":[{"id":"github","name":"GitHub"},{"id":"mintlify","name":"Mintlify"}]},{"title":"Feature branch setup","prompt":"Build a workflow. When a GitHub pull request opens, create a PlanetScale development branch from its configured parent and report the new branch state.","integrations":[{"id":"github","name":"GitHub"},{"id":"planetscale","name":"PlanetScale"}]},{"title":"Railway deploy on merge","prompt":"Create a workflow that watches GitHub for merges to the main branch, triggers a Railway service deployment for the matching environment, and posts the deployment status back as a Slack notification.","integrations":[{"id":"github","name":"GitHub"},{"id":"railway","name":"Railway"},{"id":"slack","name":"Slack"}]},{"title":"Railway preview environment provisioner","prompt":"Create a workflow that watches GitHub for new pull requests, creates a fresh Railway environment for the branch, upserts the required environment variables, deploys the service, and comments the live preview URL back on the PR.","integrations":[{"id":"github","name":"GitHub"},{"id":"railway","name":"Railway"}]},{"title":"Sentry release tracker on deploy","prompt":"Create a workflow that watches GitHub for merges to main, creates a new Sentry release with the commit range, marks the deploy in Sentry for the production environment, and posts the release notes and linked issues to Slack so the team knows what shipped.","integrations":[{"id":"github","name":"GitHub"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Vercel preview deploy reviewer","prompt":"Build a workflow that watches GitHub pull requests, finds the matching Vercel preview deployment, captures the preview URL, runs a smoke check against critical pages, and posts a status comment on the pull request with the preview link and any issues found.","integrations":[{"id":"github","name":"GitHub"},{"id":"vercel","name":"Vercel"}]},{"title":"WordPress release-notes publisher","prompt":"Create a scheduled workflow that runs every Friday, pulls merged GitHub PRs for the week, drafts a user-facing changelog, and publishes it as a WordPress post.","integrations":[{"id":"github","name":"GitHub"},{"id":"wordpress","name":"WordPress"}]}]},{"id":"gitlab","type":"gitlab","slug":"gitlab","name":"GitLab","description":"Interact with GitLab projects, issues, merge requests, and pipelines","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/gitlab","authType":"api-key","connections":[{"id":"gitlab-personal-token","kind":"personal_token","label":"Add personal token","providerId":"gitlab","setup":"fields","docsUrl":"https://docs.gitlab.com/user/profile/personal_access_tokens/","personalOnly":true,"fields":[{"id":"domain","label":"GitLab host","placeholder":"gitlab.example.com","defaultValue":"gitlab.com"},{"id":"apiToken","label":"Personal access token","placeholder":"glpat-…","secret":true,"hint":"Only you can use this connection."}]}],"operations":[{"name":"List Projects","description":"List GitLab projects accessible to the authenticated user"},{"name":"Get Project","description":"Get details of a specific GitLab project"},{"name":"List Groups","description":"List GitLab groups accessible to the authenticated user"},{"name":"Get Group","description":"Get details of a specific GitLab group"},{"name":"List Issues","description":"List issues in a GitLab project"},{"name":"Get Issue","description":"Get details of a specific GitLab issue"},{"name":"Create Issue","description":"Create a new issue in a GitLab project"},{"name":"Update Issue","description":"Update an existing issue in a GitLab project"},{"name":"Delete Issue","description":"Delete an issue from a GitLab project"},{"name":"Add Issue Comment","description":"Add a comment to a GitLab issue"},{"name":"List Merge Requests","description":"List merge requests in a GitLab project"},{"name":"Get Merge Request","description":"Get details of a specific GitLab merge request"},{"name":"Create Merge Request","description":"Create a new merge request in a GitLab project"},{"name":"Update Merge Request","description":"Update an existing merge request in a GitLab project"},{"name":"Merge Merge Request","description":"Merge a merge request in a GitLab project"},{"name":"Add MR Comment","description":"Add a comment to a GitLab merge request"},{"name":"List Pipelines","description":"List pipelines in a GitLab project"},{"name":"Get Pipeline","description":"Get details of a specific GitLab pipeline"},{"name":"Create Pipeline","description":"Trigger a new pipeline in a GitLab project"},{"name":"Retry Pipeline","description":"Retry a failed GitLab pipeline"},{"name":"Cancel Pipeline","description":"Cancel a running GitLab pipeline"},{"name":"List Repository Tree","description":"List files and directories in a GitLab project repository"},{"name":"Get File","description":"Get the contents of a file from a GitLab project repository"},{"name":"Create File","description":"Create a new file in a GitLab project repository"},{"name":"Update File","description":"Update an existing file in a GitLab project repository"},{"name":"List Commits","description":"List commits in a GitLab project repository"},{"name":"List Branches","description":"List branches in a GitLab project repository"},{"name":"Create Branch","description":"Create a new branch in a GitLab project repository"},{"name":"Delete Branch","description":"Delete a branch from a GitLab project repository"},{"name":"Compare Branches","description":"Compare two branches, tags, or commits in a GitLab project repository"},{"name":"Get MR Changes","description":"Get the file changes (diffs) of a GitLab merge request"},{"name":"Approve Merge Request","description":"Approve a GitLab merge request"},{"name":"List Pipeline Jobs","description":"List jobs for a GitLab pipeline"},{"name":"Get Job Log","description":"Get the log (trace) of a GitLab job"},{"name":"Play Job","description":"Trigger (play) a manual GitLab job"},{"name":"List Releases","description":"List releases in a GitLab project"},{"name":"Create Release","description":"Create a new release in a GitLab project"},{"name":"List Members","description":"List members of a GitLab project or group. Includes members inherited from ancestor groups by default."},{"name":"Add Member","description":"Add an existing GitLab user to a project or group at a given access level"},{"name":"Update Member","description":"Update a member\'s access level in a GitLab project or group"},{"name":"Remove Member","description":"Remove a member from a GitLab project or group"},{"name":"Invite Member by Email","description":"Invite a person to a GitLab project or group by email address"},{"name":"List Invitations","description":"List pending email invitations for a GitLab project or group"},{"name":"Update Invitation","description":"Update a pending invitation to a GitLab project or group"},{"name":"Revoke Invitation","description":"Revoke a pending email invitation to a GitLab project or group"},{"name":"List Access Requests","description":"List pending access requests for a GitLab project or group"},{"name":"Approve Access Request","description":"Approve a pending access request for a GitLab project or group"},{"name":"Deny Access Request","description":"Deny (delete) a pending access request for a GitLab project or group"},{"name":"List SAML Group Links","description":"List SAML group links for a GitLab group. Use this to detect whether a group is governed by SAML group sync before provisioning members."},{"name":"List User Memberships","description":"List a user\'s project and group memberships. Requires an administrator access token (GET /users/:id/memberships is admin-only). For a non-admin path, iterate List Members on each project or group instead."},{"name":"Search Users","description":"Search for GitLab users by name, username, or email. Email matches must be exact; private emails match only with an admin token. Use this to resolve an email to a user ID before adding a member."},{"name":"Create User","description":"Create a new GitLab user. Requires an administrator token with admin_mode on the instance."},{"name":"Update User","description":"Modify an existing GitLab user. Requires an administrator token with admin_mode on the instance."},{"name":"Delete User","description":"Delete a GitLab user. Requires an administrator token with admin_mode on the instance."},{"name":"Block User","description":""},{"name":"Unblock User","description":""},{"name":"Deactivate User","description":""},{"name":"Activate User","description":""},{"name":"Ban User","description":""},{"name":"Unban User","description":""},{"name":"Approve User Signup","description":""},{"name":"Reject User Signup","description":""},{"name":"Delete User Identity","description":"Delete a user\'s authentication identity (e.g. SAML or LDAP). Requires an administrator token with admin_mode on the instance."},{"name":"Add SAML Group Link","description":"Add a SAML group link that maps an identity-provider group to a GitLab group at a given access level (GitLab Premium/Ultimate)"},{"name":"Delete SAML Group Link","description":"Delete a SAML group link from a GitLab group (GitLab Premium/Ultimate)"}],"triggers":[{"id":"gitlab_push","name":"GitLab Push","description":"Trigger workflow when commits are pushed to a GitLab project"},{"id":"gitlab_merge_request","name":"GitLab Merge Request","description":"Trigger workflow when a merge request is opened, updated, or merged in GitLab"},{"id":"gitlab_issue","name":"GitLab Issue","description":"Trigger workflow when an issue is opened, updated, or closed in GitLab"},{"id":"gitlab_pipeline","name":"GitLab Pipeline","description":"Trigger workflow when a pipeline status changes in GitLab"},{"id":"gitlab_comment","name":"GitLab Comment","description":"Trigger workflow when a comment is added on a commit, merge request, or issue"},{"id":"gitlab_webhook","name":"GitLab Event","description":"Trigger workflow from any GitLab webhook event"}],"skills":[{"name":"provision-gitlab-member","description":"Resolve a person to a GitLab user and add them to a project or group at the right access level.","content":"# Provision GitLab Member\\n\\nUse GitLab to grant someone access to a project or group.\\n\\n## Steps\\n1. Search Users by name, username, or email to resolve the target user ID.\\n2. If the user exists, use Add Member with the project/group, user ID, access level, and an expiration date for time-boxed access. A user who is already a member is reported as a soft success.\\n3. If no GitLab user matches, use Invite Member by Email instead so they receive an email invitation at the same access level.\\n\\n## Output\\nConfirm who was added or invited, to which project/group, at what access level, and any expiration date applied."},{"name":"audit-gitlab-access-requests","description":"List pending access requests for a GitLab project or group and approve or deny each one.","content":"# Audit GitLab Access Requests\\n\\nUse GitLab to work through pending access requests.\\n\\n## Steps\\n1. List Access Requests for the project or group to see who is waiting.\\n2. For each requester, decide based on the stated policy: Approve Access Request with an explicit access level, or Deny Access Request.\\n3. Optionally List Members afterwards to confirm the roster reflects the decisions.\\n\\n## Output\\nReturn a decision log: each requester, whether they were approved (and at what level) or denied, and any requests intentionally left pending."},{"name":"review-merge-request","description":"Fetch a GitLab merge request and post a structured review comment with actionable feedback.","content":"# Review Merge Request\\n\\nUse GitLab to read a merge request and leave a useful review.\\n\\n## Steps\\n1. Get the merge request by project ID and MR IID to read its title, description, and changes.\\n2. Assess the change for correctness, missing tests, and risky edits.\\n3. Post a review note on the MR with Add MR Comment, summarizing the feedback.\\n\\n## Output\\nConfirm the comment was posted and return a short summary: what looks good, what needs changes, and any blocking concerns."},{"name":"triage-gitlab-issue","description":"Read a GitLab issue, classify it, and post a triage comment or update its fields.","content":"# Triage GitLab Issue\\n\\nUse GitLab to triage an incoming issue.\\n\\n## Steps\\n1. Get the issue by project ID and issue IID to read its title and description.\\n2. Classify it (bug, feature, question) and judge severity.\\n3. Update the issue with the right labels and assignee using Update Issue, and add a triage note with Add Issue Comment.\\n\\n## Output\\nReturn the classification, applied labels, assignee, and a one-line triage summary. Note any missing reproduction details."},{"name":"monitor-pipeline-status","description":"Check GitLab pipeline status for a project and report failures, optionally retrying a failed pipeline.","content":"# Monitor Pipeline Status\\n\\nUse GitLab to keep an eye on CI pipelines.\\n\\n## Steps\\n1. List pipelines for the project and identify the most recent runs.\\n2. Get the pipeline details for any that failed to read the status and reason.\\n3. If a failure looks transient, use Retry Pipeline to re-run it.\\n\\n## Output\\nReturn a summary of recent pipeline runs (ref, status, when) and call out any failures. If a retry was triggered, include the retried pipeline ID."},{"name":"draft-release-notes","description":"Compare two refs, summarize the merged changes, and publish a GitLab release with generated notes.","content":"# Draft Release Notes\\n\\nUse GitLab to publish a release with notes generated from the changes since the last tag.\\n\\n## Steps\\n1. Compare Branches between the previous release tag and the target ref to list the commits and diffs.\\n2. Summarize the changes into readable release notes, grouped by feature, fix, or chore.\\n3. Use Create Release with the new tag name, the generated description, and the target ref.\\n\\n## Output\\nReturn the created release\'s tag name and a confirmation that the notes were published, along with the release notes text."}],"templates":[{"title":"GitLab merge request reviewer","prompt":"Create a knowledge base from my coding standards and architecture docs. Build a scheduled workflow that lists open GitLab merge requests, fetches each diff, runs an agent that checks the code against the knowledge base and flags security issues, performance concerns, and style violations, then posts a structured review as an MR comment.","integrations":[{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab pipeline failure responder","prompt":"Build a scheduled workflow that lists recent GitLab pipelines on the main branch, finds newly failed runs, summarizes the root cause from the job logs, identifies the most likely owner from recent commits, opens a GitLab issue with the diagnosis, and posts an alert to Slack with a link to the failing pipeline.","integrations":[{"id":"gitlab","name":"GitLab"},{"id":"slack","name":"Slack"}]},{"title":"GitLab issue triager","prompt":"Create a scheduled workflow that runs every hour, pulls new GitLab issues, classifies each by component, severity, and effort, applies labels and assigns the right owner, and posts a daily Slack digest of unassigned and stale issues so nothing slips through.","integrations":[{"id":"gitlab","name":"GitLab"},{"id":"slack","name":"Slack"}]},{"title":"GitLab release publisher","prompt":"Build a scheduled workflow that detects new GitLab release tags, gathers merged merge requests since the previous tag, groups changes by component, drafts release notes as a file, and posts the formatted summary back as a comment on the release.","integrations":[{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab project health digest","prompt":"Create a scheduled weekly workflow that pulls open issues, stale merge requests, recent pipeline failures, and contributor activity for every GitLab project, logs metrics to a tracking table, and sends a Slack health digest to engineering leadership.","integrations":[{"id":"gitlab","name":"GitLab"},{"id":"slack","name":"Slack"}]},{"title":"GitLab merge request unblocker","prompt":"Build a scheduled daily workflow that lists open GitLab merge requests, identifies those blocked on review for more than two days, sends targeted Slack DMs to the assigned reviewers with the MR link, and updates a table tracking unblock actions.","integrations":[{"id":"gitlab","name":"GitLab"},{"id":"slack","name":"Slack"}]},{"title":"GitLab access governance agent","prompt":"Build a scheduled workflow that lists pending GitLab access requests and invitations across our key groups, checks each requester against a table of approved teams, approves or denies the access requests at the right access level, revokes stale invitations older than 14 days, and posts a summary of every access decision to Slack.","integrations":[{"id":"gitlab","name":"GitLab"},{"id":"slack","name":"Slack"}]},{"title":"GitLab repository knowledge base","prompt":"Create a knowledge base that ingests GitLab project files, merge request descriptions, and issue threads, then build an agent I can ask things like \\"how does the billing module handle proration?\\" or \\"which MR introduced the rate limiter?\\" and get answers with GitLab citations.","integrations":[{"id":"gitlab","name":"GitLab"}]}]},{"id":"gmail","type":"gmail_v2","slug":"gmail","name":"Gmail","description":"Send, read, search, and move Gmail messages or trigger workflows from Gmail events","category":"Email","docsUrl":"https://docs.sim.ai/integrations/gmail","authType":"oauth","connections":[{"id":"google-email","kind":"oauth","label":"Connect with OAuth","providerId":"google-email","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/gmail","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/gmail.send","label":"Send emails"},{"id":"https://www.googleapis.com/auth/gmail.modify","label":"Read, compose, send, and modify email messages"},{"id":"https://www.googleapis.com/auth/gmail.labels","label":"View and manage email labels"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Send Email","description":"Send emails using Gmail"},{"name":"Read Email","description":"Read emails from Gmail"},{"name":"Draft Email","description":"Draft emails using Gmail"},{"name":"Edit Draft","description":"Update an existing Gmail draft in place without deleting and recreating it."},{"name":"Search Email","description":"Search emails in Gmail"},{"name":"Move Email","description":"Move emails between Gmail labels/folders"},{"name":"Mark as Read","description":"Mark a Gmail message as read"},{"name":"Mark as Unread","description":"Mark a Gmail message as unread"},{"name":"Archive Email","description":"Archive a Gmail message (remove from inbox)"},{"name":"Unarchive Email","description":"Unarchive a Gmail message (move back to inbox)"},{"name":"Delete Email","description":"Delete a Gmail message (move to trash)"},{"name":"Add Label","description":"Add label(s) to a Gmail message"},{"name":"Remove Label","description":"Remove label(s) from a Gmail message"}],"triggers":[{"id":"gmail_poller","name":"Gmail Email Trigger","description":"Triggers when new emails are received in Gmail (requires Gmail credentials)"}],"skills":[{"name":"triage-inbox","description":"Sort unread email by urgency and draft replies for the most important messages.","content":"# Triage Inbox\\n\\nReview unread Gmail messages and bring order to the inbox.\\n\\n## Steps\\n1. Read unread messages from the relevant time window.\\n2. Classify each as Urgent, Today, This week, or FYI based on sender, subject, and content.\\n3. For Urgent and Today items, draft a concise reply.\\n4. Flag anything that needs a meeting or a decision from someone else.\\n\\n## Output\\nReturn a prioritized list: each message with its sender, a one-line summary, the assigned priority, and the draft reply where one was written. Do not send anything without confirmation."},{"name":"summarize-email-thread","description":"Condense a long email thread into the key points, decisions, and action items.","content":"# Summarize Email Thread\\n\\nGiven a Gmail thread, produce a tight summary.\\n\\n## Steps\\n1. Read every message in the thread in order.\\n2. Identify the core topic, what was decided, and what is still open.\\n3. Pull out action items and who owns each.\\n\\n## Output\\n- A one-sentence TL;DR.\\n- Key decisions as bullets.\\n- Action items with owners.\\n- Open questions that still need an answer."},{"name":"draft-reply-from-context","description":"Draft a contextual reply to an email in the right tone, ready for review.","content":"# Draft Reply From Context\\n\\nWrite a reply to an incoming email that is ready to send after a quick review.\\n\\n## Steps\\n1. Read the email and any prior thread context.\\n2. Determine what the sender is asking for and the appropriate tone (formal, friendly, brief).\\n3. Draft a reply that answers every question and proposes clear next steps.\\n\\n## Output\\nA complete draft reply with subject and body. Keep it concise, match the sender style, and leave placeholders in brackets for any detail you cannot infer. Do not send without confirmation."},{"name":"find-and-extract-emails","description":"Search Gmail for messages matching a query and extract the details you need.","content":"# Find And Extract Emails\\n\\nLocate specific emails and pull structured information from them.\\n\\n## Steps\\n1. Build a Gmail search query from the request (sender, subject keywords, date range, label, has attachment).\\n2. Retrieve matching messages.\\n3. Extract the requested fields from each, for example invoice amounts, order numbers, contact details, or attachment names.\\n\\n## Output\\nA structured list of the matching emails with the extracted fields, plus a link or message id for each so the source can be opened."}],"templates":[{"title":"Affinity stale deal reminders","prompt":"Create a scheduled workflow that finds Affinity deals with no interaction in 30 days, creates a follow-up reminder on each one with a specific next step, and emails the owner a list of what went quiet.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"affinity","name":"Affinity"}]},{"title":"Agiloft renewal tracker","prompt":"Build a scheduled workflow that finds Agiloft contracts with renewals due in the next 90 days, creates a renewal-prep task in the CRM, and emails the account owner.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"agiloft","name":"Agiloft"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Ahrefs + Similarweb growth scoreboard","prompt":"Build a scheduled monthly workflow that joins Ahrefs SEO data with Similarweb traffic intelligence, writes a growth scoreboard table, and emails leadership.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"ahrefs","name":"Ahrefs"},{"id":"similarweb","name":"Similarweb"}]},{"title":"Airtable digest reporter","prompt":"Build a scheduled weekly workflow that summarizes activity in a chosen Airtable base — new rows, status changes, completed items — and emails a digest to the project owner.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"airtable","name":"Airtable"}]},{"title":"Trigger Gmail from Airtable records","prompt":"Build a workflow that watches Airtable for new or updated records and sends a personalised Gmail message for each one, so outreach and follow-ups go out automatically.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"airtable","name":"Airtable"}]},{"title":"ArXiv paper alerter","prompt":"Build a scheduled workflow that queries ArXiv for new papers on tracked topics, summarizes abstracts with an agent, and emails the digest to the research team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"arxiv","name":"ArXiv"}]},{"title":"Asana weekly project digest","prompt":"Build a scheduled weekly workflow that summarizes Asana project progress — completed, in-progress, at-risk — and emails a status update to each project sponsor.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"asana","name":"Asana"}]},{"title":"Ashby stage-change responder","prompt":"Create a workflow that detects when an Ashby application moves into a new stage, sends the candidate a stage-appropriate email, prepares the interviewer brief in a file, and updates a recruiting tracking table so coordinators always know who is next.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"ashby","name":"Ashby"}]},{"title":"Athena weekly executive metrics","prompt":"Create a scheduled weekly workflow that runs a set of AWS Athena queries against the data lake for revenue, retention, and usage metrics, writes the results to a metrics table, and emails a formatted scorecard to leadership.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"athena","name":"Athena"}]},{"title":"Attio email-to-record logger","prompt":"Build a workflow that watches Gmail for emails to or from Attio contacts, logs each as an interaction on the matching record, and creates a follow-up task if mentioned.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"attio","name":"Attio"}]},{"title":"Attio outreach orchestrator","prompt":"Create a workflow that watches Attio for contacts entering the outreach stage, drafts a personalized first-touch email, and queues it for the rep to review and send.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"attio","name":"Attio"}]},{"title":"Bitbucket engineering activity digest","prompt":"Create a scheduled workflow that summarizes recent Bitbucket commits, pull request activity, and pipeline results across a repository into a concise engineering digest delivered by email.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Brex spend anomaly alert","prompt":"Build a scheduled workflow that lists recent Brex card transactions, flags any transaction above a configurable threshold, and emails the finance team a report of flagged transactions with merchant details.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"brex","name":"Brex"}]},{"title":"Brex budget utilization report","prompt":"Build a weekly workflow that lists Brex budgets and spend limits, computes utilization for each budget from its amount and current period balance, stores the results in a table, and emails a summary report.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"brex","name":"Brex"}]},{"title":"Cal.com booking prep brief","prompt":"Build a workflow that runs 30 minutes before a Cal.com booking, researches the attendee with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"calcom","name":"Cal.com"},{"id":"apollo","name":"Apollo"}]},{"title":"Cal.com no-show recovery","prompt":"Build a workflow that detects Cal.com no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"calcom","name":"Cal.com"}]},{"title":"Calendly meeting-prep brief","prompt":"Build a workflow that runs 30 minutes before a Calendly booking, researches the attendee and company with Apollo, and emails the host a structured prep brief.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"calendly","name":"Calendly"},{"id":"apollo","name":"Apollo"}]},{"title":"Calendly no-show recovery","prompt":"Build a workflow that detects Calendly no-shows, sends a polite reschedule email with a one-tap link, and updates the deal record with the no-show event.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"calendly","name":"Calendly"}]},{"title":"Calendly booking prep brief","prompt":"Create a workflow that on a new Calendly booking fetches the scheduled event and invitee details, researches the attendee and their company, and emails the meeting owner a one-page prep brief before the call.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"calendly","name":"Calendly"}]},{"title":"CB Insights funding window alerts","prompt":"Build a workflow that checks the estimated funding window for each company in my pipeline every week and emails me the ones entering their window in the next 60 days, with the cohort rate and their last round.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights portfolio exit digest","prompt":"Build a scheduled workflow that reads portfolio exits for the investors I track, summarizes each exit with the company, round, and amount, and emails a weekly digest to the investment team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"cbinsights","name":"CB Insights"}]},{"title":"Expired invitation follow-up","prompt":"Create a workflow triggered when a Checkr invitation expires that looks up the candidate, sends a friendly reminder email explaining the next steps, creates a fresh invitation for the same package, and records the follow-up in a tracking table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"checkr","name":"Checkr"}]},{"title":"Clay outbound personalizer","prompt":"Create a workflow that reads a prospect record from a Sim table — including the role and company signals already gathered — drafts a personalized first-touch email, queues it for review, and pushes the prospect to a Clay table via the populate webhook for further enrichment.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"clay","name":"Clay"}]},{"title":"Clerk inactive-user cleaner","prompt":"Build a scheduled workflow that finds Clerk users with no sign-ins in 180 days, sends a re-engagement email, and bans accounts that stay inactive after a grace period.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"clerk","name":"Clerk"}]},{"title":"ClickUp overdue-task nudger","prompt":"Build a scheduled workflow that searches ClickUp for tasks past their due date, adds a comment asking for a status update, and emails each assignee a digest of their overdue work.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"clickup","name":"ClickUp"}]},{"title":"CloudTrail offboarding evidence pack","prompt":"Build a workflow that, given a departing employee username, looks up all their AWS CloudTrail activity from the last 90 days, summarizes the resources they touched, and emails an evidence pack to the security team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"Coda project status digest","prompt":"Build a scheduled workflow that reads the project tracker table in a Coda doc each morning, has an agent flag overdue and blocked projects, and emails a status digest to project leads with links to each row.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"coda","name":"Coda"}]},{"title":"Context.dev site change watcher","prompt":"Build a scheduled workflow that maps a site sitemap with Context.dev, scrapes new or changed pages to markdown, summarizes the differences, and emails a digest.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"context_dev","name":"Context.dev"}]},{"title":"Convex user onboarding automation","prompt":"Create a workflow that receives new-signup webhooks, runs a Convex mutation to provision the user record with defaults, and sends a personalized welcome email.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"convex","name":"Convex"}]},{"title":"Crunchbase acquisition digest","prompt":"Create a scheduled workflow that searches Crunchbase for acquisitions announced this week in my industry, summarizes each deal — acquirer, target, price, and terms — and emails the digest to the strategy team every Friday.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Datadog SLO weekly report","prompt":"Create a scheduled weekly workflow that queries Datadog timeseries for key service SLOs, lists which monitors fired during the week, writes the SLO compliance numbers to a table, and emails an availability summary to the on-call leads.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"datadog","name":"Datadog"}]},{"title":"Daytona file transformer","prompt":"Create a workflow that receives a document from a form, uploads it to a Daytona sandbox, runs a conversion script on it, downloads the transformed file, and emails it back to the requester.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"daytona","name":"Daytona"}]},{"title":"Downdetector report-spike watcher","prompt":"Build a scheduled workflow that fetches the last hour of Downdetector reports for a company slug, compares the latest bucket against the company baseline, and emails me when reports spike well above baseline.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"downdetector","name":"Downdetector"}]},{"title":"Dub outbound link personalizer","prompt":"Build a workflow that reads a leads table, generates a per-lead Dub short link with the lead identifier in UTM and metadata, attaches the personalized link to the outreach email body, and tracks delivery in the table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"dub","name":"Dub"}]},{"title":"Dynatrace config audit","prompt":"Create a scheduled weekly workflow that reads the Dynatrace audit log for configuration changes, highlights changes made outside business hours or by service accounts, and emails a compliance summary to the platform team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"dynatrace","name":"Dynatrace"}]},{"title":"ElevenLabs voice greeting generator","prompt":"Create a workflow that reads a table of new enterprise customers, generates a personalized ElevenLabs voice greeting with their account manager voice, and emails the audio file to the customer on day one.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"ElevenLabs + Pulse meeting voice digest","prompt":"Build a workflow that takes Pulse meeting insights, narrates them with an ElevenLabs voice, and emails the audio digest to the team for asynchronous review.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"elevenlabs","name":"ElevenLabs"},{"id":"pulse","name":"Pulse"}]},{"title":"Exa daily research digest","prompt":"Build a scheduled workflow that runs Exa searches on tracked topics each morning, summarizes top hits with citations, and emails the user a research digest.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"exa","name":"Exa"}]},{"title":"Fathom weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists Fathom meetings from the past week, summarizes the key decisions and commitments across calls with an agent, and emails the digest to the team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"fathom","name":"Fathom"}]},{"title":"Fathom sales-call action items","prompt":"Create a workflow that after a Fathom meeting pulls the summary and transcript, extracts the customer commitments and next steps with an agent, creates follow-up tasks in the CRM, and emails a recap to the attendees.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"fathom","name":"Fathom"}]},{"title":"Daily pipeline health digest","prompt":"Create a scheduled daily workflow that lists every Fivetran connection, collects its sync history and data volumes for the last day, and emails the data team a digest of failures, delays, and the largest loads.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"fivetran","name":"Fivetran"}]},{"title":"Gamma deck from doc","prompt":"Build a workflow that takes a Google Docs source, generates a Gamma deck from the structure and bullet points, and emails the deck link to the author for polish.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"gamma","name":"Gamma"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Gmail auto-reply agent","prompt":"Create a workflow that reads my Gmail inbox, identifies emails that need a response, and drafts contextual replies for each one. Schedule it to run every hour.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"Gmail outbound sequence builder","prompt":"Build a workflow that reads leads from my table, researches each prospect and their company on the web, writes a personalized cold email tailored to their role and pain points, and sends it via Gmail. Schedule it to run daily to process new leads automatically.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"Gmail knowledge search","prompt":"Create a knowledge base connected to my Gmail so all my emails are automatically synced, chunked, and searchable. Then build an agent I can ask things like \\"what did Sarah say about the pricing proposal?\\" or \\"find the contract John sent last month\\" and get instant answers with the original email cited.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"Gmail triage assistant","prompt":"Build a workflow that scans my Gmail inbox every hour, categorizes emails by urgency and type (action needed, FYI, follow-up), drafts replies for routine messages, and sends me a prioritized summary in Slack so I only open what matters. Schedule it to run hourly.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Gmail invoice processor","prompt":"Build a workflow that processes invoice PDFs from Gmail, extracts vendor name, amount, due date, and line items, then logs everything to a tracking table and sends a Slack alert for invoices due within 7 days.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Gmail to CRM activity logger","prompt":"Build a workflow that reads new Gmail threads with customers, extracts the contact, deal context, and key points discussed, and logs a timestamped activity to the matching HubSpot contact or deal so every conversation stays attached to the record.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Gmail attachment vault","prompt":"Create a workflow that watches Gmail for new emails with attachments, saves each attachment into a categorized folder in Google Drive based on sender and subject, and logs a row to a tracking table with the file link and source email.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Gmail to Notion email capture","prompt":"Build a workflow that monitors Gmail for incoming emails, extracts structured data from each one, and stores it as a Notion database entry — useful for lead capture, support tickets, and meeting scheduling.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"notion","name":"Notion"}]},{"title":"AppSheet daily status digest","prompt":"Create a scheduled workflow that runs daily, finds all AppSheet rows where Status is \\"Open\\", summarizes them with an agent, and emails the summary to the operations team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"BigQuery + Sheets exec dashboard","prompt":"Build a scheduled workflow that pulls a BigQuery executive dashboard query weekly, writes the result into a chosen Google Sheet, and notifies leadership the new snapshot is ready.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_bigquery","name":"Google BigQuery"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Google Books reading list builder","prompt":"Create a workflow that takes a topic, finds top-rated Google Books titles, writes a curated reading-list file with summaries, and emails it to the user.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_books","name":"Google Books"}]},{"title":"Calendar interview scheduler","prompt":"Build a workflow that when a candidate reaches the interview stage finds open slots across the panel\'s Google Calendars, creates the interview event with the video link, invites everyone, and emails the candidate the confirmation.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Google Contacts birthday reminder","prompt":"Build a scheduled workflow that runs daily, surfaces upcoming birthdays from Google Contacts, and emails the user a reminder with personalized message suggestions.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Forms event RSVP tracker","prompt":"Build a workflow that captures Google Forms event RSVPs into a table, sends confirmation emails, and provides a daily attendee dashboard to the organizer.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Forms quiz grader","prompt":"Build a workflow that captures Google Forms quiz responses, scores each automatically with an agent, writes scores to a tables-based gradebook, and emails the student.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Maps competitor location finder","prompt":"Build a workflow that uses Google Maps to find competitor locations in a target city, writes coordinates and details to a table, and emails the sales team a route map.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_maps","name":"Google Maps"}]},{"title":"Google Meet daily meeting links","prompt":"Create a scheduled workflow that reads the day\'s meetings from a table each morning, creates a Google Meet space for each one, and emails attendees the agenda and join link via Gmail.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Daily news digest","prompt":"Create a scheduled daily workflow that runs Google searches for the topics and competitors I care about, picks the most relevant fresh results, summarizes each in a sentence, and emails me a curated digest every morning.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_search","name":"Google Search"}]},{"title":"Google Sheets data validator","prompt":"Create a scheduled workflow that validates a Google Sheets spreadsheet against a typed schema, flags rows with errors, writes a remediation column, and emails the sheet owner.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Google Slides win-loss recap","prompt":"Build a workflow that aggregates closed-won and closed-lost deals from Salesforce monthly, generates a Google Slides recap with patterns and insights, and emails it to the sales team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_slides","name":"Google Slides"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Tasks digest","prompt":"Build a scheduled daily workflow that summarizes Google Tasks due today and tomorrow, and emails the user a prioritized digest each morning.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Google Tasks from Gmail","prompt":"Create a workflow that watches Gmail for emails marked with a task label, extracts the action and due date, and creates a Google Tasks entry with a link back to the email.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Google Tasks completion digest","prompt":"Create a scheduled weekly workflow that summarizes Google Tasks completed by the user, captures the throughput, and emails a personal productivity report.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Greenhouse interview scheduler","prompt":"Build a workflow that runs after a Greenhouse application reaches the interview stage, finds the right interviewer panel based on job stage, proposes time slots from Google Calendar, drafts a coordination email to the candidate, and confirms the booking in a tracking table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"greenhouse","name":"Greenhouse"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Greenhouse offer drafter","prompt":"Create a workflow that takes an approved Greenhouse application, pulls compensation bands from a knowledge base, drafts a tailored offer letter file, prepares an explanation email, and routes both to the hiring manager for review before sending to the candidate.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse rejection follow-up","prompt":"Build a workflow that runs when a Greenhouse candidate is rejected, drafts a warm and respectful rejection email tailored to how far they progressed, sends it via Gmail, and logs the candidate with their interest areas to a future-talent table for re-engagement.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse interview prep packet","prompt":"Create a workflow that runs the morning of every Greenhouse interview, pulls the candidate profile, prior interview notes, and job rubric, assembles a one-page prep file for the interviewer, and emails it with a Slack DM reminder thirty minutes before the slot.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Hex executive metrics email","prompt":"Create a scheduled weekly workflow that runs a Hex executive dashboard notebook, summarizes the run results, and emails a snapshot with the dashboard link to the leadership distribution list every Monday morning.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hex","name":"Hex"}]},{"title":"Hex + Amplitude product notebook","prompt":"Create a scheduled workflow that runs a Hex notebook joining Amplitude data with internal sources weekly, captures retention and feature adoption, and emails a summary with the notebook link to the product team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hex","name":"Hex"},{"id":"amplitude","name":"Amplitude"}]},{"title":"Send personalised emails from HubSpot events","prompt":"Build a workflow that triggers whenever a HubSpot contact enters a new lifecycle stage and sends a personalised Gmail message tailored to that stage.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"HubSpot pipeline weekly digest","prompt":"Create a scheduled weekly workflow that lists HubSpot deals by stage, computes movement and at-risk deals with an agent, logs the snapshot to a table, and emails a pipeline summary to the sales leadership team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Backfill HubSpot contact email history from Gmail","prompt":"Build a workflow that finds HubSpot contacts in the lead stage with no logged email activity, searches my Gmail for each person’s thread, and logs it back to HubSpot as an email engagement associated with the contact.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Identity Center orphaned-access finder","prompt":"Create a scheduled workflow that lists AWS Identity Center account assignments, flags principals with stale or unexpected access, emails owners for confirmation, and writes the findings to a security dashboard table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"incident.io customer comms drafter","prompt":"Build a workflow that during a high-severity incident.io incident drafts customer status-page copy and a tailored email update, holds for approval, and dispatches once approved.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"incidentio","name":"incident.io"}]},{"title":"Jotform submission webhook fan-out","prompt":"Create a workflow that registers a Jotform webhook on a form pointing at an API trigger, then processes each incoming submission by writing it to a table and emailing the submitter a confirmation.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"jotform","name":"Jotform"}]},{"title":"Jotform weekly response digest","prompt":"Create a scheduled workflow that runs every Monday, lists the past week of Jotform submissions across every form, has an agent summarize the themes and outliers, and emails the digest to the operations team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"jotform","name":"Jotform"}]},{"title":"Kalshi macroeconomic dashboard","prompt":"Build a scheduled workflow that pulls Kalshi probability markets for selected macroeconomic events, writes the implied probabilities to a tables-based dashboard, and emails a weekly summary.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"kalshi","name":"Kalshi"}]},{"title":"LaTeX invoice generator","prompt":"Build a workflow that takes invoice line items from a table, fills a LaTeX invoice template, compiles it to PDF, and emails the invoice to the customer.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"latex","name":"LaTeX"}]},{"title":"LaTeX certificate generator","prompt":"Create a workflow that reads attendee names from a spreadsheet, fills a LaTeX certificate template for each attendee, compiles the PDFs, and emails each certificate to its recipient.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"latex","name":"LaTeX"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Linkup daily digest","prompt":"Create a scheduled daily workflow that runs Linkup searches on tracked topics, summarizes the top hits with citations, and emails the user a research digest.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"linkup","name":"Linkup"}]},{"title":"Logfire LLM cost tracker","prompt":"Build a scheduled daily workflow that queries Logfire for spans emitted by LLM instrumentation, extracts token counts from the attributes JSON, aggregates spend per model and per service into a table, and emails finance when a service trends over budget.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"logfire","name":"Logfire"}]},{"title":"Luma event reminder cadence","prompt":"Create a workflow that sends scheduled reminders to Luma event registrants — 7 days, 24 hours, 1 hour out — with personalized content based on RSVP type.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"luma","name":"Luma"}]},{"title":"Luma post-event followup","prompt":"Create a scheduled workflow that runs the day after a Luma event, pulls the guest list, segments attendees from no-shows, sends each segment a tailored followup, and writes attendance to the CRM.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"luma","name":"Luma"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Luma new-registrant welcome","prompt":"Create a scheduled workflow that pulls the Luma event guest list, finds registrants added since the last run, and sends each a personalized welcome email with what to expect and how to prepare.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"luma","name":"Luma"}]},{"title":"Claude Managed Agents weekly report","prompt":"Build a scheduled workflow that runs a Claude Managed Agents session every Monday to compile last week’s metrics into a spreadsheet, then sends the finished file to the leadership list over Gmail.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Daily ServiceDesk Plus SLA breach report","prompt":"Every weekday at 8am, list ServiceDesk Plus requests whose due-by time has passed and that are not yet resolved. Summarize them by support group and email the summary to the service desk manager.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Excel financial close automator","prompt":"Build a scheduled workflow that closes the books each period — pulls Stripe and accounting data, updates a Microsoft Excel close workbook, and emails the controller the reconciled file.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"stripe","name":"Stripe"}]},{"title":"Excel commission calculator","prompt":"Build a workflow that pulls closed Salesforce deals each month, computes commission per rep using a Microsoft Excel commission model, and emails the per-rep statements.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Mintlify traffic digest","prompt":"Build a scheduled workflow that exports Mintlify page views, unique visitors, and top search queries each week, writes them to a table, and emails a digest highlighting pages with rising AI traffic.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"mintlify","name":"Mintlify"}]},{"title":"Modal document summarizer","prompt":"Create a workflow that takes an uploaded document, sends its text to a Modal Endpoint for summarization, and emails the summary back to the requester.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"modal","name":"Modal"}]},{"title":"Monday client portal","prompt":"Create a workflow that mirrors a Monday project board into a client-facing summary table, refreshes hourly, and emails the client a snapshot link each week.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"monday","name":"Monday"}]},{"title":"New Relic cost-by-service breakdown","prompt":"Build a scheduled monthly workflow that runs NRQL queries to attribute data ingest and compute to each New Relic entity, writes a per-team cost breakdown to a table, and emails finance the services trending over budget.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"new_relic","name":"New Relic"}]},{"title":"Okta new-hire provisioning","prompt":"Build a workflow that polls Workday for new hires, creates the matching Okta user, adds them to the right groups for their role, and emails IT a provisioning summary.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"okta","name":"Okta"},{"id":"workday","name":"Workday"}]},{"title":"OneDrive Excel-pipeline opener","prompt":"Build a scheduled workflow that polls OneDrive for new Excel data drops, normalizes each, writes to a downstream table, and emails the analyst that the latest file is ready.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"onedrive","name":"OneDrive"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Otter weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists the week’s Otter conversations in a channel, summarizes recurring themes and decisions from their outlines, and emails the digest to the team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"otter","name":"Otter.ai"}]},{"title":"Parallel AI daily topic digest","prompt":"Build a scheduled daily workflow that uses Parallel AI search across the topics a team follows, extracts the key facts from the top results, and emails a concise cited digest each morning.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"Persona onboarding verification","prompt":"Build a workflow triggered when a new customer signs up that creates a Persona inquiry from our KYC template with their name and email pre-filled, generates a one-time verification link, and emails it to the customer.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"persona","name":"Persona"}]},{"title":"Persona decision router","prompt":"Build a workflow that takes an inquiry ID, fetches the inquiry from Persona, and routes on its status: approved customers get a welcome email, needs-review inquiries post to a compliance Slack channel with a summary, and declined inquiries update our CRM.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"persona","name":"Persona"},{"id":"slack","name":"Slack"}]},{"title":"Persona re-verification campaign","prompt":"Build a scheduled workflow that lists Persona accounts, finds ones whose latest approved inquiry is older than a year, creates a new inquiry for each from our re-verification template, and emails customers a one-time verification link.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"persona","name":"Persona"}]},{"title":"Pipedrive activity-from-email logger","prompt":"Create a workflow that watches Gmail for emails to or from Pipedrive contacts, logs each as an activity, and creates a follow-up task if next steps are mentioned.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"pipedrive","name":"Pipedrive"}]},{"title":"Pipedrive renewal forecast","prompt":"Build a workflow that pulls Pipedrive customer renewals due in the next 90 days, generates a personalized renewal-prep brief, and emails the account owner.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"pipedrive","name":"Pipedrive"}]},{"title":"PitchBook competitor watch","prompt":"Build a scheduled workflow that fetches PitchBook similar companies for my main product, checks each one for new financing rounds and recent news, summarizes what changed with an agent, and emails the competitive brief to the product team every Monday.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"pitchbook","name":"PitchBook"}]},{"title":"Polymarket position digest","prompt":"Create a scheduled daily workflow that summarizes Polymarket holdings, PnL per market, and notable movements, and emails the report to the trading team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Profound executive AI-search digest","prompt":"Create a scheduled monthly workflow that aggregates Profound visibility, share-of-voice, and citation trends into a Markdown report file with commentary, and emails the AI-search performance digest to leadership.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"profound","name":"Profound"}]},{"title":"Quartr filing watcher","prompt":"Create a scheduled workflow that checks Quartr daily for new annual and interim reports from my portfolio companies, downloads each report PDF to Files, and emails me a summary of what was filed.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"quartr","name":"Quartr"}]},{"title":"RabbitMQ broker health digest","prompt":"Create a scheduled daily workflow that reads the RabbitMQ broker overview and queue list, compares depth and consumer counts against yesterday, and emails the platform team a health digest.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RevenueCat renewal recovery","prompt":"Build a scheduled workflow that lists RevenueCat subscribers with failed renewals, segments them by plan and tenure, drafts a tailored win-back email, sends it via Gmail, and tracks recovery outcomes in a table with retry cadence rules.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"RevenueCat trial expiry digest","prompt":"Build a scheduled daily workflow that lists RevenueCat subscribers whose trials expire in the next three days, ranks them by engagement, drafts a personalized conversion nudge, and emails the success team a prioritized list to call.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"Rippling manager change alerts","prompt":"Create a scheduled workflow that polls Rippling workers for manager reassignments, notifies the worker and the new manager via email, schedules a thirty-minute intro on Google Calendar, and logs the transition in a tracking table for HR visibility.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"rippling","name":"Rippling"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Rocketlane status digest","prompt":"Create a scheduled weekly workflow that lists active Rocketlane projects with their status and due dates, summarizes progress and anything overdue per customer, and emails the digest to the delivery team every Monday morning.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rocketlane invoice monitor","prompt":"Build a scheduled workflow that lists Rocketlane invoices with an outstanding amount greater than zero and a due date in the past, pulls their payments, and emails the finance team a list of overdue invoices with amounts outstanding.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Competitor blog watcher","prompt":"Build a workflow that triggers when a competitor publishes a new RSS item, summarizes the post and flags anything relevant to our roadmap with an agent, and emails the brief to the team.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"S3 export-to-customer flow","prompt":"Build a workflow that generates a per-customer data export file, uploads it to a customer-scoped S3 prefix, and emails the customer a download link once the upload completes.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"s3","name":"S3"}]},{"title":"SailPoint certification progress digest","prompt":"Build a scheduled workflow that lists active SailPoint campaigns and certifications, computes completion percentages, and emails a progress digest to certification owners.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"sailpoint","name":"SailPoint"}]},{"title":"SAP supplier invoice intake","prompt":"Build a workflow that ingests inbound supplier invoice PDFs from Gmail, extracts header and line-item data with an agent, validates the vendor against SAP S/4HANA suppliers, creates the supplier invoice via OData, and writes the outcome to a finance audit table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"Semrush competitor ad watch","prompt":"Create a scheduled workflow that pulls Semrush domain paid keywords and paid competitors for my top three rivals, diffs them against last week, and emails the growth team a summary of new ad copy and bids.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"semrush","name":"Semrush"}]},{"title":"Semrush + Ahrefs visibility scoreboard","prompt":"Build a scheduled monthly workflow that joins Semrush domain overview data with Ahrefs backlink metrics, writes a combined visibility scoreboard table, and emails leadership.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"semrush","name":"Semrush"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Shopify unpaid order recovery","prompt":"Build a scheduled workflow that lists Shopify orders left open and unpaid in the past day, drafts a personalized recovery email referencing the items, and sends it via Gmail while logging recovery attempts to a table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"shopify","name":"Shopify"}]},{"title":"Shopify VIP segmenter","prompt":"Build a scheduled weekly workflow that pulls Shopify customers, uses amount spent and lifetime order count to group them into VIP and regular cohorts in a tracking table, and emails the marketing team via Gmail with a list of new VIPs to nurture.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"shopify","name":"Shopify"}]},{"title":"Shopify fulfillment tracker","prompt":"Create a scheduled workflow that lists Shopify orders and their fulfillment status, updates a status table with fulfillment status and tracking links, and proactively emails customers when their order misses an SLA so support gets ahead of the inquiry.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"shopify","name":"Shopify"}]},{"title":"Shopify product launcher","prompt":"Build a workflow that takes a new product brief, creates a draft product in Shopify, creates its variants with pricing, adds it to a collection using Collections To Join, drafts a launch announcement, and sends a Slack and Gmail draft announcement for marketing review. Publish to sales channels in Shopify after approval.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"shopify","name":"Shopify"},{"id":"slack","name":"Slack"}]},{"title":"Sixtyfour deal-prep packet","prompt":"Build a workflow that runs Sixtyfour the morning of every meeting, generates a meeting-prep packet with company and attendee research, and emails the rep.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Smartlead weekly outbound digest","prompt":"Create a scheduled weekly workflow that lists Smartlead campaigns, pulls analytics by date for the last seven days for each active campaign, computes open, click, and reply rates, ranks best and worst performers, and emails the digest to the sales lead.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"smartlead","name":"Smartlead"}]},{"title":"Splunk security digest","prompt":"Build a scheduled daily workflow that dispatches a Splunk saved search for failed authentication attempts, waits for the job to finish, and emails a security digest with the top source IPs.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"splunk","name":"Splunk"}]},{"title":"Sportmonks league standings report","prompt":"Build a scheduled weekly workflow that pulls the Sportmonks football standings and topscorers for a season, formats a league table with recent form, and emails the report to the group.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Sportmonks championship tracker","prompt":"Create a scheduled weekly workflow that pulls the Sportmonks motorsport driver and constructor standings for the current season, formats the championship tables, and emails them to the group.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Spotify podcast episode digest","prompt":"Create a scheduled workflow that fetches the latest episodes for a set of Spotify shows, summarizes each episode’s description, and emails a weekly listening digest to the team.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"Spotify new-music newsletter","prompt":"Create a workflow that searches Spotify for this week’s releases from followed artists, builds a formatted newsletter section with track links, and drafts the email for the music team to send.","integrations":[{"id":"gmail","name":"Gmail"}]},{"title":"Square refund pattern monitor","prompt":"Create a scheduled weekly workflow that lists Square payments and their refunds, classifies each refund by reason and location, flags any location with an unusually high refund rate, and emails finance a narrative report with recommended actions.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"square","name":"Square"}]},{"title":"Square new customer welcome","prompt":"Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"square","name":"Square"},{"id":"slack","name":"Slack"}]},{"title":"Square invoice chase automation","prompt":"Create a scheduled workflow that lists Square invoices for a location, finds those that are unpaid past their due date, sends a polite reminder email per customer, and logs every chase action to a collections table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"square","name":"Square"}]},{"title":"Stripe failed payment recovery","prompt":"Build a workflow that listens for Stripe failed-payment events, looks up the customer, classifies the failure reason, drafts a tailored recovery email and a Slack alert to the success team, and logs the attempt in a tracking table so recovery rate can be measured.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Stripe invoice chaser","prompt":"Build a scheduled workflow that lists Stripe invoices overdue by more than seven days, sends a polite chase email tailored to the customer history, escalates to a Slack alert at thirty days, and writes every action into a collections tracking table.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Stripe customer welcome flow","prompt":"Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"stripe","name":"Stripe"},{"id":"calendly","name":"Calendly"},{"id":"slack","name":"Slack"}]},{"title":"Supabase customer record sync","prompt":"Build a workflow that listens for Stripe new-customer events and upserts a row into a Supabase customers table with the correct plan and metadata, then emails a welcome message.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"supabase","name":"Supabase"},{"id":"stripe","name":"Stripe"}]},{"title":"Textract receipt OCR","prompt":"Build a workflow that processes Gmail attachments with AWS Textract, extracts vendor, date, total, and category, logs each receipt to an expense table, and tags reimbursable items.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"textract","name":"AWS Textract"}]},{"title":"Thrive CPD shortfall report","prompt":"Create a scheduled monthly workflow that queries Thrive CPD user summaries for a date range, compares logged minutes against each audience CPD requirement, and emails managers a list of learners below target.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"thrive","name":"Thrive"}]},{"title":"Tinybird executive KPI report","prompt":"Create a scheduled weekly workflow that queries several Tinybird pipes for the company’s headline KPIs, assembles them into a Markdown report file with trend commentary, and emails it to the leadership team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"tinybird","name":"Tinybird"}]},{"title":"TinyFish regulatory filing digest","prompt":"Build a workflow that fetches a regulator’s notices page with TinyFish every morning, extracts new filings into a schema, and emails a digest of anything matching your watch list.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"tinyfish","name":"TinyFish"}]},{"title":"Trello weekly digest","prompt":"Build a scheduled weekly workflow that summarizes Trello board movements — cards completed, blocked, in-progress — and emails the digest to the project owner.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"trello","name":"Trello"}]},{"title":"Trigger.dev compute cost reporter","prompt":"Create a weekly scheduled workflow that uses Trigger.dev Execute Query to aggregate compute cost and duration per task for the past week, and emails a cost report to the team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Typeform event survey analyzer","prompt":"Create a workflow that processes Typeform event survey responses, summarizes feedback themes, writes structured insights to a feedback table, and emails the organizer the digest.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"typeform","name":"Typeform"}]},{"title":"Vanta vulnerability SLA watcher","prompt":"Create a scheduled workflow that lists Vanta vulnerabilities with SLA deadlines in the next 7 days, groups them by severity and vulnerable asset, and emails the security team a prioritized remediation list.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"vanta","name":"Vanta"}]},{"title":"Wealthbox client review prep","prompt":"Create a workflow that runs the morning of each Wealthbox client meeting, gathers recent emails, notes, and tasks for that client, and emails the advisor a prep brief.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Wealthbox task auto-creator","prompt":"Build a workflow that listens for Gmail messages tagged \\"client action\\", classifies the action, and creates a matching task on the Wealthbox client record.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Wealthbox birthday reminder","prompt":"Build a scheduled workflow that runs daily, reads the Wealthbox contacts tracked in a table to find birthdays in the next 7 days, and emails advisors a reminder with a personalized message draft.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Workday comp review prep","prompt":"Create a scheduled workflow that pulls Workday workers and their current compensation, joins with a performance ratings table, drafts manager-by-manager compensation review packets as files, and emails each manager their packet ahead of the cycle.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"workday","name":"Workday"}]},{"title":"You.com long-running research","prompt":"Create a workflow that starts You.com Research in the background at frontier effort, then a scheduled workflow that checks the task with Get Research Task and emails the report when it completes.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"youcom","name":"You.com"}]},{"title":"YouTube channel performance digest","prompt":"Create a scheduled weekly workflow that pulls a YouTube channel’s public stats and recent videos, ranks the top performers by views, writes a digest file, and emails it to the content team.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"youtube","name":"YouTube"}]},{"title":"Zoom meeting prep brief","prompt":"Create a scheduled workflow that runs each morning, lists today’s Zoom meetings, researches attendees with Apollo and the web, and emails a prep brief 30 minutes before each meeting.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"zoom","name":"Zoom"},{"id":"apollo","name":"Apollo"}]},{"title":"Zoom webinar follow-up","prompt":"Build a workflow that runs after a Zoom webinar, pulls the registrant and attendee lists, sends a follow-up email with the recording link, and writes attendance into HubSpot for marketing scoring.","integrations":[{"id":"gmail","name":"Gmail"},{"id":"zoom","name":"Zoom"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"gong","type":"gong","slug":"gong","name":"Gong","description":"Read Gong data, upload calls, assign or unassign flow prospects, and request data erasure","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/gong","authType":"api-key","connections":[],"operations":[{"name":"List Calls","description":"Retrieve call data by date range from Gong."},{"name":"Create Call","description":"Upload call metadata to Gong and let Gong pull the media from a URL."},{"name":"Get Call","description":"Retrieve detailed data for a specific call from Gong."},{"name":"Get Call Transcript","description":"Retrieve transcripts of calls from Gong by call IDs or date range."},{"name":"Get Extensive Calls","description":"Retrieve detailed call data including trackers, topics, highlights, and AI spotlight content (brief, outline, key points, call outcome) from Gong."},{"name":"List Users","description":"List all users in your Gong account."},{"name":"Get User","description":"Retrieve details for a specific user from Gong."},{"name":"Aggregate Activity","description":"Retrieve aggregated activity statistics for users by date range from Gong."},{"name":"Day-by-Day Activity","description":"Retrieve detailed day-by-day activity (call IDs per activity type) for users by date range from Gong."},{"name":"Aggregate by Period","description":"Retrieve aggregated user activity grouped into time periods (day, week, month, quarter, year) by date range from Gong."},{"name":"Interaction Stats","description":"Retrieve interaction statistics for users by date range from Gong. Only includes calls with Whisper enabled."},{"name":"Answered Scorecards","description":"Retrieve answered scorecards for reviewed users or by date range from Gong."},{"name":"List Library Folders","description":"Retrieve library folders from Gong."},{"name":"Get Folder Content","description":"Retrieve the list of calls in a specific library folder from Gong."},{"name":"List Scorecards","description":"Retrieve scorecard definitions from Gong settings."},{"name":"List Trackers","description":"Retrieve smart tracker and keyword tracker definitions from Gong settings."},{"name":"List Workspaces","description":"List all company workspaces in Gong."},{"name":"List Flows","description":"List Gong Engage flows (sales engagement sequences)."},{"name":"Assign Flow Prospects","description":"Assign up to 200 CRM prospects (contacts or leads) to a Gong Engage flow."},{"name":"Unassign Flow Prospects","description":"Remove a prospect from Gong Engage flows. Omit the flow ID to remove the prospect from all flows they are assigned to."},{"name":"Get Prospect Flows","description":"Get the Gong Engage flows currently assigned to the given CRM prospects."},{"name":"Get Coaching","description":"Retrieve coaching metrics for a manager from Gong."},{"name":"Ask Anything","description":"Ask a natural-language question about a CRM account, deal, contact, or lead. Gong answers from up to 60 calls and 500 emails associated with the entity. Consumes Gong credits."},{"name":"Get Brief","description":"Generate an AI brief (configured in Gong Agent Studio) for a CRM account, deal, contact, or lead. Consumes Gong credits."},{"name":"Get Logs","description":"Retrieve Gong log entries of a specific type within a time range."},{"name":"Lookup Email","description":"Find all references to an email address in Gong (calls, email messages, meetings, CRM data, engagement)."},{"name":"Lookup Phone","description":"Find all references to a phone number in Gong (calls, email messages, meetings, CRM data, and associated contacts)."},{"name":"Purge Email Address","description":"Erase all Gong data (calls, email messages, leads, contacts) referencing an email address. Asynchronous and irreversible."},{"name":"Purge Phone Number","description":"Erase all Gong data (calls, leads, contacts) referencing a phone number. Asynchronous and irreversible."}],"triggers":[{"id":"gong_webhook","name":"Gong Webhook","description":"Generic webhook trigger for all Gong events"},{"id":"gong_call_completed","name":"Gong Call Completed","description":"Trigger workflow when a call is completed and processed in Gong"}],"skills":[{"name":"summarize-call","description":"Pull a Gong call transcript and produce a structured recap with topics, objections, and next steps.","content":"# Summarize Call\\n\\nUse Gong to turn a recorded call into a clean recap.\\n\\n## Steps\\n1. Get the call by its call ID to read the metadata (participants, duration, account).\\n2. Get the call transcript for the same call ID.\\n3. Identify the main topics, customer objections, and agreed next steps from the transcript.\\n\\n## Output\\nReturn a recap: a short overview, key topics discussed, objections raised, and a list of next steps with owners. Keep it grounded in the transcript."},{"name":"extract-deal-signals","description":"Read a Gong call transcript and extract CRM-ready deal signals like decision-maker, competitor, and next step.","content":"# Extract Deal Signals\\n\\nUse Gong to turn conversation content into structured deal attributes.\\n\\n## Steps\\n1. Get the call transcript for the given call ID.\\n2. Scan for high-value signals: decision-maker, budget, timeline, competitor mentions, use case, and the agreed next step with its date.\\n3. Normalize each signal into a structured field.\\n\\n## Output\\nReturn a structured object of deal attributes (decision_maker, competitor, next_step, next_step_date, use_case, and any others found). Leave fields null when not mentioned rather than guessing, so they can be written to CRM."},{"name":"review-recent-calls","description":"List recent Gong calls in a date range and produce a digest of themes and follow-ups across them.","content":"# Review Recent Calls\\n\\nUse Gong to summarize a batch of recent calls.\\n\\n## Steps\\n1. List calls (or use Get Extensive Calls) filtered by a date range and optionally by user or workspace.\\n2. For the most relevant calls, get the transcript to pull themes and outcomes.\\n3. Roll the findings up into recurring themes, common objections, and open follow-ups across the calls.\\n\\n## Output\\nReturn a digest: a per-call one-liner, the cross-call themes, and a consolidated follow-up list. Note any call missing a clear next step."}],"templates":[{"title":"Gong sales call analyzer","prompt":"Build a workflow that pulls call transcripts from Gong after each sales call, identifies key objections raised, action items promised, and competitor mentions, updates the deal record in my CRM, and posts a call summary with next steps to the Slack deal channel.","integrations":[{"id":"gong","name":"Gong"},{"id":"slack","name":"Slack"}]},{"title":"Gong objection tracker","prompt":"Build a scheduled weekly workflow that scans Gong sales calls for recurring objections, scores frequency and stage, and writes a competitive-intel digest to Slack.","integrations":[{"id":"gong","name":"Gong"},{"id":"slack","name":"Slack"}]},{"title":"Gong deal-risk surfacer","prompt":"Create a workflow that monitors Gong conversation intelligence signals, identifies deals at risk based on talk patterns, and posts a Slack alert to the AE and manager.","integrations":[{"id":"gong","name":"Gong"},{"id":"slack","name":"Slack"}]},{"title":"Gong coaching dashboard","prompt":"Build a scheduled weekly workflow that pulls Gong per-rep metrics — talk ratio, longest monologue, question rate — and writes a coaching table for managers.","integrations":[{"id":"gong","name":"Gong"}]},{"title":"Gong customer-quote miner","prompt":"Create a workflow that processes Gong customer interview calls, extracts notable quotes and themes, and writes them to a marketing research table.","integrations":[{"id":"gong","name":"Gong"}]},{"title":"Gong CRM auto-updater","prompt":"Build a workflow that runs after a Gong sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity with notes.","integrations":[{"id":"gong","name":"Gong"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Gong competitor-mention tracker","prompt":"Create a workflow that scans Gong calls for competitor mentions, captures context and outcome, and writes the competitive intel to a tracking table.","integrations":[{"id":"gong","name":"Gong"}]}]},{"id":"google_ads","type":"google_ads","slug":"google-ads","name":"Google Ads","description":"Query campaigns, ad groups, and performance metrics","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/google_ads","authType":"oauth","connections":[{"id":"google-ads","kind":"oauth","label":"Connect with OAuth","providerId":"google-ads","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_ads","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/adwords","label":"Manage Google Ads campaigns and reporting"}],"fields":[]}],"operations":[{"name":"List Customers","description":"List Google Ads accounts directly accessible by the authenticated user; query customer_client for manager subaccounts"},{"name":"List Campaigns","description":"List campaigns in a Google Ads account with optional status filtering"},{"name":"Campaign Performance","description":"Get performance metrics for Google Ads campaigns over a date range"},{"name":"List Ad Groups","description":"List ad groups in a Google Ads campaign"},{"name":"Ad Performance","description":"Get performance metrics for individual ads over a date range"},{"name":"Custom Query (GAQL)","description":"Run a custom Google Ads Query Language (GAQL) query"}],"triggers":[],"skills":[{"name":"report-campaign-performance","description":"Pull Google Ads campaign performance for a date range and produce a clear metrics report.","content":"# Report Campaign Performance\\n\\nUse Google Ads to summarize how campaigns are performing.\\n\\n## Steps\\n1. List campaigns for the customer to know what is active.\\n2. Use Campaign Performance over the chosen date range to pull daily impressions, clicks, cost in micros, conversions, and CTR. Aggregate daily counts before calculating ratios; never average daily CTR. Convert micros to account currency by dividing by 1,000,000. Derive CPC as cost/clicks only when clicks is nonzero; ROAS requires conversion value from a compatible Custom Query and nonzero cost.\\n3. Rank campaigns by spend and by efficiency to surface what is working and what is not.\\n\\n## Output\\nReturn a per-campaign metrics table plus a short narrative: top performers, underperformers, and where spend is being wasted. Follow nextPageToken with unchanged inputs for complete coverage. Note the date range, currency and any partial coverage; test accounts do not serve ads and may return no metrics."},{"name":"analyze-ad-performance","description":"Pull ad-level Google Ads performance and identify the best and worst creatives in each ad group.","content":"# Analyze Ad Performance\\n\\nUse Google Ads to compare creatives within campaigns.\\n\\n## Steps\\n1. List campaigns for the customer, then list ad groups for each target campaign.\\n2. Use Ad Performance over the date range to pull per-ad clicks, conversions, CTR, and cost.\\n3. Within each ad group, identify the strongest and weakest ads.\\n\\n## Output\\nReturn, per ad group, the best and worst performing ads with their key metrics, plus a recommendation (scale, pause, or rewrite). Aggregate daily counts before comparing ratios; follow nextPageToken with unchanged inputs. Keep recommendations tied to sufficient data and leave changes to ads for human review."},{"name":"run-gaql-query","description":"Run a custom GAQL query against Google Ads to answer a specific reporting question.","content":"# Run GAQL Query\\n\\nUse Google Ads to answer an ad-hoc reporting question with GAQL.\\n\\n## Steps\\n1. Clarify the metrics, dimensions, and segments the question needs.\\n2. Write a valid GAQL query (SELECT fields FROM resource WHERE conditions) scoped to the customer and date range.\\n3. Use the Custom Query operation to run it and read the rows. Follow nextPageToken with the identical query and customer until it is null or an explicit user limit is reached. Report any partial coverage.\\n\\n## Output\\nReturn the result rows as a clean table along with the GAQL query that produced them, so the analysis is reproducible."}],"templates":[{"title":"Google Ads spend pacing","prompt":"Build a scheduled daily workflow that pulls Google Ads campaign spend, compares against monthly budget, and posts a Slack alert when any campaign is pacing more than 15% over.","integrations":[{"id":"google_ads","name":"Google Ads"},{"id":"slack","name":"Slack"}]},{"title":"Google Ads keyword performance report","prompt":"Create a scheduled weekly workflow that pulls Google Ads keyword performance, flags keywords with rising CPCs or dropping CTRs, and writes a recommendation list to a file.","integrations":[{"id":"google_ads","name":"Google Ads"}]},{"title":"Google Ads negative-keyword finder","prompt":"Build a scheduled workflow that scans Google Ads search-term performance weekly, identifies irrelevant terms wasting spend, and writes a recommended negative-keyword list to a file for the team to review.","integrations":[{"id":"google_ads","name":"Google Ads"}]},{"title":"Google Ads + Stripe ROAS tracker","prompt":"Create a scheduled workflow that joins Google Ads spend with Stripe revenue only where an explicit campaign ID or UTM mapping was captured, reports unmatched revenue separately, calculates attributed ROAS with that limitation, and posts the per-channel breakdown to Slack each morning.","integrations":[{"id":"google_ads","name":"Google Ads"},{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Google Ads + PageSpeed landing audit","prompt":"Create a scheduled workflow that for active Google Ads campaigns runs Google PageSpeed on the landing pages weekly, flags slow LPs, and pings the marketing team.","integrations":[{"id":"google_ads","name":"Google Ads"},{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"slack","name":"Slack"}]},{"title":"Google Ads + Profound brand comparison","prompt":"Build a scheduled workflow that joins Google Ads spend per campaign with Profound AI brand-visibility scores, writes a comparison table without claiming causal attribution, and posts findings to Slack.","integrations":[{"id":"google_ads","name":"Google Ads"},{"id":"profound","name":"Profound"},{"id":"slack","name":"Slack"}]},{"title":"Google Ads creative auditor","prompt":"Create a scheduled workflow that pulls Google Ads creatives, scores ad copy quality with an agent, and writes a per-campaign creative review file.","integrations":[{"id":"google_ads","name":"Google Ads"}]}]},{"id":"google_appsheet","type":"google_appsheet","slug":"google-appsheet","name":"Google AppSheet","description":"Read, add, edit, and delete rows in a Google AppSheet table","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/google_appsheet","authType":"api-key","connections":[],"operations":[{"name":"Find Rows","description":"Read rows from an AppSheet table. Omit the selector to return every row, or provide a Selector expression (Filter/Select/OrderBy/Top) to narrow and shape the results."},{"name":"Add Rows","description":"Add new rows to an AppSheet table. The key column value must be provided explicitly, or omitted when its Initial value expression generates it automatically (e.g. UNIQUEID())."},{"name":"Edit Rows","description":"Update existing rows in an AppSheet table. Each row must explicitly include the key column name and value, plus any columns to change."},{"name":"Delete Rows","description":"Delete rows from an AppSheet table. Each row only needs to include the key column name and value."}],"triggers":[],"skills":[{"name":"add-appsheet-row","description":"Add a new row to an AppSheet table in response to an external event.","content":"# Add AppSheet Row\\n\\nCreate a new row in an AppSheet table, e.g. when a form is submitted or an external event fires.\\n\\n## Steps\\n1. Set App ID and Table Name for the target table.\\n2. Provide the Rows JSON array with one object per new row, e.g. `[{ \\"FirstName\\": \\"Jan\\", \\"LastName\\": \\"Jones\\" }]`.\\n3. Give the key column an explicit value, or omit it if its Initial value expression (e.g. UNIQUEID()) generates it automatically.\\n4. Run the Add Rows operation and confirm the returned row includes the generated key.\\n\\n## Output\\nThe newly created row(s), including any generated key values, plus a row count."},{"name":"find-appsheet-rows","description":"Query an AppSheet table with a Selector expression to filter, sort, or limit rows.","content":"# Find AppSheet Rows\\n\\nRead rows from an AppSheet table, optionally filtered and sorted with a Selector expression.\\n\\n## Steps\\n1. Set App ID and Table Name for the target table.\\n2. Leave Selector blank to return every row, or provide an expression such as `Filter(TableName, [Status] = \\"Open\\")`.\\n3. Combine `OrderBy()` and `Top()` to sort and limit results, e.g. `Top(OrderBy(Filter(TableName, true), [Date], true), 10)`.\\n4. Run the Find Rows operation.\\n\\n## Output\\nThe matching rows and a row count, ready to feed into an agent or a downstream integration."},{"name":"sync-appsheet-updates-to-sheet","description":"Mirror updated AppSheet rows into a Google Sheet to maintain a real-time audit trail.","content":"# Sync AppSheet Updates to a Sheet\\n\\nKeep a Google Sheet in sync with changes to an AppSheet table, mirroring the pattern used in AppSheet-Zapier integrations for audit trails.\\n\\n## Steps\\n1. Use Find Rows with a Selector expression that isolates recently changed rows (e.g. filtered by a LastModified column).\\n2. For each row, append or update the corresponding row in a Google Sheet.\\n3. Schedule the workflow to run on an interval so the sheet stays current.\\n\\n## Output\\nA Google Sheet that reflects the latest AppSheet row data, useful as a shareable audit trail or reporting source."}],"templates":[{"title":"AppSheet order intake","prompt":"Build a workflow triggered by a form submission that adds a new row to an AppSheet Orders table, then posts a confirmation message to Slack with the order details.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"},{"id":"slack","name":"Slack"}]},{"title":"AppSheet daily status digest","prompt":"Create a scheduled workflow that runs daily, finds all AppSheet rows where Status is \\"Open\\", summarizes them with an agent, and emails the summary to the operations team.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"},{"id":"gmail","name":"Gmail"}]},{"title":"AppSheet inventory sync","prompt":"Build a workflow that reads updated rows from an AppSheet Inventory table, transforms the quantities with an agent, and writes the reconciled totals into a Google Sheet.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"AppSheet ticket escalation","prompt":"Build a workflow that finds AppSheet rows where Priority is \\"High\\" and Status is not \\"Resolved\\", and edits each row to add an Escalated flag, then creates a Linear issue for each one.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"},{"id":"linear","name":"Linear"}]},{"title":"AppSheet cleanup job","prompt":"Create a scheduled workflow that finds AppSheet rows older than 90 days with Status \\"Archived\\" and deletes them, then logs a summary of how many rows were removed to a table.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"AppSheet lead router","prompt":"Build a workflow that finds new AppSheet rows in a Leads table, uses an agent to classify each lead by region, and edits the row to assign the correct sales rep.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"AppSheet field service report","prompt":"Build a workflow that finds all AppSheet rows completed today in a Work Orders table, generates a summary report with an agent, and saves it as a file for the team.","integrations":[{"id":"google_appsheet","name":"Google AppSheet"}]}]},{"id":"google_bigquery","type":"google_bigquery","slug":"google-bigquery","name":"Google BigQuery","description":"Query, list, and insert data in Google BigQuery","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/google_bigquery","authType":"oauth","connections":[{"id":"google-bigquery","kind":"oauth","label":"Connect with OAuth","providerId":"google-bigquery","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_bigquery","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/bigquery","label":"View and manage data in Google BigQuery"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Run Query","description":"Run a SQL query against Google BigQuery and return the results"},{"name":"Get Query Results","description":"Fetch results for a previously submitted BigQuery job, or the next page of a Run Query result"},{"name":"List Datasets","description":"List all datasets in a Google BigQuery project"},{"name":"Create Dataset","description":"Create a new dataset in a Google BigQuery project"},{"name":"Delete Dataset","description":"Delete a dataset from a Google BigQuery project"},{"name":"List Tables","description":"List all tables in a Google BigQuery dataset"},{"name":"Get Table","description":"Get metadata and schema for a Google BigQuery table"},{"name":"Create Table","description":"Create a new table in a Google BigQuery dataset"},{"name":"Delete Table","description":"Delete a table from a Google BigQuery dataset"},{"name":"List Table Data","description":"Preview rows from a Google BigQuery table without running a query. Pair with Get Table to know the column order."},{"name":"Insert Rows","description":"Insert rows into a Google BigQuery table using streaming insert"}],"triggers":[],"skills":[{"name":"answer-question-with-sql","description":"Inspect BigQuery schema, translate a natural-language question into safe SQL, run it, and return results.","content":"# Answer Question With SQL\\n\\nUse BigQuery to answer a data question from plain English.\\n\\n## Steps\\n1. List datasets and tables, and Get Table on the relevant ones to understand the schema and column types.\\n2. Translate the question into a single read-only BigQuery Standard SQL query, scoping it with filters and a LIMIT to control cost.\\n3. Use Run Query to execute it.\\n\\n## Output\\nReturn the result rows as a table plus the exact SQL query used, so the answer is verifiable. If the schema cannot support the question, say what is missing."},{"name":"explore-dataset-schema","description":"List BigQuery datasets and tables and summarize the schema of a dataset for an analyst.","content":"# Explore Dataset Schema\\n\\nUse BigQuery to map out what data is available.\\n\\n## Steps\\n1. List datasets in the project.\\n2. List tables in the target dataset.\\n3. Get Table on each relevant table to read its columns, types, and descriptions.\\n\\n## Output\\nReturn a structured schema summary: each table with its columns, types, and a one-line purpose. Highlight likely join keys so an analyst can plan queries."},{"name":"load-rows-to-table","description":"Insert structured rows into a BigQuery table for logging or pipeline output.","content":"# Load Rows to Table\\n\\nUse BigQuery to write structured records into a table.\\n\\n## Steps\\n1. Confirm the target dataset and table, and Get Table to verify the expected columns and types.\\n2. Shape the incoming records to match the table schema exactly.\\n3. Use Insert Rows to write the batch.\\n\\n## Output\\nReturn the count of rows inserted and any rows rejected with their error. If types did not match the schema, report which fields failed rather than silently dropping data."},{"name":"provision-dataset-and-table","description":"Create a new BigQuery dataset and table with a defined schema for a new pipeline or logging destination.","content":"# Provision Dataset and Table\\n\\nUse BigQuery to set up a new destination for structured data.\\n\\n## Steps\\n1. Use Create Dataset with a dataset ID and location.\\n2. Define the column schema (name, type, mode) for the target table.\\n3. Use Create Table with that schema inside the new dataset.\\n\\n## Output\\nReturn the created dataset ID, table ID, and the resolved schema so downstream steps can insert rows with confidence the columns match."}],"templates":[{"title":"Airtable to data-warehouse sync","prompt":"Create a scheduled workflow that exports an Airtable base to BigQuery nightly with schema mapping, partitions by ingestion date, and writes the run history to a control table.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"airtable","name":"Airtable"}]},{"title":"BigQuery scheduled report runner","prompt":"Build a scheduled workflow that runs a saved BigQuery query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"slack","name":"Slack"}]},{"title":"BigQuery customer 360 builder","prompt":"Create a scheduled workflow that joins BigQuery sources — Stripe, product events, support tickets — into a single per-customer profile table refreshed daily.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"BigQuery cost-tracking alerts","prompt":"Build a scheduled daily workflow that pulls BigQuery slot and storage usage, projects month-end spend, and posts a Slack alert when projection exceeds budget.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"slack","name":"Slack"}]},{"title":"BigQuery anomaly notifier","prompt":"Create a workflow that runs BigQuery anomaly-detection queries on key metrics hourly, writes any anomalies to a tracking table, and pages the on-call data team on severe deltas.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"BigQuery + Sheets exec dashboard","prompt":"Build a scheduled workflow that pulls a BigQuery executive dashboard query weekly, writes the result into a chosen Google Sheet, and notifies leadership the new snapshot is ready.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"google_sheets","name":"Google Sheets"},{"id":"gmail","name":"Gmail"}]},{"title":"BigQuery schema drift detector","prompt":"Create a scheduled workflow that snapshots BigQuery dataset schemas, diffs against the prior snapshot, and opens a Linear ticket on unexpected schema changes.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"linear","name":"Linear"}]},{"title":"BigQuery NL analytics agent","prompt":"Build a Slack agent that lists BigQuery datasets and tables to understand the schema, translates a teammate\'s natural-language question into a safe BigQuery SQL query, runs it, and replies with the result table plus the query used.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"slack","name":"Slack"}]},{"title":"Google Slides exec metrics deck","prompt":"Create a scheduled monthly workflow that generates a Google Slides executive metrics deck from BigQuery and Stripe data, swaps the cover with the month, and shares it with leadership.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"google_slides","name":"Google Slides"},{"id":"stripe","name":"Stripe"}]},{"title":"RDS + BigQuery analytics mirror","prompt":"Build a scheduled workflow that queries analytical tables from Amazon RDS, loads the rows into BigQuery for downstream BI, and writes a sync log to a table.","integrations":[{"id":"google_bigquery","name":"Google BigQuery"},{"id":"rds","name":"Amazon RDS"}]}]},{"id":"google_books","type":"google_books","slug":"google-books","name":"Google Books","description":"Search and retrieve book information","category":"Search","docsUrl":"https://docs.sim.ai/integrations/google_books","authType":"api-key","connections":[],"operations":[{"name":"Search Volumes","description":"Search for books using the Google Books API"},{"name":"Get Volume Details","description":"Get detailed information about a specific book volume"}],"triggers":[],"skills":[{"name":"find-books-on-topic","description":"Search Google Books for the most relevant titles on a topic and return a ranked, summarized list.","content":"# Find Books on a Topic\\n\\nUse Google Books to discover authoritative titles for a subject and present a clean shortlist.\\n\\n## Steps\\n1. Take the topic or question from the request.\\n2. Run a Search Volumes operation with a focused query. Use field operators when helpful: `intitle:`, `inauthor:`, `subject:`. Set Order By to `relevance` (or `newest` for recent works).\\n3. Set Max Results (1-40) and optionally filter by Print Type (books) or eBook availability.\\n4. For the top hits, read title, authors, publisher, published date, average rating, and a short description.\\n5. Rank by relevance and rating; drop clearly off-topic results.\\n\\n## Output\\nA numbered list of up to 10 books, each with title, author(s), year, rating (if present), one-line summary, and the preview/info link. Note if a result set is thin so the requester can broaden the query."},{"name":"lookup-book-by-isbn","description":"Resolve an ISBN or title into a single canonical book record with full metadata.","content":"# Look Up a Book by ISBN or Title\\n\\nResolve a specific book to its canonical Google Books record.\\n\\n## Steps\\n1. If you have an ISBN, run Search Volumes with query `isbn:`. Otherwise search by `intitle:` plus `inauthor:` to disambiguate.\\n2. Pick the best-matching volume and capture its volume ID.\\n3. Run Get Volume Details on that volume ID for the fullest metadata.\\n4. Collect title, subtitle, authors, publisher, published date, page count, categories, language, ISBN-10/13, and description.\\n\\n## Output\\nA single structured record: title, authors, publisher, year, ISBNs, page count, categories, and the info link. If multiple editions match, list them and flag which is most likely intended."},{"name":"build-reading-list","description":"Assemble a curated, themed reading list with summaries from Google Books search results.","content":"# Build a Reading List\\n\\nTurn a topic into a curated reading list a person can act on.\\n\\n## Steps\\n1. Identify the theme and any constraints (level, recency, language) from the request.\\n2. Run one or more Search Volumes queries covering the main subtopics; use `langRestrict` and `orderBy` as needed.\\n3. For each candidate, capture authors, year, rating, and description.\\n4. Deduplicate editions of the same work and keep the best edition.\\n5. Group the final picks into 2-4 logical sections (e.g., foundational, advanced, recent).\\n\\n## Output\\nA grouped reading list. Each entry: title, author(s), year, a one-sentence reason it is included, and the preview link. Keep it to 8-15 titles unless asked otherwise."}],"templates":[{"title":"Google Books citation finder","prompt":"Build a workflow that takes a topic, queries Google Books for relevant titles and quotes, and writes a citations bibliography file for research papers.","integrations":[{"id":"google_books","name":"Google Books"}]},{"title":"Google Books reading list builder","prompt":"Create a workflow that takes a topic, finds top-rated Google Books titles, writes a curated reading-list file with summaries, and emails it to the user.","integrations":[{"id":"google_books","name":"Google Books"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Books research enricher","prompt":"Build a workflow that for each topic in a research table queries Google Books for foundational works, captures the key passages, and writes them to a knowledge base.","integrations":[{"id":"google_books","name":"Google Books"}]},{"title":"Google Books quote miner","prompt":"Create a workflow that searches Google Books for quotes on a topic, scores by relevance, and writes the top quotes to a marketing content table.","integrations":[{"id":"google_books","name":"Google Books"}]},{"title":"Google Books bibliographic agent","prompt":"Build a research agent that uses Google Books as one of its tools to find canonical sources and properly cite them in answers with ISBN and page references.","integrations":[{"id":"google_books","name":"Google Books"}]},{"title":"Google Books due-diligence helper","prompt":"Create a workflow that for a tracked person or company searches Google Books for prior publications and citations, and writes the findings to a CRM intel record.","integrations":[{"id":"google_books","name":"Google Books"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Books topic explorer","prompt":"Build an agent that explores a topic across Google Books, identifies adjacent themes from book metadata, and writes a topic map to a research file.","integrations":[{"id":"google_books","name":"Google Books"}]}]},{"id":"google_calendar","type":"google_calendar_v2","slug":"google-calendar","name":"Google Calendar","description":"Manage Google Calendar events","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/google_calendar","authType":"oauth","connections":[{"id":"google-calendar","kind":"oauth","label":"Connect with OAuth","providerId":"google-calendar","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_calendar","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/calendar","label":"View and manage calendar"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Create Event","description":"Create a new event in Google Calendar"},{"name":"List Events","description":"List events from Google Calendar"},{"name":"Get Event","description":"Get a specific event from Google Calendar"},{"name":"Update Event","description":"Update an existing event in Google Calendar"},{"name":"Delete Event","description":"Delete an event from Google Calendar"},{"name":"Move Event","description":"Move an event to a different calendar"},{"name":"Get Recurring Instances","description":"Get instances of a recurring event from Google Calendar"},{"name":"List Calendars","description":"List all calendars in the user\'s calendar list"},{"name":"Quick Add (Natural Language)","description":"Create events from natural language text"},{"name":"Invite Attendees","description":"Invite attendees to an existing Google Calendar event"},{"name":"Respond to Invitation (RSVP)","description":"RSVP to a Google Calendar event (accept, decline, or tentative) as the connected account. Only your own response changes; other guests are left untouched."},{"name":"Check Free/Busy","description":"Query free/busy information for one or more Google Calendars"},{"name":"Create Calendar","description":"Create a new secondary calendar"},{"name":"Update Calendar","description":"Update a secondary calendar\'s metadata (title, description, location, time zone)"},{"name":"Delete Calendar","description":"Permanently delete a secondary calendar (not the primary calendar)"},{"name":"Share Calendar","description":"Grant a user, group, or domain access to a calendar by creating an ACL rule"},{"name":"Update Sharing","description":"Change the access role granted by an existing calendar sharing (ACL) rule"},{"name":"List Sharing","description":"List the access control rules (sharing) for a calendar"},{"name":"Remove Sharing","description":"Revoke an access control rule (sharing) from a calendar"}],"triggers":[{"id":"google_calendar_poller","name":"Google Calendar Event Trigger","description":"Triggers when events are created, updated, or cancelled in Google Calendar"}],"skills":[{"name":"schedule-meeting","description":"Create a Google Calendar event with the right time, attendees, and details, sending invites.","content":"# Schedule a Meeting\\n\\nCreate a calendar event and invite attendees.\\n\\n## Steps\\n1. Determine the calendar (default to `primary`), title, start and end times, location, and description from the request.\\n2. Convert times to ISO 8601 with the correct timezone offset (e.g., `2025-06-03T10:00:00-08:00`).\\n3. If the request is conversational (e.g., \\"lunch with John tomorrow at noon\\"), use Quick Add instead of building each field by hand.\\n4. Run Create Event (or Quick Add) with the attendee emails as a comma-separated list.\\n5. Set Send Email Notifications to `all` so attendees are invited.\\n\\n## Output\\nConfirm the created event: title, start/end in a readable format, attendees, and the event link (htmlLink). If a conflict is likely, note it."},{"name":"summarize-daily-agenda","description":"List today\'s Google Calendar events and produce a clean, ordered agenda summary.","content":"# Summarize the Daily Agenda\\n\\nProduce a readable agenda for a day or window.\\n\\n## Steps\\n1. Resolve the target window into UTC ISO timestamps for Start Time Filter (timeMin) and End Time Filter (timeMax). For \\"today\\", use 00:00:00Z to 23:59:59Z.\\n2. Run List Events on the chosen calendar with those filters and a reasonable Max Results.\\n3. Sort events chronologically and read summary, start/end, location, and attendees for each.\\n4. Flag back-to-back meetings and any event with no agenda or description.\\n\\n## Output\\nA chronological agenda. Each line: time range, title, location (if any), and attendee count. Add a short header with total meetings and total meeting hours."},{"name":"find-and-reschedule-event","description":"Locate an existing event and update its time, attendees, or details.","content":"# Find and Reschedule an Event\\n\\nUpdate an existing calendar event.\\n\\n## Steps\\n1. If you do not have the event ID, run List Events over a suitable window and match by title/attendees to find the event ID.\\n2. Run Get Event to read the current details and confirm it is the right one.\\n3. Run Update Event with only the changed fields (new start/end in ISO 8601 with offset, new attendees, new location, or title).\\n4. Set Send Email Notifications to `all` so attendees see the change.\\n\\n## Output\\nConfirm what changed (old vs new time/attendees) and return the event link. If multiple events matched, list them and ask which to update before changing anything destructive."},{"name":"invite-attendees-to-event","description":"Add attendees to an existing Google Calendar event and notify them.","content":"# Invite Attendees to an Event\\n\\nAdd people to an event without recreating it.\\n\\n## Steps\\n1. Obtain the event ID (use List Events to find it if needed).\\n2. Collect the attendee emails to add as a comma-separated list.\\n3. Run Invite Attendees with Replace Existing set to `Add to existing attendees` (unless asked to replace the whole list).\\n4. Set Send Email Notifications to `all`.\\n\\n## Output\\nConfirm the added attendees and the resulting full attendee list, with the event link."},{"name":"rsvp-to-event","description":"Accept, decline, or tentatively accept a Google Calendar invitation.","content":"# RSVP to an Event\\n\\nChange your own response to an invitation without touching the guest list.\\n\\n## Steps\\n1. Find the event with List Events over the right time window. List Events returns each occurrence of a recurring meeting with its own ID, so responding with that ID changes only that occurrence.\\n2. Run Respond to Invitation (RSVP) with Response set to `Yes (accept)`, `No (decline)`, or `Maybe (tentative)`, and an optional note.\\n3. Do not use Update Event or Invite Attendees to RSVP; they edit the guest list, not your response.\\n\\n## Output\\nConfirm the event title, the occurrence start time, and the confirmed response returned by the tool."}],"templates":[{"title":"Discord event reminder","prompt":"Create a scheduled workflow that reads upcoming Luma or Google Calendar events, posts a reminder in the matching Discord channel 24 hours before, and pings RSVP attendees by role.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"discord","name":"Discord"},{"id":"luma","name":"Luma"}]},{"title":"Calendar meeting prep agent","prompt":"Create an agent that checks my Google Calendar each morning, researches every attendee and topic on the web, and prepares a brief for each meeting so I walk in fully prepared. Schedule it to run every weekday morning.","integrations":[{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Calendar SMS appointment reminders","prompt":"Create a scheduled workflow that checks Google Calendar each morning for appointments in the next 24 hours, and sends an SMS reminder to each attendee via Twilio with the meeting time, location, and any prep notes.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Booking-to-calendar scheduler","prompt":"Build a workflow that on a new Calendly booking creates the matching Google Calendar event, invites the attendees, attaches the meeting agenda, and writes the event link back so both systems stay in sync.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"calendly","name":"Calendly"}]},{"title":"Calendar daily agenda digest","prompt":"Create a scheduled weekday workflow that lists my Google Calendar events for the day, summarizes them with attendee context and prep notes, and posts a clean morning agenda to Slack.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"slack","name":"Slack"}]},{"title":"Calendar interview scheduler","prompt":"Build a workflow that when a candidate reaches the interview stage finds open slots across the panel\'s Google Calendars, creates the interview event with the video link, invites everyone, and emails the candidate the confirmation.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"gmail","name":"Gmail"}]},{"title":"Calendar meeting-load weekly report","prompt":"Create a scheduled weekly workflow that lists Google Calendar events for the team, computes total meeting hours and recurring-meeting load per person, writes the breakdown to a table, and flags anyone over the focus-time threshold.","integrations":[{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Calendar event note-taker prep","prompt":"Build a workflow that scans upcoming Google Calendar events for external meetings, researches each company and attendee, drafts talking points, and updates the event description so the notes travel with the invite.","integrations":[{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Google Contacts + Calendar grouper","prompt":"Create a workflow that groups Google Contacts into labels based on meeting frequency in Google Calendar, so frequent collaborators are easy to find when composing emails.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Tasks calendar block builder","prompt":"Build a workflow that on a Google Tasks creation also inserts a Google Calendar focus block with the task title, so the time is actually reserved.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Greenhouse to onboarding kickoff","prompt":"Build a workflow that fires when a Greenhouse application is marked hired, gathers the new hire profile, kicks off an onboarding plan in a table, schedules week-one meetings via Google Calendar, and posts a welcome announcement to Slack.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse interview scheduler","prompt":"Build a workflow that runs after a Greenhouse application reaches the interview stage, finds the right interviewer panel based on job stage, proposes time slots from Google Calendar, drafts a coordination email to the candidate, and confirms the booking in a tracking table.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"greenhouse","name":"Greenhouse"},{"id":"gmail","name":"Gmail"}]},{"title":"Luma calendar import","prompt":"Build a scheduled workflow that pulls the Luma event guest list and creates a personalized Google Calendar invite for each new registrant with the event details, location, and prep links.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"luma","name":"Luma"}]},{"title":"Obsidian daily journal agent","prompt":"Build a workflow that pulls calendar events, completed tasks, and journal prompts, and generates a daily Obsidian note draft for the user to review and annotate.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"obsidian","name":"Obsidian"}]},{"title":"Rippling new-hire provisioning","prompt":"Build a scheduled workflow that polls Rippling for new workers, creates accounts in the matching downstream tools, drops each new hire into the right Slack channels, books day-one onboarding via Google Calendar, and writes provisioning status to a tracking table.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"rippling","name":"Rippling"},{"id":"slack","name":"Slack"}]},{"title":"Rippling manager change alerts","prompt":"Create a scheduled workflow that polls Rippling workers for manager reassignments, notifies the worker and the new manager via email, schedules a thirty-minute intro on Google Calendar, and logs the transition in a tracking table for HR visibility.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"rippling","name":"Rippling"},{"id":"gmail","name":"Gmail"}]},{"title":"Slack onboarding automation","prompt":"Build a workflow that when triggered with a new hire\'s info, creates their accounts, sends a personalized welcome message in Slack, schedules 1:1s with their team on Google Calendar, shares relevant onboarding docs from the knowledge base, and tracks completion in a table.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"slack","name":"Slack"}]},{"title":"WhatsApp appointment confirmations","prompt":"Build a workflow that reads upcoming Google Calendar appointments each morning and sends a WhatsApp confirmation with date, time, and a one-tap reschedule link.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"whatsapp","name":"WhatsApp"}]},{"title":"Workday new-hire kickoff","prompt":"Build a scheduled workflow that polls Workday for newly hired employees, gathers each one’s position and start date, kicks off provisioning in downstream tools, assigns an onboarding plan, schedules introductions on Google Calendar, and notifies the team in Slack.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"workday","name":"Workday"},{"id":"slack","name":"Slack"}]},{"title":"Workday termination workflow","prompt":"Build a workflow triggered by an approved offboarding request that initiates the Workday Terminate Employee business process, deactivates downstream accounts, schedules an exit interview on Google Calendar, and writes a compliance record to an audit table.","integrations":[{"id":"google_calendar","name":"Google Calendar"},{"id":"workday","name":"Workday"}]}]},{"id":"google_contacts","type":"google_contacts","slug":"google-contacts","name":"Google Contacts","description":"Manage Google Contacts","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/google_contacts","authType":"oauth","connections":[{"id":"google-contacts","kind":"oauth","label":"Connect with OAuth","providerId":"google-contacts","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_contacts","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/contacts","label":"View and manage Google Contacts"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Create Contact","description":"Create a new contact in Google Contacts"},{"name":"Get Contact","description":"Get a specific contact from Google Contacts"},{"name":"List Contacts","description":"List contacts from Google Contacts"},{"name":"Search Contacts","description":"Search contacts in Google Contacts by name, email, phone, or organization"},{"name":"Update Contact","description":"Update an existing contact in Google Contacts"},{"name":"Delete Contact","description":"Delete a contact from Google Contacts"}],"triggers":[],"skills":[{"name":"add-contact","description":"Create a new Google Contact with name, email, phone, and organization details.","content":"# Add a Contact\\n\\nCreate a new entry in Google Contacts.\\n\\n## Steps\\n1. Gather the contact fields from the request: first name (required), last name, email, phone, organization, job title, and notes.\\n2. Before creating, run Search Contacts on the email or full name to avoid duplicates.\\n3. If no match exists, run Create Contact with the gathered fields and the appropriate email/phone types (work, home, mobile).\\n4. Capture the new resource name from the response.\\n\\n## Output\\nConfirm the created contact with name, email, organization, and the resource name. If a likely duplicate was found, surface it and ask before creating."},{"name":"find-contact","description":"Search Google Contacts by name, email, phone, or organization and return matches.","content":"# Find a Contact\\n\\nLook up someone in Google Contacts.\\n\\n## Steps\\n1. Build a query from whatever identifier you have (name, email, phone, or organization).\\n2. Run Search Contacts with that query and a sensible Page Size.\\n3. If you need full details for one match, take its resource name and run Get Contact.\\n\\n## Output\\nA list of matching contacts with name, email, phone, organization, and resource name. If exactly one matches, return its full record; if several match, list them so the requester can disambiguate."},{"name":"update-contact-details","description":"Update fields on an existing Google Contact such as email, phone, or job title.","content":"# Update Contact Details\\n\\nModify an existing Google Contact safely.\\n\\n## Steps\\n1. If you do not have the resource name, run Search Contacts to find it.\\n2. Run Get Contact to read the current values and capture the ETag (required for updates).\\n3. Run Update Contact with the resource name, the ETag, and the changed fields only.\\n4. If the update fails on a stale ETag, re-run Get Contact and retry with the fresh ETag.\\n\\n## Output\\nConfirm which fields changed (old vs new) and return the updated record. Never update without first fetching the current ETag."}],"templates":[{"title":"Google Contacts CRM sync","prompt":"Build a scheduled workflow that mirrors Google Contacts into HubSpot, adding new contacts and updating fields, and writing a sync log for hygiene tracking.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Google Contacts duplicate cleaner","prompt":"Create a scheduled workflow that scans Google Contacts for duplicates, merges them deterministically, and writes a cleanup report for review.","integrations":[{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Contacts enricher","prompt":"Build a scheduled workflow that scans Google Contacts for entries missing company or title, enriches each via Apollo, and writes the enriched contact back to Google Contacts.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"apollo","name":"Apollo"}]},{"title":"Google Contacts + Calendar grouper","prompt":"Create a workflow that groups Google Contacts into labels based on meeting frequency in Google Calendar, so frequent collaborators are easy to find when composing emails.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Google Contacts birthday reminder","prompt":"Build a scheduled workflow that runs daily, surfaces upcoming birthdays from Google Contacts, and emails the user a reminder with personalized message suggestions.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Contacts deal-mapper","prompt":"Create a workflow that maps Google Contacts to active Salesforce opportunities by email domain, tagging contacts as deal-relevant for fast follow-ups.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Contacts new-hire onboarder","prompt":"Build a workflow that on a new hire in Workday adds the new employee to relevant Google Contacts groups based on department and team.","integrations":[{"id":"google_contacts","name":"Google Contacts"},{"id":"workday","name":"Workday"}]}]},{"id":"google_docs","type":"google_docs","slug":"google-docs","name":"Google Docs","description":"Read, write, create, and edit documents","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/google_docs","authType":"oauth","connections":[{"id":"google-docs","kind":"oauth","label":"Connect with OAuth","providerId":"google-docs","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_docs","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/drive.file","label":"View and manage Google Drive files you open or create with Sim"},{"id":"https://www.googleapis.com/auth/drive","label":"View, edit, create, and delete all Google Drive files"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Read Document","description":"Read content from a Google Docs document"},{"name":"Write to Document","description":"Append content to a Google Docs document. Content is inserted literally; Markdown is not interpreted. For formatted output from Markdown, use the Create operation with the markdown toggle enabled."},{"name":"Create Document","description":"Create a new Google Docs document"},{"name":"Insert Text","description":"Insert text at a specific index in a Google Docs document. When no index is provided, text is appended to the end of the document. Text is inserted literally; Markdown is not interpreted."},{"name":"Find & Replace Text","description":"Replace all occurrences of a search string with new text across a Google Docs document."},{"name":"Insert Table","description":"Insert an empty table with the given number of rows and columns into a Google Docs document. When no index is provided, the table is appended to the end of the document."},{"name":"Insert Image","description":"Insert an inline image from a public URL into a Google Docs document. The image must be publicly accessible and under 50 MB. When no index is provided, the image is appended to the end of the document."},{"name":"Insert Page Break","description":"Insert a page break into a Google Docs document. When no index is provided, the page break is appended to the end of the document."},{"name":"Apply Text Style","description":"Apply bold, italic, underline, and/or font size to a range of text in a Google Docs document, identified by its start and end character index."},{"name":"Apply Paragraph Style","description":"Apply a named paragraph style (such as a heading or title) and/or alignment to the paragraphs overlapping a range of text in a Google Docs document, identified by its start and end character index."},{"name":"Create Bullets","description":"Add bulleted or numbered list formatting to the paragraphs overlapping a range of text in a Google Docs document, using a chosen bullet glyph preset."},{"name":"Delete Bullets","description":"Remove bullet or numbered list formatting from the paragraphs overlapping a range of text in a Google Docs document, identified by its start and end character index."},{"name":"Delete Content Range","description":"Delete all content between a start and end character index in a Google Docs document. The endIndex is exclusive and must be greater than the startIndex."},{"name":"Create Named Range","description":"Create a named range over a span of content in a Google Docs document so it can be referenced or deleted later. The name may be 1-256 characters and need not be unique."},{"name":"Delete Named Range","description":"Delete one or more named ranges from a Google Docs document by their ID or by name. Provide exactly one of namedRangeId or name; deleting by name removes all ranges sharing that name. The content itself is not removed."}],"triggers":[],"skills":[{"name":"create-document-from-content","description":"Create a new Google Doc with a title and formatted content in a chosen folder.","content":"# Create a Document from Content\\n\\nGenerate a new Google Doc from supplied or drafted content.\\n\\n## Steps\\n1. Determine the document title and the body content from the request.\\n2. If the content uses headings, bold, lists, tables, or links, enable the Markdown option so it renders as formatted Doc content; otherwise leave it off for plain text.\\n3. Optionally set the parent folder ID to file the doc in the right place.\\n4. Run the Create Document operation with the title, content, and folder.\\n\\n## Output\\nConfirm creation and return the document ID and link. If a folder was specified, confirm it was placed there."},{"name":"summarize-document","description":"Read a Google Doc and produce a concise summary with key points and action items.","content":"# Summarize a Document\\n\\nRead a Doc and distill it.\\n\\n## Steps\\n1. Obtain the document ID (select the doc or pass its ID).\\n2. Run the Read Document operation to pull the full text.\\n3. Identify the main thesis, key points, decisions, and any action items or owners.\\n4. Keep the summary faithful to the source; do not invent details not present.\\n\\n## Output\\nA short summary: a one-line gist, 3-6 bullet key points, and an Action Items section (owner + task) if any exist. Reference the doc link."},{"name":"append-to-document","description":"Write additional content into an existing Google Doc, such as a running log or report section.","content":"# Append to a Document\\n\\nAdd a new section to an existing Doc.\\n\\n## Steps\\n1. Obtain the target document ID.\\n2. Draft the content to add, clearly delimited (e.g., a dated heading for a running log).\\n3. Run the Write to Document operation with the document ID and the new content.\\n4. For recurring updates, prefix each entry with a date or section header so the doc stays organized.\\n\\n## Output\\nConfirm the content was written and return the document link. Summarize in one line what was appended."}],"templates":[{"title":"CrowdStrike coverage report doc","prompt":"Create a scheduled workflow that aggregates CrowdStrike sensor status, OS version, and policy assignment, and generates a coverage report doc in Google Docs for the security team.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"Discord community manager","prompt":"Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"discord","name":"Discord"},{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"Gamma deck from doc","prompt":"Build a workflow that takes a Google Docs source, generates a Gamma deck from the structure and bullet points, and emails the deck link to the author for polish.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"gamma","name":"Gamma"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Docs review request","prompt":"Build a workflow that reads a Google Doc when its title is marked ready for review, summarizes the key points with an agent, and posts a review request with the doc link to the named reviewers in Slack.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"slack","name":"Slack"}]},{"title":"Google Docs change digester","prompt":"Create a scheduled weekly workflow that reads each tracked Google Doc, compares its content against the snapshot stored in a table, summarizes what changed with an agent, and posts a digest to the team in Slack.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"slack","name":"Slack"}]},{"title":"Google Docs translation copy","prompt":"Build a workflow that takes a Google Docs document and creates translated copies into target languages with Google Translate, links them in the source, and notifies the localization team.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Meeting notes to Google Docs","prompt":"Create a workflow that after a meeting pulls the transcript, summarizes decisions, action items, and owners with an agent, and creates a formatted Google Docs document in the shared team folder with a link posted to Slack.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"slack","name":"Slack"}]},{"title":"Google Docs proposal generator","prompt":"Build a workflow that on a closed-won deal reads the account details, creates a Google Docs document from the proposal template, fills in customer name, scope, and pricing, and shares the draft with the account owner for review.","integrations":[{"id":"google_docs","name":"Google Docs"}]},{"title":"Google Docs weekly report","prompt":"Create a scheduled weekly workflow that reads metrics from my tables, writes a narrative status report with an agent, and appends the new section to a running Google Docs document so leadership has one living record.","integrations":[{"id":"google_docs","name":"Google Docs"}]},{"title":"Google Docs knowledge sync","prompt":"Build a workflow that reads a set of Google Docs in a folder, extracts their content, and upserts it into a knowledge base so the team can ask questions and get answers grounded in the latest docs.","integrations":[{"id":"google_docs","name":"Google Docs"}]},{"title":"Greptile onboarding explainer","prompt":"Create a workflow where a new engineer asks how a part of the codebase works, Greptile answers against the indexed repository with cited files, and the explanation is saved to a Google Doc.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"greptile","name":"Greptile"}]},{"title":"incident.io postmortem starter","prompt":"Create a scheduled workflow that polls incident.io for recently resolved incidents, pulls the Slack thread, related Sentry errors, and deploy timeline, then drafts a postmortem doc in Google Docs.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"incidentio","name":"incident.io"},{"id":"sentry","name":"Sentry"}]},{"title":"Notion customer support bot","prompt":"Create a knowledge base and connect it to my Notion or Google Docs so it stays synced with my product documentation automatically. Then build an agent that answers customer questions using it with sourced citations and deploy it as a chat endpoint.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"notion","name":"Notion"}]},{"title":"PagerDuty postmortem starter","prompt":"Create a scheduled workflow that polls PagerDuty for newly resolved incidents and opens a postmortem doc for each with the timeline, responders, and Slack thread linked, ready for the team to fill in root cause.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"SharePoint policy publisher","prompt":"Build a workflow that turns a Google Docs policy update into a published SharePoint page, posts the change diff to the policies team in Microsoft Teams, and writes the version history.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Slack standup summary","prompt":"Create a scheduled workflow that reads the #standup Slack channel each morning, summarizes what everyone is working on, identifies blockers, and posts a structured recap to a Google Docs document.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"slack","name":"Slack"}]},{"title":"Telegram daily standup poller","prompt":"Create a scheduled workflow that posts a daily standup prompt to a Telegram group, collects the replies, and writes a structured standup digest to a Google Doc.","integrations":[{"id":"google_docs","name":"Google Docs"},{"id":"telegram","name":"Telegram"}]}]},{"id":"google_drive","type":"google_drive","slug":"google-drive","name":"Google Drive","description":"Manage files, folders, and permissions","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/google_drive","authType":"oauth","connections":[{"id":"google-drive","kind":"oauth","label":"Connect with OAuth","providerId":"google-drive","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_drive","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/drive.file","label":"View and manage Google Drive files you open or create with Sim"},{"id":"https://www.googleapis.com/auth/drive","label":"View, edit, create, and delete all Google Drive files"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"List Files","description":"List files and folders in Google Drive with complete metadata"},{"name":"Search Files","description":"Search for files in Google Drive using advanced query syntax (e.g., fullText contains, mimeType, modifiedTime, etc.)"},{"name":"Get File Info","description":"Get metadata for a specific file in Google Drive by its ID"},{"name":"Get File Content","description":"Get content from a file in Google Drive with complete metadata (exports Google Workspace files automatically)"},{"name":"Create Folder","description":"Create a new folder in Google Drive with complete metadata returned"},{"name":"Create File","description":"Upload a file to Google Drive with complete metadata returned"},{"name":"Upload File","description":"Upload a file to Google Drive with complete metadata returned"},{"name":"Download File","description":"Download a file from Google Drive with complete metadata (exports Google Workspace files automatically)"},{"name":"Copy File","description":"Create a copy of a file in Google Drive"},{"name":"Move File","description":"Move a file or folder to a different folder in Google Drive"},{"name":"Update File","description":"Update file metadata in Google Drive (rename, move, star, add description)"},{"name":"Move to Trash","description":"Move a file to the trash in Google Drive (can be restored later)"},{"name":"Restore from Trash","description":"Restore a file from the trash in Google Drive"},{"name":"Delete Permanently","description":"Permanently delete a file from Google Drive (bypasses trash)"},{"name":"Share File","description":"Share a file with a user, group, domain, or make it public"},{"name":"Remove Sharing","description":"Remove a permission from a file (revoke access)"},{"name":"List Permissions","description":"List all permissions (who has access) for a file in Google Drive"},{"name":"Export File","description":"Export a Google Workspace file (Docs, Sheets, Slides, Drawings) to a chosen format such as PDF, DOCX, XLSX, or CSV"},{"name":"List Revisions","description":"List the revision history of a file in Google Drive"},{"name":"Get Revision","description":"Get metadata for a specific revision of a file in Google Drive"},{"name":"List Comments","description":"List comments on a file in Google Drive"},{"name":"Create Comment","description":"Add a comment to a file in Google Drive"},{"name":"Delete Comment","description":"Delete a comment from a file in Google Drive"},{"name":"Get Drive Info","description":"Get information about the user and their Google Drive (storage quota, capabilities)"}],"triggers":[{"id":"google_drive_poller","name":"Google Drive File Trigger","description":"Triggers when files are created, modified, or deleted in Google Drive"}],"skills":[{"name":"find-file-in-drive","description":"Search Google Drive with query syntax to locate files by name, type, content, or date.","content":"# Find a File in Drive\\n\\nLocate files using Drive query syntax.\\n\\n## Steps\\n1. Translate the request into a Drive query. Common clauses: `name contains \'term\'`, `fullText contains \'term\'`, `mimeType = \'application/pdf\'`, `modifiedTime > \'2024-01-01T00:00:00\'`, `\'email\' in owners`, `trashed = false`.\\n2. Run the Search Files operation with that query and a Results Per Page value.\\n3. If results are too broad, add `and` clauses (file type, owner, date) to narrow.\\n4. For a chosen result, run Get File Info for full metadata.\\n\\n## Output\\nA list of matching files: name, type, owner, modified date, and the file ID. Highlight the single best match if the intent was specific."},{"name":"organize-files-into-folders","description":"Create folders and move or copy files in Google Drive to keep storage organized.","content":"# Organize Files into Folders\\n\\nFile and tidy Drive content.\\n\\n## Steps\\n1. Identify the target structure: which folder should exist and what goes in it.\\n2. If the destination folder does not exist, run Create Folder (set its parent if needed) and capture the new folder ID.\\n3. For each file to relocate, run Move File with the destination folder ID. Use Copy File instead when the original must stay in place.\\n4. Optionally run Update File to rename files to a consistent convention.\\n\\n## Output\\nA summary of what was created and moved: destination folder link, count of files relocated, and any renames applied."},{"name":"share-file-with-people","description":"Grant access to a Google Drive file for users, groups, a domain, or anyone with the link.","content":"# Share a File\\n\\nGrant access to a Drive file with the right permission level.\\n\\n## Steps\\n1. Obtain the file ID (select it or run Search Files).\\n2. Decide the share target: a specific user/group email, an entire domain, or anyone with the link.\\n3. Choose the permission level: Viewer (reader), Commenter, or Editor (writer).\\n4. Run the Share File operation with the target and role. For user/group shares, optionally include a notification message.\\n\\n## Output\\nConfirm who now has access and at what level, plus the file link. Avoid `anyone` unless explicitly requested."},{"name":"read-file-content","description":"Extract the text content of a Google Drive file, exporting Workspace files to a usable format.","content":"# Read File Content\\n\\nPull the text out of a Drive file for downstream use.\\n\\n## Steps\\n1. Obtain the file ID.\\n2. Run the Get File Content operation. For Google Docs/Sheets/Slides, set Export Format (Auto picks the best, or choose Plain Text / PDF / DOCX explicitly).\\n3. For non-Workspace files (PDF, TXT), the content is returned directly.\\n4. Use the returned text for summarization, extraction, or indexing.\\n\\n## Output\\nReturn the extracted content (or a summary of it if large), noting the file name and the export format used."}],"templates":[{"title":"Confluence multi-source knowledge hub","prompt":"Create a knowledge base and connect it to Confluence, Notion, and Google Drive so all my company documentation is automatically synced, chunked, and embedded. Then deploy a Q&A agent that can answer questions across all sources with citations.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"}]},{"title":"DocuSign completed contract archiver","prompt":"Build a scheduled workflow that polls DocuSign for completed envelopes, downloads the signed PDF, saves it to a Google Drive contracts folder, and writes the metadata into a contracts table.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"docusign","name":"DocuSign"}]},{"title":"Gmail attachment vault","prompt":"Create a workflow that watches Gmail for new emails with attachments, saves each attachment into a categorized folder in Google Drive based on sender and subject, and logs a row to a tracking table with the file link and source email.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Drive personal notes assistant","prompt":"Create a knowledge base and connect it to my Google Drive, Notion, or Obsidian so all my notes, docs, and articles are automatically synced and embedded. Then build an agent that I can ask anything — it should answer with citations and deploy as a chat endpoint.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"notion","name":"Notion"},{"id":"obsidian","name":"Obsidian"}]},{"title":"Google Drive knowledge search","prompt":"Create a knowledge base connected to my Google Drive so all documents, spreadsheets, and presentations are automatically synced and searchable. Then build an agent I can ask things like \\"find the board deck from last quarter\\" or \\"what were the KPIs in the marketing plan?\\" and get answers with doc links.","integrations":[{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Drive contract intake","prompt":"Create a workflow that watches a Google Drive intake folder for new contract PDFs, extracts clauses with Reducto, writes structured terms to a table, and pings legal in Slack.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"reducto","name":"Reducto"},{"id":"slack","name":"Slack"}]},{"title":"Google Drive new-hire kit deployer","prompt":"Build a workflow triggered by a new hire in Greenhouse that copies the standard Google Drive onboarding folder, shares it with the new hire, and writes the link into the onboarding tracker.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Google Drive retention enforcer","prompt":"Create a scheduled monthly workflow that finds Google Drive files past the retention horizon, requires owner approval over Slack, and archives or deletes per the policy.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"slack","name":"Slack"}]},{"title":"Drive intake auto-filer","prompt":"Build a workflow that watches a Google Drive intake folder for new uploads, reads each file\'s content to classify it by type and customer, creates the right destination folder, and moves the file there with a renamed, consistent filename.","integrations":[{"id":"google_drive","name":"Google Drive"}]},{"title":"Drive document Q&A assistant","prompt":"Create a knowledge base synced from a Google Drive folder, then build an agent that searches the synced documents to answer team questions and replies with the answer plus a link to the source file in Drive.","integrations":[{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Meet conference recap to Drive","prompt":"Build a workflow that pulls the conference record and participant list for a finished Google Meet, generates a structured attendance and follow-up recap with an agent, and saves the document to a per-team folder in Google Drive.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Google Translate doc localizer","prompt":"Create a workflow that watches a Google Drive folder of source-language docs, translates each into target languages with Google Translate while preserving structure, and writes the localized files back.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Persona audit PDF archive","prompt":"Build a workflow that takes an approved inquiry ID, downloads the inquiry summary PDF from Persona, and uploads it to a compliance archive folder in Google Drive named by customer reference ID.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"persona","name":"Persona"}]},{"title":"Qdrant document ingestion","prompt":"Build a workflow that watches a Google Drive folder for new docs, chunks each, generates embeddings, and upserts the vectors into a Qdrant collection with rich metadata.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"qdrant","name":"Qdrant"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Reducto + knowledge base loader","prompt":"Build a workflow that parses every PDF in a Drive folder with Reducto, normalizes the structure, and upserts chunks into a knowledge base with section-aware metadata so retrieval returns the right passage.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"reducto","name":"Reducto"}]},{"title":"Textract form-to-table","prompt":"Build a workflow that pushes scanned forms from Google Drive through AWS Textract analyze-document, extracts key-value pairs and tables, and writes structured rows to a Sim table for downstream automations.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"textract","name":"AWS Textract"}]},{"title":"Zoho Desk attachment archiver","prompt":"When a Zoho Desk ticket thread includes an attachment, download the file and upload it to Google Drive in a folder named after the ticket number.","integrations":[{"id":"google_drive","name":"Google Drive"},{"id":"zoho_desk","name":"Zoho Desk"}]}]},{"id":"google_forms","type":"google_forms","slug":"google-forms","name":"Google Forms","description":"Manage Google Forms and responses","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/google_forms","authType":"oauth","connections":[{"id":"google-forms","kind":"oauth","label":"Connect with OAuth","providerId":"google-forms","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_forms","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/drive","label":"View, edit, create, and delete all Google Drive files"},{"id":"https://www.googleapis.com/auth/forms.body","label":"View and manage Google Forms"},{"id":"https://www.googleapis.com/auth/forms.responses.readonly","label":"View responses to Google Forms"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Get Responses","description":"Retrieve a single response or list responses from a Google Form"},{"name":"Get Form","description":"Retrieve a form structure including its items, settings, and metadata"},{"name":"Create Form","description":"Create a new Google Form with a title"},{"name":"Batch Update","description":"Apply multiple updates to a form (add items, update info, change settings, etc.)"},{"name":"Set Publish Settings","description":"Update the publish settings of a form (publish/unpublish, accept responses)"},{"name":"Create Watch","description":"Create a notification watch for form changes (schema changes or new responses)"},{"name":"List Watches","description":"List all notification watches for a form"},{"name":"Delete Watch","description":"Delete a notification watch from a form"},{"name":"Renew Watch","description":"Renew a notification watch for another 7 days"}],"triggers":[{"id":"google_forms_webhook","name":"Google Forms Webhook","description":"Trigger workflow from Google Form submissions (via Apps Script forwarder)"}],"skills":[{"name":"collect-form-responses","description":"Retrieve and structure responses from a Google Form for analysis or routing.","content":"# Collect Form Responses\\n\\nPull submissions from a Google Form.\\n\\n## Steps\\n1. Select the form (or pass its form ID).\\n2. Run the Get Responses operation; set Page Size to cover the expected volume. Leave Response ID empty to fetch all, or set it to fetch one specific submission.\\n3. To map answers to questions, run Get Form once and use the item titles to label each answer.\\n4. Normalize each response into clean rows keyed by question.\\n\\n## Output\\nA structured list of responses with respondent answers labeled by question. Include the total count and the time range covered."},{"name":"analyze-survey-results","description":"Read Google Form responses and summarize trends, sentiment, and notable findings.","content":"# Analyze Survey Results\\n\\nTurn raw form responses into insight.\\n\\n## Steps\\n1. Run Get Form to learn the questions and their types (choice, scale, text).\\n2. Run Get Responses to pull all submissions.\\n3. For choice/scale questions, compute distributions and averages. For free-text, cluster into themes and gauge sentiment.\\n4. Surface the strongest signals and any outliers or recurring complaints.\\n\\n## Output\\nA digest: response count, per-question breakdown (top choices, averages), 3-5 key themes from free text, and notable verbatim quotes. Keep numbers accurate to the data."},{"name":"create-form","description":"Create a new Google Form and add questions via batch update.","content":"# Create a Form\\n\\nBuild a new Google Form with questions.\\n\\n## Steps\\n1. Run Create Form with the form title (and optional document title). Capture the returned form ID.\\n2. Build a Batch Update requests array to add questions. Use `createItem` with `choiceQuestion` (RADIO/CHECKBOX/DROP_DOWN), `textQuestion`, or `scaleQuestion`, each at a `location.index`.\\n3. Run Batch Update on the form ID with that requests array.\\n4. If the form should accept submissions, run Set Publish Settings with Published on.\\n\\n## Output\\nConfirm the form was created, list the questions added, and return the responder URL and form ID."}],"templates":[{"title":"Google Forms to CRM","prompt":"Build a workflow that watches Google Forms responses, enriches each submitter with company data, and pushes qualified leads into HubSpot with the right owner and source.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Google Forms support intake","prompt":"Create a workflow that turns Google Forms support submissions into Zendesk tickets, prioritizes them with an agent, and posts the new ticket to the support Slack channel.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"zendesk","name":"Zendesk"},{"id":"slack","name":"Slack"}]},{"title":"Google Forms event RSVP tracker","prompt":"Build a workflow that captures Google Forms event RSVPs into a table, sends confirmation emails, and provides a daily attendee dashboard to the organizer.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Forms survey analyzer","prompt":"Create a workflow that processes Google Forms survey responses, classifies sentiment and themes with an agent, and writes a weekly insight digest to Slack.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"slack","name":"Slack"}]},{"title":"Google Forms approvals router","prompt":"Build a workflow that turns Google Forms approval requests into Slack messages with quick-action buttons, captures the decision, and emails the requester the outcome.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"slack","name":"Slack"}]},{"title":"Google Forms PTO collector","prompt":"Create a workflow that processes PTO requests from Google Forms, captures manager approval over Slack, and updates the HR table with approved time off.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"slack","name":"Slack"}]},{"title":"Google Forms quiz grader","prompt":"Build a workflow that captures Google Forms quiz responses, scores each automatically with an agent, writes scores to a tables-based gradebook, and emails the student.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Sheets forms cleanup","prompt":"Create a workflow that normalizes Google Sheets data submitted from Google Forms — title casing, phone formats, deduplication — and writes clean rows to a downstream sheet.","integrations":[{"id":"google_forms","name":"Google Forms"},{"id":"google_sheets","name":"Google Sheets"}]}]},{"id":"google_groups","type":"google_groups","slug":"google-groups","name":"Google Groups","description":"Manage Google Workspace Groups and their members","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/google_groups","authType":"oauth","connections":[{"id":"google-groups","kind":"oauth","label":"Connect with OAuth","providerId":"google-groups","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_groups","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/admin.directory.group","label":"Manage Google Workspace groups"},{"id":"https://www.googleapis.com/auth/admin.directory.group.member","label":"Manage Google Workspace group memberships"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"List Groups","description":"List all groups in a Google Workspace domain"},{"name":"Get Group","description":"Get details of a specific Google Group by email or group ID"},{"name":"Create Group","description":"Create a new Google Group in the domain"},{"name":"Update Group","description":"Update an existing Google Group"},{"name":"Delete Group","description":"Delete a Google Group"},{"name":"List Members","description":"List all members of a Google Group"},{"name":"Get Member","description":"Get details of a specific member in a Google Group"},{"name":"Add Member","description":"Add a new member to a Google Group"},{"name":"Update Member Role","description":"Update a member\'s role in a Google Group (promote or demote)"},{"name":"Remove Member","description":"Remove a member from a Google Group"},{"name":"Check Membership","description":"Check if a user is a member of a Google Group"},{"name":"List Aliases","description":"List all email aliases for a Google Group"},{"name":"Add Alias","description":"Add an email alias to a Google Group"},{"name":"Remove Alias","description":"Remove an email alias from a Google Group"},{"name":"Get Settings","description":"Get the settings for a Google Group including access permissions, moderation, and posting options"},{"name":"Update Settings","description":"Update the settings for a Google Group including access permissions, moderation, and posting options"}],"triggers":[],"skills":[{"name":"add-member-to-group","description":"Add a user to a Google Workspace group with a chosen role and confirm membership.","content":"# Add a Member to a Group\\n\\nGrant someone membership in a Workspace group.\\n\\n## Steps\\n1. Identify the group email or ID and the member email.\\n2. Run Check Membership first to see if the user is already a member; skip the add if so.\\n3. Run Add Member with the member email and the desired role (MEMBER, MANAGER, or OWNER; default MEMBER).\\n4. Optionally run Check Membership again to confirm the add succeeded.\\n\\n## Output\\nConfirm the user was added (or already present), the role granted, and the group. Note if the operation requires admin privileges that were missing."},{"name":"audit-group-membership","description":"List the members and roles of a Google Group for access review or compliance.","content":"# Audit Group Membership\\n\\nProduce a membership roster for a group.\\n\\n## Steps\\n1. Identify the group email or ID.\\n2. Run List Members with a Max Results value; optionally filter by roles (OWNER, MANAGER, MEMBER).\\n3. Page through results using the next page token until all members are collected.\\n4. Separate owners/managers from regular members and flag any external-domain addresses.\\n\\n## Output\\nA roster grouped by role: owners, managers, members. Include total counts and a list of any external members for review."},{"name":"create-group","description":"Create a new Google Workspace group with an email, name, and description.","content":"# Create a Group\\n\\nStand up a new Workspace group.\\n\\n## Steps\\n1. Decide the group email address, display name, and a clear description of its purpose.\\n2. Run List Groups (filter by the intended email/name) to confirm it does not already exist.\\n3. Run Create Group with the email, name, and description.\\n4. Optionally run Add Member to seed initial owners/managers.\\n\\n## Output\\nConfirm the created group with its email, name, and description. List any initial members added. Note that this requires Workspace admin access."},{"name":"remove-member-from-group","description":"Remove a user from a Google Group, useful for offboarding and access cleanup.","content":"# Remove a Member from a Group\\n\\nRevoke a user\'s group membership.\\n\\n## Steps\\n1. Identify the group email/ID and the member email or ID.\\n2. Run Check Membership to confirm the user is actually a member.\\n3. If present, run Remove Member with the group and member keys.\\n4. For offboarding across many groups, run List Groups filtered by `memberKey:` first to find every group the user belongs to, then remove from each.\\n\\n## Output\\nConfirm the removal per group, and for offboarding list every group the user was removed from. Note any failures for manual follow-up."}],"templates":[{"title":"Google Groups onboarding sync","prompt":"Create a workflow that watches Rippling or Greenhouse for new hires, adds them to the right Google Groups based on team and department, and emails the new hire a list of the groups joined.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"rippling","name":"Rippling"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Google Groups quarterly access review","prompt":"Build a scheduled workflow that runs each quarter, lists every Google Group with members and owners, writes the report to a table for compliance review, and pings owners to confirm membership in Slack.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"slack","name":"Slack"}]},{"title":"Google Groups departure cleanup","prompt":"Create a workflow that watches Workday or Rippling for terminations and removes the departing user from every Google Group they belonged to, writing the change to a security audit log.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"workday","name":"Workday"},{"id":"rippling","name":"Rippling"}]},{"title":"Google Groups self-serve requester","prompt":"Build a workflow that accepts a Google Group access request via a form, gets manager approval over Slack, adds the user to the group, and notifies the requester when access is granted.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"slack","name":"Slack"}]},{"title":"Google Groups distribution-list audit","prompt":"Create a scheduled workflow that scans Google Groups marked as distribution lists, flags external members against an allowlist, and posts a Slack report to the security team.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"slack","name":"Slack"}]},{"title":"Google Groups empty-group cleanup","prompt":"Build a scheduled workflow that lists Google Groups with no members, opens a confirmation thread with the owner in Slack, and deletes the group once approved.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"slack","name":"Slack"}]},{"title":"Google Groups settings hardening","prompt":"Create a scheduled workflow that reads the settings for every Google Group, flags groups that allow external posting or open membership against policy, and posts the findings to the security team in Slack.","integrations":[{"id":"google_groups","name":"Google Groups"},{"id":"slack","name":"Slack"}]}]},{"id":"google_maps","type":"google_maps","slug":"google-maps","name":"Google Maps","description":"Geocoding, directions, places, and distance calculations","category":"Search","docsUrl":"https://docs.sim.ai/integrations/google_maps","authType":"api-key","connections":[],"operations":[{"name":"Geocode Address","description":"Convert an address into geographic coordinates (latitude and longitude)"},{"name":"Reverse Geocode","description":"Convert geographic coordinates (latitude and longitude) into a human-readable address"},{"name":"Get Directions","description":"Get directions and route information between two locations"},{"name":"Distance Matrix","description":"Calculate travel distance and time between multiple origins and destinations"},{"name":"Search Places","description":"Search for places using a text query"},{"name":"Nearby Places","description":"Search for places of a given type within a radius of a location"},{"name":"Place Details","description":"Get detailed information about a specific place"},{"name":"Get Elevation","description":"Get elevation data for a location"},{"name":"Get Timezone","description":"Get timezone information for a location"},{"name":"Snap to Roads","description":"Snap GPS coordinates to the nearest road segment"},{"name":"Speed Limits","description":"Get speed limits for road segments. Requires either path coordinates or placeIds."},{"name":"Validate Address","description":"Validate and standardize a postal address"},{"name":"Geolocate (WiFi/Cell)","description":"Geolocate a device using WiFi access points, cell towers, or IP address"},{"name":"Air Quality","description":"Get current air quality data for a location"},{"name":"Pollen Forecast","description":"Get a daily pollen forecast (grass, tree, weed) for a location"},{"name":"Solar Potential","description":"Get solar potential and panel insights for the building nearest a location"}],"triggers":[],"skills":[{"name":"geocode-address","description":"Convert an address into latitude/longitude coordinates with a normalized formatted address.","content":"# Geocode an Address\\n\\nTurn a street address into coordinates.\\n\\n## Steps\\n1. Take the address string from the request.\\n2. Run the Geocode Address operation; optionally set a Region Bias (country code) to disambiguate.\\n3. Read the returned lat, lng, formatted address, place ID, and location type.\\n4. If multiple candidates are likely, note the accuracy/location type so the requester can confirm.\\n\\n## Output\\nReturn the formatted address, latitude, longitude, and place ID. To go the other way (coordinates to address), use Reverse Geocode instead."},{"name":"get-directions","description":"Compute a route between two locations with distance, duration, and turn-by-turn steps.","content":"# Get Directions\\n\\nRoute between an origin and a destination.\\n\\n## Steps\\n1. Capture origin and destination (addresses or `lat,lng`).\\n2. Choose Travel Mode (driving, walking, bicycling, transit) and optionally features to Avoid (tolls, highways, ferries).\\n3. Add Waypoints (pipe-separated) for intermediate stops if requested, and pick Units (metric/imperial).\\n4. Run the Get Directions operation.\\n\\n## Output\\nReturn total distance and duration (as text and numeric), start/end addresses, and a concise turn-by-turn step list. Mention the travel mode used."},{"name":"find-nearby-places","description":"Search for places matching a query near a location and return ranked results.","content":"# Find Nearby Places\\n\\nDiscover places (restaurants, hotels, etc.) near a spot.\\n\\n## Steps\\n1. Build the Search Query (e.g., \\"coffee near Times Square\\") and set a Location Bias (`lat,lng`) and Radius if known.\\n2. Optionally constrain by Place Type (restaurant, hotel, gas_station, etc.).\\n3. Run the Search Places operation.\\n4. For a chosen result, run Place Details with its Place ID to get rating, hours, phone, and website.\\n\\n## Output\\nA ranked list of places: name, address, rating and number of ratings, open-now status, and place ID. Include phone/website for the top pick when details were fetched."},{"name":"calculate-travel-distances","description":"Compute distances and travel times from one origin to many destinations.","content":"# Calculate Travel Distances\\n\\nGet a distance matrix from an origin to multiple destinations.\\n\\n## Steps\\n1. Set the Origin and provide Destinations as a pipe-separated list (e.g., \\"New York, NY|Boston, MA\\").\\n2. Choose Travel Mode and Units; optionally set features to Avoid.\\n3. Run the Distance Matrix operation.\\n4. Read each row for distance and duration to each destination.\\n\\n## Output\\nA table of destinations sorted by travel time or distance, each with distance text and duration text. Useful for picking the nearest option or planning routes."},{"name":"find-places-nearby","description":"Find places of a given type within a radius of a coordinate, ranked by popularity or distance, without needing a text query.","content":"# Find Places Nearby\\n\\nDiscover places around a fixed point (e.g., a store, delivery stop, or event venue) by type and radius, without a free-text search.\\n\\n## Steps\\n1. Set the Latitude/Longitude of the center point and a Radius (meters, up to 50000).\\n2. Optionally constrain by Place Type (restaurant, hotel, pharmacy, etc.) and choose Rank By (Popularity or Distance).\\n3. Set Max Results if you only need the top few.\\n4. Run the Nearby Places operation.\\n\\n## Output\\nA list of nearby places with name, address, coordinates, rating, number of ratings, open-now status, and business status, ordered per the chosen ranking. Use Place Details with a result\'s place ID for phone/website/hours."}],"templates":[{"title":"Google Maps competitor location finder","prompt":"Build a workflow that uses Google Maps to find competitor locations in a target city, writes coordinates and details to a table, and emails the sales team a route map.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Maps territory builder","prompt":"Create a workflow that takes a list of CRM accounts, geocodes them via Google Maps, clusters into territories, and writes the assignment to a tables-based territory plan.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Maps event-attendee proximity","prompt":"Build a workflow that for a Luma event sorts registrants by proximity to the venue via Google Maps, writes the list, and offers a quick-action transport option.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"luma","name":"Luma"}]},{"title":"Google Maps logistics planner","prompt":"Create a workflow that takes a delivery list, optimizes the route via Google Maps directions, and writes a per-driver itinerary to a tables-based dispatcher view.","integrations":[{"id":"google_maps","name":"Google Maps"}]},{"title":"Google Maps store-locator updater","prompt":"Build a scheduled workflow that audits store locations on the website against Google Maps Places data, flags out-of-date hours or addresses, and pings the team to correct.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"slack","name":"Slack"}]},{"title":"Google Maps review tracker","prompt":"Create a scheduled workflow that watches Google Maps reviews of brand locations daily, classifies sentiment, and pings the right manager in Slack on new negative reviews.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"slack","name":"Slack"}]},{"title":"Google Maps lead-by-region exporter","prompt":"Build a workflow that uses Google Maps to find businesses matching an ICP in a region, enriches via Hunter, and writes the prospect list to HubSpot.","integrations":[{"id":"google_maps","name":"Google Maps"},{"id":"hunter","name":"Hunter.io"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"google_meet","type":"google_meet","slug":"google-meet","name":"Google Meet","description":"Create and manage Google Meet meetings","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/google_meet","authType":"oauth","connections":[{"id":"google-meet","kind":"oauth","label":"Connect with OAuth","providerId":"google-meet","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_meet","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/meetings.space.created","label":"Create and manage Google Meet meeting spaces created by Sim"},{"id":"https://www.googleapis.com/auth/meetings.space.readonly","label":"View information about your Google Meet conferences"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Create Space","description":"Create a new Google Meet meeting space"},{"name":"Get Space","description":"Get details of a Google Meet meeting space by name or meeting code"},{"name":"End Conference","description":"End the active conference in a Google Meet space"},{"name":"List Conference Records","description":"List conference records for meetings you organized"},{"name":"Get Conference Record","description":"Get details of a specific conference record"},{"name":"List Participants","description":"List participants of a conference record"}],"triggers":[],"skills":[{"name":"create-meeting-space","description":"Create a Google Meet space and return its join link and meeting code.","content":"# Create a Meeting Space\\n\\nSpin up a Google Meet space to share.\\n\\n## Steps\\n1. Decide the Access Type: Open (anyone with link), Trusted (organization members), or Restricted (invited only).\\n2. Optionally set Entry Point Access if the space should only be joinable from the creating app.\\n3. Run the Create Space operation.\\n4. Capture the meeting URI and meeting code from the response.\\n\\n## Output\\nReturn the meeting link (meetingUri), the meeting code, the access type, and the space resource name so it can be referenced or shared."},{"name":"summarize-meeting-attendance","description":"Pull a Google Meet conference record and its participants to report who attended.","content":"# Summarize Meeting Attendance\\n\\nReport attendance for a finished meeting.\\n\\n## Steps\\n1. If you only have the space, run List Conference Records (filter by `space.name = \\"spaces/...\\"`) to find the conference record name.\\n2. Run Get Conference Record to read start time, end time, and duration.\\n3. Run List Participants on that conference record name, paging through results.\\n4. Build the attendee list and compute meeting duration.\\n\\n## Output\\nAn attendance summary: meeting start/end and duration, total participant count, and the list of participants. Flag the meeting if no participants are recorded."},{"name":"list-recent-conferences","description":"List recent Google Meet conference records for reporting or archival.","content":"# List Recent Conferences\\n\\nEnumerate past Meet conferences.\\n\\n## Steps\\n1. Run List Conference Records with a Page Size; optionally apply a Filter (e.g., by space name or time).\\n2. Page through using the next page token until you have the needed window.\\n3. For each record capture the conference record name, associated space, start time, and end time.\\n4. Optionally fetch participants per record (List Participants) when attendance is needed.\\n\\n## Output\\nA list of conferences sorted by start time, each with space, start/end, and duration. Include the conference record name so any record can be drilled into."}],"templates":[{"title":"Google Meet conference recap to Drive","prompt":"Build a workflow that pulls the conference record and participant list for a finished Google Meet, generates a structured attendance and follow-up recap with an agent, and saves the document to a per-team folder in Google Drive.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Meet daily meeting links","prompt":"Create a scheduled workflow that reads the day\'s meetings from a table each morning, creates a Google Meet space for each one, and emails attendees the agenda and join link via Gmail.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Meet conference record archiver","prompt":"Build a scheduled workflow that lists Google Meet conference records, captures attendance and duration per meeting, and writes the history to a source-of-truth meetings table for reporting.","integrations":[{"id":"google_meet","name":"Google Meet"}]},{"title":"Google Meet auto-invite from CRM","prompt":"Create a workflow that watches Salesforce for new meetings logged on opportunities, creates a matching Google Meet event, invites the right attendees, and writes the meeting link back to the opportunity.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Meet daily standup link","prompt":"Build a scheduled workflow that posts the day’s Google Meet standup link to the team Slack channel five minutes before standup, with the rolling agenda from the standup table.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"slack","name":"Slack"}]},{"title":"Google Meet customer interview logger","prompt":"Create a workflow that takes a customer-interview note or transcript, pulls the matching Google Meet conference record and participants for context, extracts themes, quotes, and feature requests with an agent, and writes structured rows to a research table.","integrations":[{"id":"google_meet","name":"Google Meet"}]},{"title":"Google Meet retro publisher","prompt":"Build a workflow that runs after a sprint-retro Google Meet, summarizes what went well, what to improve, and action items, and posts the retro to a Notion page tagged with the sprint number.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"notion","name":"Notion"}]},{"title":"Google Tasks from meetings","prompt":"Build a workflow that runs after Google Meet meetings, extracts action items from the transcript, and creates Google Tasks entries for the owner with due dates.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Notion meeting-notes capture","prompt":"Build a workflow that runs after a Google Meet call, fetches the transcript, and creates a structured Notion page under the right project with attendees, decisions, and action items.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"notion","name":"Notion"}]},{"title":"Obsidian meeting-note autopopulator","prompt":"Create a workflow that runs after a Google Meet meeting, fetches the transcript, and appends a structured meeting note to an Obsidian vault under the right project folder.","integrations":[{"id":"google_meet","name":"Google Meet"},{"id":"obsidian","name":"Obsidian"}]}]},{"id":"google_pagespeed","type":"google_pagespeed","slug":"google-pagespeed","name":"Google PageSpeed","description":"Analyze webpage performance with Google PageSpeed Insights","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/google_pagespeed","authType":"api-key","connections":[],"operations":[{"name":"Google PageSpeed Analyze","description":"Analyze a webpage for performance, accessibility, SEO, and best practices using Google PageSpeed Insights."}],"triggers":[],"skills":[{"name":"audit-page-performance","description":"Run a PageSpeed Insights analysis on a URL and report scores and Core Web Vitals.","content":"# Audit Page Performance\\n\\nMeasure a page with PageSpeed Insights (Lighthouse).\\n\\n## Steps\\n1. Take the page URL.\\n2. Choose the Strategy: mobile (recommended for ranking) or desktop. Run once per strategy if both are needed.\\n3. Optionally set Categories (performance, accessibility, best-practices, seo) and Locale.\\n4. Run the analysis and read the category scores plus Core Web Vitals (LCP, FCP, CLS, TBT, Speed Index, TTI).\\n\\n## Output\\nA report: per-category scores (0-100), Core Web Vitals with their display values, and the final URL analyzed. Call out any metric in the poor range and the strategy used."},{"name":"compare-mobile-vs-desktop","description":"Analyze a page on both mobile and desktop and contrast the scores and vitals.","content":"# Compare Mobile vs Desktop\\n\\nContrast a page\'s performance across form factors.\\n\\n## Steps\\n1. Run the analysis on the URL with Strategy = mobile.\\n2. Run it again with Strategy = desktop.\\n3. Line up the category scores and Core Web Vitals from each run.\\n4. Identify the biggest gaps (typically LCP/TBT on mobile).\\n\\n## Output\\nA side-by-side comparison table of mobile vs desktop scores and key vitals, plus a short note on where mobile lags and what likely causes it."},{"name":"track-core-web-vitals","description":"Capture Core Web Vitals for one or more pages to feed a monitoring history.","content":"# Track Core Web Vitals\\n\\nCapture CWV metrics for trend tracking.\\n\\n## Steps\\n1. For each target URL, run the analysis (usually Strategy = mobile) limiting Categories to performance for speed.\\n2. Extract LCP, CLS, TBT, FCP, Speed Index, and TTI numeric values plus the performance score.\\n3. Stamp each row with the URL and analysis timestamp.\\n4. Compare against any prior baseline to detect regressions.\\n\\n## Output\\nOne row per URL with the performance score and CWV numeric values, ready to append to a history table. Flag any metric that regressed beyond a threshold versus the baseline."}],"templates":[{"title":"Google Ads + PageSpeed landing audit","prompt":"Create a scheduled workflow that for active Google Ads campaigns runs Google PageSpeed on the landing pages weekly, flags slow LPs, and pings the marketing team.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"google_ads","name":"Google Ads"},{"id":"slack","name":"Slack"}]},{"title":"PageSpeed monitor for top pages","prompt":"Create a scheduled workflow that runs Google PageSpeed Insights weekly against my top landing pages, writes mobile and desktop scores to a tables-based history, and flags regressions in Slack.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"slack","name":"Slack"}]},{"title":"PageSpeed sitemap audit","prompt":"Build a workflow that takes a sitemap URL, runs Google PageSpeed Insights against every page in batches, summarizes Core Web Vitals across the site, and saves the report as a file.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"PageSpeed pre-deploy gate","prompt":"Build a workflow triggered by a Vercel preview deployment that runs Google PageSpeed Insights against the preview URL, posts the scores as a GitHub PR comment, and fails the check if scores drop below threshold.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"vercel","name":"Vercel"},{"id":"github","name":"GitHub"}]},{"title":"PageSpeed CWV regression watcher","prompt":"Build a scheduled workflow that runs Google PageSpeed Insights daily for the top pages, captures Core Web Vitals, and pages on-call when LCP or CLS regress beyond threshold.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PageSpeed accessibility tracker","prompt":"Build a scheduled weekly workflow that runs Google PageSpeed Insights with the accessibility audit, writes per-page scores to a tracking table, and opens Linear tickets on regressions.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"linear","name":"Linear"}]},{"title":"PageSpeed CWV release gate","prompt":"Create a workflow triggered after a marketing-site deploy that runs Google PageSpeed Insights on the key landing pages for both mobile and desktop, compares Core Web Vitals against the prior baseline, and posts a pass/fail summary to Slack with the specific metrics that regressed.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"slack","name":"Slack"}]},{"title":"PageSpeed competitor benchmark","prompt":"Build a workflow that runs Google PageSpeed Insights against my homepage and a list of competitor URLs on mobile, compares the performance scores and Core Web Vitals side by side, and writes the ranked benchmark to a sheet.","integrations":[{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"google_sheets","name":"Google Sheets"}]}]},{"id":"google_search","type":"google_search","slug":"google-search","name":"Google Search","description":"Search the web","category":"Search","docsUrl":"https://docs.sim.ai/integrations/google_search","authType":"api-key","connections":[],"operations":[{"name":"Google Search","description":"Search the web with the Custom Search API"}],"triggers":[],"skills":[{"name":"search-the-web","description":"Run a Google web search and return the most relevant results with titles and links.","content":"# Search the Web\\n\\nFind current information with Google Custom Search.\\n\\n## Steps\\n1. Turn the request into an effective query. Use operators when helpful: \\"exact phrase\\", `site:domain.com`, `-exclude`, `OR`, `filetype:pdf`.\\n2. Set Number of Results to a sensible value (e.g., 10).\\n3. Run the search with the API key and Custom Search Engine ID.\\n4. Read the result items: title, link, and snippet.\\n\\n## Output\\nA ranked list of results, each with title, URL, and a one-line snippet. Drop low-relevance hits and note if the query returned little so it can be broadened."},{"name":"research-and-summarize","description":"Search Google for a topic, gather the best sources, and synthesize a cited answer.","content":"# Research and Summarize\\n\\nAnswer a question from fresh web sources.\\n\\n## Steps\\n1. Break the question into 1-3 focused search queries.\\n2. Run each search and collect the most relevant result items (title, link, snippet).\\n3. Synthesize a concise answer grounded in the snippets; do not assert facts the sources do not support.\\n4. Attribute each claim to its source link.\\n\\n## Output\\nA short, sourced answer followed by a list of the sources used (title + URL). If sources conflict, say so rather than guessing."},{"name":"monitor-mentions","description":"Search Google for recent mentions of a brand, person, or keyword and surface notable hits.","content":"# Monitor Mentions\\n\\nFind recent web mentions of a target term.\\n\\n## Steps\\n1. Build queries for the brand/person/keyword, optionally scoped with `site:` for specific outlets or quotes for exact names.\\n2. Run the searches and collect result items.\\n3. Filter out irrelevant or stale hits and dedupe near-identical results.\\n4. Classify each remaining mention (e.g., news, review, social) and gauge tone where possible.\\n\\n## Output\\nA list of notable mentions: title, source URL, a one-line summary, and a tone tag. Lead with the most significant items."}],"templates":[{"title":"Daily news digest","prompt":"Create a scheduled daily workflow that runs Google searches for the topics and competitors I care about, picks the most relevant fresh results, summarizes each in a sentence, and emails me a curated digest every morning.","integrations":[{"id":"google_search","name":"Google Search"},{"id":"gmail","name":"Gmail"}]},{"title":"Lead company researcher","prompt":"Build a workflow that watches my leads table for new rows, runs Google searches for each company\'s recent news, funding, and leadership, summarizes the findings with an agent, and writes a research brief back to the row.","integrations":[{"id":"google_search","name":"Google Search"}]},{"title":"SERP rank tracker","prompt":"Create a scheduled weekly workflow that runs Google searches for my target keywords, records where my domain appears in the results, logs positions to a tables-based scorecard, and posts a Slack summary of gainers and losers.","integrations":[{"id":"google_search","name":"Google Search"},{"id":"slack","name":"Slack"}]},{"title":"Brand mention monitor","prompt":"Build a scheduled workflow that searches Google for new mentions of my brand and key executives, filters out noise with an agent, and posts notable mentions with links to a Slack channel for the comms team.","integrations":[{"id":"google_search","name":"Google Search"},{"id":"slack","name":"Slack"}]},{"title":"Research-backed answer agent","prompt":"Create an agent that takes any question, runs targeted Google searches to gather current sources, synthesizes a concise answer with citations, and returns it so the team gets sourced answers instead of guesses.","integrations":[{"id":"google_search","name":"Google Search"}]},{"title":"Content gap explorer","prompt":"Build a workflow that runs Google searches for a seed topic and its related queries, extracts the recurring subtopics and questions competitors rank for, and writes a prioritized content brief to a table.","integrations":[{"id":"google_search","name":"Google Search"}]},{"title":"Support answer finder","prompt":"Create a workflow that on a new support ticket runs Google searches scoped to our docs and trusted sources, finds the most relevant pages, and drafts a sourced reply for the agent to review before sending.","integrations":[{"id":"google_search","name":"Google Search"}]}]},{"id":"google_sheets","type":"google_sheets_v2","slug":"google-sheets","name":"Google Sheets","description":"Read, write, and update data with sheet selection","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/google_sheets","authType":"oauth","connections":[{"id":"google-sheets","kind":"oauth","label":"Connect with OAuth","providerId":"google-sheets","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_sheets","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/drive.file","label":"View and manage Google Drive files you open or create with Sim"},{"id":"https://www.googleapis.com/auth/drive","label":"View, edit, create, and delete all Google Drive files"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Read Data","description":"Read data from a Google Sheets spreadsheet"},{"name":"Write Data","description":"Write data to a Google Sheets spreadsheet"},{"name":"Update Data","description":"Update data in a Google Sheets spreadsheet"},{"name":"Append Data","description":"Append data to the end of a Google Sheets spreadsheet"},{"name":"Clear Data","description":"Clear values from a specific range in a Google Sheets spreadsheet"},{"name":"Get Spreadsheet Info","description":"Get metadata about a Google Sheets spreadsheet including title and sheet list"},{"name":"Create Spreadsheet","description":"Create a new Google Sheets spreadsheet"},{"name":"Batch Read","description":"Read multiple ranges from a Google Sheets spreadsheet in a single request"},{"name":"Batch Update","description":"Update multiple ranges in a Google Sheets spreadsheet in a single request"},{"name":"Batch Clear","description":"Clear multiple ranges in a Google Sheets spreadsheet in a single request"},{"name":"Copy Sheet","description":"Copy a sheet from one spreadsheet to another"},{"name":"Delete Rows","description":"Delete rows from a sheet in a Google Sheets spreadsheet"},{"name":"Delete Sheet","description":"Delete a sheet/tab from a Google Sheets spreadsheet"},{"name":"Delete Spreadsheet","description":"Permanently delete a Google Sheets spreadsheet using the Google Drive API"}],"triggers":[{"id":"google_sheets_poller","name":"Google Sheets New Row Trigger","description":"Triggers when new rows are added to a Google Sheet"}],"skills":[{"name":"read-sheet-data","description":"Read rows from a Google Sheet, optionally filtering by a column value.","content":"# Read Sheet Data\\n\\nPull data out of a spreadsheet tab.\\n\\n## Steps\\n1. Select the spreadsheet and the Sheet (tab) to read.\\n2. Optionally set a Cell Range (e.g., A1:D100); leave blank to read the used range.\\n3. To narrow rows, set Filter Column (a header name), Filter Value, and Match Type (contains, exact, gt, etc.).\\n4. Run the Read Data operation and treat the first row as headers if present.\\n\\n## Output\\nReturn the rows (as a 2D array or labeled objects keyed by header), the range read, and a filter summary if a filter was applied. Note the row count."},{"name":"append-rows-to-sheet","description":"Add new rows to the end of a Google Sheet without overwriting existing data.","content":"# Append Rows to a Sheet\\n\\nAdd records to the bottom of a tab.\\n\\n## Steps\\n1. Select the spreadsheet and Sheet (tab).\\n2. Build the Values as a JSON array of arrays (each inner array is a row) or array of objects keyed by column.\\n3. Set Insert Data Option to Insert Rows so existing data is not overwritten.\\n4. Choose Value Input Option: User Entered (parses formulas/dates) or Raw.\\n5. Run the Append Data operation.\\n\\n## Output\\nConfirm the append: updated range, rows added, and the table range. Ensure column order matches the sheet headers."},{"name":"update-cells","description":"Write or update values in a specific range of a Google Sheet.","content":"# Update Cells\\n\\nWrite values into a targeted range.\\n\\n## Steps\\n1. Select the spreadsheet and Sheet (tab) and set the Cell Range to write (e.g., B2:D2).\\n2. Build the Values JSON so its dimensions match the range.\\n3. Pick Value Input Option: User Entered to evaluate formulas, or Raw to store literal text.\\n4. Run the Update Data operation (use Write Data to set a fresh block).\\n\\n## Output\\nConfirm updated range and the count of updated cells/rows/columns. If writing formulas, confirm User Entered was used so they evaluate."},{"name":"create-spreadsheet","description":"Create a new Google Sheets spreadsheet with named tabs and return its link.","content":"# Create a Spreadsheet\\n\\nStand up a new spreadsheet.\\n\\n## Steps\\n1. Set the Spreadsheet Title.\\n2. Optionally provide Sheet Names as a comma-separated list (e.g., \\"Data, Summary\\").\\n3. Run the Create Spreadsheet operation and capture the spreadsheet ID and URL.\\n4. Follow up with Write or Append operations to populate the tabs.\\n\\n## Output\\nReturn the new spreadsheet title, ID, URL, and the list of sheets created. Hand back the ID so subsequent steps can write to it."}],"templates":[{"title":"Flint location pages from a spreadsheet","prompt":"Build a workflow that reads city and service data from Google Sheets and uses Flint to generate a local landing page per city from a template, then writes each published URL back to the sheet.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"flint","name":"Flint"}]},{"title":"AppSheet inventory sync","prompt":"Build a workflow that reads updated rows from an AppSheet Inventory table, transforms the quantities with an agent, and writes the reconciled totals into a Google Sheet.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"BigQuery + Sheets exec dashboard","prompt":"Build a scheduled workflow that pulls a BigQuery executive dashboard query weekly, writes the result into a chosen Google Sheet, and notifies leadership the new snapshot is ready.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"google_bigquery","name":"Google BigQuery"},{"id":"gmail","name":"Gmail"}]},{"title":"PageSpeed competitor benchmark","prompt":"Build a workflow that runs Google PageSpeed Insights against my homepage and a list of competitor URLs on mobile, compares the performance scores and Core Web Vitals side by side, and writes the ranked benchmark to a sheet.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"Google Sheets approval gate","prompt":"Build a workflow that watches a Google Sheets row for a status change to \\"review\\", posts the row context to Slack with approval buttons, and writes the decision back.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"slack","name":"Slack"}]},{"title":"Google Sheets to Stripe payouts","prompt":"Create a workflow that reads a Google Sheets payouts ledger, validates each row, processes Stripe payouts in batches, and writes the result and Stripe ID back.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"stripe","name":"Stripe"}]},{"title":"Google Sheets CRM updater","prompt":"Build a scheduled workflow that pulls Salesforce opportunities, refreshes the Google Sheets spreadsheet that ops uses for weekly forecasting, and notes the last-updated timestamp.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Sheets data validator","prompt":"Create a scheduled workflow that validates a Google Sheets spreadsheet against a typed schema, flags rows with errors, writes a remediation column, and emails the sheet owner.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Sheets inventory sync","prompt":"Build a workflow that pulls Shopify inventory into Google Sheets hourly, calculates days-of-cover, and highlights items needing reorder for the ops team.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"shopify","name":"Shopify"}]},{"title":"Google Sheets forms cleanup","prompt":"Create a workflow that normalizes Google Sheets data submitted from Google Forms — title casing, phone formats, deduplication — and writes clean rows to a downstream sheet.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Send Slack messages from Google Sheets","prompt":"Build a workflow that watches a Google Sheets spreadsheet for new rows or changes, then posts formatted Slack updates to keep stakeholders informed in real time.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"slack","name":"Slack"}]},{"title":"Sync Google Sheets data into Notion","prompt":"Create an agent that reads rows from Google Sheets and transforms them into structured Notion database entries for richer documentation and cross-team project tracking.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"notion","name":"Notion"}]},{"title":"Harmonic contact coverage audit","prompt":"Create a workflow that resolves a team-visible Harmonic people saved search, pages all results, hydrates URN-only records in batches, flags duplicates and missing contact fields, and writes the review queue to Google Sheets.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"harmonic","name":"Harmonic"}]},{"title":"LaTeX certificate generator","prompt":"Create a workflow that reads attendee names from a spreadsheet, fills a LaTeX certificate template for each attendee, compiles the PDFs, and emails each certificate to its recipient.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"latex","name":"LaTeX"},{"id":"gmail","name":"Gmail"}]},{"title":"Stripe weekly metrics report","prompt":"Build a scheduled workflow that pulls data from Stripe and my database every Monday, calculates key metrics like MRR, churn, new subscriptions, and failed payments, writes results to Google Sheets, and sends the team a Slack summary with week-over-week trends.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Onboard new hires into Thrive","prompt":"Build a workflow that, when a new employee row is added to a Google Sheet, creates the user in Thrive with their ref, name, email, job title, and manager, then adds them to the relevant onboarding audience.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"thrive","name":"Thrive"}]},{"title":"Tag Thrive learners by skill","prompt":"Build a workflow that searches Thrive users by status, then adds skill tags and updates skill levels for each learner based on a mapping in a spreadsheet.","integrations":[{"id":"google_sheets","name":"Google Sheets"},{"id":"thrive","name":"Thrive"}]}]},{"id":"google_slides","type":"google_slides_v2","slug":"google-slides","name":"Google Slides","description":"Read, write, and create presentations","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/google_slides","authType":"oauth","connections":[{"id":"google-drive","kind":"oauth","label":"Connect with OAuth","providerId":"google-drive","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_slides","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/drive.file","label":"View and manage Google Drive files you open or create with Sim"},{"id":"https://www.googleapis.com/auth/drive","label":"View, edit, create, and delete all Google Drive files"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Read Presentation","description":"Read content from a Google Slides presentation"},{"name":"Write to Presentation","description":"Write or update content in a Google Slides presentation"},{"name":"Create Presentation","description":"Create a new Google Slides presentation"},{"name":"Copy Presentation","description":"Copy a template presentation in Drive to a new file. Use this before merging data so the original template is never modified."},{"name":"Export Presentation","description":"Export a presentation to PDF, PPTX, ODP, TXT, PNG, JPEG, or SVG via the Drive export endpoint. Stores the exported file as an execution file when execution context is available."},{"name":"Batch Update (Raw)","description":"Run a raw Slides API batchUpdate with a list of Request objects. Use this when the higher-level tools do not cover an operation, or to bundle multiple operations into a single atomic batch (all-or-nothing)."},{"name":"Replace All Text","description":"Find and replace all occurrences of text throughout a Google Slides presentation"},{"name":"Replace All Shapes With Image","description":"Find every shape whose text matches the given token (e.g. {{cover-image}}) and replace it with an image, preserving the shape\'s position and bounds."},{"name":"Replace Image","description":"Replace the source of an existing image with a new image URL, preserving the image\'s position, size, and properties."},{"name":"Update Image Properties","description":"Update image properties — brightness, contrast, transparency, crop, outline, link — on an existing image."},{"name":"Add Slide","description":"Add a new slide to a Google Slides presentation with a specified layout"},{"name":"Add Image","description":"Insert an image into a specific slide in a Google Slides presentation"},{"name":"Get Thumbnail","description":"Generate a thumbnail image of a specific slide in a Google Slides presentation"},{"name":"Get Page","description":"Get detailed information about a specific slide/page in a Google Slides presentation"},{"name":"Delete Object","description":"Delete a page element (shape, image, table, etc.) or an entire slide from a Google Slides presentation"},{"name":"Duplicate Object","description":"Duplicate an object (slide, shape, image, table, etc.) in a Google Slides presentation"},{"name":"Reorder Slides","description":"Move one or more slides to a new position in a Google Slides presentation"},{"name":"Create Table","description":"Create a new table on a slide in a Google Slides presentation"},{"name":"Create Shape","description":"Create a shape (rectangle, ellipse, text box, arrow, etc.) on a slide in a Google Slides presentation"},{"name":"Create Line","description":"Create a line or connector on a slide."},{"name":"Insert Text","description":"Insert text into a shape or table cell in a Google Slides presentation. Use this to add text to text boxes, shapes, or table cells."},{"name":"Delete Text","description":"Delete text from a shape or table cell. Use range type ALL to clear all text, or FIXED_RANGE / FROM_START_INDEX to delete a specific span."},{"name":"Update Text Style","description":"Update the styling of text in a shape or table cell (bold, italic, font family, font size, foreground/background color, link, etc.). Only the fields you set are applied."},{"name":"Update Paragraph Style","description":"Update paragraph styling — alignment, line spacing, indents, space above/below — for text in a shape or table cell."},{"name":"Create Paragraph Bullets","description":"Convert paragraphs in a shape or table cell into a bulleted or numbered list using a Google Slides bullet preset."},{"name":"Delete Paragraph Bullets","description":"Remove bullets/numbering from paragraphs in a shape or table cell."},{"name":"Update Shape Properties","description":"Update a shape\'s appearance — background fill color, outline, link, content alignment, autofit. Pass only the properties you want to change."},{"name":"Update Page Properties","description":"Update slide/page background — solid color or stretched picture — and other page properties."},{"name":"Update Slide Properties","description":"Update slide-specific properties such as whether the slide is skipped during presentation."},{"name":"Update Alt Text","description":"Set the accessibility title and/or description (alt text) of a page element such as an image, shape, or group."},{"name":"Update Element Transform","description":"Move, resize, scale, or shear a page element. Translate is specified in points; applyMode controls whether the transform is absolute (default) or relative (multiplied with the current transform)."},{"name":"Update Z-Order","description":"Bring elements to front, send to back, or step them one layer forward/backward."},{"name":"Group Objects","description":"Group two or more page elements on the same slide into a single object group."},{"name":"Ungroup Objects","description":"Ungroup one or more object groups, releasing their children back to the slide."},{"name":"Update Line Properties","description":"Update line appearance — color, weight, dash style, arrows, link."},{"name":"Update Line Category","description":"Change a connector line\'s category (STRAIGHT, BENT, or CURVED)."},{"name":"Reroute Line","description":"Reroute a connector line so it efficiently connects its endpoint shapes — useful after moving the shapes the line connects."},{"name":"Insert Table Rows","description":"Insert one or more rows into a table, above or below a reference cell."},{"name":"Insert Table Columns","description":"Insert one or more columns into a table, left or right of a reference cell."},{"name":"Delete Table Row","description":"Delete the row containing the reference cell from a table."},{"name":"Delete Table Column","description":"Delete the column containing the reference cell from a table."},{"name":"Merge Table Cells","description":"Merge a rectangular range of table cells into a single cell. The range starts at (rowIndex, columnIndex) and covers rowSpan × columnSpan cells."},{"name":"Unmerge Table Cells","description":"Unmerge any merged cells within the given table range."},{"name":"Update Table Cell Properties","description":"Update background fill and content alignment for a range of table cells."},{"name":"Update Table Border Properties","description":"Update border color, weight, and dash style for a position (e.g. ALL, INNER, OUTER) in a table range."},{"name":"Update Table Column Properties","description":"Update column widths and other column-level table properties."},{"name":"Update Table Row Properties","description":"Update minimum row heights and other row-level table properties."},{"name":"Embed Sheets Chart","description":"Embed a chart from a Google Sheets spreadsheet onto a slide. LINKED charts can be refreshed; NOT_LINKED_IMAGE inserts a static image of the chart."},{"name":"Refresh Sheets Chart","description":"Refresh an embedded linked Sheets chart so it reflects the latest spreadsheet data."},{"name":"Replace All Shapes With Sheets Chart","description":"Find every shape matching a text token (e.g. {{revenue-chart}}) and replace each with the same embedded Sheets chart, preserving the shape\'s position and bounds."},{"name":"Embed Video","description":"Embed a YouTube or Google Drive video on a slide."},{"name":"Update Video Properties","description":"Update video playback options (autoPlay, mute, start/end) and outline."}],"triggers":[],"skills":[{"name":"generate-deck-from-template","description":"Copy a Google Slides template and replace placeholder text and images with data to produce a finished deck.","content":"# Generate Deck From Template\\n\\nProduce a finished presentation by copying a template deck and filling in dynamic values.\\n\\n## Steps\\n1. Create a copy of the template presentation, or create a new presentation, and capture its presentationId.\\n2. For each placeholder token (e.g. {{company}}, {{date}}, {{metric}}), call replace all text to substitute the real value across every slide.\\n3. Replace placeholder images by adding images to the relevant slides, sizing and positioning them on the page.\\n4. Add or duplicate slides for repeating sections (one per item) so the deck length matches the data.\\n5. Read the presentation back to confirm every placeholder was resolved.\\n\\n## Output\\nReturn the presentationId and the shareable link. Note any placeholders that had no matching data so they can be reviewed."},{"name":"build-metrics-slide","description":"Add a slide with a table and shapes that summarizes KPIs or metrics into a Google Slides deck.","content":"# Build Metrics Slide\\n\\nInsert a clean, data-driven metrics slide into an existing presentation.\\n\\n## Steps\\n1. Add a new slide to the target presentation and capture the new slide objectId.\\n2. Create a table on the slide sized to the number of metrics (rows) and columns needed.\\n3. Insert text into each cell with the metric name, current value, and change vs prior period.\\n4. Optionally create shape callouts for headline numbers and apply text and paragraph styles for emphasis.\\n5. Get a thumbnail to verify layout and readability.\\n\\n## Output\\nReturn the slide objectId and a thumbnail link. Summarize which metrics were added."},{"name":"extract-deck-content","description":"Read a Google Slides presentation and extract all slide text into a structured outline.","content":"# Extract Deck Content\\n\\nPull the full text of a presentation into a structured outline for summarization or repurposing.\\n\\n## Steps\\n1. Read the presentation by ID to get all slides and page elements.\\n2. For each slide, collect title text, body text, table cell text, and speaker notes if present.\\n3. Preserve slide order and group text under each slide number.\\n4. Skip purely decorative elements with no text.\\n\\n## Output\\nReturn a numbered outline (one section per slide) with the extracted text. Useful as input for a summary, recap email, or knowledge base entry."},{"name":"rebrand-deck","description":"Roll out a brand or naming change across an entire deck by swapping text and logo images everywhere.","content":"# Rebrand Deck\\n\\nApply a consistent brand or naming change across every slide in one pass.\\n\\n## Steps\\n1. Read the presentation by ID to confirm which terms and logo placeholders appear.\\n2. For each old-to-new term (product name, tagline, company name), call replace all text so it updates across every slide at once.\\n3. Replace the old logo by calling replace all shapes with image, or replace image on each logo element, with the new asset URL.\\n4. Optionally update shape or page properties to match new brand colors.\\n5. Read the presentation back to confirm no stale terms or logos remain.\\n\\n## Output\\nReturn the presentationId and a list of the terms and images that were replaced, flagging any old references that still appear."}],"templates":[{"title":"Google Slides QBR generator","prompt":"Build a workflow that takes a customer account, pulls usage and support data, and generates a Google Slides QBR deck from a template with the metrics auto-filled.","integrations":[{"id":"google_slides","name":"Google Slides"}]},{"title":"Google Slides weekly board update","prompt":"Create a scheduled weekly workflow that updates a Google Slides board deck with the latest KPIs from tables, swaps the cover image, and shares the link to the leadership thread.","integrations":[{"id":"google_slides","name":"Google Slides"},{"id":"slack","name":"Slack"}]},{"title":"Google Slides case-study builder","prompt":"Build a workflow that takes a customer story brief and generates a Google Slides case-study deck from a template, including pull quotes, metrics, and a logo.","integrations":[{"id":"google_slides","name":"Google Slides"}]},{"title":"Google Slides pitch personalizer","prompt":"Create a workflow that takes a Salesforce opportunity, generates a Google Slides pitch deck personalized to the account, and attaches it to the opportunity record.","integrations":[{"id":"google_slides","name":"Google Slides"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Slides training builder","prompt":"Build a workflow that takes a knowledge base topic, generates a Google Slides training deck with structured slides, talking points, and quiz slides at the end.","integrations":[{"id":"google_slides","name":"Google Slides"}]},{"title":"Google Slides exec metrics deck","prompt":"Create a scheduled monthly workflow that generates a Google Slides executive metrics deck from BigQuery and Stripe data, swaps the cover with the month, and shares it with leadership.","integrations":[{"id":"google_slides","name":"Google Slides"},{"id":"google_bigquery","name":"Google BigQuery"},{"id":"stripe","name":"Stripe"}]},{"title":"Google Slides win-loss recap","prompt":"Build a workflow that aggregates closed-won and closed-lost deals from Salesforce monthly, generates a Google Slides recap with patterns and insights, and emails it to the sales team.","integrations":[{"id":"google_slides","name":"Google Slides"},{"id":"salesforce","name":"Salesforce"},{"id":"gmail","name":"Gmail"}]}]},{"id":"google_tasks","type":"google_tasks","slug":"google-tasks","name":"Google Tasks","description":"Manage Google Tasks","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/google_tasks","authType":"oauth","connections":[{"id":"google-tasks","kind":"oauth","label":"Connect with OAuth","providerId":"google-tasks","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_tasks","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/tasks","label":"Create, read, update, and delete Google Tasks"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Create Task","description":"Create a new task in a Google Tasks list"},{"name":"List Tasks","description":"List all tasks in a Google Tasks list"},{"name":"Get Task","description":"Retrieve a specific task by ID from a Google Tasks list"},{"name":"Update Task","description":"Update an existing task in a Google Tasks list"},{"name":"Delete Task","description":"Delete a task from a Google Tasks list"},{"name":"List Task Lists","description":"Retrieve all task lists for the authenticated user"}],"triggers":[],"skills":[{"name":"capture-action-items","description":"Turn a list of action items into Google Tasks with titles, notes, and due dates in the right task list.","content":"# Capture Action Items\\n\\nConvert extracted action items into well-formed Google Tasks.\\n\\n## Steps\\n1. List the available task lists and pick the target list (default to the primary list if none specified).\\n2. For each action item, create a task with a concise title, detailed notes for context, and a due date if one was given.\\n3. Avoid duplicates by skipping items whose title already exists in the list.\\n\\n## Output\\nReturn the created task IDs and titles, grouped by task list. Note any items skipped as duplicates."},{"name":"list-due-and-overdue","description":"List open Google Tasks that are due soon or overdue across a task list for a daily review.","content":"# List Due and Overdue Tasks\\n\\nSurface tasks that need attention for a daily or weekly review.\\n\\n## Steps\\n1. List the task lists, or use a specified list.\\n2. List tasks in the list, including completed status and due dates.\\n3. Filter to incomplete tasks and split into Overdue (due before today) and Due Soon (due within the next few days).\\n4. Sort each group by due date ascending.\\n\\n## Output\\nReturn two sections, Overdue and Due Soon, each with task title, due date, and task ID. Useful for posting a standup or reminder digest."},{"name":"complete-task-by-title","description":"Find a Google Task by its title and mark it completed.","content":"# Complete Task By Title\\n\\nMark a task done when given a title rather than an ID.\\n\\n## Steps\\n1. List tasks in the relevant task list and match the requested title (case-insensitive, allow partial match).\\n2. If multiple match, prefer the incomplete one; if still ambiguous, return the candidates and ask for clarification.\\n3. Update the matched task to set its status to completed.\\n4. Confirm the update by reading the task back.\\n\\n## Output\\nReturn the completed task title and ID, or the list of ambiguous candidates if no single match was found."}],"templates":[{"title":"Google Tasks digest","prompt":"Build a scheduled daily workflow that summarizes Google Tasks due today and tomorrow, and emails the user a prioritized digest each morning.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Tasks from Gmail","prompt":"Create a workflow that watches Gmail for emails marked with a task label, extracts the action and due date, and creates a Google Tasks entry with a link back to the email.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Tasks from meetings","prompt":"Build a workflow that runs after Google Meet meetings, extracts action items from the transcript, and creates Google Tasks entries for the owner with due dates.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Google Tasks completion digest","prompt":"Create a scheduled weekly workflow that summarizes Google Tasks completed by the user, captures the throughput, and emails a personal productivity report.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Tasks rolling cleanup","prompt":"Build a scheduled workflow that runs daily, archives Google Tasks completed more than 30 days ago, and surfaces tasks past their due date for re-prioritization.","integrations":[{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Google Tasks Slack sync","prompt":"Create a workflow that watches Slack for messages tagged with the saved-task emoji, captures the message and creates a Google Tasks entry with a link to the Slack thread.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"slack","name":"Slack"}]},{"title":"Google Tasks calendar block builder","prompt":"Build a workflow that on a Google Tasks creation also inserts a Google Calendar focus block with the task title, so the time is actually reserved.","integrations":[{"id":"google_tasks","name":"Google Tasks"},{"id":"google_calendar","name":"Google Calendar"}]}]},{"id":"google_translate","type":"google_translate","slug":"google-translate","name":"Google Translate","description":"Translate text using Google Cloud Translation","category":"AI","docsUrl":"https://docs.sim.ai/integrations/google_translate","authType":"api-key","connections":[],"operations":[{"name":"Translate Text","description":"Translate text between languages using the Google Cloud Translation API. Supports auto-detection of the source language."},{"name":"Detect Language","description":"Detect the language of text using the Google Cloud Translation API."}],"triggers":[],"skills":[{"name":"translate-to-language","description":"Translate a block of text into a target language using Google Cloud Translation.","content":"# Translate To Language\\n\\nTranslate text into a specified target language.\\n\\n## Steps\\n1. Take the source text and the target language code (e.g. es, fr, ja).\\n2. If the source language is unknown, detect it first; otherwise pass it explicitly for accuracy.\\n3. Call translate text with the target language and capture the translated output.\\n4. For long content, split into paragraph-sized chunks and translate each to preserve formatting.\\n\\n## Output\\nReturn the translated text along with the detected or supplied source language and the target language. Preserve line breaks from the original."},{"name":"detect-and-route-language","description":"Detect the language of incoming text and route or label it accordingly.","content":"# Detect and Route Language\\n\\nIdentify the language of a message so it can be routed, labeled, or translated.\\n\\n## Steps\\n1. Call detect language on the input text and capture the language code and confidence.\\n2. If confidence is low, fall back to detecting on a longer sample or flag as uncertain.\\n3. Decide the route: if the detected language differs from the team language, translate it; otherwise pass through unchanged.\\n\\n## Output\\nReturn the detected language code, confidence, and a recommended action (translate or pass-through). Include the translated text when translation was performed."},{"name":"localize-message-set","description":"Translate one source message into several target languages for multilingual delivery.","content":"# Localize Message Set\\n\\nProduce localized versions of a single message for multiple audiences.\\n\\n## Steps\\n1. Take the source text and the list of target language codes.\\n2. For each target language, call translate text with the source language set explicitly for consistency.\\n3. Keep placeholders, names, and URLs intact across all translations.\\n\\n## Output\\nReturn a mapping of language code to translated text. Note any target language where translation appeared incomplete or unchanged."}],"templates":[{"title":"Google Docs translation copy","prompt":"Build a workflow that takes a Google Docs document and creates translated copies into target languages with Google Translate, links them in the source, and notifies the localization team.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Google Translate doc localizer","prompt":"Create a workflow that watches a Google Drive folder of source-language docs, translates each into target languages with Google Translate while preserving structure, and writes the localized files back.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Translate Intercom replier","prompt":"Build a workflow that detects the language of a new Intercom message, translates it to the agent language with Google Translate, drafts a reply, then translates the reply back before sending.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"intercom","name":"Intercom"}]},{"title":"Google Translate + Hugging Face confidence","prompt":"Create a workflow that runs Google Translate then scores translation quality with a Hugging Face model, flags low-confidence segments for human review, and writes the scored output.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"huggingface","name":"Hugging Face"}]},{"title":"Google Translate + Mistral Parser localization","prompt":"Build a workflow that uses Mistral Parser to extract structured content from source-language PDFs and Google Translate to localize each section while preserving structure.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Google Translate Confluence localization","prompt":"Create a workflow that watches Confluence pages tagged for localization, translates each into the target languages with Google Translate, and publishes localized copies.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"confluence","name":"Confluence"}]},{"title":"Google Translate ticket auto-reply","prompt":"Build a workflow that on a new support ticket detects the customer\'s language with Google Translate, translates the message to English for the agent, drafts a reply, then translates the response back into the customer\'s language before sending.","integrations":[{"id":"google_translate","name":"Google Translate"}]},{"title":"Google Translate Slack translator","prompt":"Create a workflow that watches an international Slack channel, detects non-English messages with Google Translate, translates them to the team\'s language, and posts the translation in a thread so everyone stays in the loop.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"slack","name":"Slack"}]},{"title":"Slack thread translator","prompt":"Build a workflow that watches international Slack channels, detects non-English messages, translates them with Google Translate, and posts the English version in a thread so the wider team stays in the loop.","integrations":[{"id":"google_translate","name":"Google Translate"},{"id":"slack","name":"Slack"}]}]},{"id":"google_vault","type":"google_vault","slug":"google-vault","name":"Google Vault","description":"Search, export, and manage matters, holds, exports, and saved queries in Vault","category":"Security","docsUrl":"https://docs.sim.ai/integrations/google_vault","authType":"oauth","connections":[{"id":"google-vault","kind":"oauth","label":"Connect with OAuth","providerId":"google-vault","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/google_vault","requiredScopes":[{"id":"https://www.googleapis.com/auth/userinfo.email","label":"View email address"},{"id":"https://www.googleapis.com/auth/userinfo.profile","label":"View basic profile info"},{"id":"https://www.googleapis.com/auth/ediscovery","label":"Manage Google Vault matters, holds, and exports"},{"id":"https://www.googleapis.com/auth/ediscovery.readonly","label":"View Google Vault matters, holds, and saved queries"},{"id":"https://www.googleapis.com/auth/devstorage.read_only","label":"Read files from Google Cloud Storage"}],"fields":[]},{"id":"google-service-account","kind":"service_account","providerId":"google-service-account","label":"Add service account","setup":"google-json","docsUrl":"https://docs.sim.ai/integrations/google-service-account","fields":[{"id":"serviceAccountJson","label":"JSON key","placeholder":"Paste the service-account JSON key","secret":true,"multiline":true}]}],"operations":[{"name":"Create Export","description":"Create an export in a matter"},{"name":"List Exports","description":"List exports for a matter"},{"name":"Delete Export","description":"Delete an export from a matter"},{"name":"Download Export File","description":"Download a single file from a Google Vault export (GCS object)"},{"name":"Create Hold","description":"Create a hold in a matter"},{"name":"List Holds","description":"List holds for a matter"},{"name":"Update Hold","description":"Replace the name, query, and scope of an existing hold. This is a full-resource update: fetch the current hold first (Vault List Holds) and resupply every field you want to keep — any field left blank is cleared, not left unchanged."},{"name":"Delete Hold","description":"Delete a hold and release its covered accounts"},{"name":"Add Held Accounts","description":"Add accounts to an existing hold"},{"name":"Remove Held Accounts","description":"Remove accounts from an existing hold"},{"name":"Create Matter","description":"Create a new matter in Google Vault"},{"name":"List Matters","description":"List matters, or get a specific matter if matterId is provided"},{"name":"Update Matter","description":"Update the name and/or description of a matter"},{"name":"Close Matter","description":"Close a matter"},{"name":"Reopen Matter","description":"Reopen a closed matter"},{"name":"Delete Matter","description":"Permanently delete a matter (must be closed first)"},{"name":"Undelete Matter","description":"Restore a deleted matter"},{"name":"Add Matter Collaborator","description":"Add a collaborator (or transfer ownership) to a matter"},{"name":"Remove Matter Collaborator","description":"Remove a collaborator from a matter"},{"name":"Create Saved Query","description":"Save a reusable search query in a matter"},{"name":"List Saved Queries","description":"List saved queries in a matter, or get a specific one if savedQueryId is provided"},{"name":"Delete Saved Query","description":"Delete a saved query from a matter"}],"triggers":[],"skills":[{"name":"open-legal-hold","description":"Create a Vault matter and place a legal hold on custodians for an investigation or litigation.","content":"# Open Legal Hold\\n\\nStand up a Vault matter and preserve data for the relevant custodians.\\n\\n## Steps\\n1. Create a matter with a clear name and description tied to the case or investigation.\\n2. List existing matters first to avoid creating a duplicate for the same case.\\n3. Create a hold on the matter for the named custodians and the relevant service (mail, Drive, etc.).\\n4. List holds on the matter to confirm the custodians were preserved.\\n\\n## Output\\nReturn the matterId, the holdId, and the list of custodians now under hold. Note any custodian that could not be added."},{"name":"run-discovery-export","description":"Create a Vault export for a matter using a search query, then retrieve the export files.","content":"# Run Discovery Export\\n\\nProduce an export of matching data for eDiscovery or compliance review.\\n\\n## Steps\\n1. Identify or create the matter for the export.\\n2. Create an export with the search query, date range, and target accounts/org unit scoped as narrowly as possible.\\n3. List exports on the matter and poll until the new export status is completed.\\n4. Download the export files once the export is ready.\\n\\n## Output\\nReturn the exportId, its status, and the downloaded file references. Summarize the query and scope used so the export is auditable."},{"name":"audit-active-holds","description":"List Vault matters and their holds to produce a custodian preservation status report.","content":"# Audit Active Holds\\n\\nGenerate a status report of which matters and custodians are currently preserved.\\n\\n## Steps\\n1. List all matters and capture their IDs, names, and states.\\n2. For each open matter, list its holds and the custodians and services covered.\\n3. Flag matters with no holds and custodians that appear across multiple matters.\\n\\n## Output\\nReturn a per-matter summary listing holds, services, and custodians, plus a flagged section for matters missing holds. Suitable for a monthly legal review."},{"name":"close-out-matter","description":"Wind down a resolved matter by closing it, and permanently delete it once retention requirements are satisfied.","content":"# Close Out Matter\\n\\nRetire a matter once the underlying investigation or litigation is resolved.\\n\\n## Steps\\n1. List the holds on the matter and confirm none still need to be preserved; delete any holds that are no longer required.\\n2. Close the matter.\\n3. If the matter should be permanently removed and your retention policy allows it, delete the closed matter (reopen or undelete if this was done in error).\\n\\n## Output\\nReturn the matterId, its final state, and which holds (if any) were deleted before close-out."},{"name":"manage-hold-scope","description":"Add or remove custodians from an existing legal hold as the custodian list for a matter changes.","content":"# Manage Hold Scope\\n\\nKeep an existing hold in sync with the current custodian list without recreating it.\\n\\n## Steps\\n1. List the holds on the matter and identify the target hold.\\n2. Add newly relevant custodians to the hold by email.\\n3. Remove custodians who have left the investigation scope by account ID.\\n4. Fetch the hold again by its ID to confirm the accounts field reflects the change.\\n\\n## Output\\nReturn the holdId and the accounts added and removed, noting any that failed with their error status."}],"templates":[{"title":"Google Vault legal hold automator","prompt":"Build a scheduled workflow that polls Salesforce for new legal-hold instructions, creates a Google Vault matter and hold for the named custodians, and notifies legal with the hold details.","integrations":[{"id":"google_vault","name":"Google Vault"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Vault hold auditor","prompt":"Create a scheduled workflow that lists Google Vault matters and holds, flags custodians missing expected holds, and writes the findings to a compliance review table.","integrations":[{"id":"google_vault","name":"Google Vault"}]},{"title":"Google Vault eDiscovery exporter","prompt":"Build a workflow that takes an eDiscovery request, runs a Google Vault search, exports the matters into structured archives, and writes the export manifest.","integrations":[{"id":"google_vault","name":"Google Vault"}]},{"title":"Google Vault hold reviewer","prompt":"Create a scheduled workflow that lists Google Vault holds across matters, summarizes their custodians and scope, and writes a review report for the legal team to approve.","integrations":[{"id":"google_vault","name":"Google Vault"}]},{"title":"Google Vault sensitive-term exporter","prompt":"Build a scheduled workflow that creates Google Vault exports for sensitive search terms weekly, downloads the export results, and writes the matching items to a compliance review queue.","integrations":[{"id":"google_vault","name":"Google Vault"}]},{"title":"Google Vault export archiver","prompt":"Create a scheduled workflow that creates Google Vault matter exports, downloads the export files, archives them to S3 long-term storage, and writes the manifest to a compliance table.","integrations":[{"id":"google_vault","name":"Google Vault"},{"id":"s3","name":"S3"}]},{"title":"Google Vault custodian dashboard","prompt":"Build a scheduled monthly workflow that summarizes Google Vault holds and custodians, generates a status dashboard, and writes it to a legal review file.","integrations":[{"id":"google_vault","name":"Google Vault"}]}]},{"id":"grafana","type":"grafana","slug":"grafana","name":"Grafana","description":"Interact with Grafana dashboards, alerts, and annotations","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/grafana","authType":"api-key","connections":[],"operations":[{"name":"List Dashboards","description":"Search and list all dashboards"},{"name":"Get Dashboard","description":"Get a dashboard by its UID"},{"name":"Create Dashboard","description":"Create a new dashboard"},{"name":"Update Dashboard","description":"Update an existing dashboard. Fetches the current dashboard and merges your changes."},{"name":"Delete Dashboard","description":"Delete a dashboard by its UID"},{"name":"List Alert Rules","description":"List all alert rules in the Grafana instance"},{"name":"Get Alert Rule","description":"Get a specific alert rule by its UID"},{"name":"Get Alert Rule Group","description":"Read an alert rule group: its evaluation interval and every rule in it. The interval is the group-level knob that decides how often those rules are evaluated, which the individual alert rule operations do not expose."},{"name":"Create Alert Rule","description":"Create a new alert rule"},{"name":"Update Alert Rule","description":"Update an existing alert rule. Fetches the current rule and merges your changes."},{"name":"Delete Alert Rule","description":"Delete an alert rule by its UID"},{"name":"List Contact Points","description":"List all alert notification contact points"},{"name":"Create Contact Point","description":"Create a notification contact point (e.g., Slack, email, PagerDuty)"},{"name":"Update Contact Point","description":"Replace a contact point by its UID. Grafana has no partial update for contact points, so every field is rewritten — resend the name, type, and full settings, or the omitted ones are reset."},{"name":"Delete Contact Point","description":"Permanently delete a contact point by its UID. Grafana refuses the delete while the contact point is still referenced by the notification policy tree or by an alert rule."},{"name":"Create Annotation","description":"Create an annotation on a dashboard or as a global annotation"},{"name":"List Annotations","description":"Query annotations by time range, dashboard, or tags"},{"name":"Update Annotation","description":"Update an existing annotation"},{"name":"Delete Annotation","description":"Delete an annotation by its ID"},{"name":"List Data Sources","description":"List all data sources configured in Grafana"},{"name":"Get Data Source","description":"Get a data source by its ID or UID"},{"name":"Query Data Source","description":"Run one or more queries against a Grafana data source that has a backend implementation, and read the values back. This is how you get actual metric numbers out of Grafana rather than dashboard or alert configuration."},{"name":"Check Data Source Health","description":"Test connectivity to a data source by its UID"},{"name":"List Folders","description":"List all folders in Grafana"},{"name":"Create Folder","description":"Create a new folder in Grafana"},{"name":"Get Folder","description":"Get a folder by its UID"},{"name":"Update Folder","description":"Update (rename) a folder. Fetches the current folder and merges your changes."},{"name":"Delete Folder","description":"Delete a folder by its UID"},{"name":"Move Folder","description":"Move a folder under a different parent folder, or to the root by leaving the parent empty. Returns the folder with its new ancestry."},{"name":"Get Health","description":"Check the health of the Grafana instance (version, database status)"}],"triggers":[],"skills":[{"name":"annotate-deploy","description":"Create a Grafana annotation marking a deploy or incident so it shows on dashboards.","content":"# Annotate Deploy\\n\\nMark a deploy, release, or incident on Grafana dashboards for correlation.\\n\\n## Steps\\n1. Build the annotation text (e.g. version, PR link, who triggered it) and tags for filtering.\\n2. Create an annotation with the event time, or a time range for incidents with a start and end.\\n3. Optionally scope the annotation to a specific dashboard so it appears only there.\\n4. List annotations for the window to confirm it was recorded.\\n\\n## Output\\nReturn the annotation ID, time, and tags. Useful for correlating metric changes with deploys later."},{"name":"review-firing-alerts","description":"List Grafana alert rules and surface those currently firing with their contact points.","content":"# Review Firing Alerts\\n\\nProduce a snapshot of alerting health for an on-call handoff or incident triage.\\n\\n## Steps\\n1. Run List Annotations with `type: \'alert\'` over the window you care about. Alert-state transitions are recorded as annotations and carry `newState` and `prevState`, which is how you find what actually fired — the alert rule operations return rule *definitions*, never live instance state.\\n2. Run List Alert Rules to join each firing rule id back to its title, folder, condition, and labels.\\n3. Optionally run Query Data Source on the rule\'s own query to see how far the metric is from its threshold right now.\\n4. Run List Contact Points, and Get Alert Rule Group for the evaluation interval, so each firing rule maps to who gets notified and how often it is checked.\\n5. Group findings by severity label or folder.\\n\\n## Output\\nReturn the rules that transitioned into a firing state in the window, each with its title, the transition, its notification target, and its group evaluation interval. Say explicitly that this is derived from state-change annotations rather than a live instance snapshot, and give the window covered."},{"name":"audit-dashboards","description":"List Grafana dashboards and folders and report data sources each depends on.","content":"# Audit Dashboards\\n\\nInventory dashboards and the data sources they rely on.\\n\\n## Steps\\n1. List folders and dashboards to build the full inventory.\\n2. Get details for each dashboard of interest to read its panels and referenced data sources.\\n3. List data sources, then check the health of each one to flag dashboards pointing at unreachable or deprecated sources.\\n\\n## Output\\nReturn an inventory grouped by folder, each dashboard with its UID and the data sources it uses, plus a flagged list of dashboards whose data sources failed their health check."},{"name":"provision-monitoring-folder","description":"Create a Grafana folder and seed it with a starter dashboard for a new service or team.","content":"# Provision Monitoring Folder\\n\\nSet up an organized monitoring home for a new service or team.\\n\\n## Steps\\n1. Create a folder with a descriptive title for the service or team.\\n2. List data sources and pick the one the new dashboard should query.\\n3. Create a dashboard inside the folder with starter panels for the key metrics.\\n4. Get the dashboard back to confirm it was created in the right folder.\\n\\n## Output\\nReturn the folder UID and the new dashboard UID and link. Note the data source the dashboard was wired to."},{"name":"provision-alerting","description":"Stand up a Grafana alert rule and the contact point it notifies for a new service.","content":"# Provision Alerting\\n\\nWire up end-to-end alerting for a service: a notification target plus the rule that fires to it.\\n\\n## Steps\\n1. List existing contact points to avoid duplicating one.\\n2. Create a contact point for the destination (Slack, email, or PagerDuty) with its settings.\\n3. Create an alert rule in the target folder with the query data, condition, and for-duration.\\n4. Get the alert rule back to confirm it was created and is not paused.\\n\\n## Output\\nReturn the new contact point UID and alert rule UID, with the data source and threshold the rule evaluates."}],"templates":[{"title":"Grafana alert auto-context","prompt":"Build a scheduled workflow that reads Grafana alert-state annotations to find rules that just started firing, queries the underlying data source for the current metric value, summarizes the two together with an agent, and posts the enriched alert to PagerDuty and Slack.","integrations":[{"id":"grafana","name":"Grafana"},{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"Grafana SLO scorecard","prompt":"Create a scheduled weekly workflow that runs SLI queries against a Grafana data source for each service, calculates error budget burn rates from the returned series, and writes a scorecard to a tables-based SRE review board.","integrations":[{"id":"grafana","name":"Grafana"}]},{"title":"Grafana dashboard auditor","prompt":"Build a scheduled workflow that scans Grafana dashboards monthly for broken panels, unused dashboards, and missing alerts, and writes a cleanup queue for the platform team.","integrations":[{"id":"grafana","name":"Grafana"}]},{"title":"Grafana metric export","prompt":"Create a workflow that runs a set of Grafana data source queries on schedule and writes the returned series into a Sim table, so the metrics can be combined with business data for unified reporting.","integrations":[{"id":"grafana","name":"Grafana"}]},{"title":"Grafana incident annotator","prompt":"Build a scheduled workflow that polls PagerDuty for new incidents and adds Grafana annotations to relevant dashboards with the incident link, so engineers can see the context immediately on the timeline.","integrations":[{"id":"grafana","name":"Grafana"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Grafana on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of Grafana alerts by service and severity, and posts an on-call digest to Slack each morning.","integrations":[{"id":"grafana","name":"Grafana"},{"id":"slack","name":"Slack"}]},{"title":"Grafana + Linear feature-impact","prompt":"Build a scheduled workflow that queries a Grafana data source for latency and error rates, compares each series against the prior period to spot regressions, correlates them with recent Linear releases, and posts a regression review to the team Slack with the suspected change.","integrations":[{"id":"grafana","name":"Grafana"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]}]},{"id":"grain","type":"grain_v2","slug":"grain","name":"Grain","description":"Access meeting recordings, transcripts, and AI summaries","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/grain","authType":"api-key","connections":[],"operations":[{"name":"List Recordings","description":"List recordings from Grain with optional filters and pagination"},{"name":"Get Recording","description":"Get details of a single recording by ID"},{"name":"Get Transcript","description":"Get the full transcript of a recording"},{"name":"List Views","description":"List available Grain views for webhook subscriptions"},{"name":"List Teams","description":"List all teams in the workspace"},{"name":"List Meeting Types","description":"List all meeting types in the workspace"},{"name":"Create Webhook","description":"Create a webhook to receive recording events"},{"name":"List Webhooks","description":"List all webhooks for the account"},{"name":"Delete Webhook","description":"Delete a webhook by ID"}],"triggers":[{"id":"grain_recording_added_v2","name":"Grain Recording Added","description":"Trigger when a new recording is added in Grain"},{"id":"grain_recording_updated_v2","name":"Grain Recording Updated","description":"Trigger when a recording is updated in Grain"},{"id":"grain_recording_deleted_v2","name":"Grain Recording Deleted","description":"Trigger when a recording is deleted in Grain"},{"id":"grain_highlight_added_v2","name":"Grain Highlight Added","description":"Trigger when a new highlight/clip is created in Grain"},{"id":"grain_highlight_updated_v2","name":"Grain Highlight Updated","description":"Trigger when a highlight/clip is updated in Grain"},{"id":"grain_highlight_deleted_v2","name":"Grain Highlight Deleted","description":"Trigger when a highlight/clip is deleted in Grain"},{"id":"grain_story_added_v2","name":"Grain Story Added","description":"Trigger when a new story is created in Grain"},{"id":"grain_story_updated_v2","name":"Grain Story Updated","description":"Trigger when a story is updated in Grain"},{"id":"grain_story_deleted_v2","name":"Grain Story Deleted","description":"Trigger when a story is deleted in Grain"},{"id":"grain_upload_status_v2","name":"Grain Upload Status","description":"Trigger on progress updates for recordings uploaded to Grain"},{"id":"grain_all_events_v2","name":"Grain All Events","description":"Trigger on every Grain event (recordings, highlights, stories, uploads)"}],"skills":[{"name":"summarize-recent-calls","description":"Pull recent Grain recordings and produce a digest of key takeaways and action items per call.","content":"# Summarize Recent Calls\\n\\nTurn recent meeting recordings into a readable digest.\\n\\n## Steps\\n1. List recordings, optionally filtered by a before/after datetime window, and paginate with the cursor if needed.\\n2. For each recording, get the recording details and the transcript.\\n3. From each transcript, extract the main topic, key takeaways, decisions, and action items with owners.\\n4. Keep the per-call summary concise and consistent in structure.\\n\\n## Output\\nReturn a digest with one section per call: title, date, participants, takeaways, and action items. Suitable for a daily or weekly recap."},{"name":"extract-deal-signals","description":"Scan Grain sales-call transcripts for buying signals, objections, and competitor mentions.","content":"# Extract Deal Signals\\n\\nMine sales transcripts for signals that move a deal forward.\\n\\n## Steps\\n1. List recordings for the target time window, filtering by meeting type or team to isolate sales calls (use List Meeting Types / List Teams to find the IDs).\\n2. Get the transcript for each recording.\\n3. Classify mentions into buying signals, objections/risks, competitor mentions, and next steps, capturing the verbatim quote and context.\\n4. Apply a framework (e.g. MEDDIC or SPICED) if one is specified to tag each insight.\\n\\n## Output\\nReturn a structured list of signals grouped by category, each with the quote, the call it came from, and a suggested follow-up. Useful for CRM notes or a deal review."},{"name":"pull-transcript","description":"Retrieve a specific Grain recording and its full transcript by ID.","content":"# Pull Transcript\\n\\nFetch a single recording and its transcript for downstream use.\\n\\n## Steps\\n1. If only a title or date is known, list recordings and match to find the recording ID.\\n2. Get the recording details for metadata (title, participants, duration, date).\\n3. Get the transcript for the recording.\\n4. Clean the transcript into readable speaker-labeled turns.\\n\\n## Output\\nReturn the recording metadata plus the formatted transcript. This is the building block for summaries, follow-up emails, or knowledge base ingestion."},{"name":"audit-grain-webhooks","description":"List, create, and prune Grain webhook subscriptions so external systems only receive the events they need.","content":"# Audit Grain Webhooks\\n\\nKeep webhook subscriptions tidy and pointed at live endpoints.\\n\\n## Steps\\n1. List webhooks, optionally filtered by event type or enabled/disabled state.\\n2. Compare against the endpoints and event types that should exist; flag disabled hooks and hooks pointing at dead URLs.\\n3. Delete stale or duplicate webhooks by ID.\\n4. Create any missing webhooks with the right event type (note: the endpoint must respond 2xx to a reachability test on creation).\\n\\n## Output\\nReturn a reconciliation summary: hooks kept, hooks deleted, hooks created, each with event type and URL."},{"name":"segment-calls-by-team","description":"Break down Grain call volume and content by team or meeting type for reporting.","content":"# Segment Calls By Team\\n\\nProduce a per-team or per-meeting-type view of call activity.\\n\\n## Steps\\n1. List teams and meeting types to get their IDs.\\n2. For each segment, list recordings filtered by that team or meeting type over the reporting window, paginating with the cursor.\\n3. Aggregate counts, total duration, and notable calls per segment.\\n\\n## Output\\nReturn a table-style summary per segment: call count, total hours, and links to representative recordings. Useful for weekly ops or enablement reporting."}],"templates":[{"title":"Grain highlight to CRM","prompt":"Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.","integrations":[{"id":"grain","name":"Grain"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Grain customer-quote miner","prompt":"Create a workflow that processes Grain customer interview recordings, extracts notable quotes and themes, and writes them to a marketing research table.","integrations":[{"id":"grain","name":"Grain"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"grain","name":"Grain"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Grain weekly call digest","prompt":"Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.","integrations":[{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]},{"title":"Grain coaching dashboard","prompt":"Build a scheduled weekly workflow that analyzes Grain sales calls per rep, calculates talk ratio, objection handling, and next-step clarity, and writes coaching notes to a table.","integrations":[{"id":"grain","name":"Grain"}]},{"title":"Grain + Notion knowledge sync","prompt":"Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.","integrations":[{"id":"grain","name":"Grain"},{"id":"notion","name":"Notion"}]},{"title":"Grain competitor mentions tracker","prompt":"Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.","integrations":[{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]},{"title":"Grain highlight to CRM","prompt":"Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.","integrations":[{"id":"grain","name":"Grain"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Grain customer-quote miner","prompt":"Create a workflow that processes Grain customer interview recordings, extracts notable quotes and themes, and writes them to a marketing research table.","integrations":[{"id":"grain","name":"Grain"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"grain","name":"Grain"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Grain weekly call digest","prompt":"Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.","integrations":[{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]},{"title":"Grain coaching dashboard","prompt":"Build a scheduled weekly workflow that analyzes Grain sales calls per rep, calculates talk ratio, objection handling, and next-step clarity, and writes coaching notes to a table.","integrations":[{"id":"grain","name":"Grain"}]},{"title":"Grain + Notion knowledge sync","prompt":"Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.","integrations":[{"id":"grain","name":"Grain"},{"id":"notion","name":"Notion"}]},{"title":"Grain competitor mentions tracker","prompt":"Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.","integrations":[{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]}]},{"id":"granola","type":"granola","slug":"granola","name":"Granola","description":"Access meeting notes, transcripts, and audit events from Granola","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/granola","authType":"api-key","connections":[],"operations":[{"name":"List Notes","description":"Lists meeting notes from Granola with optional date filters and pagination."},{"name":"Get Note","description":"Retrieves a specific meeting note from Granola by ID, including summary, attendees, calendar event details, and optionally the transcript."},{"name":"Get Transcript","description":"Retrieves a meeting transcript from Granola one page at a time, including when Get Note reports the transcript is too large to return inline."},{"name":"List Folders","description":"Lists folders from Granola, sorted alphabetically, with pagination."},{"name":"List Audit Events","description":"Lists workspace audit events from Granola, with optional action and date filters. Events are returned in collection order and retained for one year."},{"name":"Create Webhook Endpoint","description":"Registers an HTTPS URL in Granola to receive note event deliveries. The signing secret is returned only by this operation and cannot be retrieved later."},{"name":"List Webhook Endpoints","description":"Lists the Granola webhook endpoints the API key can manage. A personal key sees the endpoints it created; a workspace admin sees every endpoint in the workspace. Signing secrets are never included."},{"name":"Update Webhook Endpoint","description":"Updates a Granola webhook endpoint. Each supplied field replaces its current value; omitted fields are left unchanged. Use enabled to pause or resume deliveries."},{"name":"Delete Webhook Endpoint","description":"Deletes a Granola webhook endpoint by ID, stopping its event deliveries immediately."}],"triggers":[{"id":"granola_note_generated","name":"Granola Note Generated","description":"Trigger workflow when the first AI summary for a Granola note is generated"},{"id":"granola_note_edited","name":"Granola Note Edited","description":"Trigger workflow when a Granola note summary is edited or regenerated"},{"id":"granola_note_access_granted","name":"Granola Note Access Granted","description":"Trigger workflow when a Granola note is shared with you, directly or via a folder"},{"id":"granola_webhook","name":"Granola Events","description":"Trigger workflow on any Granola note event"}],"skills":[{"name":"digest-meeting-notes","description":"List recent Granola notes and produce a structured digest of takeaways and action items.","content":"# Digest Meeting Notes\\n\\nTurn recent Granola meeting notes into a concise digest.\\n\\n## Steps\\n1. List notes, optionally limited to a recent time window.\\n2. For each note, get the full note content.\\n3. Extract the meeting title, key decisions, takeaways, and action items with owners and due dates if present.\\n4. Keep each meeting summary short and uniformly structured.\\n\\n## Output\\nReturn a digest with one section per meeting: title, date, decisions, takeaways, and action items. Suitable for a team recap or daily summary."},{"name":"extract-action-items","description":"Read a Granola note and pull out a clean list of action items with owners.","content":"# Extract Action Items\\n\\nIsolate the follow-ups from a single meeting note.\\n\\n## Steps\\n1. If only a title or date is known, list notes and match to find the note ID.\\n2. Get the note content.\\n3. Identify every action item, normalizing each into a clear task with an owner and due date when stated.\\n4. Drop duplicates and merge near-identical items.\\n\\n## Output\\nReturn a list of action items, each with the task, owner, and due date. Ready to push into a task manager or tracking table."},{"name":"log-decisions","description":"Scan Granola notes for decisions made and compile them into a dated decision log.","content":"# Log Decisions\\n\\nBuild an auditable record of decisions captured in meetings.\\n\\n## Steps\\n1. List notes across the target window.\\n2. Get each note and identify explicit decisions, the rationale, and who made them.\\n3. Normalize each into a row with date, decision, owner, and context.\\n\\n## Output\\nReturn a chronological decision log, each entry with date, decision, owner, and supporting context. Useful for writing to a decision-tracking table."}],"templates":[{"title":"Granola meeting brief","prompt":"Build a scheduled workflow that reads upcoming meetings from Granola notes, researches attendees and topic with Apollo, and posts a prep brief to Slack before each meeting.","integrations":[{"id":"granola","name":"Granola"},{"id":"apollo","name":"Apollo"},{"id":"slack","name":"Slack"}]},{"title":"Granola action-item ticket creator","prompt":"Create a workflow that extracts action items from Granola meeting notes, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"granola","name":"Granola"},{"id":"linear","name":"Linear"},{"id":"asana","name":"Asana"}]},{"title":"Granola CRM updater","prompt":"Build a workflow that runs after a Granola sales meeting, summarizes the meeting notes into a deal-ready summary, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"granola","name":"Granola"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Granola weekly digest","prompt":"Create a scheduled weekly workflow that aggregates Granola meeting notes, identifies recurring themes and decisions, and writes a digest to the team Slack channel.","integrations":[{"id":"granola","name":"Granola"},{"id":"slack","name":"Slack"}]},{"title":"Granola + Notion publisher","prompt":"Build a scheduled workflow that polls Granola for new meeting notes, generates a polished meeting-notes page in Notion under the right team space, and links the original Granola note.","integrations":[{"id":"granola","name":"Granola"},{"id":"notion","name":"Notion"}]},{"title":"Granola customer-interview extractor","prompt":"Create a workflow that processes Granola customer-interview notes, extracts notable quotes and pain points, and writes them to a tables-based research log.","integrations":[{"id":"granola","name":"Granola"}]},{"title":"Granola decision-log keeper","prompt":"Build a workflow that scans Granola meeting notes for decisions made, writes each to a tables-based decision log with date, owner, and context, and shares the link.","integrations":[{"id":"granola","name":"Granola"}]}]},{"id":"greenhouse","type":"greenhouse_v2","slug":"greenhouse","name":"Greenhouse","description":"Manage recruiting with Greenhouse Harvest v3","category":"HR","docsUrl":"https://docs.sim.ai/integrations/greenhouse","authType":"oauth","connections":[{"id":"greenhouse","kind":"oauth","label":"Connect with OAuth","providerId":"greenhouse","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/greenhouse","requiredScopes":[{"id":"harvest:application_stages:list","label":"View Greenhouse application stages"},{"id":"harvest:applications:convert_to_candidate","label":"Convert prospects to candidates for Greenhouse applications"},{"id":"harvest:applications:create","label":"Create Greenhouse applications"},{"id":"harvest:applications:destroy","label":"Delete Greenhouse applications"},{"id":"harvest:applications:hire","label":"Mark Greenhouse applications as hired"},{"id":"harvest:applications:list","label":"View Greenhouse applications"},{"id":"harvest:applications:move","label":"Move Greenhouse applications between stages or jobs"},{"id":"harvest:applications:reject","label":"Reject Greenhouse applications"},{"id":"harvest:applications:unreject","label":"Reverse Greenhouse application rejections"},{"id":"harvest:applications:update","label":"Update Greenhouse applications"},{"id":"harvest:applied_candidate_tags:create","label":"Apply Greenhouse tags to candidates"},{"id":"harvest:applied_candidate_tags:destroy","label":"Remove Greenhouse tags from candidates"},{"id":"harvest:applied_candidate_tags:list","label":"View Greenhouse applied candidate tags"},{"id":"harvest:attachments:create","label":"Create Greenhouse attachments"},{"id":"harvest:attachments:destroy","label":"Delete Greenhouse attachments"},{"id":"harvest:attachments:list","label":"View Greenhouse attachments"},{"id":"harvest:candidate_educations:list","label":"View Greenhouse candidate education histories"},{"id":"harvest:candidate_employments:list","label":"View Greenhouse candidate employment histories"},{"id":"harvest:candidate_tags:create","label":"Create Greenhouse candidate tags"},{"id":"harvest:candidate_tags:list","label":"View Greenhouse candidate tags"},{"id":"harvest:candidates:create","label":"Create Greenhouse candidates"},{"id":"harvest:candidates:destroy","label":"Delete Greenhouse candidates"},{"id":"harvest:candidates:list","label":"View Greenhouse candidates"},{"id":"harvest:candidates:update","label":"Update Greenhouse candidates"},{"id":"harvest:close_reasons:list","label":"View Greenhouse close reasons"},{"id":"harvest:custom_field_options:list","label":"View Greenhouse custom field options"},{"id":"harvest:custom_fields:list","label":"View Greenhouse custom fields"},{"id":"harvest:departments:list","label":"View Greenhouse departments"},{"id":"harvest:email_templates:list","label":"View Greenhouse email templates"},{"id":"harvest:interviews:list","label":"View Greenhouse interviews"},{"id":"harvest:job_hiring_managers:list","label":"View Greenhouse job hiring managers"},{"id":"harvest:job_interview_stages:list","label":"View Greenhouse job interview stages"},{"id":"harvest:job_owners:list","label":"View Greenhouse job owners"},{"id":"harvest:jobs:list","label":"View Greenhouse jobs"},{"id":"harvest:notes:create","label":"Create Greenhouse notes"},{"id":"harvest:notes:list","label":"View Greenhouse notes"},{"id":"harvest:offers:list","label":"View Greenhouse offers"},{"id":"harvest:offices:list","label":"View Greenhouse offices"},{"id":"harvest:openings:list","label":"View Greenhouse openings"},{"id":"harvest:prospect_pool_stages:list","label":"View Greenhouse prospect pool stages"},{"id":"harvest:prospect_pools:list","label":"View Greenhouse prospect pools"},{"id":"harvest:referrers:list","label":"View Greenhouse referrers"},{"id":"harvest:rejection_reasons:list","label":"View Greenhouse rejection reasons"},{"id":"harvest:scorecards:list","label":"View Greenhouse scorecards"},{"id":"harvest:sources:list","label":"View Greenhouse sources"},{"id":"harvest:users:list","label":"View Greenhouse users"}],"fields":[]},{"id":"greenhouse-service-account","kind":"service_account","providerId":"greenhouse-service-account","label":"Add API credential","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/greenhouse","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true}]}],"operations":[{"name":"List Candidates","description":"Lists candidates from Greenhouse with optional filtering by date, job, or email"},{"name":"Get Candidate","description":"Retrieves a specific candidate by ID with full details including contact info, education, and employment history"},{"name":"Create Candidate","description":"Creates a candidate profile and optionally its first application."},{"name":"Update Candidate","description":"Updates selected candidate fields. Read the current candidate first: supplied arrays replace the entire existing collection. Send the complete desired array, or [] to remove all entries."},{"name":"Delete Candidate","description":"Delete candidate using Greenhouse Harvest v3."},{"name":"List Applications","description":"Lists applications from Greenhouse with optional filtering by job, status, or date"},{"name":"Get Application","description":"Retrieves a specific application by ID with full details including source, stage, answers, and attachments"},{"name":"Create Application","description":"Creates a job application or prospect application for an existing candidate."},{"name":"Update Application","description":"Update application using Greenhouse Harvest v3."},{"name":"Move Application","description":"Moves or advances an application using its current stage as a guard; configured stage rules may send emails."},{"name":"Convert Prospect","description":"Converts a prospect application into a new candidate application on a job already associated with the prospect."},{"name":"Reject Application","description":"Rejects an application; optionally sends or schedules the configured rejection email."},{"name":"Unreject Application","description":"Restores a rejected application to its previous stage and clears its rejection reason and notes."},{"name":"Hire Application","description":"Marks an application hired and closes its opening; provide opening_id when the job has multiple open openings."},{"name":"Delete Application","description":"Delete application using Greenhouse Harvest v3."},{"name":"List Jobs","description":"Lists jobs from Greenhouse with optional filtering by status, department, or office"},{"name":"Get Job","description":"Retrieves a specific job by ID with full details including hiring team, openings, and custom fields"},{"name":"List Job Interview Stages","description":"Lists one page of job interview stages with cursor pagination and documented filters."},{"name":"List Application Stages","description":"Lists one page of application stages with cursor pagination and documented filters."},{"name":"List Job Hiring Managers","description":"Lists one page of job hiring managers with cursor pagination and documented filters."},{"name":"List Job Owners","description":"Lists one page of job owners with cursor pagination and documented filters."},{"name":"List Openings","description":"Lists one page of openings with cursor pagination and documented filters."},{"name":"List Interviews","description":"Lists one page of interviews with cursor pagination and documented filters."},{"name":"List Scorecards","description":"Lists one page of scorecards with cursor pagination and documented filters."},{"name":"List Offers","description":"Lists one page of offers with cursor pagination and documented filters."},{"name":"List Notes","description":"Lists one page of notes with cursor pagination and documented filters."},{"name":"Create Note","description":"Creates a candidate note or activity entry, or logs an email without sending it."},{"name":"List Attachments","description":"Lists one page of attachments with cursor pagination and documented filters."},{"name":"Create Attachment","description":"Attaches a file to an application. A new resume or cover letter reclassifies the previous attachment of that type as other."},{"name":"Delete Attachment","description":"Delete attachment using Greenhouse Harvest v3."},{"name":"List Candidate Tags","description":"Lists one page of candidate tags with cursor pagination and documented filters."},{"name":"Create Candidate Tag","description":"Create candidate tag using Greenhouse Harvest v3."},{"name":"List Applied Candidate Tags","description":"Lists one page of applied candidate tags with cursor pagination and documented filters."},{"name":"Apply Candidate Tag","description":"Apply candidate tag using Greenhouse Harvest v3."},{"name":"Remove Candidate Tag","description":"Removes an applied tag by its applied_candidate_tags row ID, leaving the tag dictionary intact."},{"name":"List Candidate Educations","description":"Lists one page of candidate educations with cursor pagination and documented filters."},{"name":"List Candidate Employments","description":"Lists one page of candidate employments with cursor pagination and documented filters."},{"name":"List Users","description":"Lists Greenhouse users (recruiters, hiring managers, admins) with optional filtering"},{"name":"Get User","description":"Retrieves a specific Greenhouse user by ID"},{"name":"List Departments","description":"Lists all departments configured in Greenhouse"},{"name":"List Offices","description":"Lists all offices configured in Greenhouse"},{"name":"List Sources","description":"Lists one page of sources with cursor pagination and documented filters."},{"name":"List Referrers","description":"Lists one page of referrers with cursor pagination and documented filters."},{"name":"List Rejection Reasons","description":"Lists one page of rejection reasons with cursor pagination and documented filters."},{"name":"List Close Reasons","description":"Lists one page of close reasons with cursor pagination and documented filters."},{"name":"List Prospect Pools","description":"Lists one page of prospect pools with cursor pagination and documented filters."},{"name":"List Prospect Pool Stages","description":"Lists one page of prospect pool stages with cursor pagination and documented filters."},{"name":"List Custom Fields","description":"Lists one page of custom fields with cursor pagination and documented filters."},{"name":"List Custom Field Options","description":"Lists one page of custom field options with cursor pagination and documented filters."},{"name":"List Email Templates","description":"Lists one page of email templates with cursor pagination and documented filters."}],"triggers":[{"id":"greenhouse_candidate_hired","name":"Greenhouse Candidate Hired","description":"Trigger workflow when a candidate is hired"},{"id":"greenhouse_new_application","name":"Greenhouse New Application","description":"Trigger workflow when a new application is submitted"},{"id":"greenhouse_candidate_stage_change","name":"Greenhouse Candidate Stage Change","description":"Trigger workflow when a candidate changes interview stages"},{"id":"greenhouse_candidate_rejected","name":"Greenhouse Candidate Rejected","description":"Trigger workflow when a candidate is rejected"},{"id":"greenhouse_offer_created","name":"Greenhouse Offer Created","description":"Trigger workflow when a new offer is created"},{"id":"greenhouse_job_created","name":"Greenhouse Job Created","description":"Trigger workflow when a new job is created"},{"id":"greenhouse_job_updated","name":"Greenhouse Job Updated","description":"Trigger workflow when a job is updated"},{"id":"greenhouse_webhook","name":"Greenhouse Webhook (Endpoint Events)","description":"Trigger on whichever event types you select for this URL in Greenhouse. Sim does not filter deliveries for this trigger."}],"skills":[{"name":"build-pipeline-report","description":"Report active applications by job and interview stage.","content":"# Build Pipeline Report\\n\\n## Steps\\n1. List open jobs.\\n2. List applications filtered by job_ids and status=active, following nextCursor one page at a time.\\n3. Join job_interview_stage_id to List Job Interview Stages and use List Application Stages for time in stage.\\n4. Aggregate counts and flag stalled stages.\\n\\n## Output\\nReturn per-job stage counts and bottlenecks without making hiring decisions."},{"name":"assemble-candidate-brief","description":"Collect a candidate profile and related recruiting records for interviewer preparation.","content":"# Assemble Candidate Brief\\n\\n## Steps\\n1. Get the candidate by ID.\\n2. List applications using candidate_ids.\\n3. Retrieve related notes, attachment metadata, education, and employment using their candidate filters.\\n4. Get the job and list its interview stages.\\n\\n## Output\\nReturn a sourced candidate brief with role context and attachment links for the interviewer."},{"name":"sync-candidate-intake","description":"Create a candidate and application from an approved recruiting intake record.","content":"# Sync Candidate Intake\\n\\n## Steps\\n1. Look up the candidate by email to avoid duplicate intake.\\n2. Resolve job, source, and custom-field identifiers.\\n3. Create the candidate with contact details and an optional first application, or create an application for the existing candidate.\\n4. Record the resulting identifiers and add an intake note.\\n\\n## Output\\nReturn the candidate and application IDs with the intake note ID. Preserve the source record for reconciliation."}],"templates":[{"title":"Background check on offer","prompt":"Build a workflow that runs when a candidate reaches the offer stage in Greenhouse, creates the candidate in Checkr with their email, sends a Checkr invitation for the role’s package, and posts the invitation link and status to the hiring channel in Slack.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"checkr","name":"Checkr"},{"id":"slack","name":"Slack"}]},{"title":"Google Drive new-hire kit deployer","prompt":"Build a workflow triggered by a new hire in Greenhouse that copies the standard Google Drive onboarding folder, shares it with the new hire, and writes the link into the onboarding tracker.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Groups onboarding sync","prompt":"Create a workflow that watches Rippling or Greenhouse for new hires, adds them to the right Google Groups based on team and department, and emails the new hire a list of the groups joined.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"google_groups","name":"Google Groups"},{"id":"rippling","name":"Rippling"}]},{"title":"Greenhouse pipeline monitor","prompt":"Build a scheduled workflow that syncs open jobs and candidates from Greenhouse to a tracking table daily, flags candidates who have been in the same stage for more than 5 days, and sends a Slack summary to hiring managers with pipeline stats and bottlenecks.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse to onboarding kickoff","prompt":"Build a workflow that fires when a Greenhouse application is marked hired, gathers the new hire profile, kicks off an onboarding plan in a table, schedules week-one meetings via Google Calendar, and posts a welcome announcement to Slack.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"google_calendar","name":"Google Calendar"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse candidate enricher","prompt":"Create a workflow that watches for new Greenhouse candidates, enriches each profile with LinkedIn background, GitHub activity, and public writing, and writes a structured research summary to a recruiting table for recruiters to review.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"linkedin","name":"LinkedIn"},{"id":"github","name":"GitHub"}]},{"title":"Greenhouse interview scheduler","prompt":"Build a workflow that runs after a Greenhouse application reaches the interview stage, finds the right interviewer panel based on job stage, proposes time slots from Google Calendar, drafts a coordination email to the candidate, and confirms the booking in a tracking table.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"google_calendar","name":"Google Calendar"},{"id":"gmail","name":"Gmail"}]},{"title":"Greenhouse offer drafter","prompt":"Create a workflow that takes an approved Greenhouse application, pulls compensation bands from a knowledge base, drafts a tailored offer letter file, prepares an explanation email, and routes both to the hiring manager for review before sending to the candidate.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"gmail","name":"Gmail"}]},{"title":"Greenhouse rejection follow-up","prompt":"Build a workflow that runs when a Greenhouse candidate is rejected, drafts a warm and respectful rejection email tailored to how far they progressed, sends it via Gmail, and logs the candidate with their interest areas to a future-talent table for re-engagement.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"gmail","name":"Gmail"}]},{"title":"Greenhouse interview prep packet","prompt":"Create a workflow that runs the morning of every Greenhouse interview, pulls the candidate profile, prior interview notes, and job rubric, assembles a one-page prep file for the interviewer, and emails it with a Slack DM reminder thirty minutes before the slot.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse pipeline report","prompt":"Build a scheduled workflow that lists open Greenhouse jobs and active applications, follows every cursor page, joins current interview stages and time-in-stage records, and writes per-role counts and stalled stages to a recruiting table. Send the report to Slack.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse candidate intake","prompt":"Build a workflow that checks Greenhouse candidates by email before creating an approved intake profile, adds an application to the selected job, records the intake note, and stores the returned identifiers for reconciliation.","integrations":[{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse interviewer brief","prompt":"Build a workflow that lists upcoming Greenhouse interviews, retrieves the related candidate, application, job, notes, and attachment metadata, and drafts a sourced preparation brief for interviewer review.","integrations":[{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse hiring ownership audit","prompt":"Build a scheduled workflow that lists open jobs, hiring managers, job owners, departments, offices, and users. Join their IDs into a role-ownership table and flag jobs missing a recruiter or hiring manager.","integrations":[{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse scorecard follow-up","prompt":"Build a workflow that lists completed Greenhouse interviews and related scorecards, identifies pending feedback, and prepares a Slack reminder for the recruiting coordinator to review.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"slack","name":"Slack"}]},{"title":"Greenhouse approved candidate updates","prompt":"Build a workflow that reads a Greenhouse candidate profile, merges approved contact changes into the complete existing arrays, updates only the intended fields, and records a note describing the approved changes.","integrations":[{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse prospect organization","prompt":"Build a workflow that lists Greenhouse prospect pools and stages, creates an approved prospect application for an existing candidate, applies the selected candidate tags, and records the application and applied-tag identifiers in a tracking table.","integrations":[{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Typeform candidate screener","prompt":"Build a workflow that captures Typeform applicant responses, scores them against the role rubric with an agent, and creates a Greenhouse candidate with the score attached.","integrations":[{"id":"greenhouse","name":"Greenhouse"},{"id":"typeform","name":"Typeform"}]}]},{"id":"greptile","type":"greptile","slug":"greptile","name":"Greptile","description":"AI-powered codebase search and Q&A","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/greptile","authType":"api-key","connections":[],"operations":[{"name":"Query","description":"Query repositories in natural language and get answers with relevant code references. Greptile uses AI to understand your codebase and answer questions."},{"name":"Index Repository","description":"Submit a repository to be indexed by Greptile. Indexing must complete before the repository can be queried. Small repos take 3-5 minutes, larger ones can take over an hour."},{"name":"Check Status","description":"Check the indexing status of a repository. Use this to verify if a repository is ready to be queried or to monitor indexing progress."}],"triggers":[],"skills":[{"name":"answer-codebase-question","description":"Ask Greptile a natural-language question about an indexed repository and return a cited answer.","content":"# Answer Codebase Question\\n\\nGet an accurate, source-cited answer about how a codebase works.\\n\\n## Steps\\n1. Confirm the repository is indexed by checking its index status; if not ready, index it first and wait.\\n2. Query Greptile with the natural-language question (e.g. how authentication flows, where payments are processed).\\n3. Capture the answer along with the file and function references it cites.\\n4. If the answer is vague, refine the question with more specifics and re-query.\\n\\n## Output\\nReturn the answer plus a list of cited files and symbols. Useful for onboarding, debugging, and understanding unfamiliar code."},{"name":"review-pull-request","description":"Use Greptile to assess how a PR diff interacts with the rest of the repo and draft review notes.","content":"# Review Pull Request\\n\\nProduce a codebase-aware review of a set of changes.\\n\\n## Steps\\n1. Ensure the repository is indexed (check status, index if needed).\\n2. Query Greptile describing the changed files and ask how they interact with the rest of the codebase, what might break, and what edge cases to test.\\n3. Collect the impact analysis and the cited files affected beyond the diff.\\n4. Organize findings into bugs/risks, style/consistency, and suggested tests.\\n\\n## Output\\nReturn structured review notes grouped by severity, each with the cited file and a concrete suggestion. Ready to post as a PR comment."},{"name":"index-and-verify-repo","description":"Trigger Greptile indexing for a repository and poll until it is ready to query.","content":"# Index and Verify Repo\\n\\nMake a repository queryable in Greptile.\\n\\n## Steps\\n1. Start indexing for the repository, specifying the remote, owner/repo, and branch.\\n2. Poll the index status until it reports completed or fails.\\n3. On failure, report the error and the branch/remote used so it can be corrected.\\n4. On success, run a quick sanity query to confirm answers come back with citations.\\n\\n## Output\\nReturn the final index status, the branch indexed, and the result of the sanity query. Confirms the repo is ready for codebase questions and reviews."}],"templates":[{"title":"Greptile Slack Q&A bot","prompt":"Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files.","integrations":[{"id":"greptile","name":"Greptile"},{"id":"slack","name":"Slack"}]},{"title":"Greptile onboarding explainer","prompt":"Create a workflow where a new engineer asks how a part of the codebase works, Greptile answers against the indexed repository with cited files, and the explanation is saved to a Google Doc.","integrations":[{"id":"greptile","name":"Greptile"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Greptile PR review context","prompt":"Build a workflow that takes a pull request, asks Greptile how the changed code interacts with the rest of the repository, and writes a review comment summarizing impact and risks with cited files.","integrations":[{"id":"greptile","name":"Greptile"},{"id":"github","name":"GitHub"}]},{"title":"Slack code Q&A bot","prompt":"Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files so the team gets quick, sourced engineering answers.","integrations":[{"id":"greptile","name":"Greptile"},{"id":"slack","name":"Slack"}]}]},{"id":"harmonic","type":"harmonic","slug":"harmonic","name":"Harmonic","description":"Search and enrich private-market contacts","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/harmonic","authType":"api-key","connections":[{"id":"harmonic-service-account","kind":"service_account","providerId":"harmonic-service-account","label":"Add API key","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/harmonic","fields":[{"id":"apiToken","label":"Team API key","placeholder":"Paste Harmonic team API key","secret":true}]}],"operations":[{"name":"Search People with Scout","description":"Ask Harmonic Scout to find people using natural language and return a stable, workflow-ready contacts table."},{"name":"Enrich Person","description":"Resolve a LinkedIn profile URL or email address into a normalized Harmonic contact, queueing enrichment when the person is not yet in Harmonic."},{"name":"Get Person","description":"Fetch one Harmonic person by numeric ID or URN, including any email resolved by a completed enrichment job."},{"name":"Batch Get People","description":"Fetch full Harmonic person profiles for up to 500 combined numeric IDs and person URNs."},{"name":"Get Company Employees","description":"List person URNs for a company, filtered by role group and employment status. Pair with Batch Get People to hydrate contacts."},{"name":"List People Saved Searches","description":"List the team-shared Harmonic saved searches that target people. Use a returned ID or URN to fetch results."},{"name":"Get People Saved Search Results","description":"Get one page of a Harmonic people saved search. Full records become contacts; URN-only rows are exposed for Batch Get People."},{"name":"Get People Saved Search Net-New Results","description":"Get only the people newly matching a subscribed Harmonic people saved search, so a monitor does not reprocess the whole result set."},{"name":"Clear People Saved Search Net-New Results","description":"Acknowledge net-new people on a saved search so the next poll returns only fresh matches. Clearing everything requires setting the scope explicitly."},{"name":"Submit Email Enrichment Job","description":"Queue bulk email enrichment for up to 5,000 people, given either person URNs or LinkedIn profile URLs."},{"name":"Get Email Enrichment Job","description":"Check a Harmonic bulk email enrichment job. Per-person results appear once the job is terminal; fetch the emails with Get Person or Batch Get People."},{"name":"Get Email Enrichment Usage","description":"Read the team monthly email-enrichment quota. Check this before a large batch to avoid a quota rejection."},{"name":"Get Enrichment Status","description":"Check enrichment jobs Harmonic queued for people it did not already have, and read the person URN each one produced."}],"triggers":[],"skills":[{"name":"search-people-with-scout","description":"Turn natural-language sourcing criteria into a normalized contact table with Harmonic Scout.","content":"# Search People with Scout\\n\\nUse Harmonic Scout when the request describes the people to find rather than supplying identifiers.\\n\\n## Steps\\n1. Translate the request into a precise query that states role, company profile, geography, and any exclusions.\\n2. Run Search People with Scout once; do not retry a timed-out task automatically.\\n3. Review the returned contacts and keep the structured fields needed downstream.\\n4. Preserve personUrn whenever Harmonic supplies it so Batch Get People can hydrate the record later.\\n\\n## Output\\nReturn a contact table and the Scout task ID and status. Call out missing email or LinkedIn values instead of guessing them."},{"name":"export-people-saved-search","description":"Resolve a team-visible people saved search and page its contacts into a downstream dataset.","content":"# Export People Saved Search\\n\\nRead a Harmonic people saved search into a workflow.\\n\\n## Steps\\n1. Run List People Saved Searches and match the requested name to one search.\\n2. Run Get People Saved Search Results with that ID or URN.\\n3. Follow pageInfo.nextCursor while pageInfo.hasNext is true, using a page size no greater than 100.\\n4. Deduplicate rows by personUrn and retain any URN-only results for hydration.\\n\\n## Output\\nReturn the saved-search identity, total count, normalized contacts, unresolved person URNs, and whether pagination completed."},{"name":"hydrate-person-urns","description":"Expand Harmonic person IDs or URNs into consistent contact records for scoring and routing.","content":"# Hydrate Person URNs\\n\\nUse Batch Get People when an upstream Harmonic result contains identifiers without complete contact fields.\\n\\n## Steps\\n1. Collect the person IDs and URNs from the upstream rows.\\n2. Deduplicate identifiers and split requests so each batch contains at most 500 identifiers.\\n3. Run Batch Get People for each batch.\\n4. Join normalized contacts back to the source rows by personUrn, falling back to personId only when necessary.\\n\\n## Output\\nReturn the hydrated contacts and list any input identifiers that produced no contact."},{"name":"rank-scout-shortlist","description":"Score Harmonic Scout contacts against explicit sourcing criteria and produce a review-ready shortlist.","content":"# Rank Scout Shortlist\\n\\nTurn a broad people search into a transparent shortlist.\\n\\n## Steps\\n1. Run Search People with Scout using the requested role, company, industry, geography, and exclusion criteria.\\n2. Score each normalized contact only on fields present in the result, such as title, company, location, and summary.\\n3. Keep personUrn on every scored row and separate missing evidence from a negative match.\\n4. Sort the qualifying contacts by score and retain the rejected rows with their reasons.\\n\\n## Output\\nReturn a ranked contact table with score, evidence, and rejection reason. Do not infer missing contact attributes."},{"name":"monitor-saved-search-snapshot","description":"Compare a team-visible people saved search with a stored snapshot to identify newly seen contacts.","content":"# Monitor Saved Search Snapshot\\n\\nDetect changes in a Harmonic people saved search without relying on provider triggers.\\n\\n## Steps\\n1. Run List People Saved Searches and resolve the requested team-visible search.\\n2. Page Get People Saved Search Results until pageInfo.hasNext is false.\\n3. Deduplicate by personUrn and compare the complete set with the previously stored snapshot.\\n4. Store the new snapshot only after every page succeeds.\\n\\n## Output\\nReturn newly seen and no-longer-seen person URNs, the current total, and whether the pagination run completed."},{"name":"audit-contact-coverage","description":"Audit a Harmonic people cohort for missing email, LinkedIn, company, and role data before outreach.","content":"# Audit Contact Coverage\\n\\nCheck whether a saved-search cohort is ready for scoring or outreach.\\n\\n## Steps\\n1. Resolve the search with List People Saved Searches and page Get People Saved Search Results.\\n2. Send any URN-only results through Batch Get People in batches of at most 500.\\n3. Deduplicate by personUrn and flag contacts missing email, LinkedIn URL, current company, or current title.\\n4. Calculate coverage rates per field without filling missing values from assumptions.\\n\\n## Output\\nReturn the normalized contact table, field coverage rates, duplicate count, and rows requiring manual review."},{"name":"enrich-known-identifiers","description":"Turn LinkedIn URLs or email addresses a workflow already holds into Harmonic contacts.","content":"# Enrich Known Identifiers\\n\\nUse Enrich Person when the workflow already has an identifier rather than a description of who to find.\\n\\n## Steps\\n1. Prefer the LinkedIn profile URL; supply the email only as a fallback identifier.\\n2. Run Enrich Person once per identifier and keep personUrn from every match.\\n3. A person Harmonic does not have yet fails the block rather than returning a row: the error names the enrichment that was scheduled and carries its URN. Handle that error instead of treating it as a match, and poll Get Enrichment Status with the URN until it is COMPLETE or FAILED.\\n4. Read the resulting person with Get Person or Batch Get People once enrichment completes.\\n\\n## Output\\nReturn the hydrated contacts, the identifiers still pending enrichment, and the identifiers Harmonic could not resolve. Do not invent contact fields for unresolved rows."},{"name":"source-company-employees","description":"Build an account-based contact list from a company by role group and employment status.","content":"# Source Company Employees\\n\\nUse Get Company Employees when the request names an account rather than a person.\\n\\n## Steps\\n1. Resolve the company ID or URN, then run Get Company Employees with the requested role group, such as FOUNDERS or EXECUTIVES.\\n2. Follow pageInfo.nextCursor while pageInfo.hasNext is true, using a page size no greater than 100.\\n3. Harmonic returns person URNs only, so hydrate them with Batch Get People in batches of at most 500.\\n4. Deduplicate by personUrn before scoring or outreach.\\n\\n## Output\\nReturn the company, the role group used, the hydrated contacts, and the total employee count Harmonic reported."},{"name":"monitor-saved-search-net-new","description":"Poll only the newly matching people on a subscribed saved search and acknowledge them.","content":"# Monitor Saved Search Net-New\\n\\nUse the net-new feed instead of re-reading a whole saved search on every run.\\n\\n## Steps\\n1. Confirm the saved search is subscribed in the Harmonic console; net-new results are unavailable otherwise and there is no API to subscribe.\\n2. Run Get People Saved Search Net-New Results, optionally bounding the window with newResultsSince.\\n3. Page with pageInfo.nextCursor until pageInfo.hasNext is false, collecting contacts and URN-only rows.\\n4. Only after every page and every downstream write succeeds, run Clear People Saved Search Net-New Results for the person URNs you processed.\\n\\n## Output\\nReturn the newly matching contacts, the URNs acknowledged, and whether the run completed before anything was cleared."},{"name":"enrich-contact-emails","description":"Run Harmonic bulk email enrichment and read the resolved addresses back onto contacts.","content":"# Enrich Contact Emails\\n\\nUse bulk email enrichment when a cohort lacks addresses.\\n\\n## Steps\\n1. Run Get Email Enrichment Usage and stop if monthlyRemaining is below the batch size.\\n2. Submit person URNs or LinkedIn URLs, never both in one job, at most 5000 per job.\\n3. Record the dropped identifiers and their reasons; RECENTLY_ATTEMPTED and ALREADY_HAS_EMAIL are not failures.\\n4. Poll Get Email Enrichment Job until isTerminal is true, then pass succeededPersonUrns to Batch Get People, because the job rows never contain the address itself.\\n\\n## Output\\nReturn the hydrated contacts with their emails, the per-status counts, the dropped identifiers, and the remaining monthly quota."}],"templates":[{"title":"Harmonic contact finder","prompt":"Build a chat-driven workflow that turns a sourcing request such as \\"find FDEs in enterprise software\\" into a Harmonic Scout search and writes the normalized contacts to a table for review.","integrations":[{"id":"harmonic","name":"Harmonic"}]},{"title":"Harmonic saved search sync","prompt":"Create a scheduled workflow that resolves a team-visible Harmonic people saved search, pages every result, compares person URNs with the prior table snapshot, and posts newly seen contacts to Slack.","integrations":[{"id":"harmonic","name":"Harmonic"},{"id":"slack","name":"Slack"}]},{"title":"Harmonic contact hydrator","prompt":"Build a workflow that accepts Harmonic person URNs from an earlier search, batches them in groups of 500, retrieves normalized contact records, and writes names, roles, companies, emails, and LinkedIn URLs to a table.","integrations":[{"id":"harmonic","name":"Harmonic"}]},{"title":"Harmonic sourcing shortlist","prompt":"Create an agent that searches Harmonic Scout for a sourcing thesis, scores the normalized contacts against explicit role, company, and location criteria, and writes the ranked shortlist with evidence to a review table.","integrations":[{"id":"harmonic","name":"Harmonic"}]},{"title":"Harmonic CRM prospect route","prompt":"Build a workflow that searches Harmonic Scout for technical buyers at target accounts, filters contacts with a usable email or LinkedIn URL, deduplicates them by person URN, and writes qualified prospects to Salesforce.","integrations":[{"id":"harmonic","name":"Harmonic"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Harmonic contact coverage audit","prompt":"Create a workflow that resolves a team-visible Harmonic people saved search, pages all results, hydrates URN-only records in batches, flags duplicates and missing contact fields, and writes the review queue to Google Sheets.","integrations":[{"id":"harmonic","name":"Harmonic"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Harmonic talent scout","prompt":"Build an agent that uses Harmonic Scout to find candidates with a requested title, industry background, and geography, ranks the normalized contacts, and sends the shortlist to a Slack hiring channel.","integrations":[{"id":"harmonic","name":"Harmonic"},{"id":"slack","name":"Slack"}]},{"title":"Harmonic batch enrichment","prompt":"Create a workflow that accepts Harmonic person IDs and URNs from a table, deduplicates and splits them into batches of at most 500, retrieves normalized contacts with Batch Get People, and writes hydrated and unmatched rows separately.","integrations":[{"id":"harmonic","name":"Harmonic"}]}]},{"id":"helpscout","type":"helpscout","slug":"help-scout","name":"Help Scout","description":"Manage Help Scout conversations, replies, notes, and customers","category":"Support","docsUrl":"https://docs.sim.ai/integrations/helpscout","authType":"oauth","connections":[{"id":"helpscout","kind":"oauth","label":"Connect with OAuth","providerId":"helpscout","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/helpscout","requiredScopes":[],"fields":[]},{"id":"helpscout-service-account","kind":"service_account","providerId":"helpscout-service-account","label":"Add app","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/helpscout","fields":[{"id":"clientId","label":"App ID","placeholder":"Paste the App ID","secret":false,"hint":"Create the app in Help Scout under Your Profile > My Apps."},{"id":"clientSecret","label":"App secret","placeholder":"Paste the App Secret","secret":true}]}],"operations":[{"name":"List Conversations","description":"List and search Help Scout conversations by inbox, folder, status, tag, assignee, or search query. Returns 25 conversations per page."},{"name":"Get Conversation","description":"Get a Help Scout conversation by ID, optionally with its threads."},{"name":"Create Conversation","description":"Create a Help Scout conversation in an inbox with a first customer message, reply, or note. A new customer is created when the email is not already known."},{"name":"Reply to Conversation","description":"Send a reply to the customer on a Help Scout conversation, or save it as a draft."},{"name":"Add Note","description":"Add an internal note to a Help Scout conversation. Customers never see notes."},{"name":"Add Customer Message","description":"Add a message from the customer to an existing Help Scout conversation, for example one received on another channel. This reopens the conversation."},{"name":"Update Conversation Status","description":"Change the status of a Help Scout conversation to active, open, pending, closed, or spam."},{"name":"Assign Conversation","description":"Assign a Help Scout conversation to a user or team."},{"name":"Unassign Conversation","description":"Remove the assignee from a Help Scout conversation."},{"name":"Update Conversation Subject","description":"Change the subject of a Help Scout conversation."},{"name":"Move Conversation","description":"Move a Help Scout conversation to another inbox."},{"name":"Set Conversation Tags","description":"Replace the full tag list on a Help Scout conversation. Tags left out are removed, [] removes every tag, and unknown tags are created."},{"name":"Update Custom Fields","description":"Replace the custom field values on a Help Scout conversation. Fields left out are cleared, except Help Scout-managed fields such as Topic and Sentiment, which keep their value. Dropdowns take the option ID and dates use YYYY-MM-DD."},{"name":"Snooze Conversation","description":"Snooze a Help Scout conversation until a future time, optionally waking it when the customer replies. A new snooze replaces the previous one."},{"name":"Unsnooze Conversation","description":"End the snooze on a Help Scout conversation. It returns to its folder (Mine, Team, or Unassigned) and is reactivated if needed."},{"name":"Change Conversation Customer","description":"Change the primary customer of a Help Scout conversation."},{"name":"Delete Conversation","description":"Delete a Help Scout conversation."},{"name":"List Threads","description":"List the threads (customer messages, replies, notes, and activity) of a Help Scout conversation, newest first, including full chat threads."},{"name":"List Customers","description":"List and search Help Scout customers by inbox, name, modification date, or search query (for example by email). Returns 50 customers per page."},{"name":"Get Customer","description":"Get a Help Scout customer by ID, including emails, phones, websites, social profiles, and properties."},{"name":"Create Customer","description":"Create a Help Scout customer with a profile, email address, and phone number."},{"name":"Update Customer","description":"Update profile fields on a Help Scout customer and add an email address or phone number. Only the fields you provide are changed."},{"name":"List Customer Properties","description":"List the customer property definitions in Help Scout (slug, type, and dropdown options) used by Update Customer Properties."},{"name":"Update Customer Properties","description":"Set or remove customer property values (for example plan or MRR) on a Help Scout customer, keyed by property slug."},{"name":"List Organizations","description":"List Help Scout organizations (companies), 50 per page, most recently active first by default."},{"name":"Get Organization","description":"Get a Help Scout organization by ID, optionally with its customer and conversation counts and property values."},{"name":"List Inboxes","description":"List the Help Scout inboxes (mailboxes) the connected user can access."},{"name":"List Folders","description":"List the folders in a Help Scout inbox with their conversation counts."},{"name":"List Custom Fields","description":"List the custom fields defined for a Help Scout inbox, with their IDs, types, and dropdown options."},{"name":"List Saved Replies","description":"List the saved replies (canned responses) in a Help Scout inbox with a preview of each."},{"name":"Get Saved Reply","description":"Get the full text of a Help Scout saved reply for email and chat."},{"name":"List Users","description":"List Help Scout users, optionally filtered by exact email or by inbox."},{"name":"Get Current User","description":"Get the Help Scout user the connection acts as, and its company ID."},{"name":"List Tags","description":"List the tags used across all Help Scout inboxes, in alphabetical order."},{"name":"List Teams","description":"List the teams in the Help Scout account. Team IDs can be used to assign conversations."},{"name":"List Workflows","description":"List Help Scout workflows, optionally filtered by inbox or by type (manual or automatic)."},{"name":"Run Workflow","description":"Run a manual Help Scout workflow on up to 50 conversations. The conversations must be in the same inbox as the workflow."}],"triggers":[{"id":"helpscout_conversation_created","name":"Help Scout Conversation Created","description":"Trigger workflow when a conversation is created in Help Scout"},{"id":"helpscout_customer_replied","name":"Help Scout Customer Replied","description":"Trigger workflow when a customer replies to a Help Scout conversation"},{"id":"helpscout_agent_replied","name":"Help Scout Agent Replied","description":"Trigger workflow when an agent replies to a Help Scout conversation (auto replies are not included)"},{"id":"helpscout_note_created","name":"Help Scout Note Created","description":"Trigger workflow when a note is added to a Help Scout conversation"},{"id":"helpscout_conversation_assigned","name":"Help Scout Conversation Assigned","description":"Trigger workflow when a Help Scout conversation is assigned"},{"id":"helpscout_conversation_status_changed","name":"Help Scout Conversation Status Changed","description":"Trigger workflow when the status of a Help Scout conversation changes"},{"id":"helpscout_conversation_tags_updated","name":"Help Scout Conversation Tags Updated","description":"Trigger workflow when the tags on a Help Scout conversation change"},{"id":"helpscout_conversation_moved","name":"Help Scout Conversation Moved","description":"Trigger workflow when a Help Scout conversation is moved to another inbox"},{"id":"helpscout_conversation_merged","name":"Help Scout Conversation Merged","description":"Trigger workflow when Help Scout conversations are merged"},{"id":"helpscout_conversation_deleted","name":"Help Scout Conversation Deleted","description":"Trigger workflow when a Help Scout conversation is deleted"},{"id":"helpscout_customer_created","name":"Help Scout Customer Created","description":"Trigger workflow when a customer is created in Help Scout (fires for every inbox)"},{"id":"helpscout_customer_updated","name":"Help Scout Customer Updated","description":"Trigger workflow when a Help Scout customer is updated"},{"id":"helpscout_webhook","name":"Help Scout Webhook (All Events)","description":"Trigger on every supported Help Scout conversation and customer event"}],"skills":[{"name":"triage-help-scout-conversation","description":"Tag, assign, and annotate a new Help Scout conversation based on its content.","content":"# Triage a Help Scout Conversation\\n\\nRoute a new conversation to the right person with the right tags.\\n\\n## Steps\\n1. Use get_conversation with includeThreads to read the subject, customer, and first message.\\n2. Decide the topic and urgency from the message; do not guess facts the customer did not state.\\n3. Call set_conversation_tags with the existing tags plus the new ones, because it replaces the whole tag list.\\n4. Call assign_conversation with the user or team ID that owns the topic (use list_users or list_teams to find IDs).\\n5. Call create_note explaining why the conversation was tagged and routed.\\n\\n## Output\\nReturn the conversation ID, the tags applied, the assignee, and the note text."},{"name":"draft-help-scout-reply","description":"Draft a reply to the latest customer message without sending it.","content":"# Draft a Help Scout Reply\\n\\nPrepare a reply an agent can review before it reaches the customer.\\n\\n## Steps\\n1. Use list_threads on the conversation and read the newest customer thread first.\\n2. Find the primary customer ID on the conversation (get_conversation).\\n3. Write the answer from verified sources only; if information is missing, say what the agent should confirm.\\n4. Call create_reply with draft set to true so nothing is sent to the customer.\\n\\n## Output\\nReturn the conversation ID, the draft thread ID, and any open questions for the agent."},{"name":"summarize-help-scout-queue","description":"Summarize open Help Scout conversations by inbox, assignee, and wait time.","content":"# Summarize the Help Scout Queue\\n\\nGive the support lead a snapshot of what needs attention.\\n\\n## Steps\\n1. Call list_conversations with status active, then pending, sorted by waitingSince; follow nextPage within a fixed page budget.\\n2. Group conversations by mailboxId and assignee; count unassigned ones separately.\\n3. Highlight conversations with the oldest customerWaitingSince timestamps.\\n\\n## Output\\nReturn counts per inbox and assignee, the longest-waiting conversations with their webUrl, and whether more pages were left unread."},{"name":"research-help-scout-customer","description":"Build a support history for a customer from Help Scout.","content":"# Research a Help Scout Customer\\n\\nCollect what support already knows about a customer.\\n\\n## Steps\\n1. Use list_customers with a query such as (email:\\"name@example.com\\") to find the customer ID.\\n2. Call get_customer for profile details, emails, phones, and properties.\\n3. Call list_conversations with status all and query (customerIds:ID) to list their conversations.\\n\\n## Output\\nReturn the customer profile, a dated list of conversations with status and subject, and any conversation still open."},{"name":"close-resolved-help-scout-conversations","description":"Close pending conversations where the customer confirmed the issue is fixed.","content":"# Close Resolved Conversations\\n\\nTidy the pending queue without closing anything still in progress.\\n\\n## Steps\\n1. Call list_conversations with status pending.\\n2. For each conversation, use list_threads and read the latest customer thread.\\n3. Only when the customer clearly confirmed the issue is resolved, call update_conversation_status with closed and add a note citing the confirming message.\\n\\n## Output\\nReturn the conversations closed and the ones left pending with the reason."},{"name":"run-help-scout-workflow-in-bulk","description":"Apply a manual Help Scout workflow to a batch of matching conversations.","content":"# Run a Manual Workflow in Bulk\\n\\nApply an existing Help Scout workflow to many conversations at once.\\n\\n## Steps\\n1. Call list_workflows with workflowType manual and the inbox ID to find the workflow ID.\\n2. Call list_conversations in the same inbox with the filters the user asked for.\\n3. Call run_workflow with up to 50 conversation IDs per call; batch larger sets.\\n\\n## Output\\nReturn the workflow name and ID and the conversation IDs it ran on."},{"name":"answer-with-help-scout-saved-reply","description":"Draft a reply from the inbox saved replies instead of writing one from scratch.","content":"# Answer with a Saved Reply\\n\\nReuse approved answers for common questions.\\n\\n## Steps\\n1. Read the newest customer thread with list_threads.\\n2. Call list_saved_replies for the conversation inbox and pick the reply whose name and preview match the question.\\n3. Call get_saved_reply for the full text and adapt only names and specifics.\\n4. Call create_reply with draft set to true so an agent reviews it before it is sent.\\n\\n## Output\\nReturn the saved reply used, the draft thread ID, and anything the agent should verify."},{"name":"enrich-help-scout-customer","description":"Fill in missing Help Scout customer profile fields from verified sources.","content":"# Enrich a Help Scout Customer\\n\\nGive agents context before they reply.\\n\\n## Steps\\n1. Call get_customer and note which of jobTitle, location, and background are empty.\\n2. Look up the missing details from the customer email domain or other verified sources.\\n3. Call update_customer with only the fields you verified; keep background under 200 characters.\\n\\n## Output\\nReturn the customer ID, the fields updated, and the source for each value."}],"templates":[{"title":"Help Scout Reply Drafter","prompt":"When a customer replies to a Help Scout conversation, read the conversation threads, search our knowledge base for the answer, and save a draft reply on the conversation for an agent to review.","integrations":[{"id":"helpscout","name":"Help Scout"}]},{"title":"New Conversation Triage","prompt":"When a Help Scout conversation is created, classify it by topic and urgency, set the matching tags, assign it to the right teammate, and add an internal note explaining the routing decision.","integrations":[{"id":"helpscout","name":"Help Scout"}]},{"title":"Daily Support Queue Digest","prompt":"Every weekday morning, list active and pending Help Scout conversations, group them by inbox and assignee, flag the ones customers have waited on longest, and post the digest to the support team in Slack.","integrations":[{"id":"helpscout","name":"Help Scout"},{"id":"slack","name":"Slack"}]},{"title":"Stale Pending Follow-Up","prompt":"Each day, find Help Scout conversations that have been pending for more than five days, add a note summarizing the last customer message, and close the ones where the customer confirmed the issue is resolved.","integrations":[{"id":"helpscout","name":"Help Scout"}]},{"title":"Customer Context Lookup","prompt":"When given a customer email, search Help Scout customers, read the customer profile and their recent conversations, and return a short history with open issues and conversation links.","integrations":[{"id":"helpscout","name":"Help Scout"}]},{"title":"Support Tag Trends","prompt":"Every Friday, list Help Scout conversations created this week, count them by tag and inbox, compare with last week, and write a summary of rising topics for the product team.","integrations":[{"id":"helpscout","name":"Help Scout"}]},{"title":"Escalate Bug Reports","prompt":"When a Help Scout conversation is tagged bug, read its threads, write a reproducible bug summary, file it as a Linear issue, and add an internal note on the conversation linking the issue.","integrations":[{"id":"helpscout","name":"Help Scout"},{"id":"linear","name":"Linear"}]},{"title":"New Customer Enrichment","prompt":"When a customer is created in Help Scout, look up their company from the email domain and update the customer job title, location, and notes so agents have context on the first reply.","integrations":[{"id":"helpscout","name":"Help Scout"}]}]},{"id":"hex","type":"hex","slug":"hex","name":"Hex","description":"Run and manage Hex projects","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/hex","authType":"api-key","connections":[],"operations":[{"name":"Run Project","description":"Execute a published Hex project. Optionally pass input parameters and control caching behavior."},{"name":"Get Run Status","description":"Check the status of a Hex project run by its run ID."},{"name":"Get Project Runs","description":"Retrieve API-triggered runs for a Hex project with optional filtering by status and pagination."},{"name":"Cancel Run","description":"Cancel an active Hex project run."},{"name":"List Projects","description":"List all projects in your Hex workspace with optional filtering by status."},{"name":"Get Project","description":"Get metadata and details for a specific Hex project by its ID."},{"name":"Update Project","description":"Update a Hex project status label (e.g., endorsement or custom workspace statuses)."},{"name":"Get Queried Tables","description":"Return the warehouse tables queried by a Hex project, including data connection and table names."},{"name":"List Users","description":"List all users in the Hex workspace with optional filtering and sorting."},{"name":"List Groups","description":"List all groups in the Hex workspace with optional sorting."},{"name":"Get Group","description":"Retrieve details for a specific Hex group."},{"name":"List Collections","description":"List all collections in the Hex workspace."},{"name":"Get Collection","description":"Retrieve details for a specific Hex collection by its ID."},{"name":"Create Collection","description":"Create a new collection in the Hex workspace to organize projects."},{"name":"Update Collection","description":"Update the name or description of an existing Hex collection."},{"name":"List Data Connections","description":"List all data connections in the Hex workspace (e.g., Snowflake, PostgreSQL, BigQuery)."},{"name":"Get Data Connection","description":"Retrieve details for a specific data connection including type, description, and configuration flags."},{"name":"Create Group","description":"Create a new group in the Hex workspace, optionally with initial members."},{"name":"Update Group","description":"Rename a Hex group or add/remove members from it."},{"name":"Delete Group","description":"Delete a group from the Hex workspace."},{"name":"Deactivate User","description":"Deactivate a user in the Hex workspace."}],"triggers":[],"skills":[{"name":"run-project-with-params","description":"Trigger a Hex project run with input parameters and poll until it completes.","content":"# Run Project With Params\\n\\nKick off a Hex project and wait for the result.\\n\\n## Steps\\n1. If only a project name is known, list projects to resolve the project ID.\\n2. Run the project, passing any input parameters the project expects.\\n3. Capture the run ID and poll the run status until it reaches a terminal state (completed, errored, or killed).\\n4. If it is still pending after a reasonable timeout, report the current status rather than blocking indefinitely.\\n\\n## Output\\nReturn the run ID, final status, and any output or result link. On error, include the failure reason."},{"name":"monitor-recent-runs","description":"List recent Hex project runs, check their statuses, and surface failures.","content":"# Monitor Recent Runs\\n\\nWatch project runs and flag the ones that failed.\\n\\n## Steps\\n1. List project runs for the relevant project or projects.\\n2. Get the run status for each recent run.\\n3. Filter to runs that errored or were killed and capture the error detail.\\n4. Group successes and failures with timestamps.\\n\\n## Output\\nReturn a summary of recent runs with status and timing, plus a flagged failures section with run IDs, error messages, and links. Suitable for an hourly monitoring digest."},{"name":"cancel-stuck-run","description":"Find a long-running or stuck Hex run and cancel it.","content":"# Cancel Stuck Run\\n\\nStop a run that is hung or no longer needed.\\n\\n## Steps\\n1. List project runs and get the status of in-progress runs.\\n2. Identify runs exceeding an expected duration or explicitly targeted for cancellation.\\n3. Cancel the run by its run ID.\\n4. Re-check the status to confirm cancellation took effect.\\n\\n## Output\\nReturn the cancelled run ID and its confirmed final status. Note any run that could not be cancelled."},{"name":"inventory-projects","description":"List Hex projects, collections, and data connections to map analytics assets.","content":"# Inventory Projects\\n\\nMap what projects and data sources exist in the workspace.\\n\\n## Steps\\n1. List projects and capture IDs, names, and owners.\\n2. List collections and get details to see how projects are grouped.\\n3. List data connections to map which sources power the projects.\\n4. Cross-reference projects to their collections and data connections.\\n\\n## Output\\nReturn an inventory of projects grouped by collection, each annotated with its data connections. Useful for governance and cleanup."},{"name":"onboard-offboard-teammate","description":"Add a new teammate to the right Hex groups on hire, or deactivate and remove them on departure.","content":"# Onboard/Offboard Teammate\\n\\nManage workspace access as people join or leave the team.\\n\\n## Steps\\n1. List users to resolve the target user by name or email, and list groups to resolve the relevant group by name.\\n2. For onboarding: add the user to the appropriate group(s) via group update.\\n3. For offboarding: remove the user from their groups via group update, then deactivate the user account.\\n4. Confirm the change by getting the group or listing users filtered by group.\\n\\n## Output\\nReturn the user and group IDs affected and the action taken (added, removed, deactivated). Flag if the user or group could not be resolved."}],"templates":[{"title":"Amplitude + Hex deep-dive notebook","prompt":"Create a workflow that triggers a Hex deep-dive notebook when an Amplitude metric crosses an anomaly threshold, runs analysis, and posts the notebook output to Slack.","integrations":[{"id":"hex","name":"Hex"},{"id":"amplitude","name":"Amplitude"},{"id":"slack","name":"Slack"}]},{"title":"Hex project notebook runner","prompt":"Create a scheduled workflow that runs a Hex notebook with parameters every morning, waits for the run to finish, and posts a summary with the published notebook link to a Slack data channel.","integrations":[{"id":"hex","name":"Hex"},{"id":"slack","name":"Slack"}]},{"title":"Hex anomaly digest","prompt":"Build a workflow that runs a Hex notebook for anomaly detection on key metrics nightly, captures detected anomalies into a table, and pages the on-call data team on Slack for severe deltas.","integrations":[{"id":"hex","name":"Hex"},{"id":"slack","name":"Slack"}]},{"title":"Hex executive metrics email","prompt":"Create a scheduled weekly workflow that runs a Hex executive dashboard notebook, summarizes the run results, and emails a snapshot with the dashboard link to the leadership distribution list every Monday morning.","integrations":[{"id":"hex","name":"Hex"},{"id":"gmail","name":"Gmail"}]},{"title":"Hex + Tinybird realtime data app","prompt":"Create a workflow that powers a Hex data app with Tinybird realtime data, refreshes the dashboard on schedule, and writes usage analytics to a table.","integrations":[{"id":"hex","name":"Hex"},{"id":"tinybird","name":"Tinybird"}]},{"title":"Hex + Stripe revenue notebook","prompt":"Build a scheduled workflow that runs a Hex notebook over Stripe payment data daily, captures MRR, churn, and expansion metrics, and posts a summary with the notebook link to a Slack data channel.","integrations":[{"id":"hex","name":"Hex"},{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Hex + Amplitude product notebook","prompt":"Create a scheduled workflow that runs a Hex notebook joining Amplitude data with internal sources weekly, captures retention and feature adoption, and emails a summary with the notebook link to the product team.","integrations":[{"id":"hex","name":"Hex"},{"id":"amplitude","name":"Amplitude"},{"id":"gmail","name":"Gmail"}]},{"title":"Hex run failure monitor","prompt":"Build a workflow that lists recent Hex project runs every hour, checks each run status, and when a scheduled notebook fails pulls the error, summarizes the likely cause with an agent, and posts a Slack alert with a link to the run.","integrations":[{"id":"hex","name":"Hex"},{"id":"slack","name":"Slack"}]}]},{"id":"hubspot","type":"hubspot","slug":"hubspot","name":"HubSpot","description":"Interact with HubSpot CRM or trigger workflows from HubSpot events","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/hubspot","authType":"oauth","connections":[{"id":"hubspot","kind":"oauth","label":"Connect with OAuth","providerId":"hubspot","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/hubspot","requiredScopes":[{"id":"crm.objects.contacts.read","label":"Read HubSpot contacts"},{"id":"crm.objects.contacts.write","label":"Create, update, and delete HubSpot contacts"},{"id":"crm.objects.companies.read","label":"Read HubSpot companies"},{"id":"crm.objects.companies.write","label":"Create, update, and delete HubSpot companies"},{"id":"crm.objects.deals.read","label":"Read HubSpot deals"},{"id":"crm.objects.deals.write","label":"Create, update, and delete HubSpot deals"},{"id":"crm.objects.owners.read","label":"Read HubSpot object owners"},{"id":"crm.objects.users.read","label":"Read HubSpot users"},{"id":"crm.objects.marketing_events.read","label":"Read HubSpot marketing events"},{"id":"crm.objects.line_items.read","label":"Read HubSpot line items"},{"id":"crm.objects.line_items.write","label":"Create, update, and delete HubSpot line items"},{"id":"crm.objects.quotes.read","label":"Read HubSpot quotes"},{"id":"crm.objects.appointments.read","label":"Read HubSpot appointments"},{"id":"crm.objects.appointments.write","label":"Create and update HubSpot appointments"},{"id":"crm.objects.carts.read","label":"Read HubSpot shopping carts"},{"id":"sales-email-read","label":"Read the content of HubSpot email engagements"},{"id":"crm.lists.read","label":"Read HubSpot lists"},{"id":"crm.lists.write","label":"Create and update HubSpot lists"},{"id":"tickets","label":"Create, read, update, and delete HubSpot tickets"},{"id":"oauth","label":"Authenticate with HubSpot OAuth"}],"fields":[]},{"id":"hubspot-service-account","kind":"service_account","providerId":"hubspot-service-account","label":"Add private app token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/hubspot-service-account","fields":[{"id":"apiToken","label":"Private app access token","placeholder":"pat-na1-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","secret":true,"hint":"HubSpot private app tokens usually start with pat-."}]}],"operations":[{"name":"Get Contacts","description":"Retrieve all contacts from HubSpot account with pagination support"},{"name":"Create Contact","description":"Create a new contact in HubSpot. Requires at least one of: email, firstname, or lastname"},{"name":"Update Contact","description":"Update an existing contact in HubSpot by ID or email"},{"name":"Search Contacts","description":"Search for contacts in HubSpot using filters, sorting, and queries"},{"name":"Delete Contact","description":"Archive a contact in HubSpot by ID (moves it to the recycling bin)"},{"name":"Get Companies","description":"Retrieve all companies from HubSpot account with pagination support"},{"name":"Create Company","description":"Create a new company in HubSpot"},{"name":"Update Company","description":"Update an existing company in HubSpot by ID or domain"},{"name":"Search Companies","description":"Search for companies in HubSpot using filters, sorting, and queries"},{"name":"Delete Company","description":"Archive a company in HubSpot by ID (moves it to the recycling bin)"},{"name":"Get Deals","description":"Retrieve all deals from HubSpot account with pagination support"},{"name":"Create Deal","description":"Create a new deal in HubSpot with the given properties (e.g., dealname, amount, dealstage)"},{"name":"Update Deal","description":"Update an existing deal in HubSpot by ID"},{"name":"Search Deals","description":"Search for deals in HubSpot using filters, sorting, and queries"},{"name":"Delete Deal","description":"Archive a deal in HubSpot by ID (moves it to the recycling bin)"},{"name":"Get Tickets","description":"Retrieve all tickets from HubSpot account with pagination support"},{"name":"Create Ticket","description":"Create a new ticket in HubSpot. Requires subject and hs_pipeline_stage properties"},{"name":"Update Ticket","description":"Update an existing ticket in HubSpot by ID"},{"name":"Search Tickets","description":"Search for tickets in HubSpot using filters, sorting, and queries"},{"name":"Delete Ticket","description":"Archive a ticket in HubSpot by ID (moves it to the recycling bin)"},{"name":"Get Notes","description":"Retrieve all notes from HubSpot account with pagination support"},{"name":"Create Note","description":"Log a note in HubSpot and optionally associate it with contacts, companies, or deals. Requires hs_timestamp and hs_note_body properties"},{"name":"Search Notes","description":"Search for notes in HubSpot using filters, sorting, and queries"},{"name":"Get Emails","description":"Retrieve all email engagements from HubSpot account with pagination support"},{"name":"Create Email","description":"Log an email engagement in HubSpot and optionally associate it with contacts. Requires the hs_timestamp property"},{"name":"Search Emails","description":"Search for email engagements in HubSpot using filters, sorting, and queries"},{"name":"Get Properties","description":"Read property definitions and their enumeration (picklist) options for a HubSpot object type, e.g. the values for lifecyclestage or hs_lead_status on contacts"},{"name":"List Associations","description":"List records of one object type associated with a given record, e.g. all emails or notes logged on a contact"},{"name":"Create Association","description":"Associate two HubSpot records. Creates the default (unlabeled) association unless an association type ID is provided"},{"name":"Delete Association","description":"Remove all associations between two HubSpot records"},{"name":"Get Association Labels","description":"Retrieve the association types (category, typeId, label) defined between two HubSpot object types"},{"name":"Get Line Items","description":"Retrieve all line items from HubSpot account with pagination support"},{"name":"Create Line Item","description":"Create a new line item in HubSpot. Requires at least a name property"},{"name":"Update Line Item","description":"Update an existing line item in HubSpot by ID"},{"name":"Search Line Items","description":"Search for line items in HubSpot using filters, sorting, and queries"},{"name":"Delete Line Item","description":"Archive a line item in HubSpot by ID (moves it to the recycling bin)"},{"name":"Get Quotes","description":"Retrieve all quotes from HubSpot account with pagination support"},{"name":"Search Quotes","description":"Search for quotes in HubSpot using filters, sorting, and queries"},{"name":"Get Appointments","description":"Retrieve all appointments from HubSpot account with pagination support"},{"name":"Create Appointment","description":"Create a new appointment in HubSpot"},{"name":"Update Appointment","description":"Update an existing appointment in HubSpot by ID"},{"name":"Get Carts","description":"Retrieve all carts from HubSpot account with pagination support"},{"name":"List Owners","description":"Retrieve all owners from HubSpot account with pagination support"},{"name":"Get Marketing Events","description":"Retrieve all marketing events from HubSpot account with pagination support"},{"name":"Get Lists","description":"Search and retrieve lists from HubSpot account"},{"name":"Create List","description":"Create a new list in HubSpot. Specify the object type and processing type (MANUAL or DYNAMIC)"},{"name":"Get List Members","description":"Retrieve the record IDs that are members of a HubSpot list, ordered by record ID"},{"name":"Add List Members","description":"Add records to a manual (static) HubSpot list by record ID"},{"name":"Remove List Members","description":"Remove records from a manual (static) HubSpot list by record ID"},{"name":"Get Users","description":"Retrieve all users from HubSpot account"}],"triggers":[{"id":"hubspot_poller","name":"HubSpot CRM Trigger","description":"Triggers when HubSpot CRM records (contacts, companies, deals, tickets, custom objects) are created or updated, or when contacts join a list"}],"skills":[{"name":"upsert-contact","description":"Find a HubSpot contact by email and update it, or create it if it does not exist.","content":"# Upsert Contact\\n\\nKeep a contact record current without creating duplicates.\\n\\n## Steps\\n1. Search contacts by the email address to check if the person already exists.\\n2. If a match is found, update the contact with the new property values.\\n3. If no match exists, create a new contact with the email and known properties.\\n4. Read the contact back to confirm the final property values.\\n\\n## Output\\nReturn the contact ID and whether it was created or updated, along with the properties that were set."},{"name":"create-deal-for-account","description":"Create a HubSpot deal and associate it with the right company and contact.","content":"# Create Deal For Account\\n\\nLog a new opportunity tied to the correct account.\\n\\n## Steps\\n1. Search companies to resolve the company by name or domain; create it if missing.\\n2. Search contacts to find the primary contact for the deal.\\n3. Create the deal with name, amount, pipeline, and stage, associating it with the company and contact.\\n4. Read the deal back to confirm associations and stage.\\n\\n## Output\\nReturn the deal ID, its stage and amount, and the associated company and contact IDs."},{"name":"triage-support-ticket","description":"Classify a HubSpot ticket, set priority, and associate it with the correct company.","content":"# Triage Support Ticket\\n\\nRoute and prioritize an incoming support ticket.\\n\\n## Steps\\n1. Get the ticket to read its subject and content.\\n2. Classify topic and priority from the content.\\n3. Update the ticket with the priority and any pipeline stage change.\\n4. Search companies to find the requesting account and associate the ticket with it.\\n\\n## Output\\nReturn the ticket ID, assigned priority and topic, and the associated company. Flag high-priority tickets for escalation."},{"name":"summarize-open-deals","description":"Search HubSpot deals by stage and produce a pipeline summary with totals.","content":"# Summarize Open Deals\\n\\nReport on the active sales pipeline.\\n\\n## Steps\\n1. Search deals filtered to open stages, paginating through all results.\\n2. Group deals by pipeline stage and capture amount and close date.\\n3. Sum amounts per stage and overall, and flag deals with a close date in the past.\\n4. Identify the largest deals and any missing key properties.\\n\\n## Output\\nReturn a per-stage breakdown with deal counts and total value, a grand total, and a flagged list of overdue or incomplete deals. Suitable for a sales pipeline review."},{"name":"build-quote-from-deal","description":"Gather a HubSpot deal and its line items to assemble a quote summary.","content":"# Build Quote From Deal\\n\\nCompile the commercial details needed to quote a deal.\\n\\n## Steps\\n1. Get the deal by ID for its name, amount, and stage.\\n2. List line items and get details to capture product, quantity, and price for each.\\n3. Get the associated quote if one exists, or summarize the line items into a draft quote.\\n4. Total the line items and compare against the deal amount, flagging mismatches.\\n\\n## Output\\nReturn the deal summary, an itemized line-item list with totals, and any existing quote reference. Flag discrepancies between the line-item total and the deal amount."},{"name":"log-email-to-contact","description":"Log an email engagement in HubSpot and associate it with a contact.","content":"# Log Email To Contact\\n\\nRecord an email activity on a contact’s timeline.\\n\\n## Steps\\n1. Search contacts by email to resolve the contact ID.\\n2. Create an email engagement with hs_timestamp, subject, body, and direction.\\n3. Associate the email with the contact (associationTypeId 198, or the default association).\\n4. List associations from the contact to emails to confirm the link.\\n\\n## Output\\nReturn the email engagement ID and the associated contact ID."},{"name":"audit-contacts-missing-activity","description":"Find contacts in a lead stage that have no logged email activity.","content":"# Audit Contacts Missing Activity\\n\\nSurface leads with no recorded email history.\\n\\n## Steps\\n1. Get properties for contacts to read the hs_lead_status options and confirm the target stage value.\\n2. Search contacts filtered to that lead status, paginating through all results.\\n3. For each contact, list associations to emails and flag those with zero associated emails.\\n4. Collect the contacts that need follow-up.\\n\\n## Output\\nReturn the list of contact IDs with no logged email activity, ready for backfill."},{"name":"maintain-static-list","description":"Search HubSpot records and keep a manual list in sync by adding and removing members.","content":"# Maintain Static List\\n\\nKeep a manual (static) list aligned with a search criterion.\\n\\n## Steps\\n1. Search contacts (or other records) matching the target criteria, paginating through all results.\\n2. Get list members to read the current membership of the list.\\n3. Add list members for matching records that are missing.\\n4. Remove list members for records that no longer match.\\n\\n## Output\\nReturn the list ID with counts of records added and removed."},{"name":"inspect-property-options","description":"Read the enumeration (picklist) values for a HubSpot property.","content":"# Inspect Property Options\\n\\nList the allowed values for a dropdown property.\\n\\n## Steps\\n1. Get properties for the object type (e.g., contacts).\\n2. Find the property by name (e.g., lifecyclestage or hs_lead_status).\\n3. Read its options array for label/value pairs.\\n\\n## Output\\nReturn the property label and its enumeration options as label/value pairs."}],"templates":[{"title":"AgentPhone lead call + transcript scoring","prompt":"Build a workflow that places an outbound AgentPhone call to a new inbound lead, retrieves the call transcript afterward, scores qualification with an agent, and writes the result into HubSpot.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"agentphone","name":"AgentPhone"}]},{"title":"AgentPhone post-call summary","prompt":"Create a workflow that runs after every AgentPhone call, summarizes the transcript with action items, and updates the linked Salesforce or HubSpot record with next steps.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"agentphone","name":"AgentPhone"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Airtable form-to-CRM","prompt":"Create a workflow that watches Airtable form submissions, enriches each row with company data, and pushes qualifying leads into HubSpot with the right owner.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"airtable","name":"Airtable"}]},{"title":"Apify lead-list builder","prompt":"Create a workflow that runs an Apify scraper on a target site, enriches each row with Clay, and writes the enriched lead list into HubSpot.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"apify","name":"Apify"},{"id":"clay","name":"Clay"}]},{"title":"Apollo enrichment to HubSpot","prompt":"Build a workflow that on a new inbound signup enriches the person and their company with Apollo, scores fit against my ICP, and creates or updates the matching contact and company in HubSpot with the enriched fields.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"apollo","name":"Apollo"}]},{"title":"Brandfetch CRM enrichment","prompt":"Create a workflow that watches new HubSpot accounts, pulls Brandfetch data for each company domain, and writes brand colors and logo URLs to the company record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"brandfetch","name":"Brandfetch"}]},{"title":"Cal.com post-meeting recap","prompt":"Create a workflow that runs after a Cal.com meeting ends, summarizes the meeting notes, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"calcom","name":"Cal.com"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Cal.com webhook to CRM","prompt":"Create a workflow triggered by a Cal.com booking webhook that creates or updates the contact in HubSpot, sets the lifecycle stage, and assigns the right owner.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"calcom","name":"Cal.com"}]},{"title":"Circleback CRM updater","prompt":"Build a workflow that runs after a Circleback sales meeting, gets the full meeting with notes and insights, summarizes it into a deal-ready update, and writes it to the matching HubSpot or Salesforce record using the attendee company domain.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"circleback","name":"Circleback"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Clay CRM enricher","prompt":"Create a scheduled workflow that reads new HubSpot contacts and pushes each one to a Clay table via the populate webhook, so Clay runs its enrichment waterfall on role, seniority, and tech-stack signals.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"clay","name":"Clay"}]},{"title":"Clay inbound lead router","prompt":"Create a workflow that scores each inbound HubSpot lead against the ICP using the fields already on the contact, routes high-fit leads to sales while parking the rest for nurture, and pushes every lead to a Clay table via the populate webhook for enrichment.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"clay","name":"Clay"}]},{"title":"Clerk new-signup pipeline","prompt":"Build a scheduled workflow that lists recent Clerk users, creates each new signup in HubSpot with the right lifecycle stage, and enrolls them in a Loops onboarding sequence.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"clerk","name":"Clerk"},{"id":"loops","name":"Loops"}]},{"title":"DuckDuckGo enrichment researcher","prompt":"Build a workflow that uses DuckDuckGo to research prospect or company context where standard enrichment is missing, and writes the findings back to the CRM record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"Email Bison + HubSpot sync","prompt":"Create a workflow that mirrors Email Bison lead status and reply outcomes into the matching HubSpot contact, logs each campaign step as an engagement, and creates a HubSpot task for sales when a lead replies positively.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Enrich CRM gap-filler","prompt":"Create a scheduled workflow that finds HubSpot contacts missing key fields, runs Enrich, and fills in the gaps so reporting is complete.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"enrich","name":"Enrich"}]},{"title":"Enrich LinkedIn role validator","prompt":"Build a scheduled workflow that reads HubSpot contacts with a LinkedIn profile URL, re-enriches each with Enrich, flags outdated roles, and updates the contact record with the current title.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"enrich","name":"Enrich"}]},{"title":"CRM enrichment sweep","prompt":"Build a scheduled workflow that pulls HubSpot contacts missing a work email or phone, runs the Work Email and Phone Number enrichments to fill the gaps, and updates each record so the database stays ready for outbound.","integrations":[{"id":"hubspot","name":"HubSpot"}]},{"title":"Fathom CRM call logger","prompt":"Build a workflow that triggers when a Fathom meeting ends, pulls the summary and CRM matches, and logs the call notes and next steps to the matched HubSpot contact.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"fathom","name":"Fathom"}]},{"title":"Findymail CRM gap-filler","prompt":"Build a scheduled workflow that finds HubSpot contacts missing verified emails, looks them up with Findymail, verifies each, and updates the contact record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"findymail","name":"Findymail"}]},{"title":"Fireflies CRM updater","prompt":"Create a workflow that runs after a Fireflies sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"fireflies","name":"Fireflies"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Flint case-study generator","prompt":"Create a workflow triggered when a deal is marked closed-won that pulls the customer details, drafts case-study context with an agent, and uses Flint to generate a case-study page from the template.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"flint","name":"Flint"}]},{"title":"Gamma RFP responder","prompt":"Build a workflow that takes an inbound RFP, generates a Gamma response deck using a knowledge base of past proposals, and attaches the deck link to the linked HubSpot deal.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gamma","name":"Gamma"}]},{"title":"Gmail to CRM activity logger","prompt":"Build a workflow that reads new Gmail threads with customers, extracts the contact, deal context, and key points discussed, and logs a timestamped activity to the matching HubSpot contact or deal so every conversation stays attached to the record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gmail","name":"Gmail"}]},{"title":"Gong CRM auto-updater","prompt":"Build a workflow that runs after a Gong sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity with notes.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gong","name":"Gong"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Google Contacts CRM sync","prompt":"Build a scheduled workflow that mirrors Google Contacts into HubSpot, adding new contacts and updating fields, and writing a sync log for hygiene tracking.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Forms to CRM","prompt":"Build a workflow that watches Google Forms responses, enriches each submitter with company data, and pushes qualified leads into HubSpot with the right owner and source.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Maps lead-by-region exporter","prompt":"Build a workflow that uses Google Maps to find businesses matching an ICP in a region, enriches via Hunter, and writes the prospect list to HubSpot.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"google_maps","name":"Google Maps"},{"id":"hunter","name":"Hunter.io"}]},{"title":"Granola CRM updater","prompt":"Build a workflow that runs after a Granola sales meeting, summarizes the meeting notes into a deal-ready summary, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"granola","name":"Granola"},{"id":"salesforce","name":"Salesforce"}]},{"title":"HubSpot deal search","prompt":"Create a knowledge base connected to my HubSpot account so all deals, contacts, and activity history are automatically synced and searchable. Then build an agent I can ask things like \\"what happened with the Stripe integration deal?\\" or \\"which deals closed last quarter over $50k?\\" and get answers with HubSpot record links.","integrations":[{"id":"hubspot","name":"HubSpot"}]},{"title":"HubSpot win/loss analyzer","prompt":"Build a workflow that pulls closed deals from HubSpot each week, analyzes patterns in wins vs losses — deal size, industry, sales cycle length, objections — and generates a report file with actionable insights on what to change. Schedule it to run every Monday.","integrations":[{"id":"hubspot","name":"HubSpot"}]},{"title":"Get HubSpot deal alerts in Slack","prompt":"Build a workflow that watches HubSpot for deal stage changes, new contacts, and revenue milestones, then posts instant Slack notifications to your sales team.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"slack","name":"Slack"}]},{"title":"Send personalised emails from HubSpot events","prompt":"Build a workflow that triggers whenever a HubSpot contact enters a new lifecycle stage and sends a personalised Gmail message tailored to that stage.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gmail","name":"Gmail"}]},{"title":"HubSpot lead enrichment and dedupe","prompt":"Build a workflow that on a new HubSpot contact searches for existing duplicates, enriches the record with company size, industry, and verified email, and updates the contact and its associated company with the cleaned data.","integrations":[{"id":"hubspot","name":"HubSpot"}]},{"title":"HubSpot pipeline weekly digest","prompt":"Create a scheduled weekly workflow that lists HubSpot deals by stage, computes movement and at-risk deals with an agent, logs the snapshot to a table, and emails a pipeline summary to the sales leadership team.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gmail","name":"Gmail"}]},{"title":"HubSpot ticket triage","prompt":"Build a workflow that on a new HubSpot support ticket classifies priority and topic, adds a triage note, associates it with the right company, and posts an alert to the support Slack channel for high-priority cases.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"slack","name":"Slack"}]},{"title":"Backfill HubSpot contact email history from Gmail","prompt":"Build a workflow that finds HubSpot contacts in the lead stage with no logged email activity, searches my Gmail for each person’s thread, and logs it back to HubSpot as an email engagement associated with the contact.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"gmail","name":"Gmail"}]},{"title":"Hunter event-list enricher","prompt":"Build a workflow that takes a Luma event registrants list, finds their work emails via Hunter, and writes the verified emails into HubSpot for followup.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"hunter","name":"Hunter.io"},{"id":"luma","name":"Luma"}]},{"title":"Hunter CRM gap-filler","prompt":"Create a scheduled workflow that finds HubSpot contacts missing email addresses, looks them up via Hunter, validates each, and updates the contact record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"hunter","name":"Hunter.io"}]},{"title":"Instantly meeting-booked sync","prompt":"Build a workflow triggered when an Instantly lead is marked meeting booked that creates or updates the matching HubSpot contact and deal so the CRM reflects pipeline from outbound.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"instantly","name":"Instantly"}]},{"title":"Jotform CRM sync for event signups","prompt":"Build a workflow that reads Jotform event registration submissions, upserts each attendee as a HubSpot contact with the answers mapped onto contact properties, and marks the submission as processed in a table.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"jotform","name":"Jotform"}]},{"title":"Ketch consent propagator","prompt":"Build a workflow that on a consent change reads the contact’s Ketch consent state and propagates it to downstream systems — HubSpot and Loops — keeping privacy preferences in sync.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"ketch","name":"Ketch"},{"id":"loops","name":"Loops"}]},{"title":"LaTeX proposal generator","prompt":"Create a workflow that pulls deal details from HubSpot, has an agent draft a tailored proposal in LaTeX, compiles it to PDF, and saves it to the deal record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"latex","name":"LaTeX"}]},{"title":"LaunchDarkly customer-segment toggler","prompt":"Build a workflow that turns a HubSpot segment into a LaunchDarkly targeting rule, keeping the rule in sync with the segment, and writes the sync log to a tracking table.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"launchdarkly","name":"LaunchDarkly"}]},{"title":"Lemlist to HubSpot logger","prompt":"Create a workflow that watches Lemlist activity and logs every send, open, click, and reply to the matching HubSpot contact as an engagement, and creates a HubSpot task for the rep on positive replies.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"lemlist","name":"Lemlist"}]},{"title":"LogRocket profile sync from CRM","prompt":"Create a workflow that watches HubSpot contact updates and pushes the plan, lifecycle stage, and account value into LogRocket as user traits so sessions can be filtered by customer segment.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"logrocket","name":"LogRocket"}]},{"title":"Luma registrant enricher","prompt":"Build a scheduled workflow that pulls the Luma event guest list, enriches each registrant with company data via Apollo, and pushes high-value attendees into HubSpot as leads.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"luma","name":"Luma"},{"id":"apollo","name":"Apollo"}]},{"title":"Luma post-event followup","prompt":"Create a scheduled workflow that runs the day after a Luma event, pulls the guest list, segments attendees from no-shows, sends each segment a tailored followup, and writes attendance to the CRM.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"luma","name":"Luma"},{"id":"gmail","name":"Gmail"}]},{"title":"Mailchimp segment builder from HubSpot","prompt":"Create a workflow that reads HubSpot lifecycle stage and ICP fields, upserts each contact into Mailchimp with the matching tags and merge fields, and recomputes named segments daily so marketing can target by CRM state.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Teams weekly metrics digest","prompt":"Create a scheduled weekly workflow that aggregates key business metrics from Stripe and HubSpot, formats them into a polished Microsoft Teams adaptive card, and posts to the leadership channel.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"stripe","name":"Stripe"}]},{"title":"Word proposal generator","prompt":"Create a workflow triggered by a closed-won HubSpot deal that generates a tailored proposal document in Word, exports it as PDF, and emails it to the customer contact.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"outlook","name":"Outlook"}]},{"title":"Otter sales call to CRM","prompt":"Create a workflow triggered by an Otter conversation shared to the sales calls channel that matches calendar guests to HubSpot contacts and logs the meeting summary and next steps on the deal.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"otter","name":"Otter.ai"}]},{"title":"Parallel AI lead enrichment pipeline","prompt":"Build a workflow that runs Parallel AI search and extract on each new inbound lead to find company size, industry, and tech stack, scores fit against the ICP, and updates the lead record with the enriched profile.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"PDL person enricher","prompt":"Build a workflow that watches CRM contacts, enriches each via People Data Labs with role, seniority, and company signals, and writes the enriched data back.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"PDL CRM gap-filler","prompt":"Create a scheduled workflow that finds CRM contacts missing key fields, runs People Data Labs to fill gaps, and writes coverage metrics to a hygiene table.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"PitchBook buying committee lookup","prompt":"Build a workflow that takes a target account, resolves it in PitchBook, pulls the current team and board members with their titles, filters to the decision-makers for my product, and syncs the mapped contacts into HubSpot.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"pitchbook","name":"PitchBook"}]},{"title":"PostHog cohort enrichment","prompt":"Create a workflow that pulls a PostHog cohort, enriches each user with HubSpot lifecycle stage and Stripe LTV, and writes the enriched cohort to a tables-based targeting view.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"posthog","name":"PostHog"},{"id":"stripe","name":"Stripe"}]},{"title":"Prospeo person enricher","prompt":"Create a workflow that watches CRM contacts, runs Prospeo enrichment to fill in title, company, and verified contact details, and writes the enriched fields back.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"prospeo","name":"Prospeo"}]},{"title":"RB2B visitor-to-HubSpot sync","prompt":"Build a workflow that resolves visitor IPs to company domains with RB2B, enriches the matched person into a business profile, and creates or updates the matching contact and company in HubSpot.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"rb2b","name":"RB2B"}]},{"title":"Sentry customer-impact mapper","prompt":"Build a workflow that takes a Sentry issue and matches affected users to CRM accounts, scoring customer impact, and creates a customer-facing incident note in HubSpot for the worst-affected accounts.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"sentry","name":"Sentry"}]},{"title":"Sixtyfour contact researcher","prompt":"Build a workflow that runs Sixtyfour AI on inbound leads, enriches with deep research-grade signals, and writes a research brief into the CRM contact record.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Smartlead + HubSpot sync","prompt":"Build a workflow that reads Smartlead campaign leads and their categories, finds or creates the matching HubSpot contact, mirrors the outreach status onto the contact, and creates a HubSpot task for a rep whenever a lead is categorized as interested.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"smartlead","name":"Smartlead"}]},{"title":"Webflow form-to-CRM","prompt":"Build a workflow that watches Webflow form submissions, enriches each with Apollo company data, and pushes qualifying leads into HubSpot with the right owner and source.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"webflow","name":"Webflow"},{"id":"apollo","name":"Apollo"}]},{"title":"Webflow + Hubspot lead-magnet","prompt":"Build a workflow that triggers on a Webflow form submission for a lead magnet, sends the asset via Loops, and writes the engagement to the matching HubSpot contact.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"webflow","name":"Webflow"},{"id":"loops","name":"Loops"}]},{"title":"Wiza to HubSpot pipeline","prompt":"Build a workflow that runs a Wiza prospect search for my target segment, reveals verified emails and phones for each match, and creates or updates the matching HubSpot contacts with the enriched fields and a lead-source tag.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"wiza","name":"Wiza"}]},{"title":"Zoom webinar follow-up","prompt":"Build a workflow that runs after a Zoom webinar, pulls the registrant and attendee lists, sends a follow-up email with the recording link, and writes attendance into HubSpot for marketing scoring.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"zoom","name":"Zoom"},{"id":"gmail","name":"Gmail"}]},{"title":"Zoom sales-call deal updater","prompt":"Build a workflow that runs after a Zoom sales call, summarizes objections, next steps, and stage signals from the transcript, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"hubspot","name":"HubSpot"},{"id":"zoom","name":"Zoom"},{"id":"salesforce","name":"Salesforce"}]}]},{"id":"huggingface","type":"huggingface","slug":"hugging-face","name":"Hugging Face","description":"Use Hugging Face Inference API","category":"AI","docsUrl":"https://docs.sim.ai/integrations/huggingface","authType":"api-key","connections":[],"operations":[{"name":"Hugging Face Chat","description":"Generate completions using Hugging Face Inference API"}],"triggers":[],"skills":[{"name":"run-chat-completion","description":"Send a prompt to a Hugging Face chat model via the Inference API and return the response.","content":"# Run Chat Completion\\n\\nGenerate a completion from an open chat model.\\n\\n## Steps\\n1. Choose the model (e.g. an instruct or chat-tuned model available via the Inference API).\\n2. Build the messages with a clear system instruction and the user prompt.\\n3. Call chat with the model and messages, setting temperature and max tokens appropriate to the task.\\n4. Capture the assistant response and any token usage returned.\\n\\n## Output\\nReturn the model output and the model name used. Note token usage when available for cost tracking."},{"name":"extract-structured-data","description":"Use a Hugging Face chat model to extract fields from unstructured text into a structured object.","content":"# Extract Structured Data\\n\\nPull named fields out of free text using an open model.\\n\\n## Steps\\n1. Define the exact fields to extract and their types.\\n2. Build a system message instructing the model to return only valid JSON matching the schema, with nulls for missing fields.\\n3. Call chat with the source text as the user message and a low temperature for determinism.\\n4. Parse the response and validate it against the expected fields; retry once with a stricter instruction if parsing fails.\\n\\n## Output\\nReturn the parsed structured object. On repeated parse failure, return the raw model text and an error note."},{"name":"compare-model-outputs","description":"Run the same prompt through two Hugging Face models and compare their outputs.","content":"# Compare Model Outputs\\n\\nEvaluate how two open models handle the same task.\\n\\n## Steps\\n1. Define the shared prompt and the two model identifiers to compare.\\n2. Call chat once per model with identical messages and generation settings.\\n3. Capture each output along with latency and token usage.\\n4. Score the outputs against the task criteria (accuracy, format, completeness).\\n\\n## Output\\nReturn both responses side by side with their latency, token usage, and a brief quality comparison. Suitable for logging to an evaluation table."}],"templates":[{"title":"Google Translate + Hugging Face confidence","prompt":"Create a workflow that runs Google Translate then scores translation quality with a Hugging Face model, flags low-confidence segments for human review, and writes the scored output.","integrations":[{"id":"huggingface","name":"Hugging Face"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Hugging Face row classifier","prompt":"Build a workflow that runs each row in a table through a Hugging Face chat model with custom labels in the prompt, writes the predicted label and a confidence rating back, and flags low-confidence rows for review.","integrations":[{"id":"huggingface","name":"Hugging Face"}]},{"title":"Hugging Face sentiment scorer","prompt":"Create a workflow that scores customer feedback with a Hugging Face chat model, writes sentiment and score columns back to the table, and pings Slack on a sudden negative spike.","integrations":[{"id":"huggingface","name":"Hugging Face"},{"id":"slack","name":"Slack"}]},{"title":"Hugging Face candidate reranker","prompt":"Create a retrieval pipeline that fetches top-50 candidates from a knowledge base, reranks them with a Hugging Face chat model scoring relevance, and returns the top-5 to the answering agent for higher precision.","integrations":[{"id":"huggingface","name":"Hugging Face"}]},{"title":"Hugging Face PII redactor","prompt":"Build a workflow that runs a Hugging Face chat model over text uploads to detect PII, redacts the sensitive entities, and writes the cleaned text to a downstream table.","integrations":[{"id":"huggingface","name":"Hugging Face"}]},{"title":"Hugging Face open-model summarizer","prompt":"Create a workflow that on a new document fetches the text and runs it through a Hugging Face chat model to produce a concise summary and key takeaways, then writes the result back to a table — keeping the workload on open-weight models you control.","integrations":[{"id":"huggingface","name":"Hugging Face"}]},{"title":"Hugging Face feedback classifier","prompt":"Build a workflow that reads new customer feedback rows, uses a Hugging Face chat model to classify sentiment and theme, writes the labels back to the table, and posts a Slack alert when negative feedback spikes.","integrations":[{"id":"huggingface","name":"Hugging Face"},{"id":"slack","name":"Slack"}]},{"title":"Hugging Face model A/B harness","prompt":"Create a workflow that runs the same prompt through a Hugging Face open model and a hosted model side by side, compares the outputs with a grading agent, and logs quality, latency, and cost to a table for evaluation.","integrations":[{"id":"huggingface","name":"Hugging Face"}]},{"title":"Perplexity + DSPy structured-output evaluator","prompt":"Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.","integrations":[{"id":"huggingface","name":"Hugging Face"},{"id":"perplexity","name":"Perplexity"},{"id":"dspy","name":"DSPy"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Perplexity + Hugging Face semantic dedup","prompt":"Build a workflow that runs Perplexity research, embeds findings with a Hugging Face encoder, deduplicates near-identical claims, and writes a clean research file.","integrations":[{"id":"huggingface","name":"Hugging Face"},{"id":"perplexity","name":"Perplexity"}]}]},{"id":"hunter","type":"hunter","slug":"hunter-io","name":"Hunter.io","description":"Find and verify professional email addresses","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/hunter","authType":"api-key","connections":[],"operations":[{"name":"Domain Search","description":"Returns all the email addresses found using one given domain name, with sources."},{"name":"Email Finder","description":"Finds the most likely email address for a person given their name and company domain."},{"name":"Email Verifier","description":"Verifies the deliverability of an email address and provides detailed verification status."},{"name":"Discover Companies","description":"Returns companies matching a set of criteria using Hunter.io AI-powered search."},{"name":"Find Company","description":"Enriches company data using domain name."},{"name":"Email Count","description":"Returns the total number of email addresses found for a domain or company."}],"triggers":[],"skills":[{"name":"find-decision-maker-emails","description":"Find verified email addresses for key roles at a target company using domain search.","content":"# Find Decision-Maker Emails\\n\\nGiven a company domain, find verified professional email addresses for the people who matter.\\n\\n## Steps\\n1. Run a domain search for the target domain (e.g. example.com).\\n2. Filter results by department or seniority (executive, sales, IT) to surface decision-makers.\\n3. For each candidate, capture the full name, role, email, and confidence score.\\n4. Drop any result below your confidence threshold (e.g. < 80).\\n\\n## Output\\nReturn a list of contacts with name, title, email, and confidence score, sorted by seniority. Note the total emails available on the domain so the user knows coverage."},{"name":"verify-email-list","description":"Verify a batch of email addresses and flag undeliverable or risky ones before sending.","content":"# Verify Email List\\n\\nClean a list of email addresses so a campaign only sends to deliverable inboxes.\\n\\n## Steps\\n1. For each address, run the email verifier.\\n2. Record the verification status (valid, invalid, accept-all, disposable, webmail) and the deliverability score.\\n3. Bucket addresses into deliverable, risky, and undeliverable.\\n\\n## Output\\nReturn the three buckets with counts, and a recommended clean list containing only deliverable addresses."},{"name":"find-person-email","description":"Find the most likely email address for a named person at a specific company.","content":"# Find a Person Email\\n\\nGiven a first name, last name, and company domain, find that person email address.\\n\\n## Steps\\n1. Run the email finder with the full name and domain.\\n2. Capture the returned email, confidence score, and the sources Hunter used.\\n3. If confidence is low, optionally run a domain search to confirm the pattern.\\n\\n## Output\\nReturn the email, confidence score, and supporting sources. State clearly when no confident match was found."}],"templates":[{"title":"Google Maps lead-by-region exporter","prompt":"Build a workflow that uses Google Maps to find businesses matching an ICP in a region, enriches via Hunter, and writes the prospect list to HubSpot.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"google_maps","name":"Google Maps"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Hunter email finder","prompt":"Build a workflow that takes a target company and role from a table, runs Hunter to find the matching email, validates it, and writes the verified contact back.","integrations":[{"id":"hunter","name":"Hunter.io"}]},{"title":"Hunter email verifier","prompt":"Create a workflow that runs a list of email addresses through Hunter verification, removes invalid emails, and writes a clean list for outbound sends.","integrations":[{"id":"hunter","name":"Hunter.io"}]},{"title":"Hunter + Email Bison outbound","prompt":"Build a workflow that uses Hunter to find prospect emails, validates each, and pushes valid prospects into an active Email Bison campaign.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Hunter domain finder","prompt":"Create a workflow that takes a list of company names, finds the matching domains via Hunter, and enriches the rows so the CRM has accurate domain data.","integrations":[{"id":"hunter","name":"Hunter.io"}]},{"title":"Hunter event-list enricher","prompt":"Build a workflow that takes a Luma event registrants list, finds their work emails via Hunter, and writes the verified emails into HubSpot for followup.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"luma","name":"Luma"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Hunter CRM gap-filler","prompt":"Create a scheduled workflow that finds HubSpot contacts missing email addresses, looks them up via Hunter, validates each, and updates the contact record.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Hunter + Apollo prospect builder","prompt":"Build a workflow that runs an Apollo search for an ICP, finds verified emails via Hunter, and writes the deliverable prospect list to a sender table.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"apollo","name":"Apollo"}]},{"title":"Hunter + Instantly outbound","prompt":"Create a workflow that finds verified prospect emails with Hunter, validates each, and loads the deliverable contacts into an active Instantly campaign.","integrations":[{"id":"hunter","name":"Hunter.io"},{"id":"instantly","name":"Instantly"}]}]},{"id":"icypeas","type":"icypeas","slug":"icypeas","name":"Icypeas","description":"Find and verify professional email addresses","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/icypeas","authType":"api-key","connections":[],"operations":[{"name":"Find Email","description":"Find a professional email address from a first name, last name, and company domain or name. Submits the search and polls until a result is available. Costs 1 credit per found email (https://www.icypeas.com/pricing)."},{"name":"Verify Email","description":"Verify whether an email address is valid and deliverable. Submits the verification and polls until a result is available. Costs 0.1 credit per verification (https://www.icypeas.com/pricing)."}],"triggers":[],"skills":[],"templates":[]},{"id":"incidentio","type":"incidentio","slug":"incident-io","name":"incident.io","description":"Manage incidents with incident.io","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/incidentio","authType":"api-key","connections":[],"operations":[{"name":"List Incidents","description":"List incidents from incident.io. Returns a list of incidents with their details including severity, status, and timestamps."},{"name":"Create Incident","description":"Create a new incident in incident.io. Requires idempotency_key, severity_id, and visibility. Optionally accepts name, summary, type, and status."},{"name":"Show Incident","description":"Retrieve detailed information about a specific incident from incident.io by its ID. Returns full incident details including custom fields and role assignments."},{"name":"Update Incident","description":"Update an existing incident in incident.io. Can update name, summary, severity, status, or type."},{"name":"List Actions","description":"List actions from incident.io. Optionally filter by incident ID."},{"name":"Show Action","description":"Get detailed information about a specific action from incident.io."},{"name":"List Follow-ups","description":"List follow-ups from incident.io. Optionally filter by incident ID."},{"name":"Show Follow-up","description":"Get detailed information about a specific follow-up from incident.io."},{"name":"List Users","description":"List all users in your Incident.io workspace. Returns user details including id, name, email, and role."},{"name":"Show User","description":"Get detailed information about a specific user in your Incident.io workspace by their ID."},{"name":"List Workflows","description":"List all workflows in your incident.io workspace."},{"name":"Create Workflow","description":"Create a new workflow in incident.io."},{"name":"Show Workflow","description":"Get details of a specific workflow in incident.io."},{"name":"Update Workflow","description":"Update an existing workflow in incident.io."},{"name":"Delete Workflow","description":"Delete a workflow in incident.io."},{"name":"List Schedules","description":"List all schedules in incident.io"},{"name":"Create Schedule","description":"Create a new schedule in incident.io"},{"name":"Show Schedule","description":"Get details of a specific schedule in incident.io"},{"name":"Update Schedule","description":"Update an existing schedule in incident.io"},{"name":"Delete Schedule","description":"Delete a schedule in incident.io"},{"name":"List Escalations","description":"List all escalation policies in incident.io"},{"name":"Create Escalation","description":"Create a new escalation policy in incident.io"},{"name":"Show Escalation","description":"Get details of a specific escalation policy in incident.io"},{"name":"List Custom Fields","description":"List all custom fields from incident.io."},{"name":"Create Custom Field","description":"Create a new custom field in incident.io."},{"name":"Show Custom Field","description":"Get detailed information about a specific custom field from incident.io."},{"name":"Update Custom Field","description":"Update an existing custom field in incident.io."},{"name":"Delete Custom Field","description":"Delete a custom field from incident.io."},{"name":"List Severities","description":"List all severity levels configured in your Incident.io workspace. Returns severity details including id, name, description, and rank."},{"name":"List Incident Statuses","description":"List all incident statuses configured in your Incident.io workspace. Returns status details including id, name, description, and category."},{"name":"List Incident Types","description":"List all incident types configured in your Incident.io workspace. Returns type details including id, name, description, and default flag."},{"name":"List Incident Roles","description":"List all incident roles in incident.io"},{"name":"Create Incident Role","description":"Create a new incident role in incident.io"},{"name":"Show Incident Role","description":"Get details of a specific incident role in incident.io"},{"name":"Update Incident Role","description":"Update an existing incident role in incident.io"},{"name":"Delete Incident Role","description":"Delete an incident role in incident.io"},{"name":"List Incident Timestamps","description":"List all incident timestamp definitions in incident.io"},{"name":"Show Incident Timestamp","description":"Get details of a specific incident timestamp definition in incident.io"},{"name":"List Incident Updates","description":"List all updates for a specific incident in incident.io"},{"name":"List Schedule Entries","description":"List all entries for a specific schedule in incident.io"},{"name":"Create Schedule Override","description":"Create a new schedule override in incident.io"},{"name":"List Escalation Paths","description":"List escalation paths in incident.io"},{"name":"Create Escalation Path","description":"Create a new escalation path in incident.io"},{"name":"Show Escalation Path","description":"Get details of a specific escalation path in incident.io"},{"name":"Update Escalation Path","description":"Update an existing escalation path in incident.io"},{"name":"Delete Escalation Path","description":"Delete an escalation path in incident.io"},{"name":"Get Who Is On Call","description":"Get who is currently on call in incident.io, as one row per ongoing shift across every schedule (or a single schedule). Also returns the shifts that take over at the next changeover."},{"name":"List Schedule Overrides","description":"List the one-off overrides layered on top of a schedule in incident.io, such as someone covering a colleague’s shift"},{"name":"List Alerts","description":"List alerts in incident.io, optionally filtered by status, source, or created date"},{"name":"Show Alert","description":"Get a single alert by ID from incident.io"},{"name":"Resolve Alert","description":"Resolve a currently firing alert in incident.io. Resolving an already-resolved alert is a no-op and returns it unchanged."},{"name":"Create Alert Event","description":"Fire an alert into incident.io through an HTTP alert source. Send the same deduplication key with status \\"resolved\\" to close the alert you opened."},{"name":"List Incident Alerts","description":"List the connections between incidents and alerts in incident.io — which alerts triggered an incident, or which incident an alert was attached to"},{"name":"Cancel Escalation","description":"Cancel an escalation in incident.io. Notifications stop, and the escalation will not advance to further levels or repeat."},{"name":"List Catalog Types","description":"List all catalog types in incident.io, including those synced from external resources. Use this to find the catalog type ID needed to list entries."},{"name":"List Catalog Entries","description":"List the entries of a catalog type in incident.io — for example every service, team, or customer recorded in the catalog"},{"name":"List Teams","description":"List all teams in the incident.io organisation, along with their members"},{"name":"Show Team","description":"Get a single team by ID from incident.io, along with its members"},{"name":"Create Follow-up","description":"Create a new follow-up on an incident in incident.io"},{"name":"Update Follow-up","description":"Update an existing follow-up in incident.io, for example to mark it completed or reassign it"},{"name":"Create Action","description":"Create a new action on an incident in incident.io"},{"name":"Update Action","description":"Update an existing action in incident.io, for example to mark it completed or reassign it"},{"name":"List Incident Participants","description":"List the participants of an incident in incident.io, split into those actively helping and those just observing"},{"name":"Grant Incident Membership","description":"Make a user a member of a private incident in incident.io"},{"name":"Revoke Incident Membership","description":"Revoke a user\'s membership of a private incident in incident.io"}],"triggers":[{"id":"incidentio_incident_created","name":"incident.io Incident Created","description":"Trigger workflow when an incident is created in incident.io"},{"id":"incidentio_incident_updated","name":"incident.io Incident Updated","description":"Trigger workflow when an incident is updated in incident.io"},{"id":"incidentio_incident_status_updated","name":"incident.io Incident Status Updated","description":"Trigger workflow when an incident\'s status changes in incident.io"},{"id":"incidentio_alert_created","name":"incident.io Alert Created","description":"Trigger workflow when an alert is created in incident.io"}],"skills":[{"name":"declare-incident-from-alert","description":"Open an incident.io incident from an inbound alert with the right severity and summary.","content":"# Declare an Incident From an Alert\\n\\nTurn a monitoring alert into a structured incident.io incident so responders can act fast.\\n\\n## Steps\\n1. Look up available severities and pick the one matching the alert impact.\\n2. Create the incident with a clear name, a summary describing impact and affected service, and the chosen severity.\\n3. Set incident type and any required custom fields from the alert payload.\\n4. Capture the new incident reference and link.\\n\\n## Output\\nReturn the incident ID, reference, severity, and link. Confirm the responder channel was created so the team can jump in."},{"name":"post-incident-update","description":"Update an active incident with current status and a progress note for stakeholders.","content":"# Post an Incident Update\\n\\nKeep stakeholders informed by moving an active incident through its lifecycle.\\n\\n## Steps\\n1. Look up the incident by reference or ID to confirm its current status.\\n2. List valid incident statuses and choose the next one (investigating, identified, monitoring, resolved).\\n3. Update the incident with the new status and a concise progress message.\\n\\n## Output\\nReturn the incident reference, the new status, and a one-line summary of what changed and when."},{"name":"on-call-handoff-report","description":"Summarize who is on call and recent open incidents for an on-call handoff.","content":"# On-Call Handoff Report\\n\\nBuild a clean handoff so the next on-call engineer knows the state of the world.\\n\\n## Steps\\n1. Get who is on call to read the ongoing shifts, and note the shifts that take over at the next changeover.\\n2. List schedule overrides so any shift cover is reflected in the handoff.\\n3. List recent incidents and filter to those that are open or recently resolved.\\n4. For each open incident, capture severity, status, and outstanding follow-ups.\\n\\n## Output\\nReturn a handoff brief: who is on call now and who takes over next, open incidents with severity and status, and follow-ups that still need owners."},{"name":"triage-firing-alerts","description":"Review firing alerts, link them to incidents, and resolve the ones that are stale.","content":"# Triage Firing Alerts\\n\\nWork the firing alert queue so real problems get an incident and noise gets closed out.\\n\\n## Steps\\n1. List alerts filtered to status firing, oldest first, and capture title, source, and when each started.\\n2. For each alert, list incident alerts to see whether it is already attached to an incident.\\n3. Group the unattached alerts by source and by the attributes they share.\\n4. Resolve alerts that are clearly stale or already handled, and flag the rest for an incident.\\n\\n## Output\\nReturn three lists: alerts already attached to an incident, alerts resolved as stale, and alerts that still need a human decision with the reason why."},{"name":"page-the-on-call-for-a-service","description":"Find who is on call for a service and raise an escalation to them.","content":"# Page the On-Call for a Service\\n\\nRoute an urgent problem to whoever is actually holding the pager right now.\\n\\n## Steps\\n1. List catalog entries for the service catalog type to resolve the service and its owning team.\\n2. Get who is on call and pick the shift covering that team’s schedule.\\n3. List escalation paths and choose the one matching the service, falling back to the on-call user IDs.\\n4. Create the escalation with a title naming the service and the symptom, using a unique idempotency key so a retry does not double-page.\\n\\n## Output\\nReturn who was paged, the escalation ID, and the schedule the on-call shift came from. If nobody is on call for that schedule, say so instead of paging a fallback silently."},{"name":"export-incident-followups","description":"Pull follow-ups from recent incidents into an actionable list for post-incident review.","content":"# Export Incident Follow-Ups\\n\\nGather the action items that came out of recent incidents so none slip through.\\n\\n## Steps\\n1. List incidents within the target time window.\\n2. For each, list its follow-ups and capture title, owner, status, and linked incident.\\n3. Group follow-ups by owner and by open vs completed.\\n\\n## Output\\nReturn a table of follow-ups grouped by owner with status and source incident, highlighting overdue or unassigned items."}],"templates":[{"title":"incident.io commander","prompt":"Build a scheduled workflow that polls incident.io for newly declared incidents, opens a Slack war-room for each, invites responders from the on-call schedule, pulls related PagerDuty alerts, and pins the runbook.","integrations":[{"id":"incidentio","name":"incident.io"},{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"incident.io postmortem starter","prompt":"Create a scheduled workflow that polls incident.io for recently resolved incidents, pulls the Slack thread, related Sentry errors, and deploy timeline, then drafts a postmortem doc in Google Docs.","integrations":[{"id":"incidentio","name":"incident.io"},{"id":"sentry","name":"Sentry"},{"id":"google_docs","name":"Google Docs"}]},{"title":"incident.io action-item tracker","prompt":"Build a workflow that watches incident.io for new follow-up actions, creates Linear tickets for each, and writes a tracking table that surfaces overdue actions on a weekly digest.","integrations":[{"id":"incidentio","name":"incident.io"},{"id":"linear","name":"Linear"}]},{"title":"incident.io weekly digest","prompt":"Create a scheduled weekly workflow that summarizes incident.io activity — declared incidents, MTTR, top affected services, action-item completion rate — and posts to Slack.","integrations":[{"id":"incidentio","name":"incident.io"},{"id":"slack","name":"Slack"}]},{"title":"incident.io customer comms drafter","prompt":"Build a workflow that during a high-severity incident.io incident drafts customer status-page copy and a tailored email update, holds for approval, and dispatches once approved.","integrations":[{"id":"incidentio","name":"incident.io"},{"id":"gmail","name":"Gmail"}]},{"title":"incident.io SLO impact mapper","prompt":"Create a workflow that on each incident.io incident maps impacted services to active SLOs, calculates SLO burn, and writes the impact analysis back to the incident timeline.","integrations":[{"id":"incidentio","name":"incident.io"}]},{"title":"incident.io noise filter","prompt":"Build a workflow that pulls incident.io declared incidents, classifies a subset as low-impact noise, auto-resolves them after auditing, and writes a noise-rate metric to a table.","integrations":[{"id":"incidentio","name":"incident.io"}]}]},{"id":"infisical","type":"infisical","slug":"infisical","name":"Infisical","description":"Manage secrets with Infisical","category":"Security","docsUrl":"https://docs.sim.ai/integrations/infisical","authType":"api-key","connections":[],"operations":[{"name":"List Secrets","description":"List all secrets in a project environment. Returns secret keys, values, comments, tags, and metadata."},{"name":"Get Secret","description":"Retrieve a single secret by name from a project environment."},{"name":"Create Secret","description":"Create a new secret in a project environment."},{"name":"Update Secret","description":"Update an existing secret in a project environment."},{"name":"Delete Secret","description":"Delete a secret from a project environment."}],"triggers":[],"skills":[{"name":"fetch-secret-for-run","description":"Retrieve a named secret from Infisical to use as a credential during a workflow run.","content":"# Fetch a Secret for a Run\\n\\nPull a single secret from Infisical so a downstream step can authenticate without hardcoding credentials.\\n\\n## Steps\\n1. Identify the project, environment (e.g. dev, staging, prod), and secret path.\\n2. Get the secret by name from that scope.\\n3. Pass the value to the consuming step. Never echo the raw secret into logs or output.\\n\\n## Output\\nConfirm the secret was retrieved (by name and environment) and that it was used. Do not print the secret value itself."},{"name":"rotate-secret","description":"Update an existing secret in Infisical with a new value as part of a rotation.","content":"# Rotate a Secret\\n\\nReplace a secret value in Infisical during a credential rotation.\\n\\n## Steps\\n1. Confirm the project, environment, and secret name to rotate.\\n2. Update the secret with the new value at that path.\\n3. Optionally read the secret back by name to confirm it now exists (without printing the value).\\n\\n## Output\\nConfirm the secret name and environment that was rotated and the timestamp. Never expose the old or new value."},{"name":"audit-environment-secrets","description":"List the secret names present in an Infisical environment for an inventory or audit.","content":"# Audit Environment Secrets\\n\\nProduce an inventory of which secrets exist in an Infisical environment without exposing their values.\\n\\n## Steps\\n1. Choose the project, environment, and path to audit.\\n2. List secrets at that scope and collect only the keys and metadata.\\n3. Compare against the expected set if one is provided and flag missing or unexpected keys.\\n\\n## Output\\nReturn a list of secret names (keys only) with count, and any discrepancies versus the expected set. Never include secret values."}],"templates":[{"title":"Infisical secret rotation orchestrator","prompt":"Build a scheduled workflow that lists Infisical secrets, generates fresh values for those due for rotation, updates them across each environment, and writes rotation status to a compliance table.","integrations":[{"id":"infisical","name":"Infisical"}]},{"title":"Infisical environment drift detector","prompt":"Create a scheduled workflow that diffs Infisical environments against expected schemas, alerts on missing or extra secrets, and writes a remediation queue.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"slack","name":"Slack"}]},{"title":"Infisical env bootstrapper","prompt":"Build a workflow that on a Workday new-hire event creates the standard set of Infisical secrets for the new engineer’s scoped dev environment from a template, and writes the provisioning record to a table.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"workday","name":"Workday"}]},{"title":"Infisical offboarding rotation","prompt":"Create a workflow that on a Workday termination rotates the shared Infisical secrets the departing engineer had access to by generating new values and updating them across environments, then writes the action log to a table.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"workday","name":"Workday"}]},{"title":"Infisical CI sync","prompt":"Build a workflow that mirrors Infisical secrets into GitHub Actions environments for CI deploys, keeping the secret store as the single source of truth.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"github","name":"GitHub"}]},{"title":"Infisical secret-inventory reviewer","prompt":"Create a scheduled quarterly workflow that lists Infisical secrets per project and environment, flags ones with weak or aged values for owner attestation in Slack, and writes the review to a compliance table.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"slack","name":"Slack"}]},{"title":"Infisical secret-inventory snapshot","prompt":"Build a scheduled workflow that lists Infisical secrets across environments, writes a redacted inventory snapshot to S3 for long-term retention, and tracks secret count trends in a table.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"s3","name":"S3"}]},{"title":"Secrets Manager + Infisical mirror","prompt":"Create a workflow that mirrors secrets between AWS Secrets Manager and Infisical for cross-cloud applications, normalizes naming, and writes a sync log.","integrations":[{"id":"infisical","name":"Infisical"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]}]},{"id":"instantly","type":"instantly","slug":"instantly","name":"Instantly","description":"Manage Instantly leads, campaigns, emails, and lead lists","category":"Email","docsUrl":"https://docs.sim.ai/integrations/instantly","authType":"api-key","connections":[],"operations":[{"name":"List Leads","description":"Retrieves Instantly V2 leads with search, campaign, list, and pagination filters."},{"name":"Get Lead","description":"Retrieves an Instantly V2 lead by ID."},{"name":"Create Lead","description":"Creates an Instantly V2 lead in a campaign or lead list."},{"name":"Patch Lead","description":"Updates fields on an existing Instantly V2 lead."},{"name":"Delete Leads","description":"Deletes Instantly V2 leads in bulk from a campaign or lead list."},{"name":"Update Lead Interest Status","description":"Submits an Instantly V2 background job to update a lead interest status."},{"name":"List Campaigns","description":"Retrieves Instantly V2 campaigns with search, status, tag, and pagination filters."},{"name":"Create Campaign","description":"Creates an Instantly V2 campaign using the documented campaign schedule schema."},{"name":"Patch Campaign","description":"Updates documented Instantly V2 campaign fields."},{"name":"Activate Campaign","description":"Activates, starts, or resumes an Instantly V2 campaign."},{"name":"Pause Campaign","description":"Pauses a running Instantly V2 campaign, stopping further email sends."},{"name":"Delete Campaign","description":"Permanently deletes an Instantly V2 campaign."},{"name":"List Emails","description":"Retrieves Instantly V2 Unibox emails with search and pagination filters."},{"name":"Reply To Email","description":"Sends an Instantly V2 reply to an existing Unibox email."},{"name":"List Lead Lists","description":"Retrieves Instantly V2 lead lists with search and pagination filters."},{"name":"Create Lead List","description":"Creates an Instantly V2 lead list."}],"triggers":[{"id":"instantly_webhook","name":"Instantly Webhook","description":"Trigger workflow on any Instantly webhook event"},{"id":"instantly_email_sent","name":"Instantly Email Sent","description":"Trigger when Instantly sends an email"},{"id":"instantly_email_opened","name":"Instantly Email Opened","description":"Trigger when a lead opens an Instantly email"},{"id":"instantly_reply_received","name":"Instantly Reply Received","description":"Trigger when a lead replies to an Instantly email"},{"id":"instantly_auto_reply_received","name":"Instantly Auto Reply Received","description":"Trigger when Instantly receives an auto-reply from a lead"},{"id":"instantly_link_clicked","name":"Instantly Link Clicked","description":"Trigger when a lead clicks a tracked Instantly link"},{"id":"instantly_email_bounced","name":"Instantly Email Bounced","description":"Trigger when an Instantly email bounces"},{"id":"instantly_lead_unsubscribed","name":"Instantly Lead Unsubscribed","description":"Trigger when an Instantly lead unsubscribes"},{"id":"instantly_account_error","name":"Instantly Account Error","description":"Trigger when Instantly reports an account-level error"},{"id":"instantly_campaign_completed","name":"Instantly Campaign Completed","description":"Trigger when an Instantly campaign completes"},{"id":"instantly_lead_neutral","name":"Instantly Lead Neutral","description":"Trigger when an Instantly lead is marked neutral"},{"id":"instantly_lead_interested","name":"Instantly Lead Interested","description":"Trigger when an Instantly lead is marked interested"},{"id":"instantly_lead_not_interested","name":"Instantly Lead Not Interested","description":"Trigger when an Instantly lead is marked not interested"},{"id":"instantly_lead_meeting_booked","name":"Instantly Lead Meeting Booked","description":"Trigger when an Instantly lead books a meeting"},{"id":"instantly_lead_meeting_completed","name":"Instantly Lead Meeting Completed","description":"Trigger when an Instantly lead completes a meeting"},{"id":"instantly_lead_closed","name":"Instantly Lead Closed","description":"Trigger when an Instantly lead is marked closed"},{"id":"instantly_lead_out_of_office","name":"Instantly Lead Out Of Office","description":"Trigger when an Instantly lead is out of office"},{"id":"instantly_lead_wrong_person","name":"Instantly Lead Wrong Person","description":"Trigger when an Instantly lead is marked wrong person"},{"id":"instantly_lead_no_show","name":"Instantly Lead No Show","description":"Trigger when an Instantly lead is marked no show"},{"id":"instantly_supersearch_enrichment_completed","name":"Instantly Supersearch Enrichment Completed","description":"Trigger when Instantly completes a Supersearch enrichment"}],"skills":[{"name":"add-leads-to-campaign","description":"Push a batch of prospects into an Instantly campaign as new leads with personalization fields.","content":"# Add Leads to a Campaign\\n\\nLoad a set of prospects into an Instantly cold-email campaign so they enter the sending sequence.\\n\\n## Steps\\n1. List campaigns and identify the target campaign by name.\\n2. For each prospect, create a lead with email, first name, last name, company, and any custom personalization variables.\\n3. Attach each lead to the chosen campaign.\\n\\n## Output\\nReturn how many leads were added, the campaign name, and any rows skipped for missing or invalid emails."},{"name":"launch-outreach-campaign","description":"Create a cold-email campaign, load a lead list, and activate it for sending.","content":"# Launch an Outreach Campaign\\n\\nStand up a new Instantly campaign end to end and start sending.\\n\\n## Steps\\n1. Create a lead list and add the target prospects to it.\\n2. Create the campaign with its sending sequence and schedule.\\n3. Add the leads to the campaign.\\n4. Activate the campaign so sending begins.\\n\\n## Output\\nReturn the campaign name, lead count, and activation status. Confirm the campaign is live."},{"name":"triage-campaign-replies","description":"Review recent campaign email replies and update each lead interest status.","content":"# Triage Campaign Replies\\n\\nProcess inbound replies on a campaign and route each lead by interest.\\n\\n## Steps\\n1. List recent emails for the campaign and identify replies from leads.\\n2. Read each reply and classify intent (interested, not interested, out of office, wrong person).\\n3. Update the matching lead interest status to reflect the classification.\\n4. For interested leads, draft a reply to the email.\\n\\n## Output\\nReturn a summary of replies by category, the leads marked interested, and any drafted responses for review."},{"name":"campaign-performance-snapshot","description":"Summarize active campaigns and their leads into a quick outreach performance snapshot.","content":"# Campaign Performance Snapshot\\n\\nGive a quick read on how outreach is going across campaigns.\\n\\n## Steps\\n1. List campaigns and note which are active.\\n2. For each active campaign, list leads and tally counts by interest status.\\n3. Pull recent emails to gauge reply volume.\\n\\n## Output\\nReturn a per-campaign snapshot: total leads, breakdown by interest status, and reply activity, highlighting the top-performing campaign."},{"name":"clean-up-lead-data","description":"Correct or enrich existing lead records so personalization and CRM sync stay accurate.","content":"# Clean Up Lead Data\\n\\nKeep lead records accurate after enrichment, verification, or manual review.\\n\\n## Steps\\n1. Look up the lead by ID or email.\\n2. Compare the current fields against the corrected or enriched data.\\n3. Patch the lead with the updated first name, last name, company, job title, phone, website, or custom variables.\\n\\n## Output\\nReturn the updated lead record and a summary of which fields changed."},{"name":"pause-underperforming-campaigns","description":"Detect campaigns with poor reply or interest rates and pause them to protect sender reputation.","content":"# Pause Underperforming Campaigns\\n\\nProtect domain and inbox reputation by pausing cold-email campaigns that are not converting.\\n\\n## Steps\\n1. List active campaigns.\\n2. For each campaign, list its leads and tally reply and interest counts.\\n3. Flag campaigns below a reply-rate threshold.\\n4. Pause each flagged campaign so no further emails are sent.\\n\\n## Output\\nReturn which campaigns were paused, their reply rates, and the campaigns left active for comparison."}],"templates":[{"title":"Instantly lead loader","prompt":"Build a workflow that reads new prospects from a table and creates each as a lead in the right Instantly campaign, then writes the Instantly lead ID back so the sender table stays in sync.","integrations":[{"id":"instantly","name":"Instantly"}]},{"title":"Instantly reply triager","prompt":"Create a workflow triggered when an Instantly reply is received that classifies intent, updates the lead interest status, and posts a Slack alert for positive replies so reps follow up fast.","integrations":[{"id":"instantly","name":"Instantly"},{"id":"slack","name":"Slack"}]},{"title":"Instantly campaign launcher","prompt":"Build a workflow that creates a new Instantly campaign from a brief, builds a lead list, loads the prospects, and activates the campaign once the list is ready.","integrations":[{"id":"instantly","name":"Instantly"}]},{"title":"Instantly performance report","prompt":"Create a scheduled weekly workflow that lists Instantly campaigns and emails, computes reply and interest rates per campaign, logs them to a table for trend tracking, and Slacks a summary to the sales team.","integrations":[{"id":"instantly","name":"Instantly"},{"id":"slack","name":"Slack"}]},{"title":"Instantly meeting-booked sync","prompt":"Build a workflow triggered when an Instantly lead is marked meeting booked that creates or updates the matching HubSpot contact and deal so the CRM reflects pipeline from outbound.","integrations":[{"id":"instantly","name":"Instantly"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Hunter + Instantly outbound","prompt":"Create a workflow that finds verified prospect emails with Hunter, validates each, and loads the deliverable contacts into an active Instantly campaign.","integrations":[{"id":"instantly","name":"Instantly"},{"id":"hunter","name":"Hunter.io"}]},{"title":"Instantly reply router","prompt":"Build a scheduled workflow that lists new Instantly campaign email replies, classifies each as interested, objection, or out-of-office with an agent, updates the lead\'s interest status, and posts hot replies to the sales Slack channel for a fast follow-up.","integrations":[{"id":"instantly","name":"Instantly"},{"id":"slack","name":"Slack"}]}]},{"id":"intercom","type":"intercom_v2","slug":"intercom","name":"Intercom","description":"Manage contacts, companies, conversations, tickets, and messages in Intercom","category":"Support","docsUrl":"https://docs.sim.ai/integrations/intercom","authType":"api-key","connections":[],"operations":[{"name":"Create Contact","description":"Create a new contact in Intercom with email, external_id, or role"},{"name":"Get Contact","description":"Get a single contact by ID from Intercom"},{"name":"Update Contact","description":"Update an existing contact in Intercom"},{"name":"List Contacts","description":"List all contacts from Intercom with pagination support"},{"name":"Search Contacts","description":"Search for contacts in Intercom using a query"},{"name":"Delete Contact","description":"Delete a contact from Intercom by ID"},{"name":"Create Company","description":"Create or update a company in Intercom"},{"name":"Get Company","description":"Retrieve a single company by ID from Intercom"},{"name":"List Companies","description":"List all companies from Intercom with pagination support. Note: This endpoint has a limit of 10,000 companies that can be returned using pagination. For datasets larger than 10,000 companies, use the Scroll API instead."},{"name":"Get Conversation","description":"Retrieve a single conversation by ID from Intercom"},{"name":"List Conversations","description":"List all conversations from Intercom with pagination support"},{"name":"Reply to Conversation","description":"Reply to a conversation as an admin in Intercom"},{"name":"Search Conversations","description":"Search for conversations in Intercom using a query"},{"name":"Create Ticket","description":"Create a new ticket in Intercom"},{"name":"Get Ticket","description":"Retrieve a single ticket by ID from Intercom"},{"name":"Update Ticket","description":"Update a ticket in Intercom (change state, assignment, attributes)"},{"name":"Create Message","description":"Create and send a new admin-initiated message in Intercom"},{"name":"List Admins","description":"Fetch a list of all admins for the workspace"},{"name":"Close Conversation","description":"Close a conversation in Intercom"},{"name":"Open Conversation","description":"Open a closed or snoozed conversation in Intercom"},{"name":"Snooze Conversation","description":"Snooze a conversation to reopen at a future time"},{"name":"Assign Conversation","description":"Assign a conversation to an admin or team in Intercom"},{"name":"List Tags","description":"Fetch a list of all tags in the workspace"},{"name":"Create Tag","description":"Create a new tag or update an existing tag name"},{"name":"Tag Contact","description":"Add a tag to a specific contact"},{"name":"Untag Contact","description":"Remove a tag from a specific contact"},{"name":"Tag Conversation","description":"Add a tag to a specific conversation"},{"name":"Create Note","description":"Add a note to a specific contact"},{"name":"Create Event","description":"Track a custom event for a contact in Intercom"},{"name":"Attach Contact to Company","description":"Attach a contact to a company in Intercom"},{"name":"Detach Contact from Company","description":"Remove a contact from a company in Intercom"}],"triggers":[{"id":"intercom_conversation_created","name":"Intercom Conversation Created","description":"Trigger workflow when a new conversation is created in Intercom"},{"id":"intercom_conversation_reply","name":"Intercom Conversation Reply","description":"Trigger workflow when someone replies to an Intercom conversation"},{"id":"intercom_conversation_closed","name":"Intercom Conversation Closed","description":"Trigger workflow when a conversation is closed in Intercom"},{"id":"intercom_contact_created","name":"Intercom Contact Created","description":"Trigger workflow when a new lead is created in Intercom"},{"id":"intercom_user_created","name":"Intercom User Created","description":"Trigger workflow when a new user is created in Intercom"},{"id":"intercom_webhook","name":"Intercom Webhook (All Events)","description":"Trigger workflow on any Intercom webhook event"}],"skills":[{"name":"triage-open-conversations","description":"Review open Intercom conversations and assign each to the right teammate with a priority.","content":"# Triage Open Conversations\\n\\nKeep the inbox moving by routing open Intercom conversations to the right people.\\n\\n## Steps\\n1. List or search open conversations.\\n2. Read each conversation to understand the customer issue and urgency.\\n3. List admins to find the right owner, then assign the conversation.\\n4. Tag the conversation by topic (billing, bug, onboarding) and add an internal note summarizing next steps.\\n\\n## Output\\nReturn each conversation with its assigned owner, applied tags, and a one-line summary. Flag anything that looks urgent."},{"name":"reply-and-resolve","description":"Draft a reply to a customer conversation, send it, and close the conversation when resolved.","content":"# Reply and Resolve\\n\\nRespond to a customer in Intercom and wrap up the conversation.\\n\\n## Steps\\n1. Get the conversation and read the full thread for context.\\n2. Draft a helpful, on-brand reply that addresses the customer question.\\n3. Reply to the conversation with the message.\\n4. If the issue is fully handled, close the conversation; otherwise snooze it until a follow-up time.\\n\\n## Output\\nReturn the reply that was sent and the final conversation state (closed or snoozed)."},{"name":"enrich-contact-record","description":"Create or update an Intercom contact and link it to its company with current details.","content":"# Enrich a Contact Record\\n\\nKeep contact data accurate by creating or updating an Intercom contact.\\n\\n## Steps\\n1. Search contacts by email to see if the person already exists.\\n2. Create the contact if missing, or update the existing record with name, role, and attributes.\\n3. Find or create the company and attach the contact to it.\\n4. Tag the contact to reflect segment or lifecycle stage.\\n\\n## Output\\nReturn the contact ID, the linked company, and the fields that were created or changed."},{"name":"open-support-ticket","description":"Create an Intercom ticket from a conversation and capture the key issue details.","content":"# Open a Support Ticket\\n\\nEscalate a customer issue into a tracked Intercom ticket.\\n\\n## Steps\\n1. Get the source conversation and summarize the issue, impact, and steps to reproduce.\\n2. Create a ticket with a clear title, the summary, and the linked contact.\\n3. Add a note to the conversation referencing the new ticket so context is preserved.\\n\\n## Output\\nReturn the ticket ID, title, linked contact, and the conversation it came from."}],"templates":[{"title":"Google Translate Intercom replier","prompt":"Build a workflow that detects the language of a new Intercom message, translates it to the agent language with Google Translate, drafts a reply, then translates the reply back before sending.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Intercom feedback analyzer","prompt":"Build a scheduled workflow that pulls support tickets and conversations from Intercom daily, categorizes them by theme and sentiment, tracks trends in a table, and sends a weekly Slack report highlighting the top feature requests and pain points.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"slack","name":"Slack"}]},{"title":"Intercom auto-resolver","prompt":"Create a knowledge base from my help center and product docs, then build a workflow that watches new Intercom conversations, attempts an answer with cited sources, and only assigns to a human admin when confidence is low or the customer asks.","integrations":[{"id":"intercom","name":"Intercom"}]},{"title":"Intercom to Linear bug ticketer","prompt":"Build a workflow triggered by new Intercom conversations that classifies whether the message is a bug report, extracts the repro steps and affected area, creates a Linear issue with the conversation transcript attached, and replies in Intercom with the issue ID.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"linear","name":"Linear"}]},{"title":"Intercom VIP escalation","prompt":"Create a workflow that monitors new Intercom conversations, looks up the contact in the CRM, and when the contact belongs to a top-tier account, snoozes the conversation, posts a Slack alert in #vip-support with full context, and tags the conversation as VIP.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"slack","name":"Slack"}]},{"title":"Intercom conversation summarizer","prompt":"Build a workflow triggered when an Intercom conversation is closed that summarizes the issue, resolution, and any follow-up actions, then appends the summary to a Notion knowledge log so the team can learn from past conversations.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"notion","name":"Notion"}]},{"title":"Intercom contact enrichment","prompt":"Create a workflow triggered when a new Intercom contact is created that enriches the contact with company, title, and seniority data from Apollo, updates the Intercom contact attributes, and adds a note with the enrichment source.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"apollo","name":"Apollo"}]},{"title":"Intercom-Zendesk migration mirror","prompt":"Build a workflow that mirrors new Intercom conversations into Zendesk as tickets during a migration window, syncs status and replies in both directions, and writes a table of every mapped conversation-to-ticket pair for audit.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Telegram support bot","prompt":"Build a Telegram bot that answers product questions using a knowledge base with citations, escalates to a human via Intercom when it cannot answer, and logs every conversation to a table.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"telegram","name":"Telegram"}]},{"title":"Zep + Intercom support continuity","prompt":"Create a Zep-backed support agent for Intercom that remembers what each customer has tried before, prefers, or escalated, so support conversations never restart from scratch.","integrations":[{"id":"intercom","name":"Intercom"},{"id":"zep","name":"Zep"}]}]},{"id":"jina","type":"jina","slug":"jina","name":"Jina","description":"Search the web or extract content from URLs","category":"Search","docsUrl":"https://docs.sim.ai/integrations/jina","authType":"api-key","connections":[],"operations":[{"name":"Read URL","description":"Extract and process web content into clean, LLM-friendly text using Jina AI Reader. Supports advanced content parsing, link gathering, and multiple output formats with configurable processing options."},{"name":"Search","description":"Search the web and return top 5 results with LLM-friendly content. Each result is automatically processed through Jina Reader API. Supports geographic filtering, site restrictions, and pagination."}],"triggers":[],"skills":[{"name":"extract-article-content","description":"Read a URL and return clean, LLM-ready text stripped of navigation and ads.","content":"# Extract Article Content\\n\\nTurn a messy web page into clean, readable text an agent can reason over.\\n\\n## Steps\\n1. Take the target URL.\\n2. Read the URL to get the parsed main content as markdown or text.\\n3. Strip boilerplate (nav, footers, ads) if any remains and keep the core article body.\\n\\n## Output\\nReturn the page title and the cleaned content, plus the source URL. Note if the page could not be fully extracted."},{"name":"research-topic-from-web","description":"Search the web for a topic and summarize the top results into a briefing.","content":"# Research a Topic From the Web\\n\\nGather and condense current web information on a topic.\\n\\n## Steps\\n1. Run a web search for the topic with a focused query.\\n2. Take the top results and read the most relevant URLs for full content.\\n3. Synthesize the findings, noting points of agreement and disagreement across sources.\\n\\n## Output\\nReturn a short briefing with key findings, each backed by the source URL it came from."},{"name":"summarize-url","description":"Fetch a single URL and produce a concise summary with the main takeaways.","content":"# Summarize a URL\\n\\nGive a quick, faithful summary of a single web page.\\n\\n## Steps\\n1. Read the URL to extract its main content.\\n2. Identify the core thesis and the most important supporting points.\\n3. Condense into a short summary without adding outside information.\\n\\n## Output\\nReturn the page title, a 3-5 bullet summary of the key takeaways, and the source URL."}],"templates":[{"title":"Jina URL-to-knowledge ingester","prompt":"Build a workflow that reads a list of source URLs with Jina Reader, converts each into clean text, and ingests the content into a research knowledge base for retrieval.","integrations":[{"id":"jina","name":"Jina"}]},{"title":"Jina web-research digest","prompt":"Create a scheduled workflow that runs Jina web search on tracked topics, reads the top results with Jina Reader, and writes a summarized digest to a research table.","integrations":[{"id":"jina","name":"Jina"}]},{"title":"Jina web-content reader","prompt":"Build a workflow that uses Jina Reader to convert any URL into clean text, summarizes with an agent, and stores the result in a research knowledge base.","integrations":[{"id":"jina","name":"Jina"}]},{"title":"Jina competitor watch","prompt":"Create a scheduled workflow that reads competitor pricing and changelog pages with Jina Reader, diffs against the last snapshot, and posts notable changes to Slack.","integrations":[{"id":"jina","name":"Jina"},{"id":"slack","name":"Slack"}]},{"title":"Jina answer enrichment","prompt":"Build a workflow that takes a user question, runs a Jina web search for current sources, reads the top pages with Jina Reader, and has an agent answer with citations.","integrations":[{"id":"jina","name":"Jina"}]},{"title":"Jina Slack research bot","prompt":"Create a Slack bot that runs Jina web search on the asked question, reads the most relevant results with Jina Reader, and replies with a summarized answer and source links.","integrations":[{"id":"jina","name":"Jina"},{"id":"slack","name":"Slack"}]},{"title":"Jina docs-to-Notion clipper","prompt":"Build a workflow that reads a submitted URL with Jina Reader, summarizes the content with an agent, and appends a clean clipped entry to a Notion research database.","integrations":[{"id":"jina","name":"Jina"},{"id":"notion","name":"Notion"}]}]},{"id":"jira","type":"jira","slug":"jira","name":"Jira","description":"Manage Jira issues, comments, attachments, and worklogs","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/jira","authType":"oauth","connections":[{"id":"jira","kind":"oauth","label":"Connect with OAuth","providerId":"jira","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/jira","requiredScopes":[{"id":"read:jira-user","label":"View Jira user profiles, including email addresses"},{"id":"read:jira-work","label":"View Jira projects and issues, and search issues"},{"id":"write:jira-work","label":"Create, edit, and delete Jira issues, comments, and worklogs"},{"id":"read:me","label":"Read profile information"},{"id":"offline_access","label":"Access account when not using the application"},{"id":"read:issue.vote:jira","label":"Read Jira issue votes"},{"id":"read:user:jira","label":"View Jira users"},{"id":"delete:issue:jira","label":"Delete Jira issues"},{"id":"delete:comment:jira","label":"Delete comments from Jira issues"},{"id":"delete:attachment:jira","label":"Delete attachments from Jira issues"},{"id":"delete:issue-worklog:jira","label":"Delete worklog entries from Jira issues"},{"id":"delete:issue-link:jira","label":"Delete links between Jira issues"},{"id":"read:servicedesk-request","label":"View service desk requests"},{"id":"write:servicedesk-request","label":"Create and update service desk requests"},{"id":"manage:servicedesk-customer","label":"Manage service desk customers and organizations"},{"id":"read:servicedesk:jira-service-management","label":"View service desks and their settings"},{"id":"read:requesttype:jira-service-management","label":"View request types available in service desks"},{"id":"read:request:jira-service-management","label":"View customer requests in service desks"},{"id":"write:request:jira-service-management","label":"Create customer requests in service desks"},{"id":"read:request.comment:jira-service-management","label":"View comments on customer requests"},{"id":"write:request.comment:jira-service-management","label":"Add comments to customer requests"},{"id":"read:servicedesk.customer:jira-service-management","label":"View customers linked to service desks"},{"id":"write:servicedesk.customer:jira-service-management","label":"Add and remove customers from service desks"},{"id":"read:organization:jira-service-management","label":"View organizations"},{"id":"write:organization:jira-service-management","label":"Create and manage organizations"},{"id":"read:servicedesk.organization:jira-service-management","label":"View organizations linked to service desks"},{"id":"write:servicedesk.organization:jira-service-management","label":"Add and remove organizations from service desks"},{"id":"read:queue:jira-service-management","label":"View service desk queues and their issues"},{"id":"read:request.sla:jira-service-management","label":"View SLA information for customer requests"},{"id":"read:request.status:jira-service-management","label":"View status of customer requests"},{"id":"write:request.status:jira-service-management","label":"Transition customer request status"},{"id":"read:request.participant:jira-service-management","label":"View participants on customer requests"},{"id":"write:request.participant:jira-service-management","label":"Add and remove participants from customer requests"},{"id":"read:request.approval:jira-service-management","label":"View approvals on customer requests"},{"id":"write:request.approval:jira-service-management","label":"Approve or decline customer requests"},{"id":"read:cmdb-object:jira","label":"View Assets objects and run AQL searches"},{"id":"write:cmdb-object:jira","label":"Create and update Assets objects"},{"id":"delete:cmdb-object:jira","label":"Delete Assets objects"},{"id":"read:cmdb-schema:jira","label":"View Assets object schemas"},{"id":"read:cmdb-type:jira","label":"View Assets object types"},{"id":"read:cmdb-attribute:jira","label":"View Assets object type attributes"},{"id":"write:sprint:jira-software","label":"Create and update Jira Software sprints"}],"fields":[]},{"id":"atlassian-service-account","kind":"service_account","providerId":"atlassian-service-account","label":"Add service account","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/atlassian-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste the API token","secret":true},{"id":"domain","label":"Site domain","placeholder":"your-team.atlassian.net"}]}],"operations":[{"name":"Read Issue","description":"Retrieve detailed information about a specific Jira issue"},{"name":"Read Bulk Issues","description":"Retrieve multiple Jira issues from a project in bulk"},{"name":"Update Issue","description":"Update a Jira issue"},{"name":"Write Issue","description":"Create a new Jira issue"},{"name":"Create Sprint","description":"Create a future sprint on a Jira Software board"},{"name":"Delete Issue","description":"Delete a Jira issue"},{"name":"Assign Issue","description":"Assign a Jira issue to a user"},{"name":"Transition Issue","description":"Move a Jira issue between workflow statuses (e.g., To Do -> In Progress)"},{"name":"Search Issues","description":"Search for Jira issues using JQL (Jira Query Language)"},{"name":"Add Comment","description":"Add a comment to a Jira issue"},{"name":"Get Comments","description":"Get all comments from a Jira issue"},{"name":"Update Comment","description":"Update an existing comment on a Jira issue"},{"name":"Delete Comment","description":"Delete a comment from a Jira issue"},{"name":"Get Attachments","description":"Get all attachments from a Jira issue"},{"name":"Add Attachment","description":"Add attachments to a Jira issue"},{"name":"Delete Attachment","description":"Delete an attachment from a Jira issue"},{"name":"Add Worklog","description":"Add a time tracking worklog entry to a Jira issue"},{"name":"Get Worklogs","description":"Get all worklog entries from a Jira issue"},{"name":"Update Worklog","description":"Update an existing worklog entry on a Jira issue"},{"name":"Delete Worklog","description":"Delete a worklog entry from a Jira issue"},{"name":"Create Issue Link","description":"Create a link relationship between two Jira issues"},{"name":"Delete Issue Link","description":"Delete a link between two Jira issues"},{"name":"Add Watcher","description":"Add a watcher to a Jira issue to receive notifications about updates"},{"name":"Remove Watcher","description":"Remove a watcher from a Jira issue"},{"name":"Get Users","description":"Get Jira users. If an account ID is provided, returns a single user. Otherwise, returns a list of all users."},{"name":"Search Users","description":"Search for Jira users by email address or display name. Returns matching users with their accountId, displayName, and emailAddress."},{"name":"List Projects","description":"List Jira projects visible to the user, with optional name/key filtering and pagination. Returns each project with id, key, name, and type."},{"name":"Get Project","description":"Get the details of a single Jira project by its ID or key, including its type, lead, components, issue types, and versions."},{"name":"Get Transitions","description":"Get the workflow transitions available for an issue in its current status. Use the returned transition IDs with the Transition Issue operation."},{"name":"List Issue Types","description":"List all issue types visible to the user across projects (e.g., Task, Bug, Story, Epic, Subtask). Useful for discovering valid issue types before creating an issue."},{"name":"Get Fields","description":"Get all system and custom fields defined in the Jira instance. Useful for discovering custom field IDs (e.g., customfield_10001) to use when writing or updating issues."}],"triggers":[{"id":"jira_issue_created","name":"Jira Issue Created","description":"Trigger workflow when a new issue is created in Jira"},{"id":"jira_issue_updated","name":"Jira Issue Updated","description":"Trigger workflow when an issue is updated in Jira"},{"id":"jira_issue_deleted","name":"Jira Issue Deleted","description":"Trigger workflow when an issue is deleted in Jira"},{"id":"jira_issue_commented","name":"Jira Issue Commented","description":"Trigger workflow when a comment is added to a Jira issue"},{"id":"jira_comment_updated","name":"Jira Comment Updated","description":"Trigger workflow when a comment is updated on a Jira issue"},{"id":"jira_comment_deleted","name":"Jira Comment Deleted","description":"Trigger workflow when a comment is deleted from a Jira issue"},{"id":"jira_worklog_created","name":"Jira Worklog Created","description":"Trigger workflow when time is logged on a Jira issue"},{"id":"jira_worklog_updated","name":"Jira Worklog Updated","description":"Trigger workflow when a worklog entry is updated on a Jira issue"},{"id":"jira_worklog_deleted","name":"Jira Worklog Deleted","description":"Trigger workflow when a worklog entry is deleted from a Jira issue"},{"id":"jira_sprint_created","name":"Jira Sprint Created","description":"Trigger workflow when a sprint is created in Jira"},{"id":"jira_sprint_started","name":"Jira Sprint Started","description":"Trigger workflow when a sprint is started in Jira"},{"id":"jira_sprint_closed","name":"Jira Sprint Closed","description":"Trigger workflow when a sprint is closed in Jira"},{"id":"jira_project_created","name":"Jira Project Created","description":"Trigger workflow when a project is created in Jira"},{"id":"jira_version_released","name":"Jira Version Released","description":"Trigger workflow when a version is released in Jira"},{"id":"jira_webhook","name":"Jira Webhook (All Events)","description":"Trigger workflow on any Jira webhook event"}],"skills":[{"name":"create-bug-from-report","description":"Turn a bug report into a well-structured Jira issue with steps, severity, and labels.","content":"# Create a Bug From a Report\\n\\nConvert a raw bug report into a clean, actionable Jira issue.\\n\\n## Steps\\n1. Parse the report for summary, steps to reproduce, expected vs actual behavior, and environment.\\n2. Create an issue in the target project with type Bug, a clear summary, and a structured description.\\n3. Set priority based on impact and add relevant labels or components.\\n4. Optionally assign it to the right owner.\\n\\n## Output\\nReturn the issue key, URL, priority, and assignee. Confirm the description includes reproduction steps."},{"name":"triage-open-issues","description":"Search open issues with JQL and propose assignees, priorities, and labels.","content":"# Triage Open Issues\\n\\nBring order to a backlog of unassigned or stale issues.\\n\\n## Steps\\n1. Search issues using JQL (e.g. unassigned and recently created in a project).\\n2. Read each issue to understand scope and urgency.\\n3. For each, propose a priority, suggested assignee, and labels; apply updates where confident.\\n4. Add a short triage comment explaining the decision.\\n\\n## Output\\nReturn a table of issues with proposed/applied priority, assignee, and labels, flagging any that need a human decision."},{"name":"transition-and-comment","description":"Move an issue to a new workflow status and post a progress comment.","content":"# Transition and Comment\\n\\nAdvance a Jira issue through its workflow with a clear note.\\n\\n## Steps\\n1. Retrieve the issue and read its current status.\\n2. Get available transitions and choose the correct next status (e.g. In Progress, In Review, Done).\\n3. Transition the issue to that status.\\n4. Add a comment summarizing what changed and any next steps.\\n\\n## Output\\nReturn the issue key, the new status, and the comment that was posted."},{"name":"sprint-status-digest","description":"Summarize issues in a project or sprint grouped by status and assignee.","content":"# Sprint Status Digest\\n\\nProduce a quick read on where work stands.\\n\\n## Steps\\n1. Search issues with JQL scoped to the project or current sprint.\\n2. Group results by status and by assignee.\\n3. Identify blocked issues, overdue items, and anything unassigned.\\n\\n## Output\\nReturn a digest: counts by status, work per assignee, and a callout list of blocked or at-risk issues with their keys."}],"templates":[{"title":"Bitbucket and Jira delivery automation","prompt":"Build a workflow that reads a Bitbucket pull request and its head commit, extracts Jira issue keys from the title, description, source branch, and commit message, summarizes delivery and pipeline status, and adds the update to the matching Jira issue.","integrations":[{"id":"jira","name":"Jira"},{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Security log ingestion monitor","prompt":"Create a scheduled workflow that lists the Fivetran connections feeding security logs from sources like Okta into Databricks, flags any that are paused, broken, or delayed, and opens a Jira ticket for each one so the SIEM pipeline never silently goes stale.","integrations":[{"id":"jira","name":"Jira"},{"id":"fivetran","name":"Fivetran"}]},{"title":"Link GitHub pull requests to Jira tickets","prompt":"Build a workflow that monitors GitHub pull requests and automatically transitions linked Jira issues when PRs are opened or merged, keeping your project board accurate without any manual updates.","integrations":[{"id":"jira","name":"Jira"},{"id":"github","name":"GitHub"}]},{"title":"Jira knowledge search","prompt":"Create a knowledge base connected to my Jira project so all tickets, comments, and resolutions are automatically synced and searchable. Then build an agent I can ask things like \\"how did we fix the auth timeout issue?\\" or \\"what was decided about the API redesign?\\" and get answers with ticket citations.","integrations":[{"id":"jira","name":"Jira"}]},{"title":"Jira sprint report generator","prompt":"Create a scheduled workflow that runs at the end of each sprint, pulls all completed, in-progress, and blocked Jira tickets, calculates velocity and carry-over, and generates a sprint summary document with charts and trends to share with the team.","integrations":[{"id":"jira","name":"Jira"}]},{"title":"Jira backlog grooming digest","prompt":"Build a scheduled weekly workflow that scans Jira backlog for tickets missing estimates, owners, or priorities, generates a grooming queue, and posts the top items to Slack.","integrations":[{"id":"jira","name":"Jira"},{"id":"slack","name":"Slack"}]},{"title":"Jira stale-ticket sweeper","prompt":"Create a scheduled workflow that lists Jira tickets with no activity in 14 days, pings the assignee in Slack with a status prompt, and updates the ticket based on the response.","integrations":[{"id":"jira","name":"Jira"},{"id":"slack","name":"Slack"}]},{"title":"Jira release notes builder","prompt":"Build a workflow that pulls Jira tickets resolved since the last release tag, groups by feature area, and drafts user-facing release notes for marketing review.","integrations":[{"id":"jira","name":"Jira"}]},{"title":"Jira to Linear migrator","prompt":"Create a workflow that imports a Jira project into Linear, preserving status mapping, labels, comments, and assignees, and writes a mapping table for redirect URLs.","integrations":[{"id":"jira","name":"Jira"},{"id":"linear","name":"Linear"}]},{"title":"Auto-generate Confluence pages from Jira sprints","prompt":"Build a workflow that runs at the end of each Jira sprint, pulls all completed and in-progress tickets, and automatically creates a structured Confluence documentation page so sprint reporting requires no manual effort.","integrations":[{"id":"jira","name":"Jira"},{"id":"confluence","name":"Confluence"}]},{"title":"Microsoft Teams daily brief","prompt":"Build a scheduled workflow that pulls updates from your project tools — GitHub commits, Jira ticket status changes, and calendar events — and posts a formatted daily brief to your Microsoft Teams channel each morning.","integrations":[{"id":"jira","name":"Jira"},{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"github","name":"GitHub"}]},{"title":"SailPoint leaver access revocation","prompt":"Create a workflow that, given a departing employee, searches their SailPoint identity access, and submits revoke access requests for each directly-assigned entitlement with a comment referencing the offboarding ticket in Jira.","integrations":[{"id":"jira","name":"Jira"},{"id":"sailpoint","name":"SailPoint"}]},{"title":"Splunk + Jira defect linking","prompt":"Create a scheduled workflow that runs a Splunk search for recurring application exceptions and opens or updates a Jira bug for each distinct stack trace with the event count attached.","integrations":[{"id":"jira","name":"Jira"},{"id":"splunk","name":"Splunk"}]},{"title":"Systems Manager agent health watch","prompt":"Create a scheduled workflow that lists AWS Systems Manager managed nodes, identifies nodes whose agent has lost connection or is running an outdated version, and opens a Jira ticket for each one.","integrations":[{"id":"jira","name":"Jira"},{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Zendesk to Jira engineering bridge","prompt":"Build a scheduled workflow that searches Zendesk for tickets newly tagged as a bug, creates a linked Jira issue with the ticket details and customer impact, and posts the Jira link back as an internal note on the Zendesk ticket.","integrations":[{"id":"jira","name":"Jira"},{"id":"zendesk","name":"Zendesk"}]}]},{"id":"jira_service_management","type":"jira_service_management","slug":"jira-service-management","name":"Jira Service Management","description":"Interact with Jira Service Management","category":"Support","docsUrl":"https://docs.sim.ai/integrations/jira_service_management","authType":"oauth","connections":[{"id":"jira","kind":"oauth","label":"Connect with OAuth","providerId":"jira","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/jira_service_management","requiredScopes":[{"id":"read:jira-user","label":"View Jira user profiles, including email addresses"},{"id":"read:jira-work","label":"View Jira projects and issues, and search issues"},{"id":"write:jira-work","label":"Create, edit, and delete Jira issues, comments, and worklogs"},{"id":"read:me","label":"Read profile information"},{"id":"offline_access","label":"Access account when not using the application"},{"id":"read:issue.vote:jira","label":"Read Jira issue votes"},{"id":"read:user:jira","label":"View Jira users"},{"id":"delete:issue:jira","label":"Delete Jira issues"},{"id":"delete:comment:jira","label":"Delete comments from Jira issues"},{"id":"delete:attachment:jira","label":"Delete attachments from Jira issues"},{"id":"delete:issue-worklog:jira","label":"Delete worklog entries from Jira issues"},{"id":"delete:issue-link:jira","label":"Delete links between Jira issues"},{"id":"read:servicedesk-request","label":"View service desk requests"},{"id":"write:servicedesk-request","label":"Create and update service desk requests"},{"id":"manage:servicedesk-customer","label":"Manage service desk customers and organizations"},{"id":"read:servicedesk:jira-service-management","label":"View service desks and their settings"},{"id":"read:requesttype:jira-service-management","label":"View request types available in service desks"},{"id":"read:request:jira-service-management","label":"View customer requests in service desks"},{"id":"write:request:jira-service-management","label":"Create customer requests in service desks"},{"id":"read:request.comment:jira-service-management","label":"View comments on customer requests"},{"id":"write:request.comment:jira-service-management","label":"Add comments to customer requests"},{"id":"read:servicedesk.customer:jira-service-management","label":"View customers linked to service desks"},{"id":"write:servicedesk.customer:jira-service-management","label":"Add and remove customers from service desks"},{"id":"read:organization:jira-service-management","label":"View organizations"},{"id":"write:organization:jira-service-management","label":"Create and manage organizations"},{"id":"read:servicedesk.organization:jira-service-management","label":"View organizations linked to service desks"},{"id":"write:servicedesk.organization:jira-service-management","label":"Add and remove organizations from service desks"},{"id":"read:queue:jira-service-management","label":"View service desk queues and their issues"},{"id":"read:request.sla:jira-service-management","label":"View SLA information for customer requests"},{"id":"read:request.status:jira-service-management","label":"View status of customer requests"},{"id":"write:request.status:jira-service-management","label":"Transition customer request status"},{"id":"read:request.participant:jira-service-management","label":"View participants on customer requests"},{"id":"write:request.participant:jira-service-management","label":"Add and remove participants from customer requests"},{"id":"read:request.approval:jira-service-management","label":"View approvals on customer requests"},{"id":"write:request.approval:jira-service-management","label":"Approve or decline customer requests"},{"id":"read:cmdb-object:jira","label":"View Assets objects and run AQL searches"},{"id":"write:cmdb-object:jira","label":"Create and update Assets objects"},{"id":"delete:cmdb-object:jira","label":"Delete Assets objects"},{"id":"read:cmdb-schema:jira","label":"View Assets object schemas"},{"id":"read:cmdb-type:jira","label":"View Assets object types"},{"id":"read:cmdb-attribute:jira","label":"View Assets object type attributes"},{"id":"write:sprint:jira-software","label":"Create and update Jira Software sprints"}],"fields":[]},{"id":"atlassian-service-account","kind":"service_account","providerId":"atlassian-service-account","label":"Add service account","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/atlassian-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste the API token","secret":true},{"id":"domain","label":"Site domain","placeholder":"your-team.atlassian.net"}]}],"operations":[{"name":"Get Service Desks","description":"Get all service desks from Jira Service Management"},{"name":"Get Request Types","description":"Get request types for a service desk in Jira Service Management"},{"name":"Create Request","description":"Create a new service request in Jira Service Management"},{"name":"Get Request","description":"Get a single service request from Jira Service Management"},{"name":"Get Requests","description":"Get multiple service requests from Jira Service Management"},{"name":"Add Comment","description":"Add a comment (public or internal) to a service request in Jira Service Management"},{"name":"Get Comments","description":"Get comments for a service request in Jira Service Management"},{"name":"Get Customers","description":"Get customers for a service desk in Jira Service Management"},{"name":"Add Customer","description":"Add customers to a service desk in Jira Service Management"},{"name":"Get Organizations","description":"Get organizations for a service desk in Jira Service Management"},{"name":"Create Organization","description":"Create a new organization in Jira Service Management"},{"name":"Add Organization","description":"Add an organization to a service desk in Jira Service Management"},{"name":"Get Queues","description":"Get queues for a service desk in Jira Service Management"},{"name":"Get SLA","description":"Get SLA information for a service request in Jira Service Management"},{"name":"Get Transitions","description":"Get available transitions for a service request in Jira Service Management"},{"name":"Transition Request","description":"Transition a service request to a new status in Jira Service Management"},{"name":"Get Participants","description":"Get participants for a request in Jira Service Management"},{"name":"Add Participants","description":"Add participants to a request in Jira Service Management"},{"name":"Get Approvals","description":"Get approvals for a request in Jira Service Management"},{"name":"Answer Approval","description":"Approve or decline an approval request in Jira Service Management"},{"name":"Get Request Type Fields","description":"Get the fields required to create a request of a specific type in Jira Service Management"},{"name":"Get Form Templates","description":"List forms (ProForma/JSM Forms) in a Jira project to discover form IDs for request types"},{"name":"Get Form Structure","description":"Get the full structure of a ProForma/JSM form including all questions, field types, choices, layout, and conditions"},{"name":"Get Issue Forms","description":"List forms (ProForma/JSM Forms) attached to a Jira issue with metadata (name, submitted status, lock)"},{"name":"Attach Form","description":"Attach a form template to an existing Jira issue or JSM request"},{"name":"Save Form Answers","description":"Save answers to a form attached to a Jira issue or JSM request"},{"name":"Submit Form","description":"Submit a form on a Jira issue or JSM request, locking it from further edits"},{"name":"Get Form","description":"Get a single form with full design, state, and answers from a Jira issue"},{"name":"Get Form Answers","description":"Get simplified answers from a form attached to a Jira issue or JSM request"},{"name":"Reopen Form","description":"Reopen a submitted form on a Jira issue or JSM request, allowing further edits"},{"name":"Delete Form","description":"Remove a form from a Jira issue or JSM request"},{"name":"Externalise Form","description":"Make a form visible to customers on a Jira issue or JSM request"},{"name":"Internalise Form","description":"Make a form internal only (not visible to customers) on a Jira issue or JSM request"},{"name":"Copy Forms","description":"Copy forms from one Jira issue to another"},{"name":"List Asset Schemas","description":"List Assets (Insight/CMDB) object schemas in Jira Service Management"},{"name":"Get Asset Schema","description":"Get a single Assets (Insight/CMDB) object schema by ID"},{"name":"List Asset Object Types","description":"List object types within an Assets (Insight/CMDB) object schema"},{"name":"Get Asset Object Type Attributes","description":"Get the attribute definitions for an Assets (Insight/CMDB) object type. Use the returned attribute IDs to build create/update payloads or map columns."},{"name":"Search Assets (AQL)","description":"Search Assets (Insight/CMDB) objects using AQL (Assets Query Language), e.g. objectType = \\"Host\\" AND Status = \\"Running\\". Supports pagination."},{"name":"Get Asset Object","description":"Get a single Assets (Insight/CMDB) object by ID, including its attribute values"},{"name":"Create Asset Object","description":"Create an Assets (Insight/CMDB) object of a given object type. Attributes use objectTypeAttributeId values from the object type definition."},{"name":"Update Asset Object","description":"Update an existing Assets (Insight/CMDB) object. Provide the attributes to change using their objectTypeAttributeId values."},{"name":"Delete Asset Object","description":"Delete an Assets (Insight/CMDB) object by ID"}],"triggers":[{"id":"jsm_request_created","name":"JSM Request Created","description":"Trigger workflow when a new service request is created in Jira Service Management"},{"id":"jsm_request_updated","name":"JSM Request Updated","description":"Trigger workflow when a service request is updated in Jira Service Management"},{"id":"jsm_request_commented","name":"JSM Request Commented","description":"Trigger workflow when a comment is added to a Jira Service Management request"},{"id":"jsm_request_resolved","name":"JSM Request Resolved","description":"Trigger workflow when a service request is resolved in Jira Service Management"},{"id":"jsm_webhook","name":"JSM Webhook (All Events)","description":"Trigger workflow on any Jira Service Management webhook event"}],"skills":[{"name":"raise-service-request","description":"Create a customer request on the right service desk with the correct request type.","content":"# Raise a Service Request\\n\\nLog an inbound customer request into the correct Jira Service Management queue.\\n\\n## Steps\\n1. Get service desks and identify the right one for the request.\\n2. Get request types for that service desk and choose the matching type.\\n3. Create the request with a clear summary, description, and any required request-type fields.\\n4. Capture the request key and reporter.\\n\\n## Output\\nReturn the request key, the service desk and request type used, and the reporter. Confirm required fields were filled."},{"name":"respond-and-update-request","description":"Add a public reply to a customer request and move it to the right status.","content":"# Respond and Update a Request\\n\\nReply to a customer on their request and advance it.\\n\\n## Steps\\n1. Get the request and read its history and current status.\\n2. Add a comment with the response (public to the customer).\\n3. Get available transitions and move the request to the appropriate status.\\n\\n## Output\\nReturn the request key, the comment added, and the new status."},{"name":"sla-breach-watch","description":"Scan open requests on a queue and flag ones at risk of breaching SLA.","content":"# SLA Breach Watch\\n\\nSurface requests that are about to miss their SLA so the team can act.\\n\\n## Steps\\n1. Get the service desk and its queues, then get requests in the target queue.\\n2. For each request, get its SLA information and time remaining.\\n3. Flag requests that are breached or close to breaching their target.\\n\\n## Output\\nReturn a prioritized list of at-risk requests with key, summary, SLA metric, and time remaining, worst first."}],"templates":[{"title":"JSM major incident broadcaster","prompt":"Build a workflow triggered when a major-incident request is created in Jira Service Management that pulls the affected service from PagerDuty, identifies the current on-call, posts a structured incident brief to a Slack war-room channel, and adds the responders as JSM request participants.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"},{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"JSM request auto-triage","prompt":"Create a workflow triggered by new Jira Service Management requests that classifies the request type, sets the correct priority based on impact and urgency, transitions it to the right initial status, and adds the assignment-group customer organization as a participant.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"JSM approval router","prompt":"Build a workflow that watches Jira Service Management requests for new approval steps, posts a Slack DM to each approver with request context and quick-action buttons, and answers the approval in JSM based on their response while keeping the request in sync.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"},{"id":"slack","name":"Slack"}]},{"title":"JSM form auto-completer","prompt":"Create a workflow that when a Jira Service Management request is created with an attached ProForma form, pre-fills the answers from the requester profile, attached email, and CMDB lookup, and saves the answers so agents only review rather than retype.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"JSM weekly service desk report","prompt":"Build a scheduled weekly workflow that pulls Jira Service Management request volume by queue, SLA performance, top request types, and bottleneck assignees, and generates a service desk health report file for the operations review.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"JSM-to-ServiceNow bridge","prompt":"Create a workflow that mirrors Jira Service Management incident requests into ServiceNow incident records and vice versa, keeping status, assignment, and comments in sync so teams on either side see the same truth.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"},{"id":"servicenow","name":"ServiceNow"}]},{"title":"JSM self-service deflection bot","prompt":"Create a knowledge base from internal IT docs, then build a Slack agent that answers employee help requests with cited steps and, when it can\'t resolve the issue, creates a Jira Service Management request with the right request type so nothing falls through.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"},{"id":"slack","name":"Slack"}]},{"title":"Outlook to JSM ticket router","prompt":"Build a workflow that reads support requests arriving in a shared Outlook mailbox, classifies the request type, and creates a Jira Service Management request in the correct service desk with the right request type, then replies from Outlook with the JSM portal link.","integrations":[{"id":"jira_service_management","name":"Jira Service Management"},{"id":"outlook","name":"Outlook"}]}]},{"id":"jotform","type":"jotform","slug":"jotform","name":"Jotform","description":"Read submissions, manage forms, and wire up webhooks in Jotform","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/jotform","authType":"api-key","connections":[],"operations":[{"name":"List Forms","description":"List the forms on a Jotform account with their titles, status, and submission counts."},{"name":"Get Form","description":"Get the details of a single Jotform form, including its status, URL, and submission counts."},{"name":"Create Form","description":"Create a new Jotform form from a list of questions, plus optional form properties and notification emails."},{"name":"Clone Form","description":"Clone an existing Jotform form and return the copy."},{"name":"Delete Form","description":"Delete a Jotform form. The API returns the form with status DELETED."},{"name":"Get Form Properties","description":"Get the settings of a form: layout, limits, redirect behavior, notification emails, and validation strings. Supply a property key to read just one."},{"name":"Update Form Properties","description":"Update form settings such as the thank-you redirect, submission limit, width, or styles. Only the supplied keys change."},{"name":"List Form Files","description":"List every file uploaded through a form, with its download URL, size, type, and the submission it came from."},{"name":"List Questions","description":"List every question on a form with its question ID, label, and field type. Question IDs are what submissions are keyed by."},{"name":"Get Question","description":"Get every property of a single form question, including its validation rules and field-specific settings."},{"name":"Create Question","description":"Add a question to an existing Jotform form."},{"name":"Create Questions","description":"Add several questions to an existing Jotform form in one call."},{"name":"Update Question","description":"Edit the properties of a form question, such as its label, order, or validation. Only the supplied properties change."},{"name":"Delete Question","description":"Delete a question from a Jotform form."},{"name":"List Form Submissions","description":"List the submissions received by one form, with each answer available both by question ID and by question label."},{"name":"List Submissions","description":"List submissions across every form on the account, optionally narrowed to specific forms or a date range."},{"name":"Get Submission","description":"Get a single Jotform submission, with its answers available both by question ID and by question label."},{"name":"Create Submission","description":"Submit an entry to a Jotform form. Answers are keyed by question ID, which the List Questions operation returns."},{"name":"Create Submissions","description":"Submit several entries to a Jotform form in one call. Each entry is keyed by question ID."},{"name":"Update Submission","description":"Edit an existing Jotform submission. Only the question IDs supplied are changed; the rest keep their stored answers."},{"name":"Delete Submission","description":"Delete a single Jotform submission."},{"name":"List Reports","description":"List every report on the account, across all forms, with the shareable URL for each Excel, CSV, grid, table, calendar, RSS, or visual report."},{"name":"List Form Reports","description":"List the reports built from one form, each with its shareable URL."},{"name":"Create Report","description":"Create a shareable report of a form, choosing the report type and which submission fields it shows."},{"name":"Get Report","description":"Get the details and shareable URL of a single Jotform report."},{"name":"Delete Report","description":"Delete an existing Jotform report."},{"name":"List Webhooks","description":"List the webhooks registered on a form. The returned IDs are what the Delete Webhook operation takes."},{"name":"Create Webhook","description":"Register a webhook on a form so every new submission is posted to the given URL. Returns the full webhook list for the form."},{"name":"Delete Webhook","description":"Remove a webhook from a form. Returns the webhooks that remain registered on the form."},{"name":"List Labels","description":"List the labels on the account as a tree. Labels are how Jotform groups forms, workflows, sheets, and apps, replacing the older folder endpoints."},{"name":"Get Label","description":"Get the name, color, and owner of a single Jotform label."},{"name":"Create Label","description":"Create a Jotform label for grouping forms and other assets, optionally nested under a parent label."},{"name":"Update Label","description":"Rename a Jotform label or change its color."},{"name":"Delete Label","description":"Delete a Jotform label along with all of its sublabels."},{"name":"List Label Resources","description":"List the assets assigned to a label — forms, workflows, sheets, and apps — with their status and titles."},{"name":"Add Label Resources","description":"Assign forms, workflows, sheets, or apps to a Jotform label."},{"name":"Remove Label Resources","description":"Unassign forms, workflows, sheets, or apps from a Jotform label."},{"name":"List Sub-Users","description":"List the sub-users on the account with the forms and folders each one can reach, and at what access level."},{"name":"Get Settings","description":"Read the account settings behind the API key, including time zone, language, and contact details."},{"name":"Update Settings","description":"Update account settings such as name, email, website, company, industry, or time zone. Only the supplied fields change."},{"name":"Get Account","description":"Get the Jotform account behind the API key, including its plan, status, time zone, and contact details."},{"name":"Get Usage","description":"Get this month usage for the account: submissions received, payments, form views, upload space, and API calls made today."},{"name":"Get History","description":"Read the account activity log: forms created, updated, deleted or purged, and account logins."}],"triggers":[{"id":"jotform_webhook","name":"Jotform Webhook","description":"Trigger workflow when a Jotform form receives a new submission"}],"skills":[{"name":"organize-forms-with-labels","description":"Group Jotform forms and other assets under labels, creating the label first when it does not exist.","content":"# Organize Forms With Labels\\n\\nLabels are how Jotform groups assets. They replace the deprecated folder endpoints.\\n\\n## Steps\\n1. List the labels to see what already exists. The response is a tree: a root entry whose sublabels hold the user-visible labels.\\n2. Create the label if it is missing, optionally nesting it under a parent and giving it a hex color.\\n3. Add the assets, each identified by an id and a type of form, workflow, sheet, or portal.\\n4. List the label resources to confirm what it now holds.\\n\\n## Output\\nThe label id, its name and color, and the assets assigned to it. Note anything that was already labeled."},{"name":"bulk-import-responses","description":"Load many rows into a Jotform form as submissions in one call, after mapping columns to question IDs.","content":"# Bulk Import Responses\\n\\nMove a batch of existing records into a Jotform form.\\n\\n## Steps\\n1. List the questions on the target form to map each source column to a question ID.\\n2. Build one entry per record, keyed by question ID, e.g. `[{\\"1\\": {\\"text\\": \\"Answer 1\\"}}]`.\\n3. Create the submissions in bulk. Send them in batches rather than one enormous request, and remember each call counts against the daily API limit.\\n4. Keep the returned submission IDs so the import can be reconciled.\\n\\n## Output\\nThe count created and their submission IDs, plus any source rows that had no matching question."},{"name":"read-form-responses","description":"Pull Jotform submissions for a form and report the answers by question label instead of question ID.","content":"# Read Form Responses\\n\\nTurn raw Jotform submissions into readable answers.\\n\\n## Steps\\n1. Identify the form. List forms if only the title is known.\\n2. List the submissions for that form. Set a limit, and use a filter such as `{\\"created_at:gt\\": \\"YYYY-MM-DD HH:MM:SS\\"}` or `{\\"new\\": \\"1\\"}` to narrow the window.\\n3. Read each submission from `values`, which is keyed by question label. Fall back to `answers` when a question has sub-fields worth reading individually.\\n\\n## Output\\nThe matched submissions with their labeled answers, the time range covered, and the total count."},{"name":"submit-to-form","description":"Submit an entry to a Jotform form, resolving question IDs from the form definition first.","content":"# Submit To Form\\n\\nCreate a Jotform submission through the API.\\n\\n## Steps\\n1. List the questions on the target form to get each question ID and field type.\\n2. Build the answers object keyed by question ID. Multi-field types such as `control_fullname` and `control_address` take an object of their sub-fields.\\n3. Create the submission and keep the returned submission ID.\\n\\n## Output\\nThe new submission ID, plus which questions were filled and which were left empty."},{"name":"set-up-submission-webhook","description":"Register a Jotform webhook so new submissions are pushed to a URL, and confirm what is already registered.","content":"# Set Up Submission Webhook\\n\\nPush Jotform submissions somewhere the moment they arrive.\\n\\n## Steps\\n1. List the webhooks already on the form so an existing one is not duplicated.\\n2. Add the webhook URL. Jotform returns the full list, including the ID of each entry.\\n3. Note the ID of the new webhook so it can be removed later.\\n\\n## Output\\nThe registered URL, its webhook ID, and every other webhook still on the form."},{"name":"build-a-form","description":"Create a Jotform form from a list of fields, then verify the questions landed as intended.","content":"# Build A Form\\n\\nCreate a form and confirm its structure.\\n\\n## Steps\\n1. Translate each requested field into a question object with a type, label, order, and name. Common types are control_textbox, control_textarea, control_dropdown, control_radio, control_checkbox, control_fileupload, control_fullname, control_email, and control_datetime.\\n2. Create the form, supplying a title in the form properties.\\n3. List the questions on the new form to confirm the order and types.\\n4. Add any missing question individually rather than recreating the form.\\n\\n## Output\\nThe form ID, its public URL, and the final question list with IDs."},{"name":"share-a-report","description":"Create a Jotform report over the chosen submission fields and return its shareable link.","content":"# Share A Report\\n\\nProduce a shareable view of a form responses.\\n\\n## Steps\\n1. List the questions on the form to pick which question IDs belong in the report.\\n2. Build the fields string from `ip`, `dt` for the submission date, and the chosen question IDs, e.g. `ip,dt,3,4`.\\n3. Create the report with a title and a type: excel, csv, grid, table, calendar, rss, or visual.\\n4. Return the report URL.\\n\\n## Output\\nThe report URL, its type, and which fields it exposes. Note whether it is password protected."}],"templates":[{"title":"Jotform submissions to a table","prompt":"Build a scheduled workflow that lists new Jotform submissions for a form every hour, filtering on submissions created since the last run, and appends each one to a table with the answers mapped to their question labels.","integrations":[{"id":"jotform","name":"Jotform"}]},{"title":"Jotform lead routing to Slack","prompt":"Create a workflow that reads unread Jotform submissions for a contact form, has an agent classify each one as a sales lead, support request, or spam, and posts the qualified leads to the sales channel in Slack.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"slack","name":"Slack"}]},{"title":"Jotform applications into a hiring pipeline","prompt":"Build a workflow that pulls Jotform job application submissions, downloads the uploaded resume files from the form, has an agent summarize each candidate against the role requirements, and creates a Notion page per applicant.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"notion","name":"Notion"}]},{"title":"Jotform submission webhook fan-out","prompt":"Create a workflow that registers a Jotform webhook on a form pointing at an API trigger, then processes each incoming submission by writing it to a table and emailing the submitter a confirmation.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"gmail","name":"Gmail"}]},{"title":"Jotform support intake into tickets","prompt":"Build a workflow that reads new Jotform support form submissions, has an agent assign a priority and category from the answers, and opens a matching Linear issue with the submission details in the description.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"linear","name":"Linear"}]},{"title":"Jotform weekly response digest","prompt":"Create a scheduled workflow that runs every Monday, lists the past week of Jotform submissions across every form, has an agent summarize the themes and outliers, and emails the digest to the operations team.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"gmail","name":"Gmail"}]},{"title":"Jotform CRM sync for event signups","prompt":"Build a workflow that reads Jotform event registration submissions, upserts each attendee as a HubSpot contact with the answers mapped onto contact properties, and marks the submission as processed in a table.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Jotform report generation on demand","prompt":"Create a workflow that takes a form ID and a date range, creates a CSV Jotform report scoped to the selected question fields, and posts the shareable report link to the requesting Slack thread.","integrations":[{"id":"jotform","name":"Jotform"},{"id":"slack","name":"Slack"}]}]},{"id":"jupyter","type":"jupyter_v2","slug":"jupyter","name":"Jupyter","description":"Manage files, notebooks, kernels, and sessions on a Jupyter server","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/jupyter","authType":"api-key","connections":[],"operations":[{"name":"List Contents","description":"List files, notebooks, and subdirectories at a path on a Jupyter server"},{"name":"Get Content","description":"Read a file or notebook from a Jupyter server"},{"name":"Create File","description":"Create a file, notebook, or directory on a Jupyter server"},{"name":"Upload File","description":"Upload a file to a Jupyter server"},{"name":"Rename Content","description":"Rename or move a file, notebook, or directory on a Jupyter server"},{"name":"Delete Content","description":"Delete a file, notebook, or directory on a Jupyter server"},{"name":"Copy Content","description":"Duplicate a file or notebook into a directory on a Jupyter server"},{"name":"List Kernels","description":"List running kernels on a Jupyter server"},{"name":"Start Kernel","description":"Start a new kernel on a Jupyter server"},{"name":"Stop Kernel","description":"Shut down a running kernel on a Jupyter server"},{"name":"Restart Kernel","description":"Restart a running kernel on a Jupyter server"},{"name":"Interrupt Kernel","description":"Interrupt a running kernel on a Jupyter server"},{"name":"List Kernel Specs","description":"List available kernel specs (languages/runtimes) on a Jupyter server"},{"name":"List Sessions","description":"List active sessions (notebook-to-kernel bindings) on a Jupyter server"},{"name":"Create Session","description":"Create a session that binds a notebook path to a (new or existing) kernel"},{"name":"Delete Session","description":"Delete a session and shut down its associated kernel on a Jupyter server"}],"triggers":[],"skills":[],"templates":[{"title":"Jupyter notebook creator","prompt":"Build a workflow that generates a Jupyter notebook from a data analysis request and creates it on a self-hosted Jupyter server.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Upload datasets to Jupyter","prompt":"Build a workflow that uploads a file from a Table row to a Jupyter server as a dataset for later analysis.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Jupyter kernel health check","prompt":"Build a scheduled workflow that lists running Jupyter kernels, restarts any kernel stuck in a busy state, and posts a summary to Slack.","integrations":[{"id":"jupyter","name":"Jupyter"},{"id":"slack","name":"Slack"}]},{"title":"Jupyter directory sync report","prompt":"Build a workflow that lists the contents of a Jupyter server directory and writes a summary of files and notebooks to a Table.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Summarize a Jupyter notebook","prompt":"Build a workflow that reads a Jupyter notebook, has an agent summarize its cells, and sends the summary in Chat.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Provision a Jupyter session","prompt":"Build a workflow that creates a Jupyter session bound to a new notebook and a fresh Python kernel whenever a new project request comes in.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Archive Jupyter notebooks","prompt":"Build a scheduled workflow that copies old notebooks on a Jupyter server into an archive directory, then deletes the originals.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Jupyter notebook creator","prompt":"Build a workflow that generates a Jupyter notebook from a data analysis request and creates it on a self-hosted Jupyter server.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Upload datasets to Jupyter","prompt":"Build a workflow that uploads a file from a Table row to a Jupyter server as a dataset for later analysis.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Jupyter kernel health check","prompt":"Build a scheduled workflow that lists running Jupyter kernels, restarts any kernel stuck in a busy state, and posts a summary to Slack.","integrations":[{"id":"jupyter","name":"Jupyter"},{"id":"slack","name":"Slack"}]},{"title":"Jupyter directory sync report","prompt":"Build a workflow that lists the contents of a Jupyter server directory and writes a summary of files and notebooks to a Table.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Summarize a Jupyter notebook","prompt":"Build a workflow that reads a Jupyter notebook, has an agent summarize its cells, and sends the summary in Chat.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Provision a Jupyter session","prompt":"Build a workflow that creates a Jupyter session bound to a new notebook and a fresh Python kernel whenever a new project request comes in.","integrations":[{"id":"jupyter","name":"Jupyter"}]},{"title":"Archive Jupyter notebooks","prompt":"Build a scheduled workflow that copies old notebooks on a Jupyter server into an archive directory, then deletes the originals.","integrations":[{"id":"jupyter","name":"Jupyter"}]}]},{"id":"kalshi","type":"kalshi_v2","slug":"kalshi","name":"Kalshi","description":"Access prediction markets and trade on Kalshi","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/kalshi","authType":"api-key","connections":[],"operations":[{"name":"Get Markets","description":"Retrieve a list of prediction markets from Kalshi with optional filtering"},{"name":"Get Market","description":"Retrieve details of a specific prediction market by ticker"},{"name":"Get Events","description":"Retrieve a list of events from Kalshi with optional filtering"},{"name":"Get Event","description":"Retrieve details of a specific event by ticker"},{"name":"Get Balance","description":"Retrieve your account balance and portfolio value from Kalshi"},{"name":"Get Positions","description":"Retrieve your open positions from Kalshi"},{"name":"Get Orders","description":"Retrieve your orders from Kalshi with optional filtering"},{"name":"Get Order","description":"Retrieve details of a specific order by ID from Kalshi"},{"name":"Get Orderbook","description":"Retrieve the orderbook (yes and no bids) for a specific market"},{"name":"Get Trades","description":"Retrieve recent trades across all markets"},{"name":"Get Candlesticks","description":"Retrieve OHLC candlestick data for a specific market"},{"name":"Get Event Candlesticks","description":"Retrieve OHLC candlestick data aggregated across all markets in an event"},{"name":"Get Fills","description":"Retrieve your portfolio\'s fills/trades from Kalshi"},{"name":"Get Settlements","description":"Retrieve your portfolio settlement history from Kalshi"},{"name":"Get Series by Ticker","description":"Retrieve details of a specific market series by ticker"},{"name":"Get Series List","description":"Retrieve a list of market series from Kalshi with optional filtering"},{"name":"Get Exchange Status","description":"Retrieve the current status of the Kalshi exchange (trading and exchange activity)"},{"name":"Get Exchange Schedule","description":"Retrieve the Kalshi exchange trading schedule and maintenance windows"},{"name":"Get Exchange Announcements","description":"Retrieve exchange-wide announcements from Kalshi"},{"name":"Create Order","description":"Create a new order on a Kalshi prediction market"},{"name":"Cancel Order","description":"Cancel an existing order on Kalshi"},{"name":"Amend Order","description":"Modify the price or quantity of an existing order on Kalshi"}],"triggers":[],"skills":[{"name":"market-odds-snapshot","description":"Pull current prices and odds for a Kalshi event and summarize the implied probabilities.","content":"# Market Odds Snapshot\\n\\nReport the current state of a Kalshi prediction market.\\n\\n## Steps\\n1. Find the event by ticker or search recent events.\\n2. Get the markets under that event and their current yes/no prices.\\n3. Convert prices to implied probabilities and capture volume and open interest.\\n\\n## Output\\nReturn each market with its current yes/no price, implied probability, and recent volume, plus a one-line read on where the market is leaning."},{"name":"track-position-pnl","description":"Report account balance, open positions, and unrealized profit or loss on Kalshi.","content":"# Track Position P&L\\n\\nGive a clear read on the current trading account state.\\n\\n## Steps\\n1. Get the account balance.\\n2. Get current positions and, for each, the market and entry exposure.\\n3. Get current market prices to estimate unrealized P&L per position.\\n\\n## Output\\nReturn balance, each open position with its market and estimated unrealized P&L, and a total exposure figure."},{"name":"place-limit-order","description":"Place a limit order on a Kalshi market after confirming price and balance.","content":"# Place a Limit Order\\n\\nSubmit a limit order on a chosen Kalshi market with guardrails.\\n\\n## Steps\\n1. Get the target market and confirm its current price and orderbook.\\n2. Check the account balance to ensure the order is affordable.\\n3. Create a limit order with the side (yes/no), price, and quantity.\\n4. Confirm the order was accepted and capture its ID.\\n\\n## Output\\nReturn the order ID, market, side, price, quantity, and status. State clearly if the order was rejected or only partially filled."}],"templates":[{"title":"Kalshi event-contract tracker","prompt":"Create a scheduled workflow that polls Kalshi for prices on tracked event contracts, writes the price history to a tables-based portfolio, and posts large-move alerts to Slack.","integrations":[{"id":"kalshi","name":"Kalshi"},{"id":"slack","name":"Slack"}]},{"title":"Kalshi macroeconomic dashboard","prompt":"Build a scheduled workflow that pulls Kalshi probability markets for selected macroeconomic events, writes the implied probabilities to a tables-based dashboard, and emails a weekly summary.","integrations":[{"id":"kalshi","name":"Kalshi"},{"id":"gmail","name":"Gmail"}]},{"title":"Kalshi + Polymarket arbitrage scanner","prompt":"Create a scheduled workflow that fetches comparable contracts on Kalshi and Polymarket, computes implied-probability spreads, writes the top arbitrage candidates to a table, and pings Slack on significant gaps.","integrations":[{"id":"kalshi","name":"Kalshi"},{"id":"polymarket","name":"Polymarket"},{"id":"slack","name":"Slack"}]},{"title":"Kalshi + Profound macro signal","prompt":"Build a scheduled workflow that combines Kalshi event-contract prices with Profound AI signal to forecast macro events and writes a thesis file weekly.","integrations":[{"id":"kalshi","name":"Kalshi"},{"id":"profound","name":"Profound"}]},{"title":"Kalshi position rebalancer","prompt":"Build a workflow that monitors Kalshi position weights against a target allocation, captures drift, and pings Slack with proposed rebalancing trades.","integrations":[{"id":"kalshi","name":"Kalshi"},{"id":"slack","name":"Slack"}]},{"title":"Kalshi earnings event tracker","prompt":"Create a workflow that pulls Kalshi earnings-event contracts, captures implied probabilities the day before each event, and writes a per-ticker table for review.","integrations":[{"id":"kalshi","name":"Kalshi"}]},{"title":"Kalshi election-market dashboard","prompt":"Build a scheduled workflow that pulls Kalshi election market prices, captures movement over time, and writes a per-race tracking table for political analysts.","integrations":[{"id":"kalshi","name":"Kalshi"}]}]},{"id":"ketch","type":"ketch","slug":"ketch","name":"Ketch","description":"Manage privacy consent, subscriptions, and data subject rights","category":"Security","docsUrl":"https://docs.sim.ai/integrations/ketch","authType":"none","connections":[],"operations":[{"name":"Get Consent","description":"Retrieve consent status for a data subject. Returns the current consent preferences for each configured purpose."},{"name":"Set Consent","description":"Update consent preferences for a data subject. Sets the consent status for specified purposes with the appropriate legal basis."},{"name":"Get Subscriptions","description":"Retrieve subscription preferences for a data subject. Returns the current subscription topic and control statuses."},{"name":"Set Subscriptions","description":"Update subscription preferences for a data subject. Sets topic and control statuses for email, SMS, and other contact methods."},{"name":"Invoke Right","description":"Submit a data subject rights request (e.g., access, delete, correct, restrict processing). Initiates a privacy rights workflow in Ketch."}],"triggers":[],"skills":[{"name":"check-user-consent","description":"Look up a user current consent state in Ketch before processing their data.","content":"# Check User Consent\\n\\nConfirm what a user has consented to before a workflow uses their data.\\n\\n## Steps\\n1. Identify the user (by identity key) and the jurisdiction/policy scope.\\n2. Get the user current consent for the relevant purposes (analytics, marketing, etc.).\\n3. Determine which downstream actions are permitted based on the consent state.\\n\\n## Output\\nReturn the consent state per purpose and a clear allow/deny decision for the intended data use. Stop the workflow if required consent is missing."},{"name":"record-consent-update","description":"Set or update a user consent choices in Ketch from a preference change.","content":"# Record a Consent Update\\n\\nPersist a user updated consent choices to Ketch.\\n\\n## Steps\\n1. Capture the user identity and the new consent choices per purpose.\\n2. Set the consent for that user in the correct jurisdiction/policy scope.\\n3. Read the consent back to confirm it was applied.\\n\\n## Output\\nConfirm the user identity, the purposes updated, and the resulting consent state."},{"name":"fulfill-data-subject-request","description":"Invoke a data subject right (access, delete) in Ketch and track the request.","content":"# Fulfill a Data Subject Request\\n\\nKick off a DSR (e.g. access or deletion) on behalf of a user.\\n\\n## Steps\\n1. Capture the requester identity and the right being exercised (access, deletion, correction).\\n2. Invoke the right in Ketch with the required identity and jurisdiction context.\\n3. Capture the request reference for tracking.\\n\\n## Output\\nReturn the request reference, the right invoked, and the requester identity so the request can be tracked to completion."},{"name":"sync-subscription-preferences","description":"Read a user subscription topics in Ketch and update them to honor an opt-in or opt-out.","content":"# Sync Subscription Preferences\\n\\nKeep a user communication preferences accurate in Ketch when they opt in or out of a channel or topic.\\n\\n## Steps\\n1. Identify the user and get their current subscription topics and controls.\\n2. Determine the requested change (e.g. opt out of the newsletter, set a global unsubscribe).\\n3. Set the subscription topics and controls to the new state for that user.\\n4. Read the subscriptions back to confirm the change applied.\\n\\n## Output\\nReturn the topics and controls that changed and the resulting opt-in or opt-out state per channel. Confirm any global unsubscribe was honored."}],"templates":[{"title":"Ketch consent propagator","prompt":"Build a workflow that on a consent change reads the contact’s Ketch consent state and propagates it to downstream systems — HubSpot and Loops — keeping privacy preferences in sync.","integrations":[{"id":"ketch","name":"Ketch"},{"id":"hubspot","name":"HubSpot"},{"id":"loops","name":"Loops"}]},{"title":"Ketch DSR fulfillment","prompt":"Create a workflow that on a Ketch data subject request collects matching personal data from connected systems, generates the export, and writes the fulfillment audit.","integrations":[{"id":"ketch","name":"Ketch"}]},{"title":"Ketch deletion-request handler","prompt":"Build a workflow that on a Ketch deletion request propagates the deletion to all connected systems, captures confirmations, and writes the chain of custody.","integrations":[{"id":"ketch","name":"Ketch"}]},{"title":"Ketch consent-drift detector","prompt":"Create a scheduled workflow that compares Ketch consent state with downstream systems, flags drift, and writes a remediation queue for the privacy team.","integrations":[{"id":"ketch","name":"Ketch"}]},{"title":"Ketch subscription sync","prompt":"Build a workflow that reads each contact’s Ketch subscription topics and mirrors the opt-in state to the marketing tool so unsubscribe preferences stay consistent across systems.","integrations":[{"id":"ketch","name":"Ketch"},{"id":"loops","name":"Loops"}]},{"title":"Ketch right-invocation handler","prompt":"Create a workflow that on an incoming privacy request invokes the matching Ketch right for the data subject, captures the confirmation, and writes the action to a compliance file.","integrations":[{"id":"ketch","name":"Ketch"}]},{"title":"Ketch consent-rate digest","prompt":"Build a scheduled monthly workflow that samples Ketch consent state across a contact list, computes opt-in rates per purpose, and writes a privacy report file for executive review.","integrations":[{"id":"ketch","name":"Ketch"}]}]},{"id":"lambda","type":"lambda","slug":"lambda","name":"Lambda","description":"Invoke, deploy, and manage AWS Lambda functions","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/lambda","authType":"api-key","connections":[],"operations":[{"name":"Invoke Function","description":"Invoke a Lambda function synchronously for its response payload, asynchronously to queue execution, or as a dry run to check permissions."},{"name":"List Functions","description":"List Lambda functions with the version-specific configuration of each"},{"name":"Get Function","description":"Get a function\'s configuration, code location, tags, and reserved concurrency"},{"name":"Get Function Configuration","description":"Get a function\'s version-specific configuration"},{"name":"Create Function","description":"Create a Lambda function from a deployment package in Amazon S3 or a container image"},{"name":"Update Function Code","description":"Update a function\'s deployment package from Amazon S3 or a container image"},{"name":"Update Function Configuration","description":"Update a function\'s settings such as memory, timeout, role, and environment variables"},{"name":"Delete Function","description":"Delete a Lambda function, or a single published version of it"},{"name":"Publish Version","description":"Publish an immutable version from the current code and configuration of a function"},{"name":"List Function Versions","description":"List the published versions of a Lambda function, plus $LATEST"},{"name":"Create Alias","description":"Create an alias that points to a published function version"},{"name":"Get Alias","description":"Get details about a Lambda function alias"},{"name":"Update Alias","description":"Update the target version, description, or traffic weights of an alias"},{"name":"Delete Alias","description":"Delete a Lambda function alias"},{"name":"List Aliases","description":"List the aliases of a Lambda function"},{"name":"Add Permission","description":"Grant an AWS service, account, or organization permission to use a function"},{"name":"Remove Permission","description":"Remove a statement from a function\'s resource-based policy"},{"name":"Get Policy","description":"Get the resource-based IAM policy attached to a function, version, or alias"},{"name":"Create Event Source Mapping","description":"Map an event source such as SQS, Kinesis, DynamoDB Streams, or Kafka to a function"},{"name":"Get Event Source Mapping","description":"Get details about an event source mapping"},{"name":"Update Event Source Mapping","description":"Update the batching, retry, filtering, or enabled state of an event source mapping"},{"name":"Delete Event Source Mapping","description":"Delete an event source mapping"},{"name":"List Event Source Mappings","description":"List event source mappings, optionally filtered by function or event source"},{"name":"Get Function Concurrency","description":"Get the reserved concurrency configured for a function"},{"name":"Set Function Concurrency","description":"Reserve a share of the account concurrency limit for a function"},{"name":"Delete Function Concurrency","description":"Remove the reserved concurrency configuration from a function"},{"name":"Get Provisioned Concurrency","description":"Get the provisioned concurrency configuration of a function version or alias"},{"name":"Set Provisioned Concurrency","description":"Allocate provisioned concurrency to a function version or alias"},{"name":"Delete Provisioned Concurrency","description":"Remove the provisioned concurrency configuration from a function version or alias"},{"name":"List Provisioned Concurrency","description":"List the provisioned concurrency configurations of a function"},{"name":"Create Function URL","description":"Create a dedicated HTTPS endpoint for a function"},{"name":"Get Function URL","description":"Get details about a function URL"},{"name":"Update Function URL","description":"Update the auth type, invoke mode, or CORS settings of a function URL"},{"name":"Delete Function URL","description":"Delete the URL configuration of a function"},{"name":"List Function URLs","description":"List the URL configurations of a function"},{"name":"Get Async Invoke Config","description":"Get the asynchronous invocation retry and destination settings of a function"},{"name":"Set Async Invoke Config","description":"Configure retry limits and destinations for asynchronous invocations of a function"},{"name":"Delete Async Invoke Config","description":"Remove the asynchronous invocation configuration of a function"},{"name":"List Async Invoke Configs","description":"List the asynchronous invocation configurations of a function"},{"name":"List Layers","description":"List Lambda layers and the latest version of each"},{"name":"List Layer Versions","description":"List the versions of a Lambda layer"},{"name":"Get Layer Version","description":"Get details and a download link for a specific layer version"},{"name":"List Tags","description":"List the tags applied to a Lambda function"},{"name":"Tag Resource","description":"Add tags to a Lambda function"},{"name":"Untag Resource","description":"Remove tags from a Lambda function"},{"name":"Get Account Settings","description":"Get the Lambda limits and usage of the current AWS account and region"},{"name":"Get Recursion Config","description":"Get the recursive loop detection setting of a function"},{"name":"Set Recursion Config","description":"Set whether Lambda stops a function that invokes itself recursively"},{"name":"Get Runtime Management Config","description":"Get the runtime update policy of a function version"},{"name":"Set Runtime Management Config","description":"Set how and when Lambda applies runtime updates to a function version"}],"triggers":[],"skills":[{"name":"invoke-lambda-function","description":"Invoke an AWS Lambda function with a JSON payload and interpret its response, including function errors and log output.","content":"# Invoke a Lambda Function\\n\\nRun a function and read back what it returned.\\n\\n## Steps\\n1. Confirm the function name, ARN, or alias to invoke, and the qualifier if a specific version or alias is needed.\\n2. Choose the invocation type: RequestResponse to wait for the result, Event to queue it, DryRun to only check permissions.\\n3. Send the JSON event payload the handler expects.\\n4. Set the log type to Tail when you need the execution log to diagnose a failure.\\n5. Check functionError before trusting the payload: a value of Handled or Unhandled means the function itself failed even though the API call succeeded.\\n\\n## Output\\nThe parsed response payload, the executed version, and, when a function error occurred, the decoded log tail and the failure reason."},{"name":"inventory-lambda-functions","description":"List Lambda functions with their runtime, memory, timeout, and architecture to build an inventory of deployed compute.","content":"# Inventory Lambda Functions\\n\\nBuild a single view of every deployed function.\\n\\n## Steps\\n1. List all functions, paginating with the returned marker until no marker comes back.\\n2. Capture name, ARN, runtime, handler, memory, timeout, architecture, and last modified date for each.\\n3. Note that listing functions returns a subset of fields, so fetch a function individually when you need its state, state reason, or runtime version.\\n4. Flag functions on runtimes AWS has deprecated.\\n\\n## Output\\nA table of functions with runtime, memory, timeout, architecture, and any that need a runtime upgrade."},{"name":"release-lambda-version","description":"Deploy new Lambda code, publish an immutable version, and shift alias traffic to it safely.","content":"# Release a Lambda Version\\n\\nShip new code without an all-at-once cutover.\\n\\n## Steps\\n1. Update the function code from the new S3 object or container image.\\n2. Wait until the function last update status is Successful before publishing.\\n3. Publish a version to freeze the current code and configuration.\\n4. Update the alias with weighted routing so a small share of traffic reaches the new version.\\n5. After the canary looks healthy, point the alias fully at the new version. To roll back, point it at the previous one.\\n\\n## Output\\nThe published version number, the alias routing configuration in effect, and confirmation of whether the release was promoted or rolled back."},{"name":"audit-lambda-permissions","description":"Read Lambda resource-based policies and function URL settings to find functions exposed more broadly than intended.","content":"# Audit Lambda Access\\n\\nFind functions that anyone can invoke.\\n\\n## Steps\\n1. For each function, read the resource-based policy.\\n2. Flag statements whose principal is a wildcard, or an AWS account outside your organization, without a source ARN or source account condition.\\n3. List the function URL configurations and flag any whose auth type is NONE.\\n4. For URLs with CORS, flag configurations that allow any origin.\\n\\n## Output\\nA per-function list of over-permissive policy statements and publicly reachable function URLs, with the specific statement ID or URL to remediate."}],"templates":[{"title":"Lambda function runner","prompt":"Create a workflow that takes a JSON request as input, invokes an AWS Lambda function with it, parses the returned payload, and posts the result to Slack. If the invocation returns a function error, include the decoded execution log tail in the alert.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"slack","name":"Slack"}]},{"title":"Lambda function inventory","prompt":"Build a scheduled weekly workflow that lists every AWS Lambda function in the account, captures runtime, memory, timeout, last modified date, and architecture, and writes the inventory into a tracking table so the platform team can spot deprecated runtimes.","integrations":[{"id":"lambda","name":"Lambda"}]},{"title":"Lambda deprecated runtime sweep","prompt":"Create a scheduled monthly workflow that lists all Lambda functions, flags any running a deprecated runtime, groups them by owning team using function tags, and opens a Linear ticket per team with the list of functions that need upgrading.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"linear","name":"Linear"}]},{"title":"Lambda blue-green release","prompt":"Build a workflow that updates a Lambda function from a new S3 deployment package, publishes a version, shifts 10 percent of alias traffic to it with weighted routing, waits for approval in Slack, then promotes the alias to 100 percent or rolls it back.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"slack","name":"Slack"}]},{"title":"Lambda concurrency guard","prompt":"Create a scheduled workflow that reads Lambda account settings and each function reserved concurrency, detects when unreserved concurrency drops below a safe floor, and alerts the on-call channel with the functions consuming the most reserved capacity.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"slack","name":"Slack"}]},{"title":"Lambda event source auditor","prompt":"Build a scheduled workflow that lists every Lambda event source mapping, flags any whose state is not Enabled or whose last processing result reports errors, summarizes the likely cause, and posts a daily digest to Slack.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"slack","name":"Slack"}]},{"title":"Lambda permission reviewer","prompt":"Create a scheduled workflow that reads the resource-based policy of every Lambda function, flags statements that grant access to a wildcard principal or an account outside your organization, and writes a written findings report for the security team.","integrations":[{"id":"lambda","name":"Lambda"}]},{"title":"Lambda public URL detector","prompt":"Build a scheduled workflow that lists Lambda function URL configurations across your functions, flags any whose auth type is NONE or whose CORS allows any origin, and opens a Linear ticket for each exposed endpoint.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"linear","name":"Linear"}]},{"title":"Lambda async failure triage","prompt":"Create a workflow that reads the asynchronous invocation configuration of a Lambda function, pulls failed invocation records from its on-failure destination queue, invokes the function again in dry run mode to check permissions, and summarizes the failure cause in Slack.","integrations":[{"id":"lambda","name":"Lambda"},{"id":"slack","name":"Slack"}]}]},{"id":"langsmith","type":"langsmith","slug":"langsmith","name":"LangSmith","description":"Forward workflow runs to LangSmith for observability","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/langsmith","authType":"api-key","connections":[],"operations":[{"name":"Create Run","description":"Forward a single run to LangSmith for ingestion."},{"name":"Create Runs Batch","description":"Forward multiple runs to LangSmith in a single batch."},{"name":"Update Run","description":"Patch an existing LangSmith run with outputs, status, or timing once it completes."},{"name":"Get Run","description":"Retrieve a single LangSmith run by ID."},{"name":"Create Feedback","description":"Attach a score, correction, or comment to a LangSmith run."}],"triggers":[],"skills":[{"name":"log-llm-run-to-langsmith","description":"Send a single LLM or chain run to LangSmith with inputs, outputs, and timing for tracing.","content":"# Log an LLM Run to LangSmith\\n\\nForward one workflow step into LangSmith so it shows up in tracing and evals.\\n\\n## Steps\\n1. Capture the run name, run type (llm, chain, tool), and the project to log into.\\n2. Record the inputs (prompt or arguments) and the outputs the step produced.\\n3. Include start and end times so latency is captured, plus any error if the step failed.\\n4. Create the run in LangSmith.\\n\\n## Output\\nConfirm the run was logged with its name, type, and project, and surface the run ID for follow-up inspection."},{"name":"batch-export-runs","description":"Send a batch of completed workflow runs to LangSmith in one call for observability.","content":"# Batch Export Runs\\n\\nShip multiple completed runs to LangSmith at once instead of one by one.\\n\\n## Steps\\n1. Collect the runs to export, each with name, type, inputs, outputs, and timing.\\n2. Assign a shared project so the runs land together.\\n3. Submit them as a single batch.\\n\\n## Output\\nReturn how many runs were exported, the project they landed in, and any runs that failed validation."},{"name":"attach-feedback-to-run","description":"Attach a score, categorical value, or correction to an existing LangSmith run for evaluation.","content":"# Attach Feedback to a Run\\n\\nRecord a human or automated judgment on a run that already exists in LangSmith.\\n\\n## Steps\\n1. Identify the run ID the feedback applies to.\\n2. Choose a feedback key (e.g. \\"correctness\\", \\"user_score\\") and a score, value, or comment.\\n3. Include a correction if the expected output is known.\\n4. Submit the feedback.\\n\\n## Output\\nConfirm the feedback ID and the run it was attached to."}],"templates":[{"title":"DSPy + LangSmith trace harness","prompt":"Create a workflow that runs a DSPy program over an eval set, logs each prediction as a LangSmith trace for evaluation, captures the quality delta against the previous run, and writes the comparison to engineering Slack.","integrations":[{"id":"langsmith","name":"LangSmith"},{"id":"dspy","name":"DSPy"},{"id":"slack","name":"Slack"}]},{"title":"Elasticsearch + LangSmith retrieval evaluator","prompt":"Create a workflow that uses LangSmith to evaluate retrieval quality from Elasticsearch versus a vector knowledge base, writes the head-to-head scores to a table.","integrations":[{"id":"langsmith","name":"LangSmith"},{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"LangSmith agent-run tracer","prompt":"Build a workflow that wraps an agent step and forwards each run to LangSmith with inputs, outputs, and latency so the ML team can trace executions in one project.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith error logger","prompt":"Create a workflow that on a failed agent step forwards a LangSmith run tagged as an error with the inputs and error message, and posts the run link to Slack for the ML team.","integrations":[{"id":"langsmith","name":"LangSmith"},{"id":"slack","name":"Slack"}]},{"title":"LangSmith feedback capture","prompt":"Build a workflow that collects user-reported agent failures from a table and attaches each as scored LangSmith feedback on the originating run for later review.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith run completion","prompt":"Build a workflow that creates a LangSmith run when an agent step starts, then updates it with outputs, status, and end time once the step finishes so traces always show the full lifecycle.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith batch run shipper","prompt":"Create a scheduled workflow that reads completed agent runs from a table and posts them to LangSmith in a single batch so observability stays in sync without per-run overhead.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith session tagger","prompt":"Build a workflow that forwards each agent run to LangSmith tagged with the originating feature and environment so traces can be filtered by surface in the LangSmith project.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith RAG step logger","prompt":"Create a workflow that runs a retrieval-augmented agent and forwards a LangSmith run per step — retriever, prompt, and llm — so the ML team can inspect each stage of the chain.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"LangSmith multi-agent tracer","prompt":"Build a workflow that forwards a LangSmith run for each agent in a multi-step pipeline under one trace, so the full conversation is visible end-to-end in LangSmith.","integrations":[{"id":"langsmith","name":"LangSmith"}]},{"title":"Rootly + LangSmith agent-incident tracker","prompt":"Build a workflow that for each Rootly incident involving an AI agent attaches the LangSmith trace, captures the failure mode, and writes the agent-quality regression analysis.","integrations":[{"id":"langsmith","name":"LangSmith"},{"id":"rootly","name":"Rootly"}]}]},{"id":"latex","type":"latex","slug":"latex","name":"LaTeX","description":"Compile LaTeX documents into PDFs","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/latex","authType":"none","connections":[],"operations":[{"name":"Compile Document","description":"Compile a LaTeX document into a PDF via the public LaTeX-on-HTTP service (latex.ytotech.com). Supports pdflatex, xelatex, lualatex, platex, uplatex, and context, plus supporting resources such as images, included .tex files, and bibliographies."},{"name":"Search Packages","description":"Search the TeX Live packages available to the LaTeX compiler by name or description, e.g. to check which packages can be used in a document."},{"name":"Get Package Details","description":"Get details about a specific TeX Live package available to the LaTeX compiler, including whether it is installed, its description, license, and related packages."},{"name":"List Fonts","description":"List the system fonts available to the LaTeX compiler, optionally filtered by name, e.g. to pick a font for xelatex or lualatex documents using fontspec."}],"triggers":[],"skills":[{"name":"compile-document-to-pdf","description":"Compile LaTeX source into a finished PDF, choosing the right compiler and reporting any compilation errors. Use whenever a polished, print-ready document is needed.","content":"# Compile Document to PDF\\n\\nTurn LaTeX source into a finished PDF.\\n\\n## Steps\\n1. Assemble the complete LaTeX source, from \\\\documentclass to \\\\end{document}.\\n2. Pick the compiler: pdflatex for standard documents, xelatex or lualatex when custom fonts or full unicode are needed.\\n3. Attach any supporting files (images, included .tex files, .bib bibliographies) as resources with the paths the source references.\\n4. Compile and capture the resulting PDF.\\n\\n## Output\\nThe compiled PDF file and its URL. If compilation fails, report the TeX errors verbatim so they can be fixed."},{"name":"generate-document-from-template","description":"Fill a LaTeX template with structured data and compile it to PDF. Use for repeatable documents like invoices, certificates, letters, and contracts.","content":"# Generate Document from Template\\n\\nProduce a templated document with real data filled in.\\n\\n## Steps\\n1. Start from the LaTeX template and identify its placeholders.\\n2. Substitute each placeholder with the provided data, escaping LaTeX special characters (&, %, $, #, _, {, }) in user-supplied values.\\n3. Compile the filled-in source to PDF.\\n4. Name the output file after the document, e.g. invoice-1042.pdf.\\n\\n## Output\\nA compiled PDF per record, named for its contents. List any records that failed to compile and why."},{"name":"typeset-math-content","description":"Write mathematical content — equations, proofs, problem sets — in LaTeX and compile a printable PDF. Use for worksheets, solution sheets, and technical notes.","content":"# Typeset Math Content\\n\\nProduce a clean PDF of mathematical material.\\n\\n## Steps\\n1. Draft the content using proper LaTeX math: inline $...$, display equations, and environments like align and theorem as appropriate.\\n2. Load only the packages the content needs (amsmath, amssymb, amsthm).\\n3. Structure the document with sections and consistent numbering.\\n4. Compile to PDF and verify there are no errors.\\n\\n## Output\\nA printable PDF of the typeset material, plus the LaTeX source so it can be edited later."},{"name":"build-report-with-bibliography","description":"Compile a report or paper that cites sources, attaching a BibTeX bibliography as a resource. Use for research reports, literature reviews, and academic writing.","content":"# Build Report with Bibliography\\n\\nCompile a citing document with its references resolved.\\n\\n## Steps\\n1. Write the report source with \\\\cite commands and a \\\\bibliography{refs} (or biblatex equivalent) reference.\\n2. Attach the BibTeX entries as a resource at the cited path, e.g. refs.bib.\\n3. Compile — the bibliography pass runs automatically.\\n4. Check the output for unresolved citation warnings and fix missing entries.\\n\\n## Output\\nThe compiled PDF with a formatted reference list. Note any citations that could not be resolved."},{"name":"fix-compilation-errors","description":"Diagnose failed LaTeX builds from the compiler error output and iterate until the document compiles. Use when a compilation returns errors instead of a PDF.","content":"# Fix Compilation Errors\\n\\nGet a failing LaTeX document to build.\\n\\n## Steps\\n1. Read the TeX error lines from the failed compile (lines starting with !), which name the problem and its location.\\n2. Apply the targeted fix: missing packages (verify availability with Get Package Details or Search Packages), unescaped special characters, unmatched braces or environments, or commands needing a different compiler (e.g. fontspec requires xelatex or lualatex — confirm the font exists with List Fonts).\\n3. Recompile and repeat until the build succeeds.\\n4. Keep edits minimal — fix the errors without rewriting the document.\\n\\n## Output\\nThe compiled PDF and a short list of the fixes that were applied."}],"templates":[{"title":"LaTeX invoice generator","prompt":"Build a workflow that takes invoice line items from a table, fills a LaTeX invoice template, compiles it to PDF, and emails the invoice to the customer.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"gmail","name":"Gmail"}]},{"title":"LaTeX research report writer","prompt":"Create a workflow where an agent researches a topic from the knowledge base, writes the findings as a LaTeX article, and compiles a polished PDF report.","integrations":[{"id":"latex","name":"LaTeX"}]},{"title":"LaTeX weekly metrics report","prompt":"Build a scheduled weekly workflow that pulls metrics from a table, typesets a LaTeX report with charts and tables, compiles it to PDF, and posts it to Slack.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"slack","name":"Slack"}]},{"title":"LaTeX offer letter generator","prompt":"Create a workflow that takes candidate details from a form, fills a LaTeX offer letter template, compiles it to PDF, and sends it for e-signature.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"docusign","name":"DocuSign"}]},{"title":"LaTeX math worksheet builder","prompt":"Build a workflow where an agent generates practice problems for a given math topic and difficulty, typesets them with LaTeX equations, and compiles a printable worksheet PDF.","integrations":[{"id":"latex","name":"LaTeX"}]},{"title":"LaTeX proposal generator","prompt":"Create a workflow that pulls deal details from HubSpot, has an agent draft a tailored proposal in LaTeX, compiles it to PDF, and saves it to the deal record.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"hubspot","name":"HubSpot"}]},{"title":"LaTeX paper digest compiler","prompt":"Build a scheduled workflow that fetches new ArXiv papers on tracked topics, has an agent summarize each one, typesets the digest as a LaTeX document, and compiles a weekly PDF.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"arxiv","name":"ArXiv"}]},{"title":"LaTeX certificate generator","prompt":"Create a workflow that reads attendee names from a spreadsheet, fills a LaTeX certificate template for each attendee, compiles the PDFs, and emails each certificate to its recipient.","integrations":[{"id":"latex","name":"LaTeX"},{"id":"google_sheets","name":"Google Sheets"},{"id":"gmail","name":"Gmail"}]}]},{"id":"launchdarkly","type":"launchdarkly","slug":"launchdarkly","name":"LaunchDarkly","description":"Manage feature flags with LaunchDarkly","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/launchdarkly","authType":"api-key","connections":[],"operations":[{"name":"List Flags","description":"List feature flags in a LaunchDarkly project."},{"name":"Get Flag","description":"Get a single feature flag by key from a LaunchDarkly project."},{"name":"Create Flag","description":"Create a new feature flag in a LaunchDarkly project."},{"name":"Update Flag","description":"Update feature flag metadata (name, description, tags, temporary, archived) using semantic patch."},{"name":"Toggle Flag","description":"Toggle a feature flag on or off in a specific LaunchDarkly environment."},{"name":"Delete Flag","description":"Delete a feature flag from a LaunchDarkly project."},{"name":"Get Flag Status","description":"Get the status of a feature flag across environments (active, inactive, launched, etc.)."},{"name":"List Projects","description":"List all projects in your LaunchDarkly account."},{"name":"List Environments","description":"List environments in a LaunchDarkly project."},{"name":"List Segments","description":"List user segments in a LaunchDarkly project and environment."},{"name":"List Members","description":"List account members in your LaunchDarkly organization."},{"name":"Get Audit Log","description":"List audit log entries from your LaunchDarkly account."}],"triggers":[],"skills":[{"name":"toggle-flag-in-environment","description":"Turn a LaunchDarkly feature flag on or off in a specific environment safely.","content":"# Toggle a Flag in an Environment\\n\\nFlip a feature flag for a target environment with a confirmation step.\\n\\n## Steps\\n1. Identify the project and the environment (e.g. production, staging) and the flag key.\\n2. Get the current flag status to confirm its present state.\\n3. Toggle the flag to the desired on/off state in that environment.\\n4. Re-check the status to confirm the change took effect.\\n\\n## Output\\nReturn the flag key, environment, previous state, and new state. Confirm the toggle was applied."},{"name":"create-feature-flag","description":"Create a new LaunchDarkly feature flag in a project with a clear key and description.","content":"# Create a Feature Flag\\n\\nStand up a new feature flag for an upcoming release.\\n\\n## Steps\\n1. Choose the project and define a descriptive flag key and human-readable name.\\n2. Set a description explaining what the flag controls and whether it is temporary or permanent.\\n3. Create the flag, defaulting it to off so it can be rolled out deliberately.\\n\\n## Output\\nReturn the flag key, name, project, and initial state. Confirm the flag starts disabled."},{"name":"flag-rollout-audit","description":"Report on a flag state across environments and recent changes from the audit log.","content":"# Flag Rollout Audit\\n\\nUnderstand where a flag stands and who changed it recently.\\n\\n## Steps\\n1. Get the flag and list environments for the project.\\n2. For each environment, capture the flag on/off state and targeting.\\n3. Pull the audit log entries for the flag to see recent changes and who made them.\\n\\n## Output\\nReturn a per-environment state table for the flag and a short changelog of recent modifications with actor and timestamp."},{"name":"emergency-flag-kill-switch","description":"Instantly disable a feature flag in production during an incident and confirm it is off.","content":"# Emergency Flag Kill-Switch\\n\\nKill a misbehaving feature in production immediately.\\n\\n## Steps\\n1. Identify the project, the production environment key, and the flag key to disable.\\n2. Toggle the flag off in that environment.\\n3. Get the flag status to confirm it is now off and no longer being served.\\n\\n## Output\\nReturn the flag key, environment, and confirmation that the flag is off, with the timestamp of the change."},{"name":"stale-flag-cleanup","description":"Find temporary or long-untouched feature flags and surface them for removal.","content":"# Stale Flag Cleanup\\n\\nKeep flag debt under control by surfacing flags that have outlived their purpose.\\n\\n## Steps\\n1. List the flags in the project, noting which are marked temporary and their creation dates.\\n2. Cross-reference the audit log to find flags with no recent changes.\\n3. Compile the candidates that are temporary and inactive into a cleanup list.\\n\\n## Output\\nReturn a list of stale flag keys with their age, temporary status, and last-change date so an owner can decide whether to archive or delete them."}],"templates":[{"title":"LaunchDarkly flag-flip auditor","prompt":"Build a scheduled workflow that reads the LaunchDarkly audit log, captures who flipped which flag and when, and writes the audit trail to a tracking table with diff context.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"}]},{"title":"LaunchDarkly stale-flag sweeper","prompt":"Create a scheduled workflow that identifies LaunchDarkly flags inactive for 60 days, opens Linear tickets to remove them, and writes the cleanup queue to a dashboard table.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"linear","name":"Linear"}]},{"title":"LaunchDarkly rollout digest","prompt":"Build a scheduled weekly workflow that lists LaunchDarkly flags with their current status and rollout percentage per environment, summarizes what changed since last week, and posts a digest to the product Slack channel.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"slack","name":"Slack"}]},{"title":"LaunchDarkly flag-flip safety gate","prompt":"Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"sentry","name":"Sentry"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"LaunchDarkly targeted rollout assistant","prompt":"Build a workflow that takes a LaunchDarkly flag and a rollout plan, advances the rollout percentage on a schedule while watching health metrics, pausing on degradation.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"datadog","name":"Datadog"}]},{"title":"LaunchDarkly + Linear release planner","prompt":"Create a workflow that watches Linear releases marked behind a LaunchDarkly flag, validates the flag exists, posts the rollout plan to Slack, and tracks rollout progress on the release ticket.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"LaunchDarkly customer-segment toggler","prompt":"Build a workflow that turns a HubSpot segment into a LaunchDarkly targeting rule, keeping the rule in sync with the segment, and writes the sync log to a tracking table.","integrations":[{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"leadmagic","type":"leadmagic","slug":"leadmagic","name":"LeadMagic","description":"Find and enrich B2B contacts, emails, mobile numbers, and company data","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/leadmagic","authType":"api-key","connections":[],"operations":[{"name":"Find Email","description":"Find someone\'s verified work email from their name and company domain. Charges 1 credit when a valid email is found; free when no result."},{"name":"Validate Email","description":"Verify an email address for deliverability. Charges 0.25 credits for definitive SMTP results (valid/invalid); unknown and RFC-invalid results are free."},{"name":"Find Mobile","description":"Find a person\'s direct mobile number from their LinkedIn profile URL or email. Charges 5 credits when a number is found; free when no result."},{"name":"Profile Search","description":"Enrich a LinkedIn profile with work history, education, skills, and contact data. Charges 1 credit per successful enrichment; free when profile not found."},{"name":"Profile to Email","description":"Extract a verified work email from a LinkedIn profile URL. Charges 5 credits when an email is found; free when no result."},{"name":"Email to Profile","description":"Retrieve a LinkedIn profile URL from a work or personal email address. Charges 10 credits when a profile is found; free when no result."},{"name":"Company Search","description":"Enrich company data including firmographics, headcount, funding, and social profiles by domain, LinkedIn URL, or name. Charges 1 credit when a company is found; free when no result."},{"name":"Role Finder","description":"Find the person holding a specific job role at a company. Charges 2 credits when a matching person is found; free when no result."},{"name":"Get Credits","description":"Retrieve the current credit balance for the authenticated LeadMagic account. This endpoint is free and consumes no credits."}],"triggers":[],"skills":[],"templates":[]},{"id":"lemlist","type":"lemlist","slug":"lemlist","name":"Lemlist","description":"Manage outreach activities, leads, and send emails via Lemlist","category":"Email","docsUrl":"https://docs.sim.ai/integrations/lemlist","authType":"api-key","connections":[],"operations":[{"name":"Get Activities","description":"Retrieves campaign activities and steps performed, including email opens, clicks, replies, and other events."},{"name":"Get Lead","description":"Retrieves lead information by email address or lead ID."},{"name":"Send Email","description":"Sends an email to a contact through the Lemlist inbox."}],"triggers":[{"id":"lemlist_email_replied","name":"Lemlist Email Replied","description":"Trigger workflow when a lead replies to an email"},{"id":"lemlist_linkedin_replied","name":"Lemlist LinkedIn Replied","description":"Trigger workflow when a lead replies to a LinkedIn message"},{"id":"lemlist_interested","name":"Lemlist Lead Interested","description":"Trigger workflow when a lead is marked as interested"},{"id":"lemlist_not_interested","name":"Lemlist Lead Not Interested","description":"Trigger workflow when a lead is marked as not interested"},{"id":"lemlist_email_opened","name":"Lemlist Email Opened","description":"Trigger workflow when a lead opens an email"},{"id":"lemlist_email_clicked","name":"Lemlist Email Clicked","description":"Trigger workflow when a lead clicks a link in an email"},{"id":"lemlist_email_bounced","name":"Lemlist Email Bounced","description":"Trigger workflow when an email bounces"},{"id":"lemlist_email_sent","name":"Lemlist Email Sent","description":"Trigger workflow when an email is sent"},{"id":"lemlist_webhook","name":"Lemlist Webhook (All Events)","description":"Trigger workflow on any Lemlist webhook event"}],"skills":[{"name":"triage-campaign-replies","description":"Pull recent Lemlist reply activity, classify each reply by intent, and surface the ones that need a human.","content":"# Triage Campaign Replies\\n\\nMonitor Lemlist replies and route them by intent so reps act on hot leads fast.\\n\\n## Steps\\n1. Get Activities filtered to the Email Replied type, optionally scoped to a campaign ID, with a sensible limit.\\n2. For each reply, look up the lead with Get Lead to attach name, company, and job title.\\n3. Classify the reply intent: interested, not interested, out-of-office, unsubscribe, or question.\\n4. For interested or question replies, build a short summary with the lead name, campaign, and the reply text.\\n\\n## Output\\nA list of replies grouped by intent. For each interested or question reply, include lead name, company, campaign, a one-line summary, and the raw reply text so a rep can respond."},{"name":"analyze-campaign-performance","description":"Compute open, click, reply, and bounce rates per campaign and per step from Lemlist activities and flag weak steps.","content":"# Analyze Campaign Performance\\n\\nTurn raw Lemlist activity into step-level metrics and concrete fixes.\\n\\n## Steps\\n1. Get Activities for the target campaign with a high limit, paging with offset until all activity is collected.\\n2. Tally events by type: emails sent, opened, clicked, replied, and bounced.\\n3. Compute open rate, click rate, reply rate, and bounce rate overall and per sequence step.\\n4. Flag steps where reply rate is low, bounce rate is high, or drop-off between steps is steep.\\n\\n## Output\\nA per-campaign and per-step metrics table plus a short list of recommendations, such as rewriting a low-reply subject line or pausing a high-bounce step."},{"name":"qualify-and-reply-to-lead","description":"Look up a Lemlist lead and send a personalized reply through their Lemlist mailbox.","content":"# Qualify and Reply to Lead\\n\\nRespond to an inbound lead with a tailored message sent from your Lemlist inbox.\\n\\n## Steps\\n1. Get Lead by email or lead ID to pull first name, company, and job title.\\n2. Draft a concise, personalized reply that references the lead context and includes a clear next step or booking link.\\n3. Send Email through Lemlist using the sender user ID, sender email, mailbox ID, contact ID, lead ID, subject, and the drafted HTML message body.\\n\\n## Output\\nConfirmation that the email was sent, the lead identity it went to, and the message body that was used."}],"templates":[{"title":"Lemlist reply router","prompt":"Create a workflow triggered by Lemlist reply webhooks that classifies each reply by intent and posts a Slack notification to the lead owner with a one-line summary, the intent, and the reply text.","integrations":[{"id":"lemlist","name":"Lemlist"},{"id":"slack","name":"Slack"}]},{"title":"Lemlist campaign analyzer","prompt":"Build a scheduled workflow that pulls Lemlist campaign activities, computes open, click, reply, and bounce rates per campaign and per step, and writes the results to a tracking table so I can spot the steps that need rewriting.","integrations":[{"id":"lemlist","name":"Lemlist"}]},{"title":"Lemlist + Apollo prospect feeder","prompt":"Create a workflow that runs an Apollo search for an ICP, enriches each prospect with role and company signals, and sends a personalized first-touch email through Lemlist with a custom opening line per prospect.","integrations":[{"id":"lemlist","name":"Lemlist"},{"id":"apollo","name":"Apollo"}]},{"title":"Lemlist interested-lead booker","prompt":"Build a workflow triggered when a Lemlist lead is marked interested that drafts a Calendly link tailored to the lead, replies to them through Lemlist with the link, and creates a follow-up task for the rep.","integrations":[{"id":"lemlist","name":"Lemlist"},{"id":"calendly","name":"Calendly"}]},{"title":"Lemlist activity dashboard","prompt":"Create a scheduled daily workflow that pulls Lemlist activity for the last 24 hours, summarizes opens, clicks, replies, and step performance per campaign, and writes a per-rep dashboard to a table.","integrations":[{"id":"lemlist","name":"Lemlist"}]},{"title":"Lemlist bounced lead sweeper","prompt":"Build a workflow triggered by Lemlist email-bounced events that looks up the lead, writes the bounce to a suppression table, and posts a Slack alert so the team can clean the list and keep quality high.","integrations":[{"id":"lemlist","name":"Lemlist"},{"id":"slack","name":"Slack"}]},{"title":"Lemlist to HubSpot logger","prompt":"Create a workflow that watches Lemlist activity and logs every send, open, click, and reply to the matching HubSpot contact as an engagement, and creates a HubSpot task for the rep on positive replies.","integrations":[{"id":"lemlist","name":"Lemlist"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"linear","type":"linear_v2","slug":"linear","name":"Linear","description":"Interact with Linear issues, projects, and more","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/linear","authType":"oauth","connections":[{"id":"linear","kind":"oauth","label":"Connect with OAuth","providerId":"linear","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/linear","requiredScopes":[{"id":"read","label":"Read issues, projects, teams, and other workspace data"},{"id":"write","label":"Create and update issues, projects, comments, and other workspace data"}],"fields":[]},{"id":"linear-service-account","kind":"service_account","providerId":"linear-service-account","label":"Add API key","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/linear-service-account","fields":[{"id":"apiToken","label":"API key","placeholder":"lin_api_...","secret":true,"hint":"Linear personal API keys start with lin_api_."}]}],"operations":[{"name":"Read Issues","description":"Fetch and filter issues from Linear"},{"name":"Get Issue","description":"Get a single issue by ID from Linear with full details"},{"name":"Create Issue","description":"Create a new issue in Linear"},{"name":"Update Issue","description":"Update an existing issue in Linear"},{"name":"Archive Issue","description":"Archive an issue in Linear"},{"name":"Unarchive Issue","description":"Unarchive (restore) an archived issue in Linear"},{"name":"Delete Issue","description":"Delete (trash) an issue in Linear"},{"name":"Search Issues","description":"Search for issues in Linear using full-text search"},{"name":"Add Label to Issue","description":"Add a label to an issue in Linear"},{"name":"Remove Label from Issue","description":"Remove a label from an issue in Linear"},{"name":"Create Comment","description":"Add a comment to an issue in Linear"},{"name":"Update Comment","description":"Edit a comment in Linear"},{"name":"Delete Comment","description":"Delete a comment from Linear"},{"name":"List Comments","description":"List all comments on an issue in Linear"},{"name":"List Projects","description":"List projects in Linear with optional filtering"},{"name":"Get Project","description":"Get a single project by ID from Linear"},{"name":"Create Project","description":"Create a new project in Linear"},{"name":"Update Project","description":"Update an existing project in Linear"},{"name":"Archive Project","description":"Archive a project in Linear"},{"name":"List Users","description":"List all users in the Linear workspace"},{"name":"List Teams","description":"List all teams in the Linear workspace"},{"name":"Get Viewer","description":"Get the currently authenticated user (viewer) information"},{"name":"List Labels","description":"List all labels in Linear workspace or team"},{"name":"Create Label","description":"Create a new label in Linear"},{"name":"Update Label","description":"Update an existing label in Linear"},{"name":"Archive Label","description":"Archive a label in Linear"},{"name":"List Workflow States","description":"List all workflow states (statuses) in Linear"},{"name":"Create Workflow State","description":"Create a new workflow state (status) in Linear"},{"name":"Update Workflow State","description":"Update an existing workflow state in Linear"},{"name":"List Cycles","description":"List cycles (sprints/iterations) in Linear"},{"name":"Get Cycle","description":"Get a single cycle by ID from Linear"},{"name":"Create Cycle","description":"Create a new cycle (sprint/iteration) in Linear"},{"name":"Get Active Cycle","description":"Get the currently active cycle for a team"},{"name":"Create Attachment","description":"Add an attachment to an issue in Linear"},{"name":"List Attachments","description":"List all attachments on an issue in Linear"},{"name":"Update Attachment","description":"Update an attachment metadata in Linear"},{"name":"Delete Attachment","description":"Delete an attachment from Linear"},{"name":"Create Issue Relation","description":"Link two issues together in Linear (blocks, relates to, duplicates)"},{"name":"List Issue Relations","description":"List all relations (dependencies) for an issue in Linear"},{"name":"Delete Issue Relation","description":"Remove a relation between two issues in Linear"},{"name":"Create Favorite","description":"Bookmark an issue, project, cycle, or label in Linear"},{"name":"List Favorites","description":"List all bookmarked items for the current user in Linear"},{"name":"Create Project Update","description":"Post a status update for a project in Linear"},{"name":"List Project Updates","description":"List all status updates for a project in Linear"},{"name":"List Notifications","description":"List notifications for the current user in Linear"},{"name":"Update Notification","description":"Mark a notification as read or unread in Linear"},{"name":"Create Customer","description":"Create a new customer in Linear"},{"name":"List Customers","description":"List all customers in Linear"},{"name":"Create Customer Request","description":"Create a customer request (need) in Linear. Assign to customer, set urgency (priority: 0 = Not important, 1 = Important), and optionally link to an issue."},{"name":"Update Customer Request","description":"Update a customer request (need) in Linear. Can change urgency, description, customer assignment, and linked issue."},{"name":"List Customer Requests","description":"List all customer requests (needs) in Linear"},{"name":"Get Customer","description":"Get a single customer by ID in Linear"},{"name":"Update Customer","description":"Update a customer in Linear"},{"name":"Delete Customer","description":"Delete a customer in Linear"},{"name":"Merge Customers","description":"Merge two customers in Linear by moving all data from source to target"},{"name":"Create Customer Status","description":"Create a new customer status in Linear"},{"name":"Update Customer Status","description":"Update a customer status in Linear"},{"name":"Delete Customer Status","description":"Delete a customer status in Linear"},{"name":"List Customer Statuses","description":"List all customer statuses in Linear"},{"name":"Create Customer Tier","description":"Create a new customer tier in Linear"},{"name":"Update Customer Tier","description":"Update a customer tier in Linear"},{"name":"Delete Customer Tier","description":"Delete a customer tier in Linear"},{"name":"List Customer Tiers","description":"List all customer tiers in Linear"},{"name":"Delete Project","description":"Delete a project in Linear"},{"name":"Create Project Label","description":"Create a new project label in Linear"},{"name":"Update Project Label","description":"Update a project label in Linear"},{"name":"Delete Project Label","description":"Delete a project label in Linear"},{"name":"List Project Labels","description":"List all project labels in Linear"},{"name":"Add Label to Project","description":"Add a label to a project in Linear"},{"name":"Remove Label from Project","description":"Remove a label from a project in Linear"},{"name":"Create Project Milestone","description":"Create a new project milestone in Linear"},{"name":"Update Project Milestone","description":"Update a project milestone in Linear"},{"name":"Delete Project Milestone","description":"Delete a project milestone in Linear"},{"name":"List Project Milestones","description":"List all milestones for a project in Linear"},{"name":"Create Project Status","description":"Create a new project status in Linear"},{"name":"Update Project Status","description":"Update a project status in Linear"},{"name":"Delete Project Status","description":"Delete a project status in Linear"},{"name":"List Project Statuses","description":"List all project statuses in Linear"}],"triggers":[{"id":"linear_issue_created_v2","name":"Linear Issue Created","description":"Trigger workflow when a new issue is created in Linear"},{"id":"linear_issue_updated_v2","name":"Linear Issue Updated","description":"Trigger workflow when an issue is updated in Linear"},{"id":"linear_issue_removed_v2","name":"Linear Issue Removed","description":"Trigger workflow when an issue is removed/deleted in Linear"},{"id":"linear_comment_created_v2","name":"Linear Comment Created","description":"Trigger workflow when a new comment is created in Linear"},{"id":"linear_comment_updated_v2","name":"Linear Comment Updated","description":"Trigger workflow when a comment is updated in Linear"},{"id":"linear_project_created_v2","name":"Linear Project Created","description":"Trigger workflow when a new project is created in Linear"},{"id":"linear_project_updated_v2","name":"Linear Project Updated","description":"Trigger workflow when a project is updated in Linear"},{"id":"linear_cycle_created_v2","name":"Linear Cycle Created","description":"Trigger workflow when a new cycle is created in Linear"},{"id":"linear_cycle_updated_v2","name":"Linear Cycle Updated","description":"Trigger workflow when a cycle is updated in Linear"},{"id":"linear_label_created_v2","name":"Linear Label Created","description":"Trigger workflow when a new label is created in Linear"},{"id":"linear_label_updated_v2","name":"Linear Label Updated","description":"Trigger workflow when a label is updated in Linear"},{"id":"linear_project_update_created_v2","name":"Linear Project Update Created","description":"Trigger workflow when a new project update is posted in Linear"},{"id":"linear_customer_request_created_v2","name":"Linear Customer Request Created","description":"Trigger workflow when a new customer request is created in Linear"},{"id":"linear_customer_request_updated_v2","name":"Linear Customer Request Updated","description":"Trigger workflow when a customer request is updated in Linear"},{"id":"linear_webhook_v2","name":"Linear Webhook","description":"Trigger workflow from Linear events you select when creating the webhook in Linear (not guaranteed to be every model or event type)."}],"skills":[{"name":"create-triaged-issue","description":"Create a Linear issue in the right team with a clear title, description, priority, and labels.","content":"# Create Triaged Issue\\n\\nTurn a request or bug report into a well-formed Linear issue.\\n\\n## Steps\\n1. If the team is unknown, List Teams and pick the team that owns the area.\\n2. Write a concise title and a description with context, steps to reproduce, and acceptance criteria.\\n3. Create Issue with the team ID, title, description, and a priority that matches severity.\\n4. Optionally Add Label to Issue for type and area labels using IDs from List Labels.\\n\\n## Output\\nThe created issue ID, its identifier and URL, and the team, priority, and labels applied."},{"name":"triage-new-issue","description":"Read a Linear issue, apply type and priority labels, set assignee and state, and comment a triage summary.","content":"# Triage New Issue\\n\\nTriage an incoming Linear issue so it lands in the right place with the right metadata.\\n\\n## Steps\\n1. Get Issue to read the title and description.\\n2. Determine the issue type, priority, and owning area from the content.\\n3. Add Label to Issue for type and priority, and Update Issue to set the assignee, state, and priority.\\n4. Create Comment with a short triage summary explaining the classification and next step.\\n\\n## Output\\nThe issue identifier, the labels added, the assignee and state set, and the triage comment posted."},{"name":"summarize-active-cycle","description":"Pull completed and open issues in the active cycle and produce a sprint progress digest.","content":"# Summarize Active Cycle\\n\\nProduce a sprint review digest from the current Linear cycle.\\n\\n## Steps\\n1. Get Active Cycle for the team to find the current cycle.\\n2. Read Issues or Search Issues scoped to that cycle, separating completed from still-open issues.\\n3. Compute counts, completion percentage, and call out blocked or at-risk issues by priority.\\n4. Summarize progress, blockers, and what is likely to slip.\\n\\n## Output\\nA digest with completed vs open counts, completion percentage, a list of blockers, and a short narrative of cycle health."},{"name":"post-project-update","description":"Assess a Linear project and post a project update with a health status and progress summary.","content":"# Post Project Update\\n\\nWrite a stakeholder-ready project update in Linear.\\n\\n## Steps\\n1. Get Project to read its current state, target date, and lead.\\n2. Read Issues for the project to gauge progress against the milestone or target date.\\n3. Decide a health status of on track, at risk, or off track based on remaining work and timeline.\\n4. Create Project Update with the chosen health and a concise body covering progress, risks, and next steps.\\n\\n## Output\\nConfirmation of the posted update, the health status chosen, and the update body."}],"templates":[{"title":"Agiloft + Linear ticket bridge","prompt":"Build a scheduled workflow that searches Agiloft for contracts flagged for engineering review and creates a Linear ticket with the contract context and a link, keeping status synced both ways.","integrations":[{"id":"linear","name":"Linear"},{"id":"agiloft","name":"Agiloft"}]},{"title":"Azure DevOps to Linear bridge","prompt":"Build a workflow that watches new Azure DevOps work items, mirrors each as a Linear issue with full context and a back-link, and keeps the team aligned across both trackers.","integrations":[{"id":"linear","name":"Linear"},{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Cloudflare SSL and zone check","prompt":"Create a scheduled weekly workflow that inspects every Cloudflare zone for SSL certificate status, security level, and zone settings drift, logs findings to a table, and opens Linear tickets for any zones that need attention.","integrations":[{"id":"linear","name":"Linear"},{"id":"cloudflare","name":"Cloudflare"}]},{"title":"CloudFormation failure investigator","prompt":"Build a scheduled workflow that polls CloudFormation stack events every few minutes, detects rollbacks and create-failed events, pulls the failure reason and recent events from the stack, summarizes the root cause, opens a Linear ticket with the diagnosis, and posts to the on-call Slack channel.","integrations":[{"id":"linear","name":"Linear"},{"id":"cloudformation","name":"CloudFormation"},{"id":"slack","name":"Slack"}]},{"title":"CloudWatch log error triager","prompt":"Create a workflow that runs a CloudWatch Logs Insights query against application log groups every few minutes, groups recurring error signatures with an agent, opens a Linear issue for any new error pattern, and posts a Slack alert.","integrations":[{"id":"linear","name":"Linear"},{"id":"cloudwatch","name":"CloudWatch"},{"id":"slack","name":"Slack"}]},{"title":"CodePipeline failure triage","prompt":"Create a scheduled workflow that polls CodePipeline executions every few minutes, and when one fails, pulls the pipeline state to find the failing stage and action error, opens a Linear issue, and alerts the on-call channel in Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"codepipeline","name":"CodePipeline"},{"id":"slack","name":"Slack"}]},{"title":"Dagster asset freshness watcher","prompt":"Build a scheduled workflow that polls Dagster assets, checks each critical asset’s latest materialization timestamp against a freshness threshold, alerts when an asset becomes stale, and opens a Linear ticket for the data-platform team.","integrations":[{"id":"linear","name":"Linear"},{"id":"dagster","name":"Dagster"}]},{"title":"Datadog alert-to-Linear bridge","prompt":"Build a scheduled workflow that polls Datadog monitors for any in an alerting state, classifies severity, creates a Linear ticket for non-paging issues with full context, and posts a Slack notification linking both.","integrations":[{"id":"linear","name":"Linear"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"Devin bug-fix dispatcher","prompt":"Create a workflow that watches for new critical errors, packages the stack trace and reproduction steps into a Devin prompt, creates a session, and updates a Linear ticket with the Devin session link and any pull requests it opens.","integrations":[{"id":"linear","name":"Linear"},{"id":"devin","name":"Devin"}]},{"title":"Devin issue-to-PR runner","prompt":"Create a workflow triggered when a Linear issue is labeled ready-for-devin that creates a Devin session with the issue context, monitors the session to completion, and comments the resulting pull request link back on the Linear issue.","integrations":[{"id":"linear","name":"Linear"},{"id":"devin","name":"Devin"}]},{"title":"Discord feature request collector","prompt":"Build a scheduled workflow that polls a Discord feedback channel for new posts, classifies them as bugs vs feature requests, opens Linear tickets for actionable items, and replies in-thread with the ticket link.","integrations":[{"id":"linear","name":"Linear"},{"id":"discord","name":"Discord"}]},{"title":"Dynatrace SLO burn-rate watch","prompt":"Build a scheduled hourly workflow that reads Dynatrace SLOs, flags any with a fast error-budget burn rate, and opens a Linear issue with the SLO name, remaining budget, and time to exhaustion.","integrations":[{"id":"linear","name":"Linear"},{"id":"dynatrace","name":"Dynatrace"}]},{"title":"Fireflies action-item ticket creator","prompt":"Build a workflow that extracts action items from a Fireflies meeting transcript, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"fireflies","name":"Fireflies"},{"id":"asana","name":"Asana"}]},{"title":"GitHub docs auto-updater","prompt":"Create a knowledge base connected to my GitHub repository so code and docs stay synced. Then build a scheduled weekly workflow that detects API changes, compares them against the knowledge base to find outdated documentation, and either updates Notion pages directly or creates Linear tickets for the needed changes.","integrations":[{"id":"linear","name":"Linear"},{"id":"github","name":"GitHub"},{"id":"notion","name":"Notion"}]},{"title":"GitHub weekly team digest","prompt":"Build a scheduled workflow that runs every Friday, pulls the week\'s GitHub commits, closed Linear issues, and key Slack conversations, then emails a formatted weekly summary to the team.","integrations":[{"id":"linear","name":"Linear"},{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]},{"title":"Sync GitHub events with Linear issues","prompt":"Build a workflow that creates Linear issues from GitHub pull requests and commits, and automatically updates their status when a PR is merged.","integrations":[{"id":"linear","name":"Linear"},{"id":"github","name":"GitHub"}]},{"title":"AppSheet ticket escalation","prompt":"Build a workflow that finds AppSheet rows where Priority is \\"High\\" and Status is not \\"Resolved\\", and edits each row to add an Escalated flag, then creates a Linear issue for each one.","integrations":[{"id":"linear","name":"Linear"},{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"BigQuery schema drift detector","prompt":"Create a scheduled workflow that snapshots BigQuery dataset schemas, diffs against the prior snapshot, and opens a Linear ticket on unexpected schema changes.","integrations":[{"id":"linear","name":"Linear"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"PageSpeed accessibility tracker","prompt":"Build a scheduled weekly workflow that runs Google PageSpeed Insights with the accessibility audit, writes per-page scores to a tracking table, and opens Linear tickets on regressions.","integrations":[{"id":"linear","name":"Linear"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"Grafana + Linear feature-impact","prompt":"Build a scheduled workflow that queries a Grafana data source for latency and error rates, compares each series against the prior period to spot regressions, correlates them with recent Linear releases, and posts a regression review to the team Slack with the suspected change.","integrations":[{"id":"linear","name":"Linear"},{"id":"grafana","name":"Grafana"},{"id":"slack","name":"Slack"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"grain","name":"Grain"},{"id":"slack","name":"Slack"}]},{"title":"Granola action-item ticket creator","prompt":"Create a workflow that extracts action items from Granola meeting notes, creates Linear or Asana tasks for each with owners and due dates, and posts a summary to Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"granola","name":"Granola"},{"id":"asana","name":"Asana"}]},{"title":"Escalate Bug Reports","prompt":"When a Help Scout conversation is tagged bug, read its threads, write a reproducible bug summary, file it as a Linear issue, and add an internal note on the conversation linking the issue.","integrations":[{"id":"linear","name":"Linear"},{"id":"helpscout","name":"Help Scout"}]},{"title":"IAM least-privilege recommender","prompt":"Create a workflow that simulates IAM principal policies against expected actions, generates least-privilege policy suggestions for over-permissioned roles, and opens Linear tickets for engineers to apply.","integrations":[{"id":"linear","name":"Linear"},{"id":"iam","name":"AWS IAM"}]},{"title":"incident.io action-item tracker","prompt":"Build a workflow that watches incident.io for new follow-up actions, creates Linear tickets for each, and writes a tracking table that surfaces overdue actions on a weekly digest.","integrations":[{"id":"linear","name":"Linear"},{"id":"incidentio","name":"incident.io"}]},{"title":"Intercom to Linear bug ticketer","prompt":"Build a workflow triggered by new Intercom conversations that classifies whether the message is a bug report, extracts the repro steps and affected area, creates a Linear issue with the conversation transcript attached, and replies in Intercom with the issue ID.","integrations":[{"id":"linear","name":"Linear"},{"id":"intercom","name":"Intercom"}]},{"title":"Jira to Linear migrator","prompt":"Create a workflow that imports a Jira project into Linear, preserving status mapping, labels, comments, and assignees, and writes a mapping table for redirect URLs.","integrations":[{"id":"linear","name":"Linear"},{"id":"jira","name":"Jira"}]},{"title":"Jotform support intake into tickets","prompt":"Build a workflow that reads new Jotform support form submissions, has an agent assign a priority and category from the answers, and opens a matching Linear issue with the submission details in the description.","integrations":[{"id":"linear","name":"Linear"},{"id":"jotform","name":"Jotform"}]},{"title":"Lambda deprecated runtime sweep","prompt":"Create a scheduled monthly workflow that lists all Lambda functions, flags any running a deprecated runtime, groups them by owning team using function tags, and opens a Linear ticket per team with the list of functions that need upgrading.","integrations":[{"id":"linear","name":"Linear"},{"id":"lambda","name":"Lambda"}]},{"title":"Lambda public URL detector","prompt":"Build a scheduled workflow that lists Lambda function URL configurations across your functions, flags any whose auth type is NONE or whose CORS allows any origin, and opens a Linear ticket for each exposed endpoint.","integrations":[{"id":"linear","name":"Linear"},{"id":"lambda","name":"Lambda"}]},{"title":"LaunchDarkly stale-flag sweeper","prompt":"Create a scheduled workflow that identifies LaunchDarkly flags inactive for 60 days, opens Linear tickets to remove them, and writes the cleanup queue to a dashboard table.","integrations":[{"id":"linear","name":"Linear"},{"id":"launchdarkly","name":"LaunchDarkly"}]},{"title":"LaunchDarkly + Linear release planner","prompt":"Create a workflow that watches Linear releases marked behind a LaunchDarkly flag, validates the flag exists, posts the rollout plan to Slack, and tracks rollout progress on the release ticket.","integrations":[{"id":"linear","name":"Linear"},{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"slack","name":"Slack"}]},{"title":"Linear knowledge search","prompt":"Create a knowledge base connected to my Linear workspace so all issues, comments, project updates, and decisions are automatically synced and searchable. Then build an agent I can ask things like \\"why did we deprioritize the mobile app?\\" or \\"what was the root cause of the checkout bug?\\" and get answers traced back to specific issues.","integrations":[{"id":"linear","name":"Linear"}]},{"title":"Linear ticket to Devin pipeline","prompt":"Create a workflow that fires when a Linear ticket gets the \\"devin\\" label, transforms the ticket description, acceptance criteria, and linked context into a Devin prompt, creates a session, and posts the session link plus an estimated completion window back on the ticket.","integrations":[{"id":"linear","name":"Linear"},{"id":"devin","name":"Devin"}]},{"title":"Meeting notes to Linear tasks","prompt":"Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.","integrations":[{"id":"linear","name":"Linear"},{"id":"asana","name":"Asana"},{"id":"slack","name":"Slack"}]},{"title":"Linear issue updates in Slack","prompt":"Build a workflow that monitors Linear for new issues, assignments, and completions, and posts a formatted Slack message for each event so your team is always in the loop.","integrations":[{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Bug report to Linear issue","prompt":"Build a workflow that watches a Slack channel for bug reports, extracts the steps to reproduce and severity with an agent, creates a labeled Linear issue in the right team, and replies in-thread with the issue link.","integrations":[{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Linear triage labeler","prompt":"Create a workflow that on a newly created Linear issue reads the title and description, adds the right labels for type and priority, assigns it to the correct team based on the area, and comments a triage summary.","integrations":[{"id":"linear","name":"Linear"}]},{"title":"Linear sprint review digest","prompt":"Build a scheduled weekly workflow that searches Linear for issues completed and still open in the active cycle, summarizes progress and blockers with an agent, logs velocity to a table, and posts a sprint review digest to Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Logfire trace investigator","prompt":"Build a workflow that takes a Logfire trace ID, fetches every span in the trace, walks the parent-child tree to find the slowest span and the first exception, and writes a plain-English root-cause summary back as a Linear comment.","integrations":[{"id":"linear","name":"Linear"},{"id":"logfire","name":"Logfire"}]},{"title":"LogRocket bug report enrichment","prompt":"Build a workflow that triggers on a new Linear bug issue, asks LogRocket for session highlights of the affected user with the bug description as the question, and comments the session breakdown on the issue.","integrations":[{"id":"linear","name":"Linear"},{"id":"logrocket","name":"LogRocket"}]},{"title":"Claude Managed Agents support triage","prompt":"Create a workflow that opens a Claude Managed Agents session per incoming ticket, has it reproduce the issue and draft a reply, and files a Linear issue when it finds a real bug.","integrations":[{"id":"linear","name":"Linear"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Word incident postmortem","prompt":"Build a workflow triggered by a resolved Linear incident that drafts a postmortem in Word from the issue timeline, exports it as PDF, and shares the PDF in the incident Slack channel.","integrations":[{"id":"linear","name":"Linear"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"slack","name":"Slack"}]},{"title":"Mintlify feedback triage","prompt":"Create a scheduled workflow that exports Mintlify user feedback daily, has an agent classify each comment by severity and theme, and opens Linear issues for the ones that need a documentation fix.","integrations":[{"id":"linear","name":"Linear"},{"id":"mintlify","name":"Mintlify"}]},{"title":"MongoDB index health monitor","prompt":"Create a scheduled workflow that scans MongoDB collections for slow queries and missing indexes, writes a remediation table, and opens Linear tickets for the worst offenders.","integrations":[{"id":"linear","name":"Linear"},{"id":"mongodb","name":"MongoDB"}]},{"title":"New Relic anomaly investigator","prompt":"Create a workflow triggered by an alert that runs targeted NRQL queries to pull the surrounding error and latency data, searches related New Relic entities for blast radius, summarizes likely causes, and opens a Linear ticket.","integrations":[{"id":"linear","name":"Linear"},{"id":"new_relic","name":"New Relic"}]},{"title":"1Password secret rotation watcher","prompt":"Create a scheduled workflow that finds 1Password items older than the rotation policy, opens a Linear ticket per item to rotate, and writes the rotation status back.","integrations":[{"id":"linear","name":"Linear"},{"id":"onepassword","name":"1Password"}]},{"title":"Otter action items to Linear","prompt":"Build a workflow that reads the action items of each completed Otter conversation and creates a Linear issue for every item, assigned to the matching teammate by email.","integrations":[{"id":"linear","name":"Linear"},{"id":"otter","name":"Otter.ai"}]},{"title":"PagerDuty alert-to-ticket bridge","prompt":"Build a workflow that creates a PagerDuty incident from inbound monitoring alerts, opens a matching Linear issue with the same severity and links the two, and logs the pairing in a table so engineering can track alert-to-fix time.","integrations":[{"id":"linear","name":"Linear"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PostHog session replay triage","prompt":"Create a scheduled workflow that lists PostHog session recordings with rage clicks or dead clicks, scores each for severity, and creates a Linear ticket for the worst sessions.","integrations":[{"id":"linear","name":"Linear"},{"id":"posthog","name":"PostHog"}]},{"title":"PostHog event taxonomy enforcer","prompt":"Build a workflow that scans PostHog events daily, flags any new event names that violate the naming convention, and opens a Linear ticket for the engineer to clean up tracking debt.","integrations":[{"id":"linear","name":"Linear"},{"id":"posthog","name":"PostHog"}]},{"title":"RabbitMQ capacity review","prompt":"Create a scheduled weekly workflow that lists every RabbitMQ queue and exchange, identifies unused queues and queues with no bindings, and posts a cleanup proposal to a Linear issue.","integrations":[{"id":"linear","name":"Linear"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"Rippling team and title audit","prompt":"Build a scheduled monthly workflow that lists Rippling teams, titles, and job functions, flags duplicates, unused values, and inconsistent naming, writes a cleanup report file, and opens a Linear task for the people operations owner of each issue.","integrations":[{"id":"linear","name":"Linear"},{"id":"rippling","name":"Rippling"}]},{"title":"Rootly retro generator","prompt":"Create a scheduled workflow that polls Rootly for recently closed incidents, drafts the retrospective doc, pulls the Slack thread and timeline, and assigns owners for follow-up actions in Linear.","integrations":[{"id":"linear","name":"Linear"},{"id":"rootly","name":"Rootly"},{"id":"slack","name":"Slack"}]},{"title":"Rootly action-item tracker","prompt":"Build a workflow that tracks Rootly follow-up actions across incidents, opens Linear tickets, and writes a tables-based dashboard that flags overdue items by owner.","integrations":[{"id":"linear","name":"Linear"},{"id":"rootly","name":"Rootly"}]},{"title":"Sentry on-call triage agent","prompt":"Build an agent that monitors Sentry for new errors, automatically triages them by severity and affected users, creates Linear tickets for critical issues with full stack traces, and sends a Slack notification to the on-call channel.","integrations":[{"id":"linear","name":"Linear"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Sentry error triage","prompt":"Build a scheduled workflow that polls Sentry for new unresolved issues, classifies severity, groups similar issues, creates a Linear ticket on first occurrence above the threshold, and pings the owning team in Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Sentry source-map verifier","prompt":"Create a scheduled workflow that scans Sentry for issues with missing or stale source maps, writes a tracking table, and opens Linear tickets for the worst offenders.","integrations":[{"id":"linear","name":"Linear"},{"id":"sentry","name":"Sentry"}]},{"title":"Temporal stuck workflow watcher","prompt":"Create a scheduled workflow that lists running Temporal executions, describes each one to inspect pending activities, flags workflows whose activities are retrying with high attempt counts, and opens a Linear ticket with the failure details.","integrations":[{"id":"linear","name":"Linear"},{"id":"temporal","name":"Temporal"}]},{"title":"Tinybird anomaly investigator","prompt":"Build a workflow triggered by an alert that calls a Tinybird pipe to pull the surrounding event data for the affected metric, has an agent summarize the likely cause, and opens a Linear issue with the supporting query results attached.","integrations":[{"id":"linear","name":"Linear"},{"id":"tinybird","name":"Tinybird"}]},{"title":"TinyFish signup flow QA","prompt":"Build a workflow that runs a TinyFish agent in strict mode against the staging signup flow every morning, checks that account creation succeeds end to end, and opens a Linear issue with the failing step when it does not.","integrations":[{"id":"linear","name":"Linear"},{"id":"tinyfish","name":"TinyFish"}]},{"title":"Trello + Linear bridge","prompt":"Create a workflow that mirrors Trello cards in a chosen list into Linear issues, keeps status and comments in sync, and writes the link back to the Trello card.","integrations":[{"id":"linear","name":"Linear"},{"id":"trello","name":"Trello"}]},{"title":"UptimeRobot incident to Linear","prompt":"Build a scheduled workflow that polls UptimeRobot for active incidents, and for any new incident creates a Linear ticket with the monitor name, cause, and root-cause URL, then posts the ticket link to Slack.","integrations":[{"id":"linear","name":"Linear"},{"id":"uptimerobot","name":"UptimeRobot"},{"id":"slack","name":"Slack"}]},{"title":"Vanta vendor review pipeline","prompt":"Build a scheduled workflow that lists Vanta vendors whose next security review is due within 30 days, looks up each vendor’s risk levels and contract dates, and creates a review task in the team’s project tracker.","integrations":[{"id":"linear","name":"Linear"},{"id":"vanta","name":"Vanta"}]},{"title":"Vercel deploy log triage","prompt":"Create a workflow that fires after each Vercel deployment, fetches the build and runtime logs, classifies warnings and errors with an agent, groups recurring issues, and opens a Linear ticket per cluster so platform regressions get addressed early.","integrations":[{"id":"linear","name":"Linear"},{"id":"vercel","name":"Vercel"}]}]},{"id":"linkedin","type":"linkedin","slug":"linkedin","name":"LinkedIn","description":"Share posts and manage your LinkedIn presence","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/linkedin","authType":"oauth","connections":[{"id":"linkedin","kind":"oauth","label":"Connect with OAuth","providerId":"linkedin","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/linkedin","requiredScopes":[{"id":"profile","label":"Access profile information"},{"id":"openid","label":"Standard authentication"},{"id":"email","label":"Access email address"},{"id":"w_member_social","label":"Post, comment, and like posts on your behalf"}],"fields":[]}],"operations":[{"name":"Share Post","description":"Share a post to your personal LinkedIn feed"},{"name":"Get Profile","description":"Retrieve your LinkedIn profile information"}],"triggers":[],"skills":[{"name":"publish-linkedin-post","description":"Draft and share a post to your LinkedIn feed with a hook, value, and a clear call-to-action.","content":"# Publish LinkedIn Post\\n\\nWrite and publish an engagement-optimized post to your LinkedIn feed.\\n\\n## Steps\\n1. Take the source idea, article, or update to post about.\\n2. Draft post text with a strong first-line hook, two to three lines of value or insight, and a clear call-to-action, kept within LinkedIn length limits.\\n3. Share Post with the drafted text and a visibility of PUBLIC or CONNECTIONS.\\n\\n## Output\\nConfirmation the post was shared, the created post ID, and the final post text used."},{"name":"repurpose-content-to-post","description":"Turn a blog post, release note, or announcement into a punchy LinkedIn post and share it.","content":"# Repurpose Content to Post\\n\\nRepurpose long-form content into a native LinkedIn post.\\n\\n## Steps\\n1. Read the source content and pull out the single most compelling insight or takeaway.\\n2. Rewrite it as a standalone LinkedIn post with a hook, a concise body, and a call-to-action or link.\\n3. Share Post with PUBLIC visibility.\\n\\n## Output\\nThe published post ID and the post text, plus a note of the source it was derived from."},{"name":"get-my-profile","description":"Fetch your LinkedIn profile information for use in downstream personalization or logging.","content":"# Get My Profile\\n\\nRetrieve your authenticated LinkedIn profile.\\n\\n## Steps\\n1. Run Get Profile to fetch the connected account profile.\\n2. Extract the fields you need, such as name and identifiers, for personalization or record-keeping.\\n\\n## Output\\nThe profile JSON and a short summary of the key fields available."}],"templates":[{"title":"Ashby candidate enricher","prompt":"Create a workflow that takes new Ashby candidates, researches each across LinkedIn and the web for relevant background, writes a structured profile summary onto the candidate as an Ashby note, and updates a recruiting table with research links.","integrations":[{"id":"linkedin","name":"LinkedIn"},{"id":"ashby","name":"Ashby"}]},{"title":"Gamma weekly content carousel","prompt":"Create a scheduled workflow that turns the week’s top blog posts into a multi-slide Gamma carousel, then queues the export for X and LinkedIn posting.","integrations":[{"id":"linkedin","name":"LinkedIn"},{"id":"gamma","name":"Gamma"},{"id":"x","name":"X"}]},{"title":"Greenhouse candidate enricher","prompt":"Create a workflow that watches for new Greenhouse candidates, enriches each profile with LinkedIn background, GitHub activity, and public writing, and writes a structured research summary to a recruiting table for recruiters to review.","integrations":[{"id":"linkedin","name":"LinkedIn"},{"id":"greenhouse","name":"Greenhouse"},{"id":"github","name":"GitHub"}]},{"title":"LinkedIn content engine","prompt":"Build a workflow that scrapes my company blog for new posts, generates LinkedIn posts with hooks, insights, and calls-to-action optimized for engagement, and saves drafts as files for my review before posting to LinkedIn.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"LinkedIn news-to-post writer","prompt":"Build a scheduled workflow that searches the web for news in my industry, drafts a short take with a hook and a call-to-action for each top story, and shares the best one to my LinkedIn feed.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"LinkedIn launch announcer","prompt":"Create a workflow that on a launch trigger from a table drafts a LinkedIn announcement post with the key details and a link, shares it to my LinkedIn feed, and marks the row as posted.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"LinkedIn weekly recap poster","prompt":"Build a scheduled weekly workflow that summarizes the week’s wins from a table, drafts a recap post with an agent, and shares it to my LinkedIn feed.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"LinkedIn content scheduler","prompt":"Create a workflow that reads a tables-based LinkedIn content calendar, posts each entry at the scheduled time, and writes the post URL back to the row.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"Blog-to-LinkedIn repurposer","prompt":"Build a workflow that on a newly published blog post drafts a punchy LinkedIn post summarizing the key insight with an agent, shares it to my LinkedIn profile, and logs the post URL to a content table for tracking.","integrations":[{"id":"linkedin","name":"LinkedIn"}]},{"title":"LinkedIn thought-leadership cadence","prompt":"Create a scheduled workflow that picks the next idea from a content table, expands it into a full LinkedIn post with an agent, shares it to my LinkedIn feed, and logs the publish time back to the row.","integrations":[{"id":"linkedin","name":"LinkedIn"}]}]},{"id":"linkup","type":"linkup","slug":"linkup","name":"Linkup","description":"Search the web with Linkup","category":"Search","docsUrl":"https://docs.sim.ai/integrations/linkup","authType":"api-key","connections":[],"operations":[{"name":"Linkup Search","description":"Search the web for information using Linkup"}],"triggers":[],"skills":[{"name":"answer-with-citations","description":"Answer a question with Linkup using a sourced answer and surface the supporting source URLs.","content":"# Answer with Citations\\n\\nGround an answer in live web facts using Linkup.\\n\\n## Steps\\n1. Set the search query to the user question, phrased clearly.\\n2. Choose the Answer output type and include sources so the response carries verifiable URLs.\\n3. Use Deep search depth for complex or multi-part questions, otherwise Standard.\\n4. Present the answer and attach the source links.\\n\\n## Output\\nA concise answer followed by a list of the source URLs that support it."},{"name":"gather-research-sources","description":"Run a Linkup search and return a ranked list of relevant sources with snippets for a topic.","content":"# Gather Research Sources\\n\\nCollect authoritative sources on a topic for downstream research.\\n\\n## Steps\\n1. Set the search query to the research topic, narrowing with key terms.\\n2. Choose the Search output type to get raw results with sources.\\n3. Optionally restrict or exclude domains, and set a from and to date to bound recency.\\n4. Review the returned sources and order them by relevance.\\n\\n## Output\\nA ranked list of sources with titles, URLs, and snippets, ready to feed a summarizer or knowledge base."},{"name":"monitor-topic-mentions","description":"Search Linkup for recent mentions of a topic, competitor, or brand within a date window.","content":"# Monitor Topic Mentions\\n\\nTrack fresh mentions of a topic or competitor.\\n\\n## Steps\\n1. Set the search query to the brand, competitor, or topic to monitor.\\n2. Use the Search output type and set the from date to the start of the window you want to cover.\\n3. Optionally restrict to news or specific domains.\\n4. Filter the results to genuinely new or relevant mentions and summarize each.\\n\\n## Output\\nA list of new mentions with source URL, date, and a one-line summary of each."}],"templates":[{"title":"Linkup research agent","prompt":"Build a research agent that uses Linkup to find authoritative sources on a topic, returns answers with citations, and saves long-form research to a knowledge base.","integrations":[{"id":"linkup","name":"Linkup"}]},{"title":"Linkup daily digest","prompt":"Create a scheduled daily workflow that runs Linkup searches on tracked topics, summarizes the top hits with citations, and emails the user a research digest.","integrations":[{"id":"linkup","name":"Linkup"},{"id":"gmail","name":"Gmail"}]},{"title":"Linkup competitor monitor","prompt":"Build a scheduled workflow that runs Linkup searches for competitor mentions weekly, scores each by relevance, and writes a log to a tables-based competitive intel base.","integrations":[{"id":"linkup","name":"Linkup"}]},{"title":"Linkup CRM account refresh","prompt":"Create a scheduled workflow that for accounts in the CRM runs Linkup research on each weekly, surfaces new signals, and writes the digest into the account record.","integrations":[{"id":"linkup","name":"Linkup"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Linkup + Slack research bot","prompt":"Build a Slack bot that answers research questions with Linkup-grounded citations, hands off to a human on low-confidence answers, and logs each conversation.","integrations":[{"id":"linkup","name":"Linkup"},{"id":"slack","name":"Slack"}]},{"title":"Linkup deep-research file","prompt":"Create a workflow that for a chosen topic runs Linkup deep research, captures the structured findings, and writes a full report file with citations.","integrations":[{"id":"linkup","name":"Linkup"}]},{"title":"Linkup pipeline-research feeder","prompt":"Build a workflow that takes a list of accounts in a research table, runs Linkup on each for the latest news, and writes findings back to the row.","integrations":[{"id":"linkup","name":"Linkup"}]}]},{"id":"linq","type":"linq","slug":"linq","name":"Linq","description":"Send iMessage, SMS, and RCS messages and manage conversations with Linq","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/linq","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send a message to an existing chat, with optional media, link, effect, or reply"},{"name":"Create Chat","description":"Start a new iMessage, SMS, or RCS chat and send the first message"},{"name":"List Chats","description":"List chats, optionally filtered by sender or participant handle"},{"name":"Get Chat","description":"Retrieve a chat by ID, including participants and line health"},{"name":"Update Chat","description":"Update chat properties such as group display name and icon"},{"name":"Mark Chat as Read","description":"Mark messages in a chat as read (only applies to 1:1 iMessage/RCS; no effect on group chats)"},{"name":"Leave Chat","description":"Leave an iMessage group chat (4+ active participants; not supported for direct chats)"},{"name":"Add Participant","description":"Add a participant to a group chat (3+ existing participants)"},{"name":"Remove Participant","description":"Remove a participant from a group chat (minimum 3 participants must remain)"},{"name":"Start Typing","description":"Show a typing indicator in a one-on-one chat (iMessage only, not group chats)"},{"name":"Stop Typing","description":"Stop the typing indicator in a one-on-one chat (iMessage only, not group chats)"},{"name":"Send Voice Memo","description":"Send a voice memo to a chat from a URL or a pre-uploaded attachment"},{"name":"Share Contact Card","description":"Share your configured contact card (Name and Photo Sharing) with a chat"},{"name":"List Messages","description":"List messages in a chat with pagination"},{"name":"List Thread","description":"List all messages in the thread that contains a given message"},{"name":"Get Message","description":"Retrieve a single message by ID, including parts, reactions, and delivery status"},{"name":"Edit Message","description":"Edit the text of a sent message (up to 5 times, within 15 minutes of sending; iMessage only)"},{"name":"Delete Message","description":"Delete a message from the Linq API only (does not unsend it; recipients still see it)"},{"name":"React to Message","description":"Add or remove a tapback reaction on a message"},{"name":"Create Attachment","description":"Upload a file to Linq as a reusable attachment (max 100MB) and get an attachment ID to send in messages"},{"name":"Get Attachment","description":"Retrieve metadata for an attachment, including its download URL and status"},{"name":"Delete Attachment","description":"Permanently delete an attachment owned by your account"},{"name":"List Phone Numbers","description":"List all phone numbers assigned to your partner account, with line health"},{"name":"Check iMessage","description":"Check whether an address (phone number or email) supports iMessage"},{"name":"Check RCS","description":"Check whether an address (phone number or email) supports RCS"},{"name":"Get Contact Card","description":"Retrieve contact cards, optionally filtered by phone number"},{"name":"Create Contact Card","description":"Set up a contact card (Name and Photo Sharing) for a phone number"},{"name":"Update Contact Card","description":"Partially update an existing active contact card for a phone number"},{"name":"Create Webhook Subscription","description":"Subscribe an HTTPS endpoint to Linq webhook events"},{"name":"List Webhook Subscriptions","description":"List all webhook subscriptions on your account"},{"name":"Get Webhook Subscription","description":"Retrieve a webhook subscription by ID"},{"name":"Update Webhook Subscription","description":"Update a webhook subscription (target URL, events, phone filter, or active state)"},{"name":"Delete Webhook Subscription","description":"Delete a webhook subscription from your account"},{"name":"List Webhook Events","description":"List all webhook event types available to subscribe to"}],"triggers":[{"id":"linq_message_received","name":"Linq Message Received","description":"Trigger workflow when an inbound message is received"},{"id":"linq_message_delivered","name":"Linq Message Delivered","description":"Trigger workflow when a message is delivered"},{"id":"linq_message_failed","name":"Linq Message Failed","description":"Trigger workflow when a message fails to deliver"},{"id":"linq_message_read","name":"Linq Message Read","description":"Trigger workflow when a message is read"},{"id":"linq_reaction_added","name":"Linq Reaction Added","description":"Trigger workflow when a reaction is added to a message"},{"id":"linq_webhook","name":"Linq Webhook (All Events)","description":"Trigger on any Linq webhook event (messages, reactions, chats, and more)"}],"skills":[{"name":"send-personalized-message","description":"Start a Linq chat and send a personalized iMessage, SMS, or RCS message to a recipient.","content":"# Send Personalized Message\\n\\nReach a person on iMessage, SMS, or RCS through Linq.\\n\\n## Steps\\n1. Create Chat with your sending number in From and the recipient handle in To.\\n2. Draft a friendly, concise message body tailored to the recipient.\\n3. Send Message to the chat with the message text, optionally setting a preferred service or media URL.\\n4. Optionally Check iMessage or Check RCS first to pick the best service for the recipient.\\n\\n## Output\\nThe chat ID, the message ID, the delivery service used, and the delivery status."},{"name":"respond-to-unread-messages","description":"List recent Linq chats and messages, draft a reply for each unread conversation, and send it.","content":"# Respond to Unread Messages\\n\\nClear an inbox by replying to recent unread Linq conversations.\\n\\n## Steps\\n1. List Chats to find active conversations, then List Messages per chat to find unread inbound messages.\\n2. For each conversation needing a reply, read the recent thread for context.\\n3. Draft a relevant reply.\\n4. Send Message to that chat ID with the drafted text.\\n\\n## Output\\nFor each handled chat: the chat ID, the reply sent, and the delivery status."},{"name":"dispatch-alert-notifications","description":"Send an RCS or SMS notification to one or more recipients from a list of alerts.","content":"# Dispatch Alert Notifications\\n\\nFan out notifications to recipients through Linq.\\n\\n## Steps\\n1. Take the list of recipients and the alert content to send.\\n2. For each recipient, Create Chat from your sending number to their handle.\\n3. Format a clear notification message and Send Message, setting the preferred service to RCS or SMS as needed.\\n4. Use an idempotency key per message so retries do not double-send.\\n\\n## Output\\nA per-recipient list of chat IDs, message IDs, and delivery statuses."}],"templates":[{"title":"Linq iMessage campaign sender","prompt":"Build a workflow that reads a contact list from a table, composes a personalized iMessage for each recipient using an agent, and sends them via Linq in batches.","integrations":[{"id":"linq","name":"Linq"}]},{"title":"Linq SMS support responder","prompt":"Create a scheduled workflow that lists recent unread Linq messages, generates a reply for each with an agent, and sends the response back to the same chat.","integrations":[{"id":"linq","name":"Linq"}]},{"title":"Linq RCS notification dispatcher","prompt":"Build a workflow that monitors a table for new alert rows, formats an RCS notification for each, and dispatches it to the relevant phone number via Linq.","integrations":[{"id":"linq","name":"Linq"}]}]},{"id":"logfire","type":"logfire","slug":"logfire","name":"Logfire","description":"Query traces, logs, and metrics in Pydantic Logfire","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/logfire","authType":"api-key","connections":[],"operations":[{"name":"Search Records","description":"Search Logfire spans and logs using structured filters for message text, service, span name, severity, environment, and exceptions. Returns the most recent matches first without writing SQL."},{"name":"Run SQL Query","description":"Run a read-only SQL query against Logfire traces, logs, and metrics. Reads the records and metrics tables using PostgreSQL-compatible syntax."},{"name":"Get Trace","description":"Fetch every span and log belonging to a Logfire trace, ordered from earliest to latest, so a single request can be reconstructed end to end."},{"name":"Get Token Info","description":"Resolve which Logfire organization and project a read token belongs to. Useful for confirming a credential targets the expected project before querying it."}],"triggers":[],"skills":[{"name":"investigate-logfire-errors","description":"Find the dominant error patterns in Logfire for a service and time window, then explain them.","content":"# Investigate Logfire Errors\\n\\nFind and explain what is failing in a service.\\n\\n## Steps\\n1. Run Search Records with the service name, a minimum level of error, and the requested time window.\\n2. Group the results by exceptionType and message to find the dominant failure patterns.\\n3. Pick the most frequent or most severe pattern and run Get Trace on one of its traceId values to see the full request path.\\n4. Read the surrounding spans to identify where in the call chain the failure originates.\\n\\n## Output\\nThe top error patterns with counts, the service and span where each originates, and a one-line likely cause per pattern. Include one representative trace ID for each."},{"name":"analyze-logfire-latency","description":"Use SQL against the Logfire records table to find the slowest operations.","content":"# Analyze Logfire Latency\\n\\nFind what is slow and quantify it.\\n\\n## Steps\\n1. Run a SQL Query aggregating duration over the records table, for example: SELECT span_name, count(*) AS n, avg(duration) AS avg_s, approx_percentile_cont(duration, 0.95) AS p95_s FROM records WHERE duration IS NOT NULL GROUP BY span_name ORDER BY p95_s DESC.\\n2. Narrow to a service with a WHERE service_name = \'...\' clause when one was named.\\n3. Take the worst span_name and run Search Records for its slowest instances, then Get Trace on one to see where the time goes.\\n\\n## Output\\nA table of the slowest operations by p95 with call counts, and for the worst one a breakdown of which child span consumes the time."},{"name":"reconstruct-logfire-trace","description":"Walk a single Logfire trace end to end and explain what happened.","content":"# Reconstruct Logfire Trace\\n\\nTurn a trace ID into a readable story of one request.\\n\\n## Steps\\n1. Run Get Trace with the trace ID. Spans come back earliest first.\\n2. Build the tree using spanId and parentSpanId to see which operations nested inside which.\\n3. Note each span duration to find where time was spent, and flag any span where isException is true.\\n4. If the trace is truncated, raise the limit and refetch.\\n\\n## Output\\nAn ordered walkthrough of the request: the entry point, each significant nested operation with its duration, and where it failed or ended. Call out the single slowest span and the first exception."},{"name":"track-logfire-llm-cost","description":"Aggregate LLM token usage and spend per model from Logfire GenAI spans.","content":"# Track Logfire LLM Cost\\n\\nAttribute AI spend to models and services.\\n\\n## Steps\\n1. Run a SQL Query against the records table reading the GenAI attributes Logfire records under OpenTelemetry conventions, for example: SELECT date_trunc(\'day\', start_timestamp) AS day, attributes->>\'gen_ai.request.model\' AS model, sum((attributes->\'gen_ai.usage.input_tokens\')::numeric) AS input_tokens, sum((attributes->\'gen_ai.usage.output_tokens\')::numeric) AS output_tokens FROM records WHERE attributes ? \'gen_ai.request.model\' GROUP BY day, model ORDER BY day DESC.\\n2. Add sum((attributes->\'operation.cost\')::numeric) AS cost_usd when the instrumentation records cost.\\n3. Slice by service_name or deployment_environment to attribute spend to a team or environment.\\n4. Cast JSON attributes to numeric before any arithmetic — they are stored as JSON, not numbers.\\n\\n## Output\\nSpend and token totals broken down by model and day, the biggest contributor, and any model whose cost per call moved materially."},{"name":"verify-logfire-token-target","description":"Confirm which Logfire organization and project a read token points at.","content":"# Verify Logfire Token Target\\n\\nCheck a credential before trusting the data it returns.\\n\\n## Steps\\n1. Run Get Token Info to resolve the organization and project the read token belongs to.\\n2. Compare them against the project the user expected to query.\\n3. If they differ, stop and report the mismatch rather than querying — the token points at another project.\\n4. When they match, proceed with Search Records or a SQL Query.\\n\\n## Output\\nThe organization and project names behind the token, and a clear statement of whether they match the expected target."}],"templates":[{"title":"Logfire error digest","prompt":"Create a scheduled workflow that runs every morning, searches Logfire for records at error level or above from the last 24 hours, groups them by service and exception type, and posts a ranked digest to Slack with the worst offenders first.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"slack","name":"Slack"}]},{"title":"Logfire trace investigator","prompt":"Build a workflow that takes a Logfire trace ID, fetches every span in the trace, walks the parent-child tree to find the slowest span and the first exception, and writes a plain-English root-cause summary back as a Linear comment.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"linear","name":"Linear"}]},{"title":"Logfire latency watchdog","prompt":"Create a workflow that runs every 15 minutes, uses SQL against the Logfire records table to compute p95 duration per span_name over the window, compares it against the prior window stored in a table, and pages on-call through PagerDuty when latency regresses more than 50 percent.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Logfire LLM cost tracker","prompt":"Build a scheduled daily workflow that queries Logfire for spans emitted by LLM instrumentation, extracts token counts from the attributes JSON, aggregates spend per model and per service into a table, and emails finance when a service trends over budget.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"gmail","name":"Gmail"}]},{"title":"Logfire release regression check","prompt":"Create a workflow that fires after each deploy, waits for a soak period, then searches Logfire for new exception types in the production environment that were not present before the release, and comments the diff on the GitHub pull request that shipped it.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"github","name":"GitHub"}]},{"title":"Logfire customer issue triage","prompt":"Build a workflow triggered by a support ticket that pulls the customer request ID from the ticket, searches Logfire for records matching that ID, fetches the full trace when one is found, and replies in Zendesk with whether the failure was user error or a backend fault.","integrations":[{"id":"logfire","name":"Logfire"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Logfire weekly reliability review","prompt":"Create a scheduled weekly workflow that runs SQL against Logfire for error rate, throughput, and duration percentiles per service, writes a narrative reliability review file for the SRE team, and highlights every service whose error budget burn accelerated week over week.","integrations":[{"id":"logfire","name":"Logfire"}]},{"title":"Logfire agent run auditor","prompt":"Build a workflow that searches Logfire for spans from your AI agent service where an exception was recorded, fetches each full trace to capture the prompt and tool calls that led to the failure, and logs a structured failure catalog to a table for prompt tuning.","integrations":[{"id":"logfire","name":"Logfire"}]}]},{"id":"logrocket","type":"logrocket","slug":"logrocket","name":"LogRocket","description":"Summarize sessions, manage users, and tag releases in LogRocket","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/logrocket","authType":"api-key","connections":[],"operations":[{"name":"Request Highlights","description":"Start a Galileo session highlights job for a user. Returns a request ID to poll with LogRocket\'s Get Highlights operation."},{"name":"Get Highlights","description":"Retrieve the result of a Galileo session highlights request. Status is PENDING until generation finishes, then READY or FAILED."},{"name":"List Exported Sessions","description":"List exported session files from the LogRocket Data Export API. Returns download URLs for JSON Lines exports, oldest first, plus a cursor for the next page."},{"name":"Get Audit Logs","description":"Export audit log entries from LogRocket, recording who viewed sessions and what actions were taken. Paginated with a cursor."},{"name":"Identify User","description":"Create or update a LogRocket user profile with demographic, financial, and engagement traits."},{"name":"Create Release","description":"Register a release version in LogRocket so uploaded source maps can decode stack traces for it. Fails with a conflict if the version already exists."}],"triggers":[],"skills":[{"name":"summarize-user-sessions","description":"Request LogRocket session highlights for a user, wait for the job to finish, and report what happened in their sessions.","content":"# Summarize User Sessions\\n\\nUse LogRocket to explain what a specific user did and where they got stuck.\\n\\n## Steps\\n1. Identify the user by email or user ID.\\n2. Optionally narrow to a time window and supply a focused question, e.g. why checkout failed.\\n3. Request session highlights and keep the returned request ID.\\n4. Poll for the result until the status is READY. It typically takes one to three minutes. A FAILED status means the request should be retried.\\n\\n## Output\\nThe overall highlights summary plus the per-session breakdown, each with its recording ID. Note the time window covered."},{"name":"investigate-reported-bug","description":"Pull LogRocket session highlights for the user who reported a bug and turn them into reproduction steps.","content":"# Investigate Reported Bug\\n\\nTurn a vague bug report into concrete reproduction steps using LogRocket sessions.\\n\\n## Steps\\n1. Extract the reporting user email or ID and the time the problem occurred.\\n2. Request session highlights for that user, scoped to a window around the report, using the bug description as the question.\\n3. Wait for the result and read the per-session highlights.\\n4. Map the described actions into ordered reproduction steps and note the failing step.\\n\\n## Output\\nReproduction steps, the observed failure, and links to the relevant recording IDs."},{"name":"sync-user-traits","description":"Create or update a LogRocket user profile with name, email, and custom traits so sessions can be segmented.","content":"# Sync User Traits\\n\\nKeep LogRocket user profiles current so sessions can be filtered by customer attributes.\\n\\n## Steps\\n1. Determine the user ID to write to. This is the identifier LogRocket already associates with the sessions.\\n2. Gather the traits to set, such as plan, lifecycle stage, or account value. Keep every key and value under 1024 characters.\\n3. Optionally supply a timestamp describing when the data was true.\\n4. Write the profile.\\n\\n## Output\\nConfirm which fields were written and note that every trait value is stored as a string."},{"name":"review-session-access","description":"Page through the LogRocket audit log to report who viewed sessions and what actions they took.","content":"# Review Session Access\\n\\nAudit who has been viewing LogRocket sessions.\\n\\n## Steps\\n1. Read the first page of audit logs, choosing a page size.\\n2. While the response reports more pages, follow the returned cursor to fetch the next page.\\n3. Group entries by actor and action to see who viewed what.\\n\\n## Output\\nA per-actor summary of actions with timestamps, plus any access that looks unexpected."},{"name":"collect-exported-sessions","description":"List LogRocket data export files and collect their download URLs for downstream processing.","content":"# Collect Exported Sessions\\n\\nGather the session export files LogRocket has produced.\\n\\n## Steps\\n1. List exported sessions, optionally starting from a timestamp and choosing a page size of up to 100.\\n2. Note that results come back oldest first, and follow the returned cursor to page forward.\\n3. Collect the download URL for each export file. Each file is JSON Lines.\\n\\n## Output\\nThe list of export URLs, the range they cover, and the cursor to resume from next run."}],"templates":[{"title":"LogRocket session triage from support tickets","prompt":"Build a workflow that triggers on a new Zendesk ticket, requests LogRocket session highlights for the reporting user, polls until the result is ready, and posts the session summary back onto the ticket as an internal note.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"zendesk","name":"Zendesk"}]},{"title":"LogRocket churn-risk session review","prompt":"Create a scheduled workflow that reads at-risk accounts from a table, requests LogRocket session highlights for each contact, and writes the summarized friction points back to the table for the customer success team.","integrations":[{"id":"logrocket","name":"LogRocket"}]},{"title":"LogRocket bug report enrichment","prompt":"Build a workflow that triggers on a new Linear bug issue, asks LogRocket for session highlights of the affected user with the bug description as the question, and comments the session breakdown on the issue.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"linear","name":"Linear"}]},{"title":"LogRocket audit log compliance export","prompt":"Create a scheduled workflow that pages through the LogRocket audit log every night, writes each entry to a compliance table, and alerts Slack when a session was viewed by someone outside the approved reviewer list.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"slack","name":"Slack"}]},{"title":"LogRocket session export pipeline","prompt":"Build a scheduled workflow that lists newly exported LogRocket session files, downloads each JSON Lines export, and loads the parsed events into a warehouse table for analysis.","integrations":[{"id":"logrocket","name":"LogRocket"}]},{"title":"LogRocket profile sync from CRM","prompt":"Create a workflow that watches HubSpot contact updates and pushes the plan, lifecycle stage, and account value into LogRocket as user traits so sessions can be filtered by customer segment.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"hubspot","name":"HubSpot"}]},{"title":"LogRocket + Sentry incident context","prompt":"Build a workflow that triggers on a new Sentry issue, requests LogRocket session highlights for the impacted user, and posts a combined stack trace plus session narrative into the incident Slack channel.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"LogRocket release tagging on deploy","prompt":"Build a workflow that runs after a GitHub deployment succeeds, registers the deployed version as a LogRocket release so stack traces decode against it, and posts the tagged version to the release channel in Slack.","integrations":[{"id":"logrocket","name":"LogRocket"},{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]}]},{"id":"loops","type":"loops","slug":"loops","name":"Loops","description":"Manage contacts and send emails with Loops","category":"Email","docsUrl":"https://docs.sim.ai/integrations/loops","authType":"api-key","connections":[],"operations":[{"name":"Create Contact","description":"Create a new contact in your Loops audience with an email address and optional properties like name, user group, and mailing list subscriptions."},{"name":"Update Contact","description":"Update an existing contact in Loops by email or userId. Creates a new contact if no match is found (upsert). Can update name, subscription status, user group, mailing lists, and custom properties."},{"name":"Find Contact","description":"Find a contact in Loops by email address or userId. Returns an array of matching contacts with all their properties including name, subscription status, user group, and mailing lists."},{"name":"Delete Contact","description":"Delete a contact from Loops by email address or userId. At least one identifier must be provided."},{"name":"Send Transactional Email","description":"Send a transactional email to a recipient using a Loops template. Supports dynamic data variables for personalization and optionally adds the recipient to your audience."},{"name":"Send Event","description":"Send an event to Loops to trigger automated email sequences for a contact. Identify the contact by email or userId and include optional event properties and mailing list changes."},{"name":"List Mailing Lists","description":"Retrieve all mailing lists from your Loops account. Returns each list with its ID, name, description, and public/private status."},{"name":"List Transactional Emails","description":"Retrieve a list of published transactional email templates from your Loops account. Returns each template with its ID, name, created/updated timestamps, and data variables."},{"name":"Create Contact Property","description":"Create a new custom contact property in your Loops account. The property name must be in camelCase format."},{"name":"List Contact Properties","description":"Retrieve a list of contact properties from your Loops account. Returns each property with its key, label, and data type. Can filter to show all properties or only custom ones."},{"name":"Check Contact Suppression","description":"Check whether a Loops contact is on the suppression list (bounced, complained, or unsubscribed) by email address or userId."},{"name":"Remove Contact Suppression","description":"Remove a Loops contact from the suppression list by email address or userId, allowing them to receive emails again. Subject to a team removal quota."},{"name":"Get Transactional Email","description":"Retrieve a single transactional email template from your Loops account by its ID, including its data variables and draft/published message IDs."}],"triggers":[{"id":"loops_email_delivered","name":"Loops Email Delivered","description":"Trigger workflow when a Loops email is delivered"},{"id":"loops_email_opened","name":"Loops Email Opened","description":"Trigger workflow when a Loops email is opened"},{"id":"loops_email_clicked","name":"Loops Email Clicked","description":"Trigger workflow when a link in a Loops email is clicked"},{"id":"loops_email_hard_bounced","name":"Loops Email Hard Bounced","description":"Trigger workflow when a Loops email hard bounces"},{"id":"loops_email_soft_bounced","name":"Loops Email Soft Bounced","description":"Trigger workflow when a Loops email soft bounces"},{"id":"loops_campaign_email_sent","name":"Loops Campaign Email Sent","description":"Trigger workflow when a Loops campaign email is sent"},{"id":"loops_loop_email_sent","name":"Loops Loop Email Sent","description":"Trigger workflow when a Loops loop email is sent"},{"id":"loops_transactional_email_sent","name":"Loops Transactional Email Sent","description":"Trigger workflow when a Loops transactional email is sent"}],"skills":[{"name":"onboard-new-contact","description":"Create a Loops contact on signup and send a transactional welcome email.","content":"# Onboard New Contact\\n\\nAdd a new signup to Loops and welcome them.\\n\\n## Steps\\n1. Create Contact with the email, first and last name, and any source or user group, plus custom properties like plan.\\n2. Send Transactional Email using the welcome template ID, passing the contact data as data variables.\\n3. Optionally Send Event with a signup event name so any onboarding automation begins.\\n\\n## Output\\nThe created contact ID, confirmation the welcome email was sent, and any event fired."},{"name":"send-product-event","description":"Fire a Loops event for a user with structured properties to trigger lifecycle automations.","content":"# Send Product Event\\n\\nDrive Loops automations from real product behavior.\\n\\n## Steps\\n1. Identify the contact by email or user ID and the event that occurred.\\n2. Build event properties as a JSON object with the relevant values, such as plan and amount.\\n3. Send Event with the event name, the contact identifier, and the properties.\\n4. Optionally update mailing list subscriptions in the same call.\\n\\n## Output\\nConfirmation the event was sent, the contact it was attributed to, and the properties included."},{"name":"enrich-contact-properties","description":"Find a Loops contact and update it with enriched custom properties and user group.","content":"# Enrich Contact Properties\\n\\nKeep Loops contact data complete and current.\\n\\n## Steps\\n1. Find Contact by email or user ID to read existing fields and spot gaps.\\n2. Gather the missing or stale values from your source or research.\\n3. Update Contact with the new custom properties, user group, and any name fields.\\n\\n## Output\\nThe updated contact ID and a summary of the properties that were set or changed."},{"name":"send-transactional-email","description":"Send a Loops transactional email from a template with personalized data variables.","content":"# Send Transactional Email\\n\\nDeliver a templated transactional email through Loops.\\n\\n## Steps\\n1. Confirm the transactional email template ID to use.\\n2. Build the data variables JSON to match the variable names in the template, such as name and a confirmation URL.\\n3. Send Transactional Email with the recipient email, template ID, and data variables, attaching files if needed.\\n\\n## Output\\nConfirmation of send success and the template ID and recipient used."},{"name":"manage-suppression-compliance","description":"Check and clear Loops suppression status for a contact to keep deliverability and unsubscribe compliance in check.","content":"# Manage Suppression Compliance\\n\\nKeep Loops sending compliant and deliverable.\\n\\n## Steps\\n1. Check Contact Suppression by email or user ID to see if the contact bounced, complained, or unsubscribed.\\n2. If the contact should be re-enabled (e.g. a confirmed re-opt-in), Remove Contact Suppression for the same identifier, noting the remaining removal quota.\\n3. Log the result so support and compliance workflows have an audit trail.\\n\\n## Output\\nThe suppression status before and after the change, plus the remaining removal quota."}],"templates":[{"title":"AgentMail + Loops support touch-points","prompt":"Create a scheduled workflow that polls AgentMail support threads and sends a Loops event for each customer milestone — first contact, resolved, escalated — so Loops can automate the right follow-up email based on real support outcomes.","integrations":[{"id":"loops","name":"Loops"},{"id":"agentmail","name":"AgentMail"}]},{"title":"Cal.com + Loops nurture","prompt":"Create a workflow that on a Cal.com booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic.","integrations":[{"id":"loops","name":"Loops"},{"id":"calcom","name":"Cal.com"}]},{"title":"Calendly + Loops nurture","prompt":"Create a workflow that on a Calendly booking enrolls the attendee into a Loops nurture campaign tailored to the meeting topic, ensuring follow-up emails reach them before the meeting.","integrations":[{"id":"loops","name":"Loops"},{"id":"calendly","name":"Calendly"}]},{"title":"Clerk new-signup pipeline","prompt":"Build a scheduled workflow that lists recent Clerk users, creates each new signup in HubSpot with the right lifecycle stage, and enrolls them in a Loops onboarding sequence.","integrations":[{"id":"loops","name":"Loops"},{"id":"clerk","name":"Clerk"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Clerk MFA enrollment chaser","prompt":"Create a scheduled workflow that finds Clerk users without MFA enrolled in 30 days, sends in-app prompts via Loops, and writes enrollment progress to a security dashboard.","integrations":[{"id":"loops","name":"Loops"},{"id":"clerk","name":"Clerk"}]},{"title":"Ketch consent propagator","prompt":"Build a workflow that on a consent change reads the contact’s Ketch consent state and propagates it to downstream systems — HubSpot and Loops — keeping privacy preferences in sync.","integrations":[{"id":"loops","name":"Loops"},{"id":"ketch","name":"Ketch"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Ketch subscription sync","prompt":"Build a workflow that reads each contact’s Ketch subscription topics and mirrors the opt-in state to the marketing tool so unsubscribe preferences stay consistent across systems.","integrations":[{"id":"loops","name":"Loops"},{"id":"ketch","name":"Ketch"}]},{"title":"Loops product event tracker","prompt":"Build a workflow that listens for product events from my tables, sends matching Loops events for each user with structured properties, and updates contact properties so Loops automations can branch on real product behavior.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Loops list hygiene","prompt":"Create a scheduled workflow that reads a Sim table of user activity to find accounts inactive for 90 days, updates each contact in Loops to the dormant user group and unsubscribes them from non-essential mailing lists, and writes a hygiene report to a table.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Loops onboarding orchestrator","prompt":"Build a workflow triggered on signup that creates a Loops contact, kicks off the onboarding event sequence, and updates user group as the user completes activation steps so the right Loops email goes out at every milestone.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Loops contact property enricher","prompt":"Create a scheduled workflow that reads a Sim table of contacts missing key custom properties, enriches each one using Clay or web research, updates the matching contact in Loops with the new properties, and tracks enrichment coverage in a table.","integrations":[{"id":"loops","name":"Loops"},{"id":"clay","name":"Clay"}]},{"title":"Loops signup welcome flow","prompt":"Build a workflow that on a new product signup creates the contact in Loops with their plan and source, sends a transactional welcome email, and fires a signup event so the onboarding campaign starts automatically.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Loops milestone event sender","prompt":"Create a workflow that watches product usage in a table for key milestones — first integration, team invite, plan upgrade — and sends the matching Loops event for each so lifecycle emails fire on real behavior instead of guesses.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Loops churn win-back","prompt":"Build a scheduled workflow that reads a Sim table of product-usage data to identify users who have gone inactive, sends each a personalized transactional win-back email through Loops, fires a re-engagement event, and logs who was contacted to a table for follow-up.","integrations":[{"id":"loops","name":"Loops"}]},{"title":"Mailchimp + Loops audience sync","prompt":"Create a workflow that keeps a Mailchimp audience and a Loops mailing list in sync: new Mailchimp subscribers create Loops contacts on the matching list, unsubscribes propagate both ways, and merge fields map cleanly to Loops contact properties.","integrations":[{"id":"loops","name":"Loops"},{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Resend + Loops onboarding emails","prompt":"Build a workflow that listens for new signups, creates a Loops contact with the right user group, and sends the welcome email through Resend with a personalized subject and body so the first impression is on-brand and fast.","integrations":[{"id":"loops","name":"Loops"},{"id":"resend","name":"Resend"}]},{"title":"Tinybird user-segment exporter","prompt":"Create a workflow that calls a Tinybird published endpoint with segment parameters, writes the user list to a table, and feeds it to a Loops campaign for targeted activation messaging.","integrations":[{"id":"loops","name":"Loops"},{"id":"tinybird","name":"Tinybird"}]},{"title":"Typeform onboarding follow-up","prompt":"Build a workflow that collects Typeform onboarding-flow responses, segments responders by job-to-be-done, and triggers tailored Loops email sequences for each segment.","integrations":[{"id":"loops","name":"Loops"},{"id":"typeform","name":"Typeform"}]},{"title":"Webflow + Hubspot lead-magnet","prompt":"Build a workflow that triggers on a Webflow form submission for a lead magnet, sends the asset via Loops, and writes the engagement to the matching HubSpot contact.","integrations":[{"id":"loops","name":"Loops"},{"id":"webflow","name":"Webflow"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"luma","type":"luma","slug":"luma","name":"Luma","description":"Manage events and guests on Luma","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/luma","authType":"api-key","connections":[],"operations":[{"name":"Get Event","description":"Retrieve details of a Luma event including name, time, location, hosts, and visibility settings."},{"name":"Create Event","description":"Create a new event on Luma with a name, start time, timezone, and optional details like description, location, and visibility."},{"name":"Update Event","description":"Update an existing Luma event. Only the fields you provide will be changed; all other fields remain unchanged."},{"name":"List Events","description":"List events from your Luma calendar with optional date range filtering, sorting, and pagination."},{"name":"Lookup Event","description":"Look up an event by its public URL or event ID to resolve its canonical ID, API ID, and approval status."},{"name":"Cancel Event","description":"Cancel a Luma event. This is irreversible and notifies all registered guests. Requires a cancellation token obtained from the Request Event Cancellation endpoint."},{"name":"Get Guests","description":"Retrieve the guest list for a Luma event with optional filtering by approval status, sorting, and pagination."},{"name":"Get Guest","description":"Retrieve a single guest\'s details on a Luma event, including approval status, registration timestamps, and contact info."},{"name":"Add Guests","description":"Add guests to a Luma event by email. Guests are added with Going (approved) status and receive one ticket of the default ticket type."},{"name":"Send Invites","description":"Send email invitations to guests for a Luma event. Unlike Add Guests (which registers guests directly), this emails an invite that recipients can accept."},{"name":"Update Guest Status","description":"Update a guest\'s approval status on a Luma event — approve, decline, waitlist, or set to pending. Identify the guest by email or guest ID."}],"triggers":[],"skills":[{"name":"create-event","description":"Create a Luma event with a name, start time, timezone, description, and visibility.","content":"# Create Event\\n\\nSpin up a new Luma event ready to share.\\n\\n## Steps\\n1. Decide the event name, start time as an ISO 8601 timestamp, and the IANA timezone.\\n2. Create Event with those fields plus an optional end time or duration, a Markdown description, and a meeting URL for virtual events.\\n3. Set visibility to public, members-only, or private as appropriate.\\n\\n## Output\\nThe created event ID and URL, with its start time, timezone, and visibility."},{"name":"add-guests-to-event","description":"Add a batch of guests to a Luma event from a list of emails and names.","content":"# Add Guests to Event\\n\\nBulk-register guests on a Luma event.\\n\\n## Steps\\n1. Confirm the target event ID.\\n2. Build the guests JSON array, one object per guest with an email and optional name or first and last name.\\n3. Add Guests with the event ID and the guest array.\\n\\n## Output\\nConfirmation of how many guests were added and the event ID they were added to."},{"name":"export-guest-list","description":"Pull a Luma event guest list, optionally filtered by approval status, for follow-up or enrichment.","content":"# Export Guest List\\n\\nRetrieve registrants for an event.\\n\\n## Steps\\n1. Get Guests for the event ID, optionally filtering by approval status such as approved or waitlist.\\n2. Page through results using the limit and pagination cursor until the full list is collected.\\n3. Extract the fields you need, such as email, name, approval status, and registered or checked-in timestamps.\\n\\n## Output\\nThe full guest list with key fields, ready to segment attendees from no-shows or feed into a CRM."},{"name":"send-event-reminders","description":"Pull the Luma guest list and prepare personalized reminders for upcoming registrants.","content":"# Send Event Reminders\\n\\nPrepare reminder content for an upcoming Luma event.\\n\\n## Steps\\n1. Get Event to read the name, start time, timezone, and meeting or location details.\\n2. Get Guests filtered to approved registrants, paging until complete.\\n3. For each guest, draft a personalized reminder with the event time in their context and the join or location info.\\n\\n## Output\\nA per-guest list of email addresses and drafted reminder messages, ready to hand to an email or messaging step."},{"name":"triage-event-registrations","description":"Review pending Luma registrations and approve, waitlist, or decline each guest.","content":"# Triage Event Registrations\\n\\nProcess pending registrations for an event with limited capacity.\\n\\n## Steps\\n1. Get Guests filtered to the pending_approval status, paging until complete.\\n2. Apply your approval criteria to each registrant (for example, work email domain or registration answers).\\n3. Update Guest Status for each guest to approved, waitlist, or declined, identifying them by email or guest ID.\\n\\n## Output\\nEach pending guest moved to a final approval status, with the applied status reported back per guest."},{"name":"invite-guests-to-event","description":"Email Luma event invitations to a list of prospects with an optional custom message.","content":"# Invite Guests to Event\\n\\nSend invitations that recipients can accept, rather than registering them outright.\\n\\n## Steps\\n1. Confirm the target event ID.\\n2. Build a guests JSON array, one object per invitee with an email and optional name.\\n3. Send Invites with the event ID, the guest array, and an optional short message.\\n\\n## Output\\nThe count of guests invited, ready to log or report."}],"templates":[{"title":"Discord event reminder","prompt":"Create a scheduled workflow that reads upcoming Luma or Google Calendar events, posts a reminder in the matching Discord channel 24 hours before, and pings RSVP attendees by role.","integrations":[{"id":"luma","name":"Luma"},{"id":"discord","name":"Discord"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Enrich event-attendee researcher","prompt":"Build a workflow that takes the Luma event attendee list, enriches each via Enrich, and writes a per-attendee research brief for the sales team.","integrations":[{"id":"luma","name":"Luma"},{"id":"enrich","name":"Enrich"}]},{"title":"Google Maps event-attendee proximity","prompt":"Build a workflow that for a Luma event sorts registrants by proximity to the venue via Google Maps, writes the list, and offers a quick-action transport option.","integrations":[{"id":"luma","name":"Luma"},{"id":"google_maps","name":"Google Maps"}]},{"title":"Hunter event-list enricher","prompt":"Build a workflow that takes a Luma event registrants list, finds their work emails via Hunter, and writes the verified emails into HubSpot for followup.","integrations":[{"id":"luma","name":"Luma"},{"id":"hunter","name":"Hunter.io"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Luma event reminder cadence","prompt":"Create a workflow that sends scheduled reminders to Luma event registrants — 7 days, 24 hours, 1 hour out — with personalized content based on RSVP type.","integrations":[{"id":"luma","name":"Luma"},{"id":"gmail","name":"Gmail"}]},{"title":"Luma registrant enricher","prompt":"Build a scheduled workflow that pulls the Luma event guest list, enriches each registrant with company data via Apollo, and pushes high-value attendees into HubSpot as leads.","integrations":[{"id":"luma","name":"Luma"},{"id":"apollo","name":"Apollo"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Luma post-event followup","prompt":"Create a scheduled workflow that runs the day after a Luma event, pulls the guest list, segments attendees from no-shows, sends each segment a tailored followup, and writes attendance to the CRM.","integrations":[{"id":"luma","name":"Luma"},{"id":"gmail","name":"Gmail"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Luma calendar import","prompt":"Build a scheduled workflow that pulls the Luma event guest list and creates a personalized Google Calendar invite for each new registrant with the event details, location, and prep links.","integrations":[{"id":"luma","name":"Luma"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Luma + Discord community sync","prompt":"Create a scheduled workflow that pulls the Luma event guest list and adds each new registrant to the matching Discord community channel with the right role for event access.","integrations":[{"id":"luma","name":"Luma"},{"id":"discord","name":"Discord"}]},{"title":"Luma event-series analytics","prompt":"Build a scheduled workflow that pulls Luma event-series data, calculates conversion from registration to attendance to next action, and writes the analytics to a report file.","integrations":[{"id":"luma","name":"Luma"}]},{"title":"Luma new-registrant welcome","prompt":"Create a scheduled workflow that pulls the Luma event guest list, finds registrants added since the last run, and sends each a personalized welcome email with what to expect and how to prepare.","integrations":[{"id":"luma","name":"Luma"},{"id":"gmail","name":"Gmail"}]},{"title":"Sixtyfour event-attendee researcher","prompt":"Create a workflow that takes a Luma event attendee list, runs Sixtyfour deep research per attendee, and writes per-person briefs for the sales team.","integrations":[{"id":"luma","name":"Luma"},{"id":"sixtyfour","name":"Sixtyfour AI"}]}]},{"id":"mailchimp","type":"mailchimp","slug":"mailchimp","name":"Mailchimp","description":"Manage audiences, campaigns, and marketing automation in Mailchimp","category":"Email","docsUrl":"https://docs.sim.ai/integrations/mailchimp","authType":"api-key","connections":[],"operations":[{"name":"Get Audiences","description":"Retrieve a list of audiences (lists) from Mailchimp"},{"name":"Get Audience","description":"Retrieve details of a specific audience (list) from Mailchimp"},{"name":"Create Audience","description":"Create a new audience (list) in Mailchimp"},{"name":"Update Audience","description":"Update an existing audience (list) in Mailchimp"},{"name":"Delete Audience","description":"Delete an audience (list) from Mailchimp"},{"name":"Get Members","description":"Retrieve a list of members from a Mailchimp audience"},{"name":"Get Member","description":"Retrieve details of a specific member from a Mailchimp audience"},{"name":"Add Member","description":"Add a new member to a Mailchimp audience"},{"name":"Add or Update Member","description":"Add a new member or update an existing member in a Mailchimp audience (upsert)"},{"name":"Update Member","description":"Update an existing member in a Mailchimp audience"},{"name":"Delete Member","description":"Archive a member from a Mailchimp audience without permanently deleting their data."},{"name":"Archive Member","description":"Request permanent deletion of a member and their identifying data. This targets delete-permanent, despite the Archive Member label; provider acceptance of the current HTTP method is unverified."},{"name":"Unarchive Member","description":"Restore an archived member to a Mailchimp audience"},{"name":"Get Campaigns","description":"Retrieve a list of campaigns from Mailchimp"},{"name":"Get Campaign","description":"Retrieve details of a specific campaign from Mailchimp"},{"name":"Create Campaign","description":"Create a new campaign in Mailchimp"},{"name":"Update Campaign","description":"Update an existing campaign in Mailchimp"},{"name":"Delete Campaign","description":"Delete a campaign from Mailchimp"},{"name":"Send Campaign","description":"Send a Mailchimp campaign"},{"name":"Schedule Campaign","description":"Schedule a Mailchimp campaign to be sent at a specific time"},{"name":"Unschedule Campaign","description":"Unschedule a previously scheduled Mailchimp campaign"},{"name":"Replicate Campaign","description":"Create a copy of an existing Mailchimp campaign"},{"name":"Get Campaign Content","description":"Retrieve the HTML and plain-text content for a Mailchimp campaign"},{"name":"Set Campaign Content","description":"Set the content for a Mailchimp campaign"},{"name":"Get Automations","description":"Retrieve a list of automations from Mailchimp"},{"name":"Get Automation","description":"Retrieve details of a specific automation from Mailchimp"},{"name":"Start Automation","description":"Start all emails in a Mailchimp automation workflow"},{"name":"Pause Automation","description":"Pause all emails in a Mailchimp automation workflow"},{"name":"Add Subscriber to Automation","description":"Manually add a subscriber to a workflow email queue"},{"name":"Get Templates","description":"Retrieve a list of templates from Mailchimp"},{"name":"Get Template","description":"Retrieve details of a specific template from Mailchimp"},{"name":"Create Template","description":"Create a new template in Mailchimp"},{"name":"Update Template","description":"Update an existing template in Mailchimp"},{"name":"Delete Template","description":"Delete a template from Mailchimp"},{"name":"Get Campaign Reports","description":"Retrieve a list of campaign reports from Mailchimp"},{"name":"Get Campaign Report","description":"Retrieve the report for a specific campaign from Mailchimp"},{"name":"Get Segments","description":"Retrieve a list of segments from a Mailchimp audience"},{"name":"Get Segment","description":"Retrieve details of a specific segment from a Mailchimp audience"},{"name":"Create Segment","description":"Create a new segment in a Mailchimp audience"},{"name":"Update Segment","description":"Update an existing segment in a Mailchimp audience"},{"name":"Delete Segment","description":"Delete a segment from a Mailchimp audience"},{"name":"Get Segment Members","description":"Retrieve members of a specific segment from a Mailchimp audience"},{"name":"Add Segment Member","description":"Add a member to a specific segment in a Mailchimp audience"},{"name":"Remove Segment Member","description":"Remove a member from a specific segment in a Mailchimp audience"},{"name":"Get Member Tags","description":"Retrieve tags associated with a member in a Mailchimp audience"},{"name":"Add Member Tags","description":"Add tags to a member in a Mailchimp audience"},{"name":"Remove Member Tags","description":"Remove tags from a member in a Mailchimp audience"},{"name":"Get Merge Fields","description":"Retrieve a list of merge fields from a Mailchimp audience"},{"name":"Get Merge Field","description":"Retrieve details of a specific merge field from a Mailchimp audience"},{"name":"Create Merge Field","description":"Create a new merge field in a Mailchimp audience"},{"name":"Update Merge Field","description":"Update an existing merge field in a Mailchimp audience"},{"name":"Delete Merge Field","description":"Delete a merge field from a Mailchimp audience"},{"name":"Get Interest Categories","description":"Retrieve a list of interest categories from a Mailchimp audience"},{"name":"Get Interest Category","description":"Retrieve details of a specific interest category from a Mailchimp audience"},{"name":"Create Interest Category","description":"Create a new interest category in a Mailchimp audience"},{"name":"Update Interest Category","description":"Update an existing interest category in a Mailchimp audience"},{"name":"Delete Interest Category","description":"Delete an interest category from a Mailchimp audience"},{"name":"Get Interests","description":"Retrieve a list of interests from an interest category in a Mailchimp audience"},{"name":"Get Interest","description":"Retrieve details of a specific interest from an interest category in a Mailchimp audience"},{"name":"Create Interest","description":"Create a new interest in an interest category in a Mailchimp audience"},{"name":"Update Interest","description":"Update an existing interest in an interest category in a Mailchimp audience"},{"name":"Delete Interest","description":"Delete an interest from an interest category in a Mailchimp audience"},{"name":"Get Landing Pages","description":"Retrieve a list of landing pages from Mailchimp"},{"name":"Get Landing Page","description":"Retrieve details of a specific landing page from Mailchimp"},{"name":"Create Landing Page","description":"Create a new landing page in Mailchimp"},{"name":"Update Landing Page","description":"Update an existing landing page in Mailchimp"},{"name":"Delete Landing Page","description":"Delete a landing page from Mailchimp"},{"name":"Publish Landing Page","description":"Publish a landing page in Mailchimp"},{"name":"Unpublish Landing Page","description":"Unpublish a landing page in Mailchimp"},{"name":"Get Batch Operations","description":"Retrieve a list of batch operations from Mailchimp"},{"name":"Get Batch Operation","description":"Retrieve details of a specific batch operation from Mailchimp"},{"name":"Create Batch Operation","description":"Create a new batch operation in Mailchimp"},{"name":"Delete Batch Operation","description":"Delete a batch operation from Mailchimp"}],"triggers":[],"skills":[{"name":"sync-contact-to-audience","description":"Add or update a contact in a Mailchimp audience with merge fields and tags.","content":"# Sync Contact to Audience\\n\\nKeep a Mailchimp audience in sync with your source of truth.\\n\\n## Steps\\n1. If the audience is unknown, Get Audiences to find the right list ID.\\n2. Use Add or Update Member with the email, subscription status, and merge fields like first and last name.\\n3. Apply segmentation with Add Member Tags for lifecycle stage or ICP tags.\\n\\n## Output\\nThe member ID and status in the audience, plus the merge fields and tags applied."},{"name":"create-and-send-campaign","description":"Create a Mailchimp campaign, set its content, and send or schedule it to an audience.","content":"# Create and Send Campaign\\n\\nLaunch an email campaign to an audience or segment.\\n\\n## Steps\\n1. Create Campaign targeting the audience or a saved segment, with the subject line and from details.\\n2. Set Campaign Content with the HTML or a template ID.\\n3. Send Campaign immediately, or Schedule Campaign for a future send time.\\n\\n## Output\\nThe campaign ID, the audience or segment targeted, and whether it was sent or scheduled with the send time."},{"name":"build-targeted-segment","description":"Create a Mailchimp segment from conditions so a campaign can target a specific slice of an audience.","content":"# Build Targeted Segment\\n\\nDefine a reusable audience segment for targeting.\\n\\n## Steps\\n1. Identify the audience and the conditions that define the segment, such as tags, merge field values, or activity.\\n2. Create Segment on that audience with the conditions and a clear name.\\n3. Optionally Get Segment Members to verify the segment matches the intended contacts.\\n\\n## Output\\nThe segment ID and name, the conditions used, and the count of matching members."},{"name":"report-campaign-performance","description":"Pull Mailchimp campaign reports and summarize open, click, and bounce performance.","content":"# Report Campaign Performance\\n\\nTurn Mailchimp report data into a readable summary.\\n\\n## Steps\\n1. Get Campaign Reports for the recent window, or Get Campaign Report for a specific campaign ID.\\n2. Extract opens, clicks, bounces, and unsubscribes per campaign.\\n3. Compute open rate, click rate, and bounce rate and flag campaigns that underperformed.\\n\\n## Output\\nA per-campaign metrics summary with rates and a short list of underperformers worth revisiting."}],"templates":[{"title":"Mailchimp newsletter curator","prompt":"Create a scheduled weekly workflow that scrapes my favorite industry news sites and blogs, picks the top stories relevant to my audience, writes summaries for each, and drafts a ready-to-send newsletter in Mailchimp.","integrations":[{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Mailchimp re-engagement campaign","prompt":"Build a workflow that finds Mailchimp members who have not opened or clicked in 90 days, drafts a re-engagement campaign with a personalized subject line per segment, and schedules it to send to those members only.","integrations":[{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Mailchimp + SendGrid hybrid sender","prompt":"Create a workflow that uses Mailchimp for marketing audience management and segmentation but sends the actual campaign through SendGrid for deliverability, syncing send results, opens, and clicks back to the Mailchimp audience as merge fields.","integrations":[{"id":"mailchimp","name":"Mailchimp"},{"id":"sendgrid","name":"SendGrid"}]},{"title":"Mailchimp campaign performance digest","prompt":"Build a scheduled workflow that pulls the previous week of Mailchimp campaign reports, compares open and click rates against my benchmarks, and posts a Slack digest with the winners, losers, and one-line takeaways.","integrations":[{"id":"mailchimp","name":"Mailchimp"},{"id":"slack","name":"Slack"}]},{"title":"Mailchimp + Loops audience sync","prompt":"Create a workflow that keeps a Mailchimp audience and a Loops mailing list in sync: new Mailchimp subscribers create Loops contacts on the matching list, unsubscribes propagate both ways, and merge fields map cleanly to Loops contact properties.","integrations":[{"id":"mailchimp","name":"Mailchimp"},{"id":"loops","name":"Loops"}]},{"title":"Mailchimp event-driven blast","prompt":"Build a workflow that listens for a launch trigger from my tables, populates a Mailchimp campaign template with the launch details, schedules it to the right segment, and logs the campaign ID and recipient count back to the table.","integrations":[{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Mailchimp segment builder from HubSpot","prompt":"Create a workflow that reads HubSpot lifecycle stage and ICP fields, upserts each contact into Mailchimp with the matching tags and merge fields, and recomputes named segments daily so marketing can target by CRM state.","integrations":[{"id":"mailchimp","name":"Mailchimp"},{"id":"hubspot","name":"HubSpot"}]},{"title":"WordPress newsletter republisher","prompt":"Build a workflow that publishes a new WordPress post and then drafts an adapted Mailchimp newsletter version, links back to the post, and queues it for the editor’s review.","integrations":[{"id":"mailchimp","name":"Mailchimp"},{"id":"wordpress","name":"WordPress"}]}]},{"id":"mailgun","type":"mailgun","slug":"mailgun","name":"Mailgun","description":"Send emails and manage mailing lists with Mailgun","category":"Email","docsUrl":"https://docs.sim.ai/integrations/mailgun","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send an email using Mailgun API"},{"name":"Get Message","description":"Retrieve a stored message by its key"},{"name":"List Messages","description":"List events (logs) for messages sent through Mailgun"},{"name":"Create Mailing List","description":"Create a new mailing list"},{"name":"Get Mailing List","description":"Get details of a mailing list"},{"name":"Add List Member","description":"Add a member to a mailing list"},{"name":"List Domains","description":"List all domains for your Mailgun account"},{"name":"Get Domain","description":"Get details of a specific domain"}],"triggers":[],"skills":[{"name":"send-transactional-email","description":"Send a transactional email through a Mailgun sending domain to one or more recipients.","content":"# Send Transactional Email\\n\\nDeliver an email through Mailgun.\\n\\n## Steps\\n1. Confirm the verified sending domain to use, listing domains first if unsure.\\n2. Compose the message with from, to, subject, and an HTML or text body.\\n3. Send Message with those fields, adding CC, BCC, or attachments as needed.\\n\\n## Output\\nConfirmation of acceptance with the Mailgun message ID and the recipients it was queued to."},{"name":"track-delivery-events","description":"Pull Mailgun events filtered by type to see what was delivered, opened, clicked, or failed.","content":"# Track Delivery Events\\n\\nMonitor what happened to your Mailgun sends.\\n\\n## Steps\\n1. List Messages or query events filtered by an event type such as delivered, failed, opened, or clicked.\\n2. Group the events by recipient and by type to see delivery outcomes.\\n3. Highlight failures and bounces that need attention.\\n\\n## Output\\nA summary of event counts by type and a list of failed or bounced recipients."},{"name":"sweep-bounces-and-complaints","description":"Collect Mailgun failed and complained events and compile the offending addresses for suppression.","content":"# Sweep Bounces and Complaints\\n\\nKeep your list clean by capturing bad addresses.\\n\\n## Steps\\n1. Query Mailgun events filtered to failed and complained types over the chosen window.\\n2. Extract the recipient addresses and the reason for each.\\n3. Compile a suppression list of addresses to stop mailing.\\n\\n## Output\\nA list of bounced and complained addresses with reasons, ready to write to a suppression table."},{"name":"add-member-to-list","description":"Create a Mailgun mailing list if needed and add a subscriber to it.","content":"# Add Member to List\\n\\nGrow a Mailgun mailing list.\\n\\n## Steps\\n1. Get Mailing List to confirm the list exists, or Create Mailing List with the address and access level if it does not.\\n2. Add List Member with the subscriber email and any name or variables.\\n\\n## Output\\nConfirmation the member was added, the list address, and the member email."}],"templates":[{"title":"Mailgun mailing list builder","prompt":"Create a scheduled workflow that watches a table of contact opt-ins, creates the matching Mailgun mailing lists by segment, adds each new opt-in as a member, and reports list health weekly to a tracking table.","integrations":[{"id":"mailgun","name":"Mailgun"}]},{"title":"Mailgun event analytics digest","prompt":"Build a scheduled workflow that pulls Mailgun message events, aggregates deliveries, opens, clicks, and complaints by tag and domain, and posts a Slack digest with anomalies and the top-performing tags of the day.","integrations":[{"id":"mailgun","name":"Mailgun"},{"id":"slack","name":"Slack"}]},{"title":"Mailgun transactional sender","prompt":"Create a workflow that receives a structured event from my application, picks the right Mailgun template and recipient, sends through Mailgun with tracking tags, then retrieves the stored message status for audit.","integrations":[{"id":"mailgun","name":"Mailgun"}]},{"title":"Mailgun + Resend transactional fallback","prompt":"Build a workflow that sends transactional emails through Mailgun by default and automatically falls back to Resend when Mailgun returns a send error or rate-limit response, normalizing the payload and writing every send and the provider used to a delivery table.","integrations":[{"id":"mailgun","name":"Mailgun"},{"id":"resend","name":"Resend"}]},{"title":"Mailgun deliverability scorecard","prompt":"Create a scheduled workflow that pulls Mailgun events for the previous week, computes per-domain deliverability, complaint rate, and bounce rate, and generates a scorecard file flagging any sending domain trending toward a deliverability problem.","integrations":[{"id":"mailgun","name":"Mailgun"}]},{"title":"Mailgun bounce list hygiene","prompt":"Build a scheduled workflow that retrieves Mailgun bounce and complaint events, compiles the offending addresses into a suppression table, and posts a summary so the marketing team can audit and clean list hygiene.","integrations":[{"id":"mailgun","name":"Mailgun"}]},{"title":"Mailgun domain verification monitor","prompt":"Create a scheduled workflow that checks the status of each Mailgun sending domain, flags any domain whose SPF, DKIM, or tracking records fall out of verification, and pages the on-call engineer in Slack with the exact records that need fixing.","integrations":[{"id":"mailgun","name":"Mailgun"},{"id":"slack","name":"Slack"}]},{"title":"SendGrid + Mailgun send scorecard","prompt":"Create a scheduled weekly workflow that sends categorized test messages through both SendGrid and Mailgun, records each provider response, latency, and error to a delivery table, and generates a scorecard file recommending which provider to use per send category.","integrations":[{"id":"mailgun","name":"Mailgun"},{"id":"sendgrid","name":"SendGrid"}]},{"title":"SES + Mailgun multi-region sender","prompt":"Build a workflow that routes transactional emails through SES in primary regions and through Mailgun for regions where SES is not provisioned, normalizing template variables and writing one unified send log to a table.","integrations":[{"id":"mailgun","name":"Mailgun"},{"id":"ses","name":"AWS SES"}]}]},{"id":"manageengine_sdp","type":"manageengine_sdp","slug":"manageengine-servicedesk-plus","name":"ManageEngine ServiceDesk Plus","description":"Manage ServiceDesk Plus Cloud requests, problems, changes, assets, and knowledge base solutions","category":"Support","docsUrl":"https://docs.sim.ai/integrations/manageengine_sdp","authType":"oauth","connections":[{"id":"manageengine-sdp","kind":"oauth","label":"Connect with OAuth","providerId":"manageengine-sdp","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/manageengine_sdp","requiredScopes":[{"id":"SDPOnDemand.requests.CREATE","label":"Create requests"},{"id":"SDPOnDemand.requests.READ","label":"View requests and their notes"},{"id":"SDPOnDemand.requests.UPDATE","label":"Update requests and add notes"},{"id":"SDPOnDemand.requests.DELETE","label":"Delete requests"},{"id":"SDPOnDemand.problems.CREATE","label":"Create problems"},{"id":"SDPOnDemand.problems.READ","label":"View problems and their notes"},{"id":"SDPOnDemand.problems.UPDATE","label":"Update problems and add notes"},{"id":"SDPOnDemand.problems.DELETE","label":"Delete problems"},{"id":"SDPOnDemand.changes.CREATE","label":"Create changes"},{"id":"SDPOnDemand.changes.READ","label":"View changes and their notes"},{"id":"SDPOnDemand.changes.UPDATE","label":"Update changes and add notes"},{"id":"SDPOnDemand.changes.DELETE","label":"Delete changes"},{"id":"SDPOnDemand.assets.CREATE","label":"Create assets"},{"id":"SDPOnDemand.assets.READ","label":"View assets"},{"id":"SDPOnDemand.assets.UPDATE","label":"Update assets"},{"id":"SDPOnDemand.assets.DELETE","label":"Delete assets"},{"id":"SDPOnDemand.solutions.CREATE","label":"Create knowledge base solutions"},{"id":"SDPOnDemand.solutions.READ","label":"View knowledge base solutions"},{"id":"SDPOnDemand.solutions.UPDATE","label":"Update knowledge base solutions"},{"id":"SDPOnDemand.solutions.DELETE","label":"Delete knowledge base solutions"},{"id":"aaaserver.profile.READ","label":"View your Zoho profile"}],"fields":[]}],"operations":[{"name":"Create Request","description":"Create a request (ticket) in ManageEngine ServiceDesk Plus Cloud with a subject, description, requester and classification."},{"name":"Get Request","description":"Retrieve a single ManageEngine ServiceDesk Plus Cloud request by ID."},{"name":"List Requests","description":"List ManageEngine ServiceDesk Plus Cloud requests, with optional search criteria, sorting and paging."},{"name":"Update Request","description":"Update a ManageEngine ServiceDesk Plus Cloud request: change its status, priority, assignment, classification or description."},{"name":"Delete Request","description":"Move a ManageEngine ServiceDesk Plus Cloud request to the trash. Deleting a request also removes its notes, tasks and worklogs."},{"name":"Add Request Note","description":"Add a note to a ManageEngine ServiceDesk Plus Cloud request, optionally making it visible to the requester."},{"name":"List Request Notes","description":"List the notes on a ManageEngine ServiceDesk Plus Cloud request."},{"name":"Create Problem","description":"Create a problem record in ManageEngine ServiceDesk Plus Cloud with a title, description and classification."},{"name":"Get Problem","description":"Retrieve a single ManageEngine ServiceDesk Plus Cloud problem by ID."},{"name":"List Problems","description":"List ManageEngine ServiceDesk Plus Cloud problems, with optional search criteria, sorting and paging."},{"name":"Update Problem","description":"Update a ManageEngine ServiceDesk Plus Cloud problem: change its title, status, assignment or classification."},{"name":"Delete Problem","description":"Delete a ManageEngine ServiceDesk Plus Cloud problem and its associated notes."},{"name":"Add Problem Note","description":"Add a note to a ManageEngine ServiceDesk Plus Cloud problem."},{"name":"List Problem Notes","description":"List the notes on a ManageEngine ServiceDesk Plus Cloud problem."},{"name":"Create Change","description":"Create a change record in ManageEngine ServiceDesk Plus Cloud with a title, stage, status and schedule."},{"name":"Get Change","description":"Retrieve a single ManageEngine ServiceDesk Plus Cloud change by ID."},{"name":"List Changes","description":"List ManageEngine ServiceDesk Plus Cloud changes, with optional search criteria, sorting and paging."},{"name":"Update Change","description":"Update a ManageEngine ServiceDesk Plus Cloud change: move its stage or status, reschedule it, or change its assignment. ServiceDesk Plus requires a comment whenever the status changes."},{"name":"Delete Change","description":"Delete a ManageEngine ServiceDesk Plus Cloud change and its associated notes."},{"name":"Add Change Note","description":"Add a note to a ManageEngine ServiceDesk Plus Cloud change."},{"name":"List Change Notes","description":"List the notes on a ManageEngine ServiceDesk Plus Cloud change."},{"name":"Create Asset","description":"Create an asset in the ManageEngine ServiceDesk Plus Cloud inventory. Requires a name and an existing product."},{"name":"Get Asset","description":"Retrieve a single ManageEngine ServiceDesk Plus Cloud asset by ID."},{"name":"List Assets","description":"List ManageEngine ServiceDesk Plus Cloud assets, with optional search criteria, sorting and paging."},{"name":"Update Asset","description":"Update a ManageEngine ServiceDesk Plus Cloud asset: reassign it, change its state, or correct its inventory details."},{"name":"Delete Asset","description":"Delete an asset from the ManageEngine ServiceDesk Plus Cloud inventory."},{"name":"Create Solution","description":"Add an article to the ManageEngine ServiceDesk Plus Cloud knowledge base under an existing topic."},{"name":"Get Solution","description":"Retrieve a single ManageEngine ServiceDesk Plus Cloud knowledge base solution by ID."},{"name":"List Solutions","description":"Search the ManageEngine ServiceDesk Plus Cloud knowledge base, with optional search criteria, sorting and paging."},{"name":"Update Solution","description":"Update a ManageEngine ServiceDesk Plus Cloud knowledge base solution: revise its body, retitle it, or move it to another topic."},{"name":"Delete Solution","description":"Delete an article from the ManageEngine ServiceDesk Plus Cloud knowledge base, along with its comments and versions."}],"triggers":[],"skills":[{"name":"triage-new-request","description":"Read an incoming ServiceDesk Plus request, classify it, and set its category, priority and support group.","content":"# Triage a ServiceDesk Plus Request\\n\\nClassify a newly created request and route it to the right owner.\\n\\n## Steps\\n1. Get Request for the request ID and read subject, description, requester and created_time.\\n2. Decide the urgency and the owning team from the content. Category, subcategory, priority and group are portal-defined picklists, so use the names configured in this portal rather than assuming a standard set.\\n3. Update Request to set category, subcategory, priority, urgency, impact and group, plus the technician email if the owner is known.\\n4. Add Request Note explaining the triage decision. Leave \\"visible to requester\\" off so the reasoning stays internal.\\n\\n## Output\\nReport the request ID and display_id, the classification and priority set, the group or technician it was routed to, and anything ambiguous that needs a human decision."},{"name":"escalate-overdue-requests","description":"Find ServiceDesk Plus requests past their SLA due-by time and escalate them with a higher priority and an owner.","content":"# Escalate Overdue Requests\\n\\nCatch requests that are breaching or about to breach their SLA.\\n\\n## Steps\\n1. List Requests with search criteria limiting the result to open statuses, sorted on due_by_time ascending so the soonest-due come first. Page with row_count (max 100) and start_index if the queue is large.\\n2. Compare each due_by_time.value — epoch milliseconds as a string — against the current time to separate already-breached requests from ones due shortly.\\n3. For each breached request, Update Request to raise the priority and set the escalation owner via technician email or group.\\n4. Add Request Note recording that it was escalated, how overdue it was, and who now owns it.\\n\\n## Output\\nA list of escalated requests with display_id, how far past due each was, the new priority, and the new owner. Include a separate at-risk list of requests due soon but not yet breached."},{"name":"deflect-with-knowledge-base","description":"Search ServiceDesk Plus solutions for an answer to an incoming request and reply with it as a requester-visible note.","content":"# Deflect a Request with the Knowledge Base\\n\\nAnswer a request from an existing solution instead of queueing it for an agent.\\n\\n## Steps\\n1. Get Request and read its subject and description to work out what is actually being asked.\\n2. List Solutions with search criteria matching the key terms against title or keywords. Try more than one phrasing before concluding nothing exists.\\n3. Get Solution on the best candidate and read its description in full — confirm it answers this request rather than a superficially similar one.\\n4. If it fits, Add Request Note quoting the relevant steps with \\"visible to requester\\" on, and Update Request to move the status toward resolution per the portal\'s workflow.\\n5. If nothing fits, leave the request open and assign it to the service desk group instead of guessing.\\n\\n## Output\\nThe request display_id, the solution ID used (or a statement that no solution matched), and the note that was posted. Never mark a request resolved on a solution you have not actually read."},{"name":"daily-service-desk-digest","description":"Summarize the current ServiceDesk Plus queue by status, priority and technician into a digest for the team.","content":"# Daily Service Desk Digest\\n\\nProduce a morning read on where the request queue stands.\\n\\n## Steps\\n1. List Requests with search criteria for the statuses you care about, setting get_total_count so the digest can report the true size of the queue rather than the page size.\\n2. Page with row_count and start_index until the queue is covered, watching has_more_rows in list_info.\\n3. Group the results by status, priority and technician, and compute counts for each group.\\n4. Flag unassigned requests, requests past due_by_time, and anything untouched since created_time.\\n\\n## Output\\nA digest with counts by status and priority, load per technician, and a callout list of unassigned and overdue requests by display_id. State the search criteria used so the numbers are reproducible."},{"name":"raise-problem-from-recurring-requests","description":"Spot repeated ServiceDesk Plus requests with a shared cause and open a problem record linking them.","content":"# Raise a Problem from Recurring Requests\\n\\nTurn a cluster of similar incidents into a tracked problem.\\n\\n## Steps\\n1. List Requests created in the recent window using a created_time search criterion, paging until covered.\\n2. Group them by category and subcategory, and look for a cluster large enough to indicate a common cause rather than coincidence.\\n3. List Problems to check whether an open problem already covers that cluster — if one does, add to it instead of opening a duplicate.\\n4. Create Problem with a title naming the symptom, a description of the pattern and its impact, and the matching category and group.\\n5. Add Problem Note listing the contributing request display_ids so the link back to the incidents is recorded.\\n\\n## Output\\nThe problem ID created (or the existing one matched), the cluster it covers, and the request display_ids attributed to it. State the time window and grouping used."},{"name":"publish-solution-from-resolved-request","description":"Turn a resolved ServiceDesk Plus request and its notes into a knowledge base solution.","content":"# Publish a Solution from a Resolved Request\\n\\nCapture a fix while the detail is still on the ticket.\\n\\n## Steps\\n1. Get Request for the resolved request and List Request Notes to read the full working history, not just the closing note.\\n2. Distil the symptom, the cause and the steps that actually fixed it. Drop customer-specific details such as names, asset tags and internal hostnames.\\n3. List Solutions first to confirm no article already covers this, so the knowledge base does not accumulate near-duplicates.\\n4. Create Solution with a title phrased the way a requester would search for it, the write-up as the content, an existing topic name, and keywords covering the phrasings people actually use.\\n5. Leave \\"visible to requesters\\" off unless the portal has approved the article — ServiceDesk Plus only honours that flag once the approval status is Approved.\\n\\n## Output\\nThe solution ID and title created, the source request display_id, and a note on anything omitted as customer-specific that a human should check before publishing."},{"name":"reclaim-assets-on-offboarding","description":"Find ServiceDesk Plus assets assigned to a departing employee and move them to a reclaim state with a request to collect them.","content":"# Reclaim Assets on Offboarding\\n\\nMake sure hardware comes back when someone leaves.\\n\\n## Steps\\n1. List Assets with a search criterion matching the departing user, paging until covered.\\n2. Get Asset on each result to confirm its current state and assignment before changing anything — a stale list row is not proof of who holds it today.\\n3. Update Asset for each one to the portal\'s reclaim state, with a state change comment naming the offboarding date and the ticket driving it.\\n4. Create Request for IT to physically collect the hardware, listing every asset name and tag in the description so nothing is missed.\\n\\n## Output\\nThe assets found with name, asset_tag and serial_number, the state each was moved to, and the request display_id raised for collection. Flag any asset you could not update and why."},{"name":"prepare-change-calendar","description":"Summarize upcoming ServiceDesk Plus changes into a weekly calendar with owners and scheduling conflicts.","content":"# Prepare the Change Calendar\\n\\nGive the change advisory board a readable week ahead.\\n\\n## Steps\\n1. List Changes with a search criterion on scheduled_start_time covering the coming week, paging until covered.\\n2. For anything needing detail, Get Change to read its stage, approval status, roll-out plan and owner.\\n3. Group by change type and by day, and read scheduled_start_time and scheduled_end_time as epoch milliseconds to find overlapping windows on the same systems.\\n4. Flag emergency changes, changes still awaiting approval, and any window that collides with another.\\n\\n## Output\\nA day-by-day calendar with change display_id, title, type, owner and window. Follow it with a conflicts section and an approvals-outstanding section. State the date range used."}],"templates":[{"title":"Triage new ServiceDesk Plus requests","prompt":"Every 15 minutes, list ServiceDesk Plus requests with status Open and no technician assigned. For each one, read the subject and description, decide whether it is a hardware, software, access or network issue, then update the request with the matching category and support group.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"File a ServiceDesk Plus ticket from Slack","prompt":"When someone posts in the #it-help Slack channel, create a ServiceDesk Plus request with their message as the description and the first line as the subject, then reply in the thread with the request number.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"},{"id":"slack","name":"Slack"}]},{"title":"Daily ServiceDesk Plus SLA breach report","prompt":"Every weekday at 8am, list ServiceDesk Plus requests whose due-by time has passed and that are not yet resolved. Summarize them by support group and email the summary to the service desk manager.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"},{"id":"gmail","name":"Gmail"}]},{"title":"Deflect ServiceDesk Plus tickets with the knowledge base","prompt":"When a new ServiceDesk Plus request arrives, search ServiceDesk Plus solutions for an article matching its subject. If one is found, add a note to the request quoting the solution and mark it visible to the requester; otherwise assign it to the service desk group.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Turn a resolved ServiceDesk Plus ticket into a solution","prompt":"Given a resolved ServiceDesk Plus request ID, read the request and its notes, then draft a knowledge base solution covering the symptom and the fix and create it under the IT Support topic with relevant keywords.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Escalate recurring ServiceDesk Plus incidents to a problem","prompt":"Once a day, list ServiceDesk Plus requests created in the last 7 days and group them by category and subcategory. For any category with five or more requests that has no matching open problem, create a problem record describing the pattern and add a note listing the request IDs.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Open a ServiceDesk Plus change from an approved plan","prompt":"When a maintenance plan is approved, create a ServiceDesk Plus change at the Submission stage with status Open, set its scheduled start and end times, assign the change manager, and add a note with the rollout steps.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Post the ServiceDesk Plus change calendar to Slack","prompt":"Every Monday morning, list ServiceDesk Plus changes scheduled for the coming week and post a summary to the #change-management Slack channel, grouped by change type and showing the owner of each.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"},{"id":"slack","name":"Slack"}]},{"title":"Sync ServiceDesk Plus asset inventory to a table","prompt":"Every night, page through all ServiceDesk Plus assets and write their name, asset tag, serial number, state and assigned user into a Sim table so the inventory can be queried and charted.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Reassign ServiceDesk Plus assets when someone leaves","prompt":"Given a departing employee email, list ServiceDesk Plus assets assigned to them, set each one to the In Store state with a state change comment naming the offboarding ticket, and create a request for IT to collect the hardware.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Summarize a ServiceDesk Plus ticket thread","prompt":"Given a ServiceDesk Plus request ID, read the request and all of its notes, then produce a short handover summary covering what was reported, what has been tried, and what the next step should be.","integrations":[{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]}]},{"id":"mem0","type":"mem0","slug":"mem0","name":"Mem0","description":"Agent memory management","category":"AI","docsUrl":"https://docs.sim.ai/integrations/mem0","authType":"api-key","connections":[],"operations":[{"name":"Add Memories","description":"Add memories to Mem0 for persistent storage and retrieval"},{"name":"Search Memories","description":"Search for memories in Mem0 using semantic search"},{"name":"Get Memories","description":"Retrieve memories from Mem0 by ID or filter criteria"}],"triggers":[],"skills":[{"name":"remember-user-context","description":"Store new facts and preferences for a user in Mem0 from the latest conversation.","content":"# Remember User Context\\n\\nPersist what you learned about a user so future sessions stay informed.\\n\\n## Steps\\n1. Identify the user ID this memory belongs to.\\n2. Build the messages array from the relevant conversation turns as role and content objects.\\n3. Add Memories with the user ID and messages so Mem0 extracts and stores the durable facts.\\n\\n## Output\\nConfirmation the memories were added for the user, with the IDs of the facts created."},{"name":"recall-relevant-memories","description":"Search a user\'s Mem0 memories for the facts relevant to the current request before answering.","content":"# Recall Relevant Memories\\n\\nGround a response in what Mem0 already knows about the user.\\n\\n## Steps\\n1. Identify the user ID.\\n2. Phrase a search query that captures the current request or topic.\\n3. Search Memories with the user ID and query.\\n4. Use the returned memories as context when drafting the answer.\\n\\n## Output\\nThe most relevant memories for the user and a note of how they should shape the response."},{"name":"review-stored-memories","description":"Retrieve a user\'s stored Mem0 memories, optionally within a date range, to audit what is known.","content":"# Review Stored Memories\\n\\nInspect what Mem0 holds for a user.\\n\\n## Steps\\n1. Identify the user ID.\\n2. Get Memories for that user, optionally bounding by a start and end date or a specific memory ID.\\n3. Page through results if there are many.\\n4. Summarize the stored facts and flag anything stale or contradictory.\\n\\n## Output\\nA readable list of the user\'s stored memories with a short summary and any items worth updating."}],"templates":[{"title":"Mem0 long-term agent memory","prompt":"Build an agent that uses Mem0 to remember user preferences and prior conversations across sessions, so follow-up requests reference real history instead of starting from scratch.","integrations":[{"id":"mem0","name":"Mem0"}]},{"title":"Mem0 sales-assistant memory","prompt":"Create a sales agent that persists per-account context in Mem0 — last call notes, open objections, agreed next steps — so every rep starts a follow-up call already up to speed.","integrations":[{"id":"mem0","name":"Mem0"}]},{"title":"Mem0 + Zep hybrid memory agent","prompt":"Create a chat agent that uses Mem0 for persistent user preferences and Zep for in-session continuity, so the agent recalls long-term context while staying coherent turn-to-turn.","integrations":[{"id":"mem0","name":"Mem0"},{"id":"zep","name":"Zep"}]},{"title":"Mem0 + Slack assistant memory","prompt":"Build a Slack bot that uses Mem0 to remember user preferences and prior conversations, so each follow-up question lands in context instead of starting fresh.","integrations":[{"id":"mem0","name":"Mem0"},{"id":"slack","name":"Slack"}]},{"title":"Mem0 + Notion personal-knowledge agent","prompt":"Create an agent that uses Mem0 to recall personal context and Notion as the source-of-truth knowledge base, answering questions with citations plus user-specific memory.","integrations":[{"id":"mem0","name":"Mem0"},{"id":"notion","name":"Notion"}]},{"title":"Mem0 customer-preference store","prompt":"Build a workflow that captures customer preferences from support interactions into Mem0 keyed by account, so future automations reference the real preferences.","integrations":[{"id":"mem0","name":"Mem0"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Mem0 onboarding-context agent","prompt":"Create an onboarding agent that adds each new user’s role, goals, and stack to Mem0 on first contact, then searches that memory on every later session so guidance stays tailored to the individual instead of generic.","integrations":[{"id":"mem0","name":"Mem0"}]},{"title":"Reducto + Mem0 contract memory","prompt":"Create a workflow that parses contracts with Reducto and writes the key terms into Mem0 per counterparty, so future interactions reference the real contract terms.","integrations":[{"id":"mem0","name":"Mem0"},{"id":"reducto","name":"Reducto"}]}]},{"id":"microsoft_dataverse","type":"microsoft_dataverse_v2","slug":"microsoft-dataverse","name":"Microsoft Dataverse","description":"Manage records in Microsoft Dataverse tables","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/microsoft_dataverse","authType":"oauth","connections":[{"id":"microsoft-dataverse","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-dataverse","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_dataverse","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"https://dynamics.microsoft.com/user_impersonation","label":"Access Microsoft Dataverse on your behalf"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[{"id":"dataverseEnvironmentUrl","label":"Environment URL","placeholder":"https://your-org.crm.dynamics.com"}]}],"operations":[{"name":"List Records","description":"Query and list records from a Microsoft Dataverse table. Supports OData query options for filtering, selecting columns, ordering, and pagination."},{"name":"Get Record","description":"Retrieve a single record from a Microsoft Dataverse table by its ID. Supports $select and $expand OData query options."},{"name":"Create Record","description":"Create a new record in a Microsoft Dataverse table. Requires the entity set name (plural table name) and record data as a JSON object."},{"name":"Update Record","description":"Update an existing record in a Microsoft Dataverse table. Only send the columns you want to change."},{"name":"Upsert Record","description":"Create or update a record in a Microsoft Dataverse table. If a record with the given ID exists, it is updated; otherwise, a new record is created."},{"name":"Delete Record","description":"Delete a record from a Microsoft Dataverse table by its ID."},{"name":"Create Multiple","description":"Create multiple records of the same table type in a single request. Each record in the Targets array must include an @odata.type annotation. Recommended batch size: 100-1000 records for standard tables."},{"name":"Update Multiple","description":"Update multiple records of the same table type in a single request. Each record must include its primary key. Only include columns that need to be changed. Recommended batch size: 100-1000 records."},{"name":"FetchXML Query","description":"Execute a FetchXML query against a Microsoft Dataverse table. FetchXML supports aggregation, grouping, linked-entity joins, and complex filtering beyond OData capabilities."},{"name":"Search","description":"Perform a full-text relevance search across Microsoft Dataverse tables. Requires Dataverse Search to be enabled on the environment. Supports simple and Lucene query syntax."},{"name":"Execute Action","description":"Execute a bound or unbound Dataverse action. Actions perform operations with side effects (e.g., Merge, GrantAccess, SendEmail, QualifyLead). For bound actions, provide the entity set name and record ID."},{"name":"Execute Function","description":"Execute a bound or unbound Dataverse function. Functions are read-only operations (e.g., RetrievePrincipalAccess, RetrieveTotalRecordCount, InitializeFrom). For bound functions, provide the entity set name and record ID."},{"name":"Upload File","description":"Upload a file to a file or image column on a Dataverse record. Supports single-request upload for files up to 128 MiB. Provide the file through the File input; its bytes are read from storage and sent as the raw request body."},{"name":"Download File","description":"Download a file from a file or image column on a Dataverse record. Stores the file in execution storage and returns a file reference, plus the base64 content and metadata directly."},{"name":"Associate Records","description":"Associate two records in Microsoft Dataverse via a navigation property. Creates a relationship between a source record and a target record. Supports both collection-valued (POST) and single-valued (PUT) navigation properties."},{"name":"Disassociate Records","description":"Remove an association between two records in Microsoft Dataverse. For collection-valued navigation properties, provide the target record ID. For single-valued navigation properties, only the navigation property name is needed."},{"name":"Get Table Metadata","description":"Retrieve table (entity) and column (attribute) definitions for a Microsoft Dataverse table by its singular logical name. Use this to look up the correct entity set name and column logical names before building record data for other operations."},{"name":"WhoAmI","description":"Retrieve the current authenticated user information from Microsoft Dataverse. Useful for testing connectivity and getting the user ID, business unit ID, and organization ID."}],"triggers":[],"skills":[{"name":"upsert-record","description":"Create or update a record in a Dataverse table by its key without duplicating.","content":"# Upsert Record\\n\\nKeep a Dataverse table in sync from an external source without creating duplicates.\\n\\n## Steps\\n1. Identify the target table and the key field that uniquely identifies the record.\\n2. Map the incoming data to the table column names.\\n3. Use Upsert Record so an existing match is updated and a new key creates a record.\\n\\n## Output\\nThe record ID and whether it was created or updated, plus the fields written."},{"name":"query-records","description":"List or query Dataverse records with filters and return the matching rows.","content":"# Query Records\\n\\nRetrieve a filtered set of rows from a Dataverse table.\\n\\n## Steps\\n1. Choose the table to query.\\n2. Use List Records with OData filters, selected columns, and ordering, or use a FetchXML Query for complex joins and aggregates.\\n3. Page through results until the needed rows are collected.\\n\\n## Output\\nThe matching records with the selected columns, ready for downstream processing."},{"name":"relevance-search","description":"Run a relevance search across Dataverse tables to find records matching a term.","content":"# Relevance Search\\n\\nFind records across Dataverse using full-text relevance search.\\n\\n## Steps\\n1. Take the search term, such as a customer name or case keyword.\\n2. Use Search with the term, choosing simple or Lucene query syntax and match-any or match-all behavior.\\n3. Review the ranked matches and pick the relevant record.\\n\\n## Output\\nA ranked list of matching records with their table and key fields."},{"name":"bulk-write-records","description":"Create or update many Dataverse records in one batch operation.","content":"# Bulk Write Records\\n\\nWrite many Dataverse rows efficiently in a single call.\\n\\n## Steps\\n1. Assemble the array of records, mapping each to the table column names.\\n2. Use Create Multiple to insert new rows, or Update Multiple to change existing rows by ID.\\n3. Verify the operation succeeded and capture any per-record errors.\\n\\n## Output\\nThe count of records written, their IDs, and any rows that failed with their error."},{"name":"discover-table-schema","description":"Look up a table entity set name and column logical names before writing data.","content":"# Discover Table Schema\\n\\nAvoid guessing at column and entity set names when a workflow targets an unfamiliar Dataverse table.\\n\\n## Steps\\n1. Take the singular table logical name (e.g., account, contact, or a custom table).\\n2. Use Get Table Metadata, optionally including column definitions.\\n3. Use the returned entity set name and column logical names to build the record data and entity set name for other operations.\\n\\n## Output\\nThe entity set name, primary key and primary name columns, and (optionally) the full list of column definitions."}],"templates":[{"title":"Dataverse record sync","prompt":"Build a scheduled workflow that mirrors records between Microsoft Dataverse and a Sim table, normalizes schemas, and posts conflict reports to Slack.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"},{"id":"slack","name":"Slack"}]},{"title":"Dataverse approval workflow","prompt":"Create a scheduled workflow that polls Dataverse for new high-value records, posts an adaptive card approval to Microsoft Teams, captures the decision, and updates the record.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Dataverse data-quality auditor","prompt":"Build a scheduled workflow that scans Dataverse tables for missing required fields, format violations, and duplicates, and writes a remediation backlog to a tracking table.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dataverse + Power BI feeder","prompt":"Create a workflow that pulls Dataverse entity data daily, transforms it into BI-ready rows in a Sim table, and stages a refresh signal for downstream Power BI consumption.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dataverse legacy CRM bridge","prompt":"Build a workflow that mirrors Salesforce contacts into Microsoft Dataverse and back, mapping fields and resolving conflicts deterministically so both CRMs stay in sync during migration.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Dataverse compliance archiver","prompt":"Create a scheduled workflow that exports Dataverse records older than the retention horizon into long-term storage, removes them from the live table, and writes the archive manifest for auditors.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dataverse case-routing agent","prompt":"Build a workflow that runs a relevance search across Microsoft Dataverse case and account tables when a new support request arrives, classifies the issue, upserts the case record with the right owner and priority, and notifies the assigned team in Microsoft Teams.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Microsoft Planner template launcher","prompt":"Create a scheduled workflow that polls Microsoft Dataverse for new projects and creates a Planner plan from the project template, populates the standard buckets, and assigns the right owners.","integrations":[{"id":"microsoft_dataverse","name":"Microsoft Dataverse"},{"id":"microsoft_planner","name":"Microsoft Planner"}]}]},{"id":"microsoft_dynamics_365","type":"microsoft_dynamics_365","slug":"microsoft-dynamics-365-crm","name":"Microsoft Dynamics 365 CRM","description":"Manage customers, sales pipelines, and support cases in Dynamics 365 CRM","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/microsoft_dynamics_365","authType":"oauth","connections":[{"id":"microsoft-dataverse","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-dataverse","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_dynamics_365","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"https://dynamics.microsoft.com/user_impersonation","label":"Access Microsoft Dataverse on your behalf"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[{"id":"dataverseEnvironmentUrl","label":"Environment URL","placeholder":"https://your-org.crm.dynamics.com"}]}],"operations":[{"name":"List Records","description":"Query supported standard Microsoft Dynamics 365 CRM records. Supports OData filtering, column selection, ordering, and one bounded page at a time."},{"name":"Get Record","description":"Retrieve one supported standard Microsoft Dynamics 365 CRM record by its ID. Supports $select and $expand OData query options."},{"name":"Create Record","description":"Create a new supported standard Microsoft Dynamics 365 CRM record using Dataverse logical column names."},{"name":"Update Record","description":"Update an existing supported standard Microsoft Dynamics 365 CRM record. Only send the columns you want to change."},{"name":"Search Records","description":"Perform a full-text relevance search across Microsoft Dataverse tables. Requires Dataverse Search to be enabled on the environment. Supports simple and Lucene query syntax."},{"name":"List Owners","description":"Query supported standard Microsoft Dynamics 365 CRM records. Supports OData filtering, column selection, ordering, and one bounded page at a time."},{"name":"Assign Record","description":"Update an existing supported standard Microsoft Dynamics 365 CRM record. Only send the columns you want to change."},{"name":"Qualify Lead","description":"Qualify a Dynamics 365 Sales lead and optionally create linked account, contact, and opportunity records."},{"name":"Close Opportunity","description":"Close a Dynamics 365 Sales opportunity as won or lost."},{"name":"Close Case","description":"Resolve and close a Dynamics 365 Customer Service case."}],"triggers":[],"skills":[{"name":"find-customer-context","description":"Find an account, contact, lead, opportunity, or case and retrieve its current CRM details.","content":"# Find Customer Context\\n\\nUse this skill when a request names a customer, prospect, deal, or support issue but does not yet provide a Dynamics 365 record ID.\\n\\n## Steps\\n1. Choose the most likely standard CRM record type.\\n2. Use Search Records with a focused search term; Dataverse Search must be enabled.\\n3. If search is unavailable, use List Records with a narrow OData filter.\\n4. Use Get Record with the selected ID and request only the columns and relationships needed.\\n5. If multiple records remain plausible, present them for user selection rather than guessing.\\n\\n## Output\\nThe selected record ID, record type, and relevant current fields."},{"name":"maintain-customer-record","description":"Create or update a standard Dynamics 365 CRM record while preserving organization-specific fields.","content":"# Maintain Customer Record\\n\\nUse this skill to add or change an account, contact, lead, opportunity, or case.\\n\\n## Steps\\n1. Identify the standard CRM record type and the logical column names required by the environment.\\n2. Search or list records first when duplicate creation is possible.\\n3. Use Create Record with a JSON object for a new row, or Get Record followed by Update Record for an existing row.\\n4. Send only fields the user intends to change; do not infer custom choice values, lookups, or required fields.\\n5. Return the affected record ID and any provider error that requires an administrator or different security role.\\n\\n## Output\\nThe affected record ID and a concise summary of the submitted fields."},{"name":"route-crm-record","description":"List candidate Dynamics 365 owners and assign a CRM record to a user or owner-capable team.","content":"# Route CRM Record\\n\\nUse this skill when an account, contact, lead, opportunity, or case must be handed to a Dynamics 365 user or team.\\n\\n## Steps\\n1. Identify the target record type and record ID.\\n2. Use List Owners for active users or owner-capable teams and keep the result to one bounded page. Treat these as candidates because Dataverse still enforces security roles and table privileges.\\n3. Ask the user to choose when more than one owner is plausible.\\n4. Use Assign Record with the chosen owner type and GUID.\\n5. Surface permission errors; assignment requires the appropriate Dataverse privileges.\\n\\n## Output\\nThe assigned record ID, owner type, and selected owner ID."},{"name":"qualify-sales-lead","description":"Qualify an approved Dynamics 365 lead and control which account, contact, and opportunity records are created.","content":"# Qualify Sales Lead\\n\\nUse this skill only after the user or an approved workflow step has decided that a lead is qualified.\\n\\n## Steps\\n1. Retrieve the lead and confirm the intended record ID.\\n2. Confirm whether qualification should create an account, contact, and opportunity; never assume all three.\\n3. When creating an opportunity, include customer or currency references only when their GUIDs and concrete types are known.\\n4. Use Qualify Lead once. Do not automatically retry this mutation.\\n5. Return the entity references that Dynamics 365 actually reports, without inventing missing record IDs.\\n\\n## Output\\nThe provider-returned created entity references and qualification success."},{"name":"review-sales-pipeline","description":"Review a bounded page of Dynamics 365 opportunities and identify deals needing attention.","content":"# Review Sales Pipeline\\n\\nUse this skill for periodic pipeline reviews or focused opportunity analysis.\\n\\n## Steps\\n1. Use List Records for opportunities with explicit selected columns, an OData filter, ordering, and a maximum page size of 100 results.\\n2. Treat a returned next-page link as evidence that the review is incomplete; do not claim full-pipeline coverage.\\n3. If totalCountLimitExceeded is true, describe the reported count as capped rather than exact.\\n4. Retrieve individual opportunities only when more context is needed.\\n5. Group the returned page by owner, stage, expected close date, or another field explicitly present in the records.\\n6. Distinguish provider data from recommendations.\\n\\n## Output\\nA current-page pipeline summary, flagged opportunities, and whether additional pages or a capped count exist."},{"name":"close-sales-opportunity","description":"Close an approved Dynamics 365 opportunity as won or lost with an explicit outcome summary.","content":"# Close Sales Opportunity\\n\\nUse this skill only after the user or an authorized workflow step has approved the final outcome.\\n\\n## Steps\\n1. Retrieve the opportunity and confirm its record ID and intended outcome.\\n2. Optionally gather a close subject and notes.\\n3. Use Close Opportunity with won or lost; supply a custom status-reason integer only when the environment defines it.\\n4. Do not retry the close action automatically.\\n5. Report the supplied opportunity ID and outcome without claiming a response status Dynamics 365 did not return.\\n\\n## Output\\nThe closed opportunity ID, chosen outcome, and action success."},{"name":"resolve-customer-case","description":"Resolve an approved Dynamics 365 case with documented resolution details and time spent.","content":"# Resolve Customer Case\\n\\nUse this skill after support work is complete and resolution has been approved.\\n\\n## Steps\\n1. Retrieve the case and confirm it is the intended active case.\\n2. Gather a concise resolution subject, optional notes, and optional nonnegative whole minutes spent.\\n3. Use Close Case once; use a custom status-reason integer only when the environment defines it.\\n4. Do not automatically retry the resolution mutation.\\n5. Surface security-role, privilege, plugin, or status-reason errors without rewriting them as success.\\n\\n## Output\\nThe resolved case ID and action success."}],"templates":[{"title":"Dynamics lead intake","prompt":"Build a workflow that receives a new prospect, searches Microsoft Dynamics 365 CRM for a matching lead, creates the lead when no match exists, and notifies the sales team in Microsoft Teams.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Dynamics lead qualification","prompt":"Create a workflow that retrieves a Dynamics 365 lead after a qualification decision, qualifies it with the requested account, contact, and opportunity choices, and sends the resulting entity references to Microsoft Teams.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Dynamics customer sync","prompt":"Build a scheduled workflow that lists Dynamics 365 accounts and contacts, normalizes the current page into a Sim table, and updates matching CRM records when approved source data changes.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Dynamics pipeline review","prompt":"Create a scheduled workflow that lists open Dynamics 365 opportunities with an OData filter, summarizes the current page by owner and expected close date, and posts the review to Slack.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"slack","name":"Slack"}]},{"title":"Dynamics stale deal follow-up","prompt":"Build a scheduled workflow that lists Dynamics 365 opportunities with old activity dates, retrieves customer context, drafts follow-up messages in Outlook, and updates the reviewed opportunities with your organization’s approved fields.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"outlook","name":"Outlook"}]},{"title":"Dynamics closed-deal handoff","prompt":"Create a workflow that closes an approved Dynamics 365 opportunity as won or lost, retrieves the related CRM context, and posts a handoff summary to Microsoft Teams.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Dynamics case routing","prompt":"Build a workflow that searches Dynamics 365 for customer and case context, lists candidate users or owner-capable teams, assigns the case to the selected owner, and notifies the support channel in Microsoft Teams.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Dynamics case resolution","prompt":"Create a workflow that retrieves an approved Dynamics 365 case, records the resolution subject, notes, and time spent, resolves the case, and sends the customer a follow-up through Outlook.","integrations":[{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"},{"id":"outlook","name":"Outlook"}]}]},{"id":"microsoft_excel","type":"microsoft_excel_v2","slug":"microsoft-excel","name":"Microsoft Excel","description":"Manage worksheets, tables, rows, and workbook sessions","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/microsoft_excel","authType":"oauth","connections":[{"id":"microsoft-excel","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-excel","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_excel","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Files.Read","label":"Read OneDrive files"},{"id":"Files.ReadWrite","label":"Read and write OneDrive files"},{"id":"Sites.Read.All","label":"Read documents and list items in all SharePoint sites"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Read Data","description":"Read data from a Microsoft Excel spreadsheet"},{"name":"Write Data","description":"Write data to a Microsoft Excel spreadsheet"},{"name":"Clear Range","description":"Clear the values and/or formatting of a range in a Microsoft Excel worksheet"},{"name":"Format Range","description":"Apply fill color and/or font formatting to a range in a Microsoft Excel worksheet"},{"name":"Create Table","description":"Create a new table over a range of cells in a Microsoft Excel workbook"},{"name":"Sort Range","description":"Sort a range or table by one or more fields in a Microsoft Excel worksheet"},{"name":"Delete Worksheet","description":"Delete a worksheet (sheet) from a Microsoft Excel workbook"},{"name":"Add Table Rows","description":"Add new rows to a Microsoft Excel table"},{"name":"Add Worksheet","description":"Create a new worksheet (sheet) in a Microsoft Excel workbook"},{"name":"List Worksheets","description":"List Worksheets in a Microsoft Excel workbook."},{"name":"Get Worksheet","description":"Get Worksheet in a Microsoft Excel workbook."},{"name":"Update Worksheet","description":"Update Worksheet in a Microsoft Excel workbook."},{"name":"List Tables","description":"List Tables in a Microsoft Excel workbook."},{"name":"Get Table","description":"Get Table in a Microsoft Excel workbook."},{"name":"Update Table","description":"Update Table in a Microsoft Excel workbook."},{"name":"Delete Table","description":"Delete Table in a Microsoft Excel workbook."},{"name":"List Table Rows","description":"List Table Rows in a Microsoft Excel workbook."},{"name":"Get Table Row","description":"Get Table Row in a Microsoft Excel workbook."},{"name":"Update Table Row","description":"Update Table Row in a Microsoft Excel workbook."},{"name":"Delete Table Row","description":"Delete Table Row in a Microsoft Excel workbook."},{"name":"Create Session","description":"Create Session in a Microsoft Excel workbook."},{"name":"Refresh Session","description":"Refresh Session in a Microsoft Excel workbook."},{"name":"Close Session","description":"Close Session in a Microsoft Excel workbook."},{"name":"Calculate Workbook","description":"Calculate in a Microsoft Excel workbook."}],"triggers":[],"skills":[{"name":"read-sheet-range","description":"Read data from a Microsoft Excel worksheet range and return the rows.","content":"# Read Sheet Range\\n\\nPull data out of an Excel workbook for analysis or downstream steps.\\n\\n## Steps\\n1. Identify the workbook and the worksheet and range to read.\\n2. Use Read Data with the spreadsheet ID and range.\\n3. Parse the returned rows into a structured form for the next step.\\n\\n## Output\\nThe values from the range as rows, plus the sheet and range they came from."},{"name":"write-sheet-data","description":"Write or update values in a Microsoft Excel worksheet range, with values, formulas, and number formats.","content":"# Write Sheet Data\\n\\nUpdate cells in an Excel workbook.\\n\\n## Steps\\n1. Identify the workbook, worksheet, and target range.\\n2. Prepare the values as rows matching the range shape.\\n3. Use Write/Update Data, using the Values field for cell data or the Formulas field for A1-style formulas.\\n\\n## Output\\nConfirmation of the cells updated and the range that was written."},{"name":"append-table-row","description":"Append a new row to a Microsoft Excel table so it stays structured and formatted.","content":"# Append Table Row\\n\\nAdd a record to an existing Excel table.\\n\\n## Steps\\n1. Identify the workbook and the table to append to.\\n2. Build the row values in the table column order.\\n3. Use Add to Table to append the row so table formatting and references update automatically.\\n\\n## Output\\nConfirmation the row was appended and the table it was added to."},{"name":"add-worksheet","description":"Add a new worksheet to a Microsoft Excel workbook to hold a new dataset or report.","content":"# Add Worksheet\\n\\nCreate a fresh worksheet inside a workbook.\\n\\n## Steps\\n1. Identify the workbook to add the sheet to.\\n2. Choose a name for the new worksheet.\\n3. Use Add Worksheet to create it, then write headers or data with Write/Update Data if needed.\\n\\n## Output\\nThe new worksheet name and confirmation it was created in the workbook."},{"name":"build-formatted-table","description":"Write data to a range, convert it into a formatted Excel table, and highlight the header row.","content":"# Build Formatted Table\\n\\nTurn raw rows into a structured, readable Excel table.\\n\\n## Steps\\n1. Use Write/Update Data to put the rows into a range (e.g. A1:D20).\\n2. Use Create Table over that range with headers enabled so filtering and references work.\\n3. Use Format Range on the header row to apply a fill color and bold font for emphasis.\\n\\n## Output\\nThe created table details plus confirmation the header formatting was applied."},{"name":"sort-and-clean-range","description":"Sort a range or table by a column and clear stale cells so the sheet stays tidy.","content":"# Sort and Clean Range\\n\\nKeep a worksheet ordered and free of leftover data.\\n\\n## Steps\\n1. Use Sort Range with the target range or table name and the column index to sort on.\\n2. Choose ascending or descending order.\\n3. Use Clear Range on any obsolete cells, choosing to clear contents, formats, or both.\\n\\n## Output\\nConfirmation of the sort and which cells were cleared."}],"templates":[{"title":"Excel financial close automator","prompt":"Build a scheduled workflow that closes the books each period — pulls Stripe and accounting data, updates a Microsoft Excel close workbook, and emails the controller the reconciled file.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"}]},{"title":"Excel invoice generator","prompt":"Create a workflow that reads a sales orders table, populates an existing Microsoft Excel invoice worksheet per order, and posts the workbook link for finance review.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"Excel report table refresher","prompt":"Build a scheduled workflow that reads rows from a source, updates a Microsoft Excel report table, and posts the workbook link to a Microsoft Teams channel.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Excel + SharePoint forecast hub","prompt":"Create a workflow that aggregates regional forecasts submitted in Microsoft Excel files on SharePoint, normalizes formats, and writes a consolidated forecast table for leadership.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"Excel commission calculator","prompt":"Build a workflow that pulls closed Salesforce deals each month, computes commission per rep using a Microsoft Excel commission model, and emails the per-rep statements.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"salesforce","name":"Salesforce"},{"id":"gmail","name":"Gmail"}]},{"title":"Excel scenario modeler","prompt":"Create a workflow that runs scenarios against a Microsoft Excel financial model — pessimistic, base, optimistic — captures outputs, and writes a comparison report to a finance file.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Excel + Power BI feeder","prompt":"Build a scheduled workflow that updates a Microsoft Excel data table from a Sim source, keeps its table ready for Power BI consumption, and notifies BI consumers in Teams.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Microsoft Planner Excel-import","prompt":"Create a workflow that takes a Microsoft Excel task list, creates matching Planner tasks in the right bucket, and writes the planner IDs back to the spreadsheet for tracking.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"OneDrive Excel-pipeline opener","prompt":"Build a scheduled workflow that polls OneDrive for new Excel data drops, normalizes each, writes to a downstream table, and emails the analyst that the latest file is ready.","integrations":[{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"onedrive","name":"OneDrive"},{"id":"gmail","name":"Gmail"}]}]},{"id":"intune","type":"intune","slug":"microsoft-intune","name":"Microsoft Intune","description":"Manage devices, application inventory, and compliance with Microsoft Intune","category":"Security","docsUrl":"https://docs.sim.ai/integrations/intune","authType":"oauth","connections":[{"id":"microsoft-intune","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-intune","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/intune","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"DeviceManagementManagedDevices.Read.All","label":"View Intune managed devices and detected apps"},{"id":"DeviceManagementConfiguration.Read.All","label":"View Intune compliance policies, device configurations, and their device statuses"},{"id":"DeviceManagementManagedDevices.PrivilegedOperations.All","label":"Perform remote Intune device actions, including syncing, rebooting, locking, and retiring devices"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"List Devices","description":"Read one page of devices from Microsoft Intune"},{"name":"Get Device","description":"Read device details from Microsoft Intune"},{"name":"List Detected Apps","description":"Read one page of detected apps from Microsoft Intune"},{"name":"Get Detected App","description":"Read detected app details from Microsoft Intune"},{"name":"List App Devices","description":"Read one page of managed devices that have a detected application installed"},{"name":"List Compliance Policies","description":"Read one page of compliance policies from Microsoft Intune"},{"name":"Get Compliance Policy","description":"Read common metadata for an Intune compliance policy"},{"name":"List Compliance Policy Device Statuses","description":"Read one page of compliance policy device statuses from Microsoft Intune"},{"name":"List Device Configurations","description":"Read one page of device configurations from Microsoft Intune"},{"name":"Get Device Configuration","description":"Read common metadata for an Intune device configuration"},{"name":"Sync Device","description":"Request a device check-in to receive pending Intune policies and actions"},{"name":"Reboot Device","description":"Request a device restart after explicit confirmation; may interrupt the signed-in user"},{"name":"Remote Lock Device","description":"Request a remote device lock after explicit confirmation on supported platforms"},{"name":"Retire Device","description":"Retire a device after explicit confirmation, removing company data and management"}],"triggers":[],"skills":[{"name":"review-device-compliance","description":"Summarize noncompliant managed devices and the freshness of their status.","content":"# Review Device Compliance\\n\\n## Steps\\n1. Read managed devices using the complianceState filter or inspect their returned compliance states.\\n2. Continue with nextLink only as needed, keeping the same operation and a bounded page budget.\\n3. Summarize owners, operating systems, and last check-in times. For a selected policy, read its device statuses for policy-specific context.\\n\\n## Output\\nReturn device IDs, compliance states, and the last known check-in. Clearly state when a page budget means the report is partial.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-us/intune/device-security/compliance/monitor-policy)"},{"name":"audit-detected-applications","description":"Review discovered software names, versions, publishers, and affected device counts.","content":"# Audit Detected Applications\\n\\n## Steps\\n1. Read detected apps one page at a time.\\n2. Compare application names and versions against the supplied software review criteria.\\n3. For an application that needs investigation, read its details and list the managed devices where it was detected.\\n\\n## Output\\nReturn application IDs, versions, counts, and affected device IDs. Discovered app inventory refreshes periodically and is not a live scan.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-gb/intune/app-management/discovered-apps)"},{"name":"triage-policy-compliance","description":"Inspect a compliance policy and summarize its per-device status.","content":"# Triage Policy Compliance\\n\\n## Steps\\n1. List compliance policies and select the requested policy ID.\\n2. Read the common policy metadata, then page through its device statuses.\\n3. Group statuses and identify devices reporting errors, conflicts, or noncompliance.\\n\\n## Output\\nReturn the policy ID, version, status groups, and last report times. These tools return common metadata, not platform-specific compliance rule settings.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-us/intune/device-management/reports/overview)"},{"name":"refresh-device-check-in","description":"Request an Intune sync while distinguishing request acceptance from device completion.","content":"# Refresh Device Check-In\\n\\n## Steps\\n1. Read the requested managed device and confirm its Intune ID and latest check-in.\\n2. Request a sync for the selected device.\\n3. If follow-up is requested, read the device again later and compare lastSyncDateTime.\\n\\n## Output\\nReturn whether the sync request was accepted and the latest observed check-in time. Do not claim policies have applied merely because Graph returned success.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-us/intune/device-management/actions/sync)"},{"name":"assess-application-exposure","description":"Find the managed devices affected by a reviewed software version.","content":"# Assess Application Exposure\\n\\n## Steps\\n1. Locate the detected application by name, publisher, and version from the app inventory.\\n2. List the devices associated with the detected application ID, continuing only within an explicit page budget.\\n3. Summarize operating systems, owners, and device compliance states for follow-up.\\n\\n## Output\\nReturn the specific application version and affected device IDs. Do not infer vulnerabilities from a name alone or claim the inventory is real-time.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-gb/intune/app-management/discovered-apps)"},{"name":"retire-approved-device","description":"Retire a selected managed device after an administrator explicitly approves removal of company data.","content":"# Retire Approved Device\\n\\n## Steps\\n1. Read the managed device and verify its Intune ID, owner, and platform against the approved request.\\n2. Explain that retirement removes company data and management; verify the administrator has completed their backup and recovery-key procedures where applicable.\\n3. Only with explicit user confirmation, request retirement for that device.\\n\\n## Output\\nReport request acceptance without claiming completion. Retirement occurs when the device checks in, and availability depends on platform and administrator permissions.\\n\\n## Reference\\n[Microsoft documentation](https://learn.microsoft.com/en-us/intune/device-management/actions/retire)"}],"templates":[{"title":"Daily Compliance Review","prompt":"Build a scheduled agent that reads Intune managed devices and flags noncompliant devices with their owners and last check-in times. Publish a concise report with device IDs for follow-up.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Software Inventory Audit","prompt":"Build an agent that pages through Intune detected apps, groups names and versions, and identifies installations of software on a supplied review list. Return affected application IDs and device counts.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Application Exposure Review","prompt":"When an application version is flagged for review, use Intune detected apps to identify its record and list the managed devices where it is installed. Produce the device names, owners, and compliance states.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Policy Deployment Triage","prompt":"Build an agent that reads a selected Intune compliance policy and its device statuses. Summarize compliant, noncompliant, conflicting, and error results with last report times.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Device Check-In Follow-Up","prompt":"Build a scheduled agent that finds Intune devices with stale check-in times and requests a sync for approved device IDs. Report accepted sync requests separately from later device check-ins.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Approved Device Retirement","prompt":"When an administrator approves a device retirement, read the Intune device and verify its ID and owner. Request retirement only with explicit confirmation and report that the request was accepted.","integrations":[{"id":"intune","name":"Microsoft Intune"}]},{"title":"Help Desk Device Actions","prompt":"Build an agent that reads an Intune device during an IT support request, summarizes its operating system and compliance status, and requests a restart or remote lock only after an administrator explicitly confirms the action.","integrations":[{"id":"intune","name":"Microsoft Intune"}]}]},{"id":"microsoft_planner","type":"microsoft_planner","slug":"microsoft-planner","name":"Microsoft Planner","description":"Manage tasks, plans, and buckets in Microsoft Planner","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/microsoft_planner","authType":"oauth","connections":[{"id":"microsoft-planner","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-planner","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_planner","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Group.ReadWrite.All","label":"Read and write all groups"},{"id":"Group.Read.All","label":"Read all groups, memberships, and group content"},{"id":"Tasks.ReadWrite","label":"Read and manage Planner tasks"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Read Task","description":"Read tasks from Microsoft Planner - get all user tasks or all tasks from a specific plan"},{"name":"Create Task","description":"Create a new task in Microsoft Planner"},{"name":"Update Task","description":"Update a task in Microsoft Planner"},{"name":"Delete Task","description":"Delete a task from Microsoft Planner"},{"name":"List Plans","description":"List all plans shared with the current user"},{"name":"Read Plan","description":"Get details of a specific Microsoft Planner plan"},{"name":"Create Plan","description":"Create a new Microsoft Planner plan owned by a Microsoft 365 group"},{"name":"Update Plan","description":"Rename a Microsoft Planner plan"},{"name":"Get Plan Details","description":"Get detailed information about a plan including category descriptions and sharing"},{"name":"Update Plan Details","description":"Update a plan\'s category (color label) descriptions and shared-with user list in Microsoft Planner"},{"name":"Delete Plan","description":"Delete a Microsoft Planner plan"},{"name":"List Buckets","description":"List all buckets in a Microsoft Planner plan"},{"name":"Read Bucket","description":"Get details of a specific bucket"},{"name":"Create Bucket","description":"Create a new bucket in a Microsoft Planner plan"},{"name":"Update Bucket","description":"Update a bucket in Microsoft Planner"},{"name":"Delete Bucket","description":"Delete a bucket from Microsoft Planner"},{"name":"Get Task Details","description":"Get detailed information about a task including checklist and references"},{"name":"Update Task Details","description":"Update task details including description, checklist items, and references in Microsoft Planner"}],"triggers":[],"skills":[{"name":"create-task-in-bucket","description":"Create a Microsoft Planner task in a specific plan and bucket with title, due date, and assignee.","content":"# Create Planner Task\\n\\nCreate a new task in a Microsoft Planner plan, placing it in the right bucket and setting a due date and owner.\\n\\n## Steps\\n1. Use List Plans to find the target plan, then List Buckets for that plan to locate the bucket id.\\n2. Run Create Task with the plan id, a clear title, and the bucket id so it lands in the right column.\\n3. If a due date was described in natural language, convert it to ISO 8601 (YYYY-MM-DDTHH:MM:SSZ) before passing dueDateTime.\\n4. Set assigneeUserId when an owner is known.\\n\\n## Output\\nConfirm the created task id and report title, bucket, due date, and assignee. Surface the etag for any follow-up updates."},{"name":"set-up-plan-buckets","description":"Create a set of stage or phase buckets in a Planner plan to organize tasks by workflow column.","content":"# Set Up Plan Buckets\\n\\nStructure a Microsoft Planner plan into the workflow columns a team needs, such as To Do, In Progress, Review, and Done, or project phases.\\n\\n## Steps\\n1. Use List Plans to find the target plan, then List Buckets to see which buckets already exist and avoid duplicates.\\n2. Run Create Bucket once per desired column, passing the plan id and a clear bucket name.\\n3. Keep names short and ordered so the board reads left to right as work progresses.\\n\\n## Output\\nList every bucket id and name that now exists in the plan, marking which were newly created. Suggest the next bucket only if a stage is clearly missing."},{"name":"add-task-checklist","description":"Add a step-by-step checklist to a Planner task so each subtask can be tracked and checked off.","content":"# Add Task Checklist\\n\\nBreak a Microsoft Planner task into trackable subtasks using its checklist.\\n\\n## Steps\\n1. Identify the target task id, using Read Task to confirm the title if needed.\\n2. Use Get Task Details to read the current checklist and capture the etag required for updates.\\n3. Run Update Task Details with the checklist items to add, passing the etag from the previous step.\\n4. Set percentComplete on the task with Update Task when progress should reflect the checklist state.\\n\\n## Output\\nConfirm the task id and list the checklist items now present. Note the refreshed etag for any further edits."}],"templates":[{"title":"Microsoft Planner sprint digest","prompt":"Create a scheduled weekly workflow that pulls Microsoft Planner bucket progress, computes completion rate per bucket, and posts a status digest to the project Microsoft Teams channel.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Microsoft Planner SLA monitor","prompt":"Build a workflow that watches Microsoft Planner tasks with due dates, sends reminders 24 hours before, and escalates to managers in Teams when items breach SLA.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Microsoft Planner Excel-import","prompt":"Create a workflow that takes a Microsoft Excel task list, creates matching Planner tasks in the right bucket, and writes the planner IDs back to the spreadsheet for tracking.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Microsoft Planner blocker watcher","prompt":"Build a scheduled workflow that scans Microsoft Planner tasks tagged blocked, identifies the blocking party, and posts a Teams ping with the context to unblock the work.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Microsoft Planner template launcher","prompt":"Create a scheduled workflow that polls Microsoft Dataverse for new projects and creates a Planner plan from the project template, populates the standard buckets, and assigns the right owners.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Microsoft Planner retrospective","prompt":"Build a scheduled workflow that runs at the end of a sprint, pulls completed Microsoft Planner tasks, summarizes wins and patterns, and writes the retro doc to a SharePoint page.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"Microsoft Planner workload balancer","prompt":"Create a scheduled weekly workflow that audits Microsoft Planner assignment load per team member, suggests rebalancing, and posts the recommendations to the manager in Teams.","integrations":[{"id":"microsoft_planner","name":"Microsoft Planner"},{"id":"microsoft_teams","name":"Microsoft Teams"}]}]},{"id":"mssql","type":"mssql","slug":"microsoft-sql-server","name":"Microsoft SQL Server","description":"Connect to Microsoft SQL Server database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/mssql","authType":"none","connections":[],"operations":[{"name":"Query (SELECT)","description":"Execute a SELECT query on a Microsoft SQL Server database"},{"name":"Insert Data","description":"Insert data into a Microsoft SQL Server table"},{"name":"Update Data","description":"Update rows in a Microsoft SQL Server table"},{"name":"Delete Data","description":"Delete rows from a Microsoft SQL Server table"},{"name":"Execute Raw SQL","description":"Execute a raw T-SQL statement on a Microsoft SQL Server database"},{"name":"Introspect Schema","description":"Introspect a Microsoft SQL Server schema to retrieve table structures, columns, keys, and indexes. Results only cover objects the login can see, so a low-privilege account returns a partial schema rather than an error"}],"triggers":[],"skills":[{"name":"query-to-answer","description":"Turn a natural-language question into a T-SQL SELECT and return the rows.","content":"# Query To Answer\\n\\nAnswer a question by generating and running a T-SQL SELECT.\\n\\n## Steps\\n1. Introspect the relevant schema first so the agent knows the real table and column names.\\n2. Have the agent write a single SELECT, using TOP (n) to bound large result sets.\\n3. Run the query and inspect rows and rowCount.\\n4. Summarize the rows back to the caller in plain language.\\n\\n## Output\\nReturn the answer text, the underlying rows, and the rowCount."},{"name":"merge-records","description":"Insert new rows or update existing ones by key so a table stays deduplicated.","content":"# Merge Records\\n\\nKeep a table in sync by inserting new rows or updating existing ones on a key.\\n\\n## Preferred: atomic MERGE with execute\\nUse the execute operation to run a single T-SQL `MERGE`, which resolves the match and the write in one statement.\\n\\n```sql\\nMERGE dbo.users AS target\\nUSING (SELECT \'u1\' AS id, \'Jane\' AS name, \'jane@example.com\' AS email) AS source\\nON target.id = source.id\\nWHEN MATCHED THEN UPDATE SET name = source.name, email = source.email\\nWHEN NOT MATCHED THEN INSERT (id, name, email) VALUES (source.id, source.name, source.email);\\n```\\n\\nAlways terminate a MERGE statement with a semicolon — SQL Server requires it.\\n\\n## Fallback: read then write\\nIf MERGE is unavailable, query the table for an existing row by key, then run insert when none exists or update with a WHERE condition on the key when one does.\\n\\n## Steps\\n1. Confirm the match key is unique.\\n2. Run execute with the MERGE statement for each record.\\n3. Inspect rowCount to confirm the write landed.\\n\\n## Output\\nReport how many records were merged and the total rowCount changed."},{"name":"document-schema","description":"Introspect a schema and produce plain-English documentation of its tables.","content":"# Document Schema\\n\\nDescribe a Microsoft SQL Server schema in readable terms.\\n\\n## Steps\\n1. Run introspect on the target schema (default dbo) to get tables, columns, keys, and indexes.\\n2. Have an agent describe what each table stores and how they relate via foreign keys.\\n3. Note primary keys and indexes that hint at common access patterns.\\n4. Assemble the descriptions into a single document.\\n\\n## Output\\nReturn the list of tables with a short description of each and the raw introspection result."},{"name":"retention-cleanup","description":"Delete rows older than a retention cutoff and report the count removed.","content":"# Retention Cleanup\\n\\nRemove stale rows on a schedule.\\n\\n## Steps\\n1. Compute the retention cutoff timestamp for the run.\\n2. Optionally query a count of rows older than the cutoff to preview the impact.\\n3. Run delete with a WHERE condition comparing the timestamp column to the cutoff.\\n4. Capture the rowCount removed for the run.\\n\\n## Output\\nReport how many rows were deleted and the cutoff that was applied."}],"templates":[{"title":"Ask SQL Server in plain English","prompt":"Build a workflow that takes a natural-language question, has an agent turn it into a T-SQL SELECT, runs it against Microsoft SQL Server, and returns the resulting rows as a readable answer.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"SQL Server metrics digest to Slack","prompt":"Create a scheduled workflow that queries key business metrics from Microsoft SQL Server each morning, has an agent summarize the numbers and notable changes, and posts the digest to a Slack channel.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"},{"id":"slack","name":"Slack"}]},{"title":"Document your SQL Server schema","prompt":"Build a workflow that introspects a Microsoft SQL Server schema to list its tables, columns, keys, and indexes, then has an agent write plain-English documentation describing what each table holds.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"Merge records into SQL Server","prompt":"Create a workflow that takes incoming records and runs a T-SQL MERGE against Microsoft SQL Server so each row is inserted when new and updated when it already exists, keeping the table free of duplicates.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"Nightly SQL Server data cleanup","prompt":"Build a scheduled workflow that deletes rows in Microsoft SQL Server older than a retention cutoff and reports how many rows were removed, so tables stay lean on an interval.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"SQL Server results to Sim table","prompt":"Create a scheduled workflow that runs a Microsoft SQL Server query for the latest records and writes each row into a Sim table, so the data is available for downstream blocks without a live database call.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"SQL Server threshold breach alert","prompt":"Build a scheduled workflow that queries a Microsoft SQL Server count or aggregate, compares it to a threshold, and posts a Slack alert only when the value crosses the limit so the team hears about problems early.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"},{"id":"slack","name":"Slack"}]},{"title":"Log form submissions to SQL Server","prompt":"Create a workflow that takes an incoming payload, validates the fields, and inserts a new row into a Microsoft SQL Server table so every submission is durably recorded.","integrations":[{"id":"mssql","name":"Microsoft SQL Server"}]}]},{"id":"microsoft_teams","type":"microsoft_teams","slug":"microsoft-teams","name":"Microsoft Teams","description":"Manage messages, reactions, and members in Teams","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/microsoft_teams","authType":"oauth","connections":[{"id":"microsoft-teams","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-teams","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_teams","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"User.Read","label":"Sign in and read your profile"},{"id":"Chat.Read","label":"Read your Teams chat messages"},{"id":"Chat.ReadWrite","label":"Read and write your Teams chat messages"},{"id":"Chat.ReadBasic","label":"Read names and members of your Teams chats"},{"id":"ChatMessage.Send","label":"Send chat messages"},{"id":"Channel.ReadBasic.All","label":"Read channel names and descriptions"},{"id":"ChannelMessage.Send","label":"Send channel messages"},{"id":"ChannelMessage.Read.All","label":"Read channel messages"},{"id":"ChannelMessage.ReadWrite","label":"Read and write channel messages"},{"id":"ChannelMember.Read.All","label":"Read team channel members"},{"id":"Group.Read.All","label":"Read all groups, memberships, and group content"},{"id":"Group.ReadWrite.All","label":"Read and write all groups"},{"id":"Team.ReadBasic.All","label":"Read team names and descriptions"},{"id":"TeamMember.Read.All","label":"Read team members"},{"id":"offline_access","label":"Access account when not using the application"},{"id":"Files.Read","label":"Read OneDrive files"},{"id":"Sites.Read.All","label":"Read documents and list items in all SharePoint sites"}],"fields":[]}],"operations":[{"name":"Read Chat Messages","description":"Read content from a Microsoft Teams chat"},{"name":"Write Chat Message","description":"Write or update content in a Microsoft Teams chat"},{"name":"Update Chat Message","description":"Update an existing message in a Microsoft Teams chat"},{"name":"Delete Chat Message","description":"Soft delete a message in a Microsoft Teams chat"},{"name":"Read Channel Messages","description":"Read content from a Microsoft Teams channel"},{"name":"Write Channel Message","description":"Write or send a message to a Microsoft Teams channel"},{"name":"Update Channel Message","description":"Update an existing message in a Microsoft Teams channel"},{"name":"Delete Channel Message","description":"Soft delete a message in a Microsoft Teams channel"},{"name":"Reply to Channel Message","description":"Reply to an existing message in a Microsoft Teams channel"},{"name":"Get Message","description":"Get a specific message from a Microsoft Teams chat or channel"},{"name":"Add Reaction","description":"Add an emoji reaction to a message in Microsoft Teams"},{"name":"Remove Reaction","description":"Remove an emoji reaction from a message in Microsoft Teams"},{"name":"List Team Members","description":"List all members of a Microsoft Teams team"},{"name":"List Channel Members","description":"List all members of a Microsoft Teams channel"},{"name":"List Chat Members","description":"List all members of a Microsoft Teams chat"},{"name":"List Teams","description":"List the Microsoft Teams the current user is a direct member of"},{"name":"List Chats","description":"List the Microsoft Teams chats the current user is part of"},{"name":"List Channels","description":"List all channels in a Microsoft Teams team"}],"triggers":[{"id":"microsoftteams_webhook","name":"Microsoft Teams Channel","description":"Trigger workflows when the outgoing webhook is @mentioned in a Microsoft Teams channel."},{"id":"microsoftteams_chat_subscription","name":"Microsoft Teams Chat","description":"Trigger workflows from Microsoft Teams chat message notifications via Microsoft Graph subscriptions. Notifications share a seven-day deduplication window keyed by subscription and message ID, so later edits may not start a separate run."}],"skills":[{"name":"post-channel-announcement","description":"Write a formatted message to a specific Microsoft Teams channel.","content":"# Post Channel Announcement\\n\\nSend an announcement or update to a Microsoft Teams channel.\\n\\n## Steps\\n1. Identify the team and channel to post to, selecting the channel id.\\n2. Compose the message body, using clear headings and bullets so it reads well in Teams.\\n3. Run Write Channel Message with the channel id and the formatted content.\\n4. If a thread already exists for the topic, use Reply to Channel Message instead to keep context together.\\n\\n## Output\\nConfirm the posted message id and channel. Quote the first line of what was posted."},{"name":"summarize-channel-activity","description":"Read recent Microsoft Teams channel messages and produce a concise digest of decisions and action items.","content":"# Summarize Channel Activity\\n\\nTurn a busy Microsoft Teams channel into a short readable digest.\\n\\n## Steps\\n1. Run Read Channel Messages for the target channel.\\n2. Group messages by topic or thread and drop noise such as greetings and reactions.\\n3. Extract decisions made, open questions, and any explicit action items with owners.\\n4. Optionally post the digest back to the channel as a new message.\\n\\n## Output\\nThree short sections: Decisions, Open Questions, Action Items. Each item one line with the person responsible when known."},{"name":"acknowledge-with-reaction","description":"React to a specific Microsoft Teams message to acknowledge it.","content":"# Acknowledge with Reaction\\n\\nAdd or remove an emoji reaction on a Microsoft Teams message.\\n\\n## Steps\\n1. Locate the message using Get Message or the known message id and channel/chat id.\\n2. Run Add Reaction with the desired reactionType to acknowledge or signal status.\\n3. Use Remove Reaction when the acknowledgment should be cleared.\\n\\n## Output\\nConfirm the reaction applied and on which message. Keep the response to one line."},{"name":"list-team-members","description":"List the members of a Microsoft Teams team or channel for routing or auditing.","content":"# List Team Members\\n\\nRetrieve who belongs to a Microsoft Teams team or channel.\\n\\n## Steps\\n1. Decide whether you need team-wide membership or a single channel and pick List Team Members or List Channel Members.\\n2. Run the operation with the team id (and channel id when needed).\\n3. Normalize the result into a clean roster of names and roles.\\n\\n## Output\\nA roster list with display name and role. Note the total count at the top."},{"name":"discover-teams-chats-channels","description":"Enumerate the teams, chats, and channels available to the connected Microsoft account before acting on them.","content":"# Discover Teams, Chats, and Channels\\n\\nResolve human-friendly names to the ids other Microsoft Teams operations need.\\n\\n## Steps\\n1. Run List Teams to see every team the connected account belongs to, or List Chats to see active chats.\\n2. If the target is a channel, run List Channels with the resolved team id to find the channel id.\\n3. If the target is a chat, run List Chat Members to confirm the right people are present before writing to it.\\n4. Feed the resolved team id, channel id, or chat id into the read/write/reply/reaction operations.\\n\\n## Output\\nReturn the matched team, chat, or channel name alongside its id so subsequent steps can reference it."}],"templates":[{"title":"Agiloft approval router","prompt":"Create a scheduled workflow that searches Agiloft for contracts needing approval, posts a Microsoft Teams adaptive card to the approver, captures the decision, and updates Agiloft.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"agiloft","name":"Agiloft"}]},{"title":"Azure AD access review","prompt":"Build a scheduled quarterly workflow that lists Azure AD group memberships, requests owner attestation in Microsoft Teams, and writes the audit log to a compliance table.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Azure AD privileged-access monitor","prompt":"Build a scheduled workflow that lists privileged Azure AD group members each run, compares against the last snapshot in a table, and pings the security Microsoft Teams channel on any add or removal.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Dataverse approval workflow","prompt":"Create a scheduled workflow that polls Dataverse for new high-value records, posts an adaptive card approval to Microsoft Teams, captures the decision, and updates the record.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dataverse case-routing agent","prompt":"Build a workflow that runs a relevance search across Microsoft Dataverse case and account tables when a new support request arrives, classifies the issue, upserts the case record with the right owner and priority, and notifies the assigned team in Microsoft Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dynamics lead intake","prompt":"Build a workflow that receives a new prospect, searches Microsoft Dynamics 365 CRM for a matching lead, creates the lead when no match exists, and notifies the sales team in Microsoft Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Dynamics lead qualification","prompt":"Create a workflow that retrieves a Dynamics 365 lead after a qualification decision, qualifies it with the requested account, contact, and opportunity choices, and sends the resulting entity references to Microsoft Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Dynamics closed-deal handoff","prompt":"Create a workflow that closes an approved Dynamics 365 opportunity as won or lost, retrieves the related CRM context, and posts a handoff summary to Microsoft Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Dynamics case routing","prompt":"Build a workflow that searches Dynamics 365 for customer and case context, lists candidate users or owner-capable teams, assigns the case to the selected owner, and notifies the support channel in Microsoft Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Excel report table refresher","prompt":"Build a scheduled workflow that reads rows from a source, updates a Microsoft Excel report table, and posts the workbook link to a Microsoft Teams channel.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Excel + Power BI feeder","prompt":"Build a scheduled workflow that updates a Microsoft Excel data table from a Sim source, keeps its table ready for Power BI consumption, and notifies BI consumers in Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Microsoft Planner sprint digest","prompt":"Create a scheduled weekly workflow that pulls Microsoft Planner bucket progress, computes completion rate per bucket, and posts a status digest to the project Microsoft Teams channel.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"Microsoft Planner SLA monitor","prompt":"Build a workflow that watches Microsoft Planner tasks with due dates, sends reminders 24 hours before, and escalates to managers in Teams when items breach SLA.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"Microsoft Planner blocker watcher","prompt":"Build a scheduled workflow that scans Microsoft Planner tasks tagged blocked, identifies the blocking party, and posts a Teams ping with the context to unblock the work.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"Microsoft Planner workload balancer","prompt":"Create a scheduled weekly workflow that audits Microsoft Planner assignment load per team member, suggests rebalancing, and posts the recommendations to the manager in Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"Microsoft Teams daily brief","prompt":"Build a scheduled workflow that pulls updates from your project tools — GitHub commits, Jira ticket status changes, and calendar events — and posts a formatted daily brief to your Microsoft Teams channel each morning.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"github","name":"GitHub"},{"id":"jira","name":"Jira"}]},{"title":"Teams incident war room","prompt":"Build a workflow triggered by a PagerDuty incident that creates a Microsoft Teams war-room channel, invites responders, posts the incident summary, and keeps the channel name in sync with incident state.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Teams sales-deal channel","prompt":"Create a workflow that listens for new Salesforce opportunities above a threshold, creates a Microsoft Teams channel for the deal, invites the account team, and pins the opportunity link.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Teams approval router","prompt":"Build a workflow that posts approval requests with quick-action buttons in Microsoft Teams, captures the decision, writes it back to the source record, and notifies the requester.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Teams weekly metrics digest","prompt":"Create a scheduled weekly workflow that aggregates key business metrics from Stripe and HubSpot, formats them into a polished Microsoft Teams adaptive card, and posts to the leadership channel.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"stripe","name":"Stripe"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Teams onboarding bot","prompt":"Build a Microsoft Teams bot that greets new hires when added to the org, walks them through onboarding tasks with progress checkboxes, and writes completion status to an HR table.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Teams ticket-bridge for Zendesk","prompt":"Create a workflow that mirrors high-priority Zendesk tickets into Microsoft Teams channels, keeps replies synced both ways, and closes the Teams thread when the ticket is resolved.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Word contract reviewer","prompt":"Create a workflow that reads a Word contract, flags clauses that deviate from the standard template, writes the findings to a table, and posts a review summary in Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"microsoft_word","name":"Microsoft Word"}]},{"title":"OneDrive contract intake","prompt":"Create a scheduled workflow that polls a OneDrive intake folder for new contract PDFs, extracts clauses with Reducto, writes the structured terms to a table, and pings legal in Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"onedrive","name":"OneDrive"},{"id":"reducto","name":"Reducto"}]},{"title":"OneDrive retention cleaner","prompt":"Create a scheduled workflow that finds OneDrive files older than the retention horizon, requires manager approval through Teams, and archives or deletes per the policy.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"onedrive","name":"OneDrive"}]},{"title":"Power BI KPI briefing","prompt":"Build a scheduled workflow that runs an approved DAX query for daily KPIs in a Power BI semantic model, summarizes successful results, and posts the briefing to Microsoft Teams. Connect the query block\'s error port to a separate failure notification.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"powerbi","name":"Power BI"}]},{"title":"Power BI pipeline refresh","prompt":"Build a workflow started by an upstream pipeline completion request that asks Power BI to refresh a selected semantic model and records the acceptance and request ID in a Sim table. Notify Microsoft Teams that the refresh was requested, then use a separate scheduled history check to observe completion.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"powerbi","name":"Power BI"}]},{"title":"Power BI freshness watch","prompt":"Build a scheduled workflow that reads semantic model refresh history, compares the most recent completed refresh with an agreed freshness deadline, and sends Microsoft Teams a stale-data warning when the deadline is missed. Report Unknown statuses separately without claiming a refresh has completed.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"powerbi","name":"Power BI"}]},{"title":"SAP Concur travel pre-approval","prompt":"Build a scheduled workflow that polls SAP Concur for pending travel requests, routes each to the right approver based on amount and destination, captures the decision over Microsoft Teams, and moves the request to the approved or sent-back state.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SAP Concur budget watcher","prompt":"Build a scheduled monthly workflow that aggregates SAP Concur spend per department, compares against budget, and pings managers in Teams when overspend is projected.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SharePoint policy publisher","prompt":"Build a workflow that turns a Google Docs policy update into a published SharePoint page, posts the change diff to the policies team in Microsoft Teams, and writes the version history.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sharepoint","name":"SharePoint"},{"id":"google_docs","name":"Google Docs"}]},{"title":"SharePoint stale-page sweeper","prompt":"Create a scheduled workflow that lists SharePoint pages not updated in 180 days, opens an owner-review thread in Teams, and archives pages once the owner approves.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"SharePoint knowledge agent","prompt":"Build an agent that indexes SharePoint sites into a knowledge base, answers internal questions with cited links, and deploys as a Teams chat endpoint.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"SharePoint external-share audit","prompt":"Create a scheduled workflow that audits SharePoint external sharing, flags items above the sensitivity threshold, and posts a security report to Teams compliance channel.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"SharePoint search-relevance auditor","prompt":"Create a scheduled workflow that runs benchmark queries against SharePoint search weekly, scores the top result relevance, and writes a quality report to Teams.","integrations":[{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"sharepoint","name":"SharePoint"}]}]},{"id":"microsoft_word","type":"microsoft_word","slug":"microsoft-word","name":"Microsoft Word","description":"Create, fill, read, edit, and export Word documents","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/microsoft_word","authType":"oauth","connections":[{"id":"microsoft-word","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-word","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/microsoft_word","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Files.Read","label":"Read your Word documents in OneDrive"},{"id":"Files.ReadWrite","label":"Read, create, and edit your Word documents in OneDrive"},{"id":"Files.Read.All","label":"Read Word documents you can access, including SharePoint libraries"},{"id":"Files.ReadWrite.All","label":"Read, create, and edit Word documents you have access to, including SharePoint libraries"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Read Document","description":"Read the text content of a Microsoft Word (.docx) document stored in OneDrive or SharePoint."},{"name":"Create Document","description":"Create a new Microsoft Word (.docx) document in OneDrive or SharePoint from text content. Supports Markdown headings (# ## ###), bullets (-), and inline **bold** / *italic*. An existing document with the same name is never overwritten — the new one is given a unique name instead."},{"name":"Create from Template","description":"Copy an existing Microsoft Word (.docx) template to a new document and fill its placeholders. The template keeps all of its formatting, styles, headers, and footers, and is never modified. An existing document with the same name is never overwritten — the new one is given a unique name instead."},{"name":"Replace Content","description":"Replace the entire contents of an existing Microsoft Word (.docx) document with new text. The previous content and its formatting are discarded — use Append to add to a document instead."},{"name":"Append Content","description":"Append plain-text paragraphs to the end of an existing Microsoft Word (.docx) document, leaving the existing content and formatting intact. Fails rather than overwriting if someone else changed the document while the edit was in flight."},{"name":"Find and Replace Text","description":"Find and replace text throughout a Microsoft Word (.docx) document, including its headers and footers. Use this to fill placeholders in a template document. Fails rather than overwriting if someone else changed the document while the edit was in flight."},{"name":"List Documents","description":"List or search Microsoft Word (.docx) documents in OneDrive or SharePoint. Non-Word items are filtered out of the results."},{"name":"Export as PDF","description":"Convert a Microsoft Word (.docx) document to PDF using Microsoft Graph and return it as a file."}],"triggers":[],"skills":[{"name":"fill-word-template","description":"Generate a document from a formatted Word template by substituting its placeholders.","content":"# Fill a Word Template\\n\\nTurn an approved template into a finished document without touching the template itself.\\n\\n## Steps\\n1. Run List Documents to locate the template and note its document id.\\n2. Run Create from Template with that template, the name for the new document, and a Placeholder Values object mapping each placeholder to its value, for example {\\"{{customer_name}}\\": \\"Acme Corp\\"}.\\n3. Read back occurrencesChanged; a count of 0 means the placeholders in the object do not match the ones in the template.\\n\\n## Output\\nReport the new document name, its link, and how many placeholders were filled."},{"name":"generate-contract-from-deal","description":"Produce a contract or offer letter from deal data and deliver it as a PDF.","content":"# Generate a Contract from Deal Data\\n\\nProduce a signed-ready document from structured data.\\n\\n## Steps\\n1. Collect the counterparty, amounts, and dates from the upstream CRM or form step.\\n2. Run Create from Template against the standard agreement template, passing those values as Placeholder Values.\\n3. Run Export as PDF on the new document so the recipient gets a fixed copy.\\n4. Hand the PDF to an email or messaging step for delivery.\\n\\n## Output\\nConfirm the document name, the filled placeholder count, and the PDF that was produced."},{"name":"summarize-word-document","description":"Read a Word document and produce a structured summary of its contents.","content":"# Summarize a Word Document\\n\\nTurn a long document into something a person can act on.\\n\\n## Steps\\n1. Run List Documents to find the document, or take its id from an upstream step.\\n2. Run Read Document to extract the text.\\n3. Pass the text to an agent with instructions on what to pull out, such as decisions, owners, and dates.\\n\\n## Output\\nReturn the summary along with the document name and link so the reader can open the source."},{"name":"append-to-running-log","description":"Add a new dated entry to the end of an existing Word document.","content":"# Append to a Running Log\\n\\nKeep one document growing instead of creating a new file each time.\\n\\n## Steps\\n1. Run List Documents to find the log document.\\n2. Compose the entry text, starting with the date so entries stay scannable.\\n3. Run Append Content with that text; each non-empty line becomes its own paragraph and the existing content is left untouched.\\n\\n## Output\\nConfirm what was appended and link to the updated document."},{"name":"export-document-as-pdf","description":"Convert a Word document to PDF for sharing or archiving.","content":"# Export a Document as PDF\\n\\nShare a fixed copy that renders the same everywhere.\\n\\n## Steps\\n1. Identify the document, either from List Documents or from an upstream step that created it.\\n2. Run Export as PDF, optionally setting the PDF File Name.\\n3. Pass the returned file to an email, upload, or messaging step.\\n\\n## Output\\nConfirm the PDF file name and where it was sent."},{"name":"rebrand-across-documents","description":"Apply a naming or terminology change across a set of Word documents, headers and footers included.","content":"# Rebrand Across Documents\\n\\nRoll out a rename without opening each file.\\n\\n## Steps\\n1. Run List Documents with a search query narrow enough to hit only the documents in scope, and review the list before editing anything.\\n2. For each document, run Find and Replace Text with the old and new terms; headers and footers are covered along with the body.\\n3. Track occurrencesChanged per document so a document that reports 0 can be checked by hand.\\n\\n## Output\\nReport each document edited, its replacement count, and any that matched nothing."},{"name":"localize-a-document","description":"Produce a translated copy of a Word document without altering the original.","content":"# Localize a Document\\n\\nCreate a language variant while leaving the source intact.\\n\\n## Steps\\n1. Run Read Document on the source to extract its text.\\n2. Translate the text with an agent, keeping the heading and bullet markers so structure survives.\\n3. Run Create Document with the translated text and a name that carries the locale, for example \\"Policy (de-DE)\\".\\n\\n## Output\\nConfirm the new document name and link, and note that the source was not modified."}],"templates":[{"title":"Word meeting-notes writer","prompt":"Build a workflow that takes a Fireflies meeting transcript, summarizes the decisions and action items, and creates a formatted Word document in the team OneDrive folder.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"},{"id":"fireflies","name":"Fireflies"},{"id":"onedrive","name":"OneDrive"}]},{"title":"Word contract reviewer","prompt":"Create a workflow that reads a Word contract, flags clauses that deviate from the standard template, writes the findings to a table, and posts a review summary in Teams.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Word weekly-report builder","prompt":"Build a scheduled weekly workflow that pulls metrics from a table, drafts a written status report, and appends the new week to a running Word document.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"}]},{"title":"Word proposal generator","prompt":"Create a workflow triggered by a closed-won HubSpot deal that generates a tailored proposal document in Word, exports it as PDF, and emails it to the customer contact.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"},{"id":"hubspot","name":"HubSpot"},{"id":"outlook","name":"Outlook"}]},{"title":"Word document knowledge sync","prompt":"Build a scheduled workflow that lists Word documents in a SharePoint library, reads each one, and syncs the extracted text into a knowledge base for retrieval.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"Word policy translator","prompt":"Create a workflow that reads an internal policy document from Word, translates it into the requested language, and creates a localized Word copy alongside the original.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"}]},{"title":"Word incident postmortem","prompt":"Build a workflow triggered by a resolved Linear incident that drafts a postmortem in Word from the issue timeline, exports it as PDF, and shares the PDF in the incident Slack channel.","integrations":[{"id":"microsoft_word","name":"Microsoft Word"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]}]},{"id":"millionverifier","type":"millionverifier","slug":"millionverifier","name":"MillionVerifier","description":"Verify email deliverability and check account credits","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/millionverifier","authType":"api-key","connections":[],"operations":[{"name":"Verify Email","description":"Verify the deliverability of an email address. Uses one verification credit."},{"name":"Get Remaining Credits","description":"Retrieve the remaining verification credits for the authenticated account."}],"triggers":[],"skills":[],"templates":[]},{"id":"mintlify","type":"mintlify","slug":"mintlify","name":"Mintlify","description":"Deploy, edit, search, and measure Mintlify documentation","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/mintlify","authType":"api-key","connections":[],"operations":[{"name":"Trigger Update","description":"Queue a deployment update for a Mintlify documentation project from its configured deployment branch. Returns a status ID for tracking progress."},{"name":"Get Update Status","description":"Get the status of a Mintlify deployment update from its status ID, including logs, commit details, and screenshots."},{"name":"Trigger Preview Deployment","description":"Create or update a Mintlify preview deployment for a Git branch. Redeploys when a preview already exists for the branch."},{"name":"Trigger Automation","description":"Run a scheduled Mintlify automation immediately instead of waiting for its next scheduled time. Only automations with a custom schedule can be triggered."},{"name":"Create Agent Job","description":"Create a background Mintlify agent job that edits your documentation from a prompt. Opens a pull request when the agent successfully edits files."},{"name":"Get Agent Job","description":"Retrieve the current status and details of a Mintlify agent job, including the pull request link once the agent opens one."},{"name":"Send Agent Message","description":"Send a follow-up instruction to an existing Mintlify agent job. The message is processed asynchronously."},{"name":"Detect AI-Sounding Prose","description":"Analyze a documentation page for AI-generated prose and return flagged passages with suggested human rewrites. Consumes one AI credit per checked page."},{"name":"Search Documentation","description":"Run a semantic and keyword search across a Mintlify documentation site, with optional version, language, tag, and group filters."},{"name":"Get Page Content","description":"Retrieve the full text content of a Mintlify documentation page by its path. Use it after a search to fetch the complete page."},{"name":"Ask Assistant","description":"Ask the Mintlify assistant, trained on your documentation, a question and get the assembled answer with its cited sources. Consumes the deployment\'s assistant credits."},{"name":"Get Feedback","description":"Export paginated user feedback from a Mintlify documentation project, with optional date-range, source, and status filters."},{"name":"Get Feedback By Page","description":"Export Mintlify feedback counts aggregated by documentation page path, broken down into thumbs up, thumbs down, and code snippet feedback."},{"name":"Get Assistant Conversations","description":"Export paginated Mintlify AI assistant conversation history, including the query, response, cited sources, and whether the question was answered."},{"name":"Get Assistant Caller Stats","description":"Get a breakdown of Mintlify assistant query counts by caller type — web, API, and other — for a date range."},{"name":"Get Search Queries","description":"Export Mintlify documentation search terms for a date range, ordered by hit count, with click-through rate and the most-clicked result path."},{"name":"Get Page Views","description":"Export Mintlify per-path and site-wide content view counts for a date range, split by human and AI bot traffic."},{"name":"Get Unique Visitors","description":"Export Mintlify per-path and site-wide approximate distinct visitor counts for a date range, split by human and AI bot traffic."}],"triggers":[],"skills":[{"name":"ship-docs-update","description":"Trigger a Mintlify documentation deployment and poll until it succeeds or fails.","content":"# Ship Docs Update\\n\\nDeploy the latest documentation and confirm it landed.\\n\\n## Steps\\n1. Trigger an update for the Mintlify project and capture the returned status ID.\\n2. Poll the update status with that ID until the status is `success` or `failure`.\\n3. On failure, read the summary and logs and report what broke.\\n4. On success, report the subdomain and the commit that shipped.\\n\\n## Output\\nThe final status, the commit SHA and message, and the deployment logs when the update failed."},{"name":"answer-from-docs","description":"Answer a question using a Mintlify documentation site and cite the pages used.","content":"# Answer From Docs\\n\\nGround an answer in a published Mintlify documentation site.\\n\\n## Steps\\n1. Search the documentation for the question.\\n2. Fetch the full content of the most relevant matching pages.\\n3. Synthesize an answer using only what those pages say.\\n4. If the docs do not cover the question, say so instead of guessing.\\n\\n## Output\\nA concise answer plus the paths of the pages it came from."},{"name":"find-docs-gaps","description":"Export Mintlify assistant conversations and surface the questions the docs could not answer.","content":"# Find Docs Gaps\\n\\nUse assistant history to find what the documentation is missing.\\n\\n## Steps\\n1. Export assistant conversations for the requested date range.\\n2. Keep the ones whose resolution status is `unanswered`.\\n3. Group the remaining questions into themes and count how often each appears.\\n4. For each theme, name the page that should cover it — existing or new.\\n\\n## Output\\nA ranked list of documentation gaps with example questions and a suggested page for each."},{"name":"run-docs-agent-job","description":"Launch a Mintlify agent job to edit documentation and follow it through to a pull request.","content":"# Run Docs Agent Job\\n\\nHand a documentation edit to the Mintlify agent.\\n\\n## Steps\\n1. Create an agent job with a specific, scoped instruction.\\n2. Poll the job until its status is `completed`, `archived`, or `failed`.\\n3. If the result needs adjusting, send a follow-up message to the same job and poll again.\\n4. Report the pull request link once one is created.\\n\\n## Output\\nThe final job status and the pull request URL, or an explanation of why no changes were made."},{"name":"report-docs-traffic","description":"Export Mintlify views, visitors, and search analytics into a single traffic summary.","content":"# Report Docs Traffic\\n\\nSummarize how a documentation site is being read.\\n\\n## Steps\\n1. Export page views and unique visitors for the date range, paginating while `hasMore` is true.\\n2. Export the top search queries for the same range.\\n3. Compare human and AI traffic per page and flag pages where AI traffic dominates.\\n4. Flag search queries with a low click-through rate — they point at missing or poorly titled pages.\\n\\n## Output\\nSite-wide totals, the top pages by traffic, and the search terms that are not finding a good result."}],"templates":[{"title":"Mintlify release-notes publisher","prompt":"Build a workflow that reads merged pull requests from GitHub, has an agent draft release notes, creates a Mintlify agent job to add them to the changelog, and triggers a docs deployment once the pull request merges.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"github","name":"GitHub"}]},{"title":"Mintlify docs-gap reporter","prompt":"Create a scheduled workflow that exports Mintlify assistant conversations weekly, filters the ones marked unanswered, groups them into themes, and posts the top documentation gaps to Slack.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"slack","name":"Slack"}]},{"title":"Mintlify support answer bot","prompt":"Build a workflow that takes an inbound support question, asks the Mintlify docs assistant for an answer, and replies in Slack with the answer and its cited documentation links.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"slack","name":"Slack"}]},{"title":"Mintlify preview deployment on PR","prompt":"Create a workflow that triggers a Mintlify preview deployment for a Git branch, polls the deployment status until it succeeds or fails, and comments the preview URL on the GitHub pull request.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"github","name":"GitHub"}]},{"title":"Mintlify prose-quality sweeper","prompt":"Build a scheduled workflow that reads documentation pages from a table, runs the Mintlify AI-prose detector on each one, and writes flagged passages and suggested rewrites back to the table for review.","integrations":[{"id":"mintlify","name":"Mintlify"}]},{"title":"Mintlify feedback triage","prompt":"Create a scheduled workflow that exports Mintlify user feedback daily, has an agent classify each comment by severity and theme, and opens Linear issues for the ones that need a documentation fix.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"linear","name":"Linear"}]},{"title":"Mintlify traffic digest","prompt":"Build a scheduled workflow that exports Mintlify page views, unique visitors, and top search queries each week, writes them to a table, and emails a digest highlighting pages with rising AI traffic.","integrations":[{"id":"mintlify","name":"Mintlify"},{"id":"gmail","name":"Gmail"}]},{"title":"Mintlify knowledge base mirror","prompt":"Create a workflow that searches a Mintlify documentation site, fetches the full content of each matching page, and loads it into a Sim knowledge base so agents can retrieve it offline.","integrations":[{"id":"mintlify","name":"Mintlify"}]}]},{"id":"mistral_parse","type":"mistral_parse_v3","slug":"mistral-parser","name":"Mistral Parser","description":"Extract text from PDF documents","category":"AI","docsUrl":"https://docs.sim.ai/integrations/mistral_parse","authType":"api-key","connections":[],"operations":[{"name":"Mistral PDF Parser","description":"Parse PDF documents using Mistral OCR API"}],"triggers":[],"skills":[{"name":"pdf-to-markdown","description":"Convert a PDF document into clean structured Markdown using Mistral OCR.","content":"# PDF to Markdown\\n\\nUse Mistral Parser to turn a PDF, including scanned image-only pages, into clean Markdown.\\n\\n## Steps\\n1. Provide the PDF as a URL or uploaded file to the parser.\\n2. Run the parse to extract text, headings, tables, and layout into Markdown.\\n3. Review the Markdown for page-break artifacts and stray headers or footers and clean them.\\n\\n## Output\\nReturn the full Markdown. Note the page count and flag any pages where OCR confidence looked low."},{"name":"extract-document-fields","description":"Parse a PDF and pull specific structured fields such as totals, dates, or names.","content":"# Extract Document Fields\\n\\nExtract a defined set of fields from a document such as an invoice, statement, or contract.\\n\\n## Steps\\n1. Run Mistral Parser on the source PDF to get the text content.\\n2. Locate the requested fields (for example vendor, total, due date, line items) within the parsed text.\\n3. Return the fields as a structured object, leaving any field that is genuinely absent as null rather than guessing.\\n\\n## Output\\nA JSON object keyed by the requested field names. List any fields that could not be found."},{"name":"summarize-long-document","description":"Parse a long PDF and produce a concise summary of its key points.","content":"# Summarize Long Document\\n\\nProduce a readable summary from a long PDF such as a report, paper, or agreement.\\n\\n## Steps\\n1. Parse the PDF with Mistral Parser to get its full text.\\n2. Identify the main sections and the most important claims, findings, or obligations.\\n3. Write a tight summary that preserves specifics like figures and dates.\\n\\n## Output\\nA short summary with a few bullet highlights. Keep numbers and named entities exact."}],"templates":[{"title":"ArXiv knowledge-base feeder","prompt":"Build a scheduled workflow that polls ArXiv for new papers in a topic, fetches PDFs, parses with Mistral Parser, and upserts the chunks into a research knowledge base.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"},{"id":"arxiv","name":"ArXiv"}]},{"title":"Google Translate + Mistral Parser localization","prompt":"Build a workflow that uses Mistral Parser to extract structured content from source-language PDFs and Google Translate to localize each section while preserving structure.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Mistral Parser for complex PDFs","prompt":"Create a workflow that uses Mistral Parser to convert dense research PDFs into clean Markdown, saves the Markdown to files, and indexes them into a knowledge base for downstream agents.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser bank statement reader","prompt":"Create a workflow that uses Mistral Parser to extract structured transactions from uploaded bank statement PDFs, writes each transaction to a finance table, and classifies expense category.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser research-paper digester","prompt":"Build a scheduled workflow that watches a research-paper folder, parses each PDF with Mistral Parser, and writes clean Markdown summaries for the knowledge base.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser legal-doc summarizer","prompt":"Create a workflow that processes legal documents with Mistral Parser, extracts the key clauses and obligations into a table, and writes a one-pager summary file.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser invoice intake","prompt":"Build a workflow that runs each incoming invoice PDF through Mistral Parser, extracts vendor, line items, totals, and due date into an accounts-payable table, and flags any invoice missing a PO number for the finance team in Slack.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"},{"id":"slack","name":"Slack"}]},{"title":"Mistral Parser scanned-contract indexer","prompt":"Create a workflow that parses scanned, image-only contracts with Mistral Parser OCR, converts them to searchable Markdown, and indexes the result into a knowledge base so legal can search obligations across every signed agreement.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser resume screener","prompt":"Build a workflow that parses uploaded resume PDFs with Mistral Parser, extracts candidate skills, experience, and contact details into a hiring table, and posts a shortlist summary to the recruiting channel in Slack.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"},{"id":"slack","name":"Slack"}]},{"title":"Perplexity + DSPy structured-output evaluator","prompt":"Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.","integrations":[{"id":"mistral_parse","name":"Mistral Parser"},{"id":"perplexity","name":"Perplexity"},{"id":"dspy","name":"DSPy"},{"id":"huggingface","name":"Hugging Face"}]}]},{"id":"modal","type":"modal","slug":"modal","name":"Modal","description":"Call deployed Modal functions and endpoints","category":"AI","docsUrl":"https://docs.sim.ai/integrations/modal","authType":"api-key","connections":[],"operations":[{"name":"Call Function","description":"Invoke a deployed Modal Web Function or Server over HTTPS"},{"name":"Chat Completion","description":"Generate a chat completion from a model served by a Modal Endpoint"},{"name":"List Models","description":"List the model IDs a Modal proxy token can reach on an endpoint"}],"triggers":[],"skills":[{"name":"call-modal-function","description":"Invoke a deployed Modal Web Function or Server over HTTPS and use its response. Use when compute lives on Modal rather than in the workflow.","content":"# Call Modal Function\\n\\nRun compute that already lives on Modal.\\n\\n## Steps\\n1. Get the function URL from the `modal deploy` output or the Modal dashboard. It looks like `https://---.modal.run`.\\n2. Use Call Function with that URL. Pick the method the function expects — POST for a function that reads a JSON body, GET for one that reads query parameters.\\n3. If the function is authenticated (Servers require this by default, Web Functions do not), fill in the Token ID and Token Secret from `modal workspace proxy-tokens create`. Leave both empty for an unauthenticated function.\\n4. Read the result from the data output. It is parsed JSON when the function responds with `application/json`, and raw text otherwise.\\n\\n## Output\\nReturn what the function produced. If the call fails, report the status code and the error body verbatim rather than retrying blindly — a 401 means the proxy token is missing or not scoped to that environment, and a 503 means a Server has no warm containers yet."},{"name":"generate-on-modal-endpoint","description":"Generate a chat completion from an open-weight model served by a Modal Endpoint. Use when inference should run on your own Modal compute.","content":"# Generate On Modal Endpoint\\n\\nRun inference on a model you host on Modal.\\n\\n## Steps\\n1. Create a proxy token with `modal workspace proxy-tokens create` and fill in the Token ID and Token Secret. Endpoints are authenticated by default.\\n2. Set the Endpoint URL. Use the URL from `modal endpoint list` for a dedicated endpoint, or leave it empty to reach Shared Endpoints through `https://inference.us-west.modal.direct`.\\n3. Set the Model. For a dedicated endpoint this is the base model repo ID; for a Shared Endpoint it is the endpoint hostname. Run List Models first when you are unsure which IDs the token can reach.\\n4. Write the user message, and add a system prompt when the response needs a fixed format or persona. Set max tokens and temperature in advanced options for long or deterministic outputs.\\n\\n## Output\\nReturn the generated content. Include the finish reason when it is not `stop` — `length` means the response was cut off and max tokens needs raising."},{"name":"audit-modal-endpoints","description":"List the models a Modal proxy token can reach and verify each one responds. Use for access audits and endpoint health checks.","content":"# Audit Modal Endpoints\\n\\nCheck which models a token reaches and whether they are serving.\\n\\n## Steps\\n1. Use List Models with the token you want to audit. Leave the Endpoint URL empty to enumerate every Shared Endpoint the token can reach, or set it to a specific endpoint URL to inspect just that one.\\n2. For each model ID returned, send a short Chat Completion (a one-word prompt with max tokens set low) to confirm it is actually serving.\\n3. Record which models responded, which failed, and the error for each failure.\\n\\n## Output\\nReturn the reachable model IDs and the result per model. A 401 means the token is invalid; a 403 on an RBAC workspace means the token is not scoped to that environment and needs `modal workspace proxy-tokens allow`."}],"templates":[{"title":"Modal GPU inference","prompt":"Build a workflow where an agent receives a question, calls a deployed Modal Web Function that runs a GPU model, and replies with the model output.","integrations":[{"id":"modal","name":"Modal"}]},{"title":"Modal self-hosted chat","prompt":"Create a workflow that answers incoming Slack messages by generating a chat completion on a Modal Endpoint running an open-weight model, then posts the reply back to the thread.","integrations":[{"id":"modal","name":"Modal"},{"id":"slack","name":"Slack"}]},{"title":"Modal batch scoring","prompt":"Build a scheduled workflow that reads pending rows from a table, calls a deployed Modal function to score each one, and writes the scores back to the table.","integrations":[{"id":"modal","name":"Modal"}]},{"title":"Modal document summarizer","prompt":"Create a workflow that takes an uploaded document, sends its text to a Modal Endpoint for summarization, and emails the summary back to the requester.","integrations":[{"id":"modal","name":"Modal"},{"id":"gmail","name":"Gmail"}]},{"title":"Modal endpoint health check","prompt":"Build a scheduled workflow that lists the models a Modal token can reach, sends a short test completion to each one, records the latency in a table, and alerts the engineering channel when an endpoint stops responding.","integrations":[{"id":"modal","name":"Modal"},{"id":"slack","name":"Slack"}]},{"title":"Modal image generation","prompt":"Create a workflow that takes a prompt from a form, calls a deployed Modal function that generates an image, and shares the result in Slack.","integrations":[{"id":"modal","name":"Modal"},{"id":"slack","name":"Slack"}]},{"title":"Modal model comparison","prompt":"Build a workflow that sends the same prompt to two Modal Endpoints, has an agent compare the two completions for accuracy and tone, and writes the verdict to a table.","integrations":[{"id":"modal","name":"Modal"}]},{"title":"Modal enrichment pipeline","prompt":"Create a workflow triggered when a new record lands in a table that calls a deployed Modal function to extract structured fields from the raw text, then updates the record with the extracted values.","integrations":[{"id":"modal","name":"Modal"}]}]},{"id":"monday","type":"monday","slug":"monday","name":"Monday","description":"Manage Monday.com boards, items, and groups","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/monday","authType":"oauth","connections":[{"id":"monday","kind":"oauth","label":"Connect with OAuth","providerId":"monday","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/monday","requiredScopes":[{"id":"boards:read","label":"Read boards, items, and columns"},{"id":"boards:write","label":"Create and modify boards, items, and groups"},{"id":"updates:read","label":"Read updates and comments"},{"id":"updates:write","label":"Create and edit updates and comments"},{"id":"webhooks:read","label":"Read webhook subscriptions"},{"id":"webhooks:write","label":"Create and manage webhook subscriptions"},{"id":"me:read","label":"Read your user profile"}],"fields":[]},{"id":"monday-service-account","kind":"service_account","providerId":"monday-service-account","label":"Add API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/monday-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste personal API token","secret":true}]}],"operations":[{"name":"List Boards","description":"List boards from your Monday.com account"},{"name":"Get Board","description":"Get a specific Monday.com board with its groups and columns"},{"name":"Get Item","description":"Get a specific item by ID from Monday.com"},{"name":"Get Items","description":"Get items from a Monday.com board"},{"name":"Search Items","description":"Search for items on a Monday.com board by column values"},{"name":"Create Item","description":"Create a new item on a Monday.com board"},{"name":"Update Item","description":"Update column values of an item on a Monday.com board"},{"name":"Change Column Value","description":"Update a single column\'s value on a Monday.com item"},{"name":"Duplicate Item","description":"Duplicate an existing item on a Monday.com board"},{"name":"Delete Item","description":"Delete an item from a Monday.com board"},{"name":"Archive Item","description":"Archive an item on a Monday.com board"},{"name":"Move Item to Group","description":"Move an item to a different group on a Monday.com board"},{"name":"Create Subitem","description":"Create a subitem under a parent item on Monday.com"},{"name":"Create Update","description":"Add an update (comment) to a Monday.com item"},{"name":"Create Group","description":"Create a new group on a Monday.com board"},{"name":"Get Groups","description":"Get the groups on a Monday.com board"},{"name":"Create Board","description":"Create a new board in Monday.com"},{"name":"Create Column","description":"Create a new column on a Monday.com board"}],"triggers":[{"id":"monday_item_created","name":"Monday Item Created","description":"Trigger workflow when a new item is created on a Monday.com board"},{"id":"monday_column_changed","name":"Monday Column Value Changed","description":"Trigger workflow when any column value changes on a Monday.com board"},{"id":"monday_status_changed","name":"Monday Status Changed","description":"Trigger workflow when a status column value changes on a Monday.com board"},{"id":"monday_item_name_changed","name":"Monday Item Name Changed","description":"Trigger workflow when an item name changes on a Monday.com board"},{"id":"monday_item_archived","name":"Monday Item Archived","description":"Trigger workflow when an item is archived on a Monday.com board"},{"id":"monday_item_deleted","name":"Monday Item Deleted","description":"Trigger workflow when an item is deleted on a Monday.com board"},{"id":"monday_item_moved","name":"Monday Item Moved to Group","description":"Trigger workflow when an item is moved to any group on a Monday.com board"},{"id":"monday_subitem_created","name":"Monday Subitem Created","description":"Trigger workflow when a subitem is created on a Monday.com board"},{"id":"monday_update_created","name":"Monday Update Posted","description":"Trigger workflow when an update or comment is posted on a Monday.com item"}],"skills":[{"name":"create-board-item","description":"Create a new item on a Monday board in the right group with column values set.","content":"# Create Board Item\\n\\nAdd an item to a Monday.com board and populate its columns.\\n\\n## Steps\\n1. Use List Boards to find the board, then Get Board to read its groups and column ids.\\n2. Run Create Item with the board id, item name, and the target group.\\n3. Map the requested fields to the correct column ids, formatting status and date columns as Monday expects.\\n4. Add a follow-up Create Update if a comment or context note is needed on the item.\\n\\n## Output\\nConfirm the new item id, board, and group. List the column values that were set."},{"name":"find-items-by-criteria","description":"Search a Monday board for items matching a value such as status or owner.","content":"# Find Items by Criteria\\n\\nLocate Monday.com items that match a given condition.\\n\\n## Steps\\n1. Identify the board and the column to filter on with Get Board.\\n2. Use Search Items or Get Items to retrieve candidates.\\n3. Filter to the items whose column value matches the requested criteria.\\n\\n## Output\\nA list of matching items with name, group, and the relevant column values. Note the total match count."},{"name":"progress-item-status","description":"Move a Monday item forward by updating its status column and group.","content":"# Progress Item Status\\n\\nAdvance a Monday.com item through its workflow.\\n\\n## Steps\\n1. Get the item with Get Item to read its current status and group.\\n2. Run Update Item to set the new status column value.\\n3. If the stage maps to a different group, use Move Item to Group to keep the board organized.\\n4. Optionally post a Create Update noting the transition.\\n\\n## Output\\nConfirm the item id, the old and new status, and the group it now sits in."}],"templates":[{"title":"Monday status digest","prompt":"Create a scheduled weekly workflow that pulls Monday board progress, computes completion rate, and posts a status update to leadership Slack with the at-risk items highlighted.","integrations":[{"id":"monday","name":"Monday"},{"id":"slack","name":"Slack"}]},{"title":"Monday board automator","prompt":"Build a workflow that watches Monday boards for status changes, applies branching automations — assign owners, set due dates, post Slack updates — based on a rules table.","integrations":[{"id":"monday","name":"Monday"},{"id":"slack","name":"Slack"}]},{"title":"Monday client portal","prompt":"Create a workflow that mirrors a Monday project board into a client-facing summary table, refreshes hourly, and emails the client a snapshot link each week.","integrations":[{"id":"monday","name":"Monday"},{"id":"gmail","name":"Gmail"}]},{"title":"Monday SLA enforcer","prompt":"Build a workflow that watches Monday items with due dates, sends reminders 24 hours before, and escalates to managers when items breach SLA.","integrations":[{"id":"monday","name":"Monday"}]},{"title":"Monday + CRM sync","prompt":"Create a workflow that mirrors Monday CRM board items into Salesforce as opportunities, keeps stage and amount synced, and writes the Salesforce ID back to the Monday item.","integrations":[{"id":"monday","name":"Monday"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Monday workspace audit","prompt":"Build a scheduled monthly workflow that audits Monday boards for unused columns, stale automations, and missing owners, and writes a cleanup plan to a tracking table.","integrations":[{"id":"monday","name":"Monday"}]},{"title":"Monday onboarding kickoff","prompt":"Create a workflow that on a new hire in Workday creates a personalized Monday onboarding board, seeds the role-specific tasks, and invites the new hire and buddy.","integrations":[{"id":"monday","name":"Monday"},{"id":"workday","name":"Workday"}]}]},{"id":"mongodb","type":"mongodb","slug":"mongodb","name":"MongoDB","description":"Connect to MongoDB database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/mongodb","authType":"none","connections":[],"operations":[{"name":"Find Documents","description":"Execute find operation on MongoDB collection"},{"name":"Insert Documents","description":"Insert documents into MongoDB collection"},{"name":"Update Documents","description":"Update documents in MongoDB collection"},{"name":"Delete Documents","description":"Delete documents from MongoDB collection"},{"name":"Aggregate Pipeline","description":"Execute MongoDB aggregation pipeline"},{"name":"Introspect Database","description":"Introspect MongoDB database to list databases, collections, and indexes"}],"triggers":[],"skills":[{"name":"find-documents","description":"Query a MongoDB collection with a filter and return the matching documents.","content":"# Find Documents\\n\\nRetrieve documents from a MongoDB collection that match a filter.\\n\\n## Steps\\n1. If the collection shape is unknown, run Introspect Database first to learn the fields.\\n2. Build a MongoDB filter document for the requested condition, using operators like $gte, $in, and $regex as needed.\\n3. Run Find Documents against the target collection with the filter, plus projection and limit when appropriate.\\n\\n## Output\\nReturn the matching documents. State the filter used and the number of results. Suggest an index if a scan looks slow."},{"name":"aggregate-report","description":"Run a MongoDB aggregation pipeline to group and summarize collection data.","content":"# Aggregate Report\\n\\nProduce a summary from a MongoDB collection using an aggregation pipeline.\\n\\n## Steps\\n1. Introspect the collection to confirm the fields to group and measure on.\\n2. Compose a pipeline with stages such as $match, $group, $sort, and $limit to compute the requested metric.\\n3. Run the Aggregate Pipeline operation and read back the grouped results.\\n\\n## Output\\nA compact table of the grouped metrics. Include the pipeline used so the query can be rerun."},{"name":"upsert-document","description":"Insert a new MongoDB document or update an existing one matched by a key.","content":"# Upsert Document\\n\\nWrite a document to MongoDB, creating it or updating the existing match.\\n\\n## Steps\\n1. Determine the key field that identifies the record uniquely.\\n2. Run Find Documents on that key to see whether a record already exists.\\n3. If it exists, run Update Documents with the new values; otherwise run Insert Documents.\\n\\n## Output\\nReport whether a document was inserted or updated and echo the key value. Confirm the affected count."}],"templates":[{"title":"MongoDB to data lake export","prompt":"Build a scheduled workflow that runs each night, exports MongoDB collections to S3 with partitioned Parquet files, and registers them in an Athena-queryable catalog.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"s3","name":"S3"}]},{"title":"MongoDB index health monitor","prompt":"Create a scheduled workflow that scans MongoDB collections for slow queries and missing indexes, writes a remediation table, and opens Linear tickets for the worst offenders.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"linear","name":"Linear"}]},{"title":"MongoDB to vector enrichment","prompt":"Build a scheduled workflow that polls a MongoDB collection for new documents, generates OpenAI embeddings, and upserts them into Pinecone with the source document ID for retrieval.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"MongoDB user-event triage","prompt":"Create a scheduled workflow that polls a MongoDB user-events collection for new records, classifies events as engagement or risk signals, and writes high-priority items to a triage table.","integrations":[{"id":"mongodb","name":"MongoDB"}]},{"title":"MongoDB orphaned-doc cleaner","prompt":"Build a scheduled workflow that runs weekly, finds orphaned references in MongoDB, dry-runs the cleanup plan, posts to Slack for approval, and executes once approved.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"slack","name":"Slack"}]},{"title":"MongoDB query digest","prompt":"Create a scheduled daily workflow that aggregates MongoDB query telemetry from the profiler, identifies the top-cost queries, and posts a Slack engineering digest.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"slack","name":"Slack"}]},{"title":"MongoDB + Tinybird feeder","prompt":"Build a scheduled workflow that batches new MongoDB records into a Tinybird pipe on a short interval, exposes the data to downstream apps, and writes the load metrics to a table.","integrations":[{"id":"mongodb","name":"MongoDB"},{"id":"tinybird","name":"Tinybird"}]}]},{"id":"mysql","type":"mysql","slug":"mysql","name":"MySQL","description":"Connect to MySQL database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/mysql","authType":"none","connections":[],"operations":[{"name":"Query (SELECT)","description":"Execute SELECT query on MySQL database"},{"name":"Insert Data","description":"Insert new record into MySQL database"},{"name":"Update Data","description":"Update existing records in MySQL database"},{"name":"Delete Data","description":"Delete records from MySQL database"},{"name":"Execute Raw SQL","description":"Execute raw SQL query on MySQL database"},{"name":"Introspect Schema","description":"Introspect MySQL database schema to retrieve table structures, columns, and relationships"}],"triggers":[],"skills":[{"name":"nl-to-sql-query","description":"Translate a plain-English question into a MySQL SELECT and return the rows.","content":"# Natural Language To SQL\\n\\nTurn a question into a MySQL query and answer from the rows.\\n\\n## Steps\\n1. Introspect the schema so the agent knows the tables and columns.\\n2. Have the agent write a single MySQL SELECT that answers the question, with a LIMIT for safety.\\n3. Run the query operation.\\n4. Summarize the returned rows into a readable answer.\\n\\n## Output\\nReturn the generated SQL, the rows, and a short natural-language summary of the result."},{"name":"scheduled-sql-report","description":"Run a MySQL query on a schedule and post a summarized report.","content":"# Scheduled SQL Report\\n\\nProduce a recurring report from MySQL data.\\n\\n## Steps\\n1. Run a query for the reporting window (for example, DATE_SUB(NOW(), INTERVAL 1 DAY)).\\n2. Read rowCount and rows to gather the metrics.\\n3. Have an agent summarize the numbers into a short update.\\n4. Deliver the summary to the target channel or file.\\n\\n## Output\\nReport the key metrics, the row count, and the delivered summary."},{"name":"document-schema","description":"Introspect a MySQL schema and generate a plain-English data dictionary.","content":"# Document Schema\\n\\nGenerate documentation from a live MySQL schema.\\n\\n## Steps\\n1. Run the introspect operation to list tables, columns, and types.\\n2. Have an agent describe each table and column in plain English.\\n3. Assemble the descriptions into a structured data dictionary.\\n4. Save the result as a file for the team.\\n\\n## Output\\nReturn the data dictionary covering every table and column, and confirm the saved file."},{"name":"upsert-records","description":"Insert new rows or update existing ones in MySQL based on a key match.","content":"# Upsert Records\\n\\nKeep a MySQL table in sync with a source of records.\\n\\n## Preferred: native MySQL upsert\\nWhen the target table has a PRIMARY KEY or UNIQUE index on the match key, run a single execute with `INSERT ... ON DUPLICATE KEY UPDATE` — MySQL inserts a new row or updates the existing one in one statement (do NOT use Postgres `ON CONFLICT`, which MySQL does not support):\\n\\n```sql\\nINSERT INTO users (id, name, email)\\nVALUES (1, \'Jane\', \'jane@example.com\')\\nON DUPLICATE KEY UPDATE name = VALUES(name), email = VALUES(email);\\n```\\n\\n## Fallback: check-then-write\\nIf there is no unique key to rely on:\\n1. For each record, run a query to check whether a row with the matching key exists.\\n2. If it exists, run update with a WHERE condition on the key.\\n3. If it does not, run insert with the record data.\\n4. Track how many rows were inserted versus updated.\\n\\n## Output\\nReturn the counts of inserted and updated rows and confirm the table is in sync."}],"templates":[{"title":"Ask your MySQL database in plain English","prompt":"Build a workflow that takes a plain-English question, has an agent translate it into a MySQL SELECT against the known schema, runs the query, and returns the rows as a readable answer.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Daily MySQL metrics report to Slack","prompt":"Create a scheduled workflow that runs a MySQL query for yesterday’s key metrics, has an agent summarize the rows into a short update, and posts the digest to a Slack channel every morning.","integrations":[{"id":"mysql","name":"MySQL"},{"id":"slack","name":"Slack"}]},{"title":"Document a MySQL schema","prompt":"Build a workflow that introspects a MySQL database schema, has an agent write plain-English descriptions of each table and column, and saves the generated data dictionary as a file.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Sync records from a Sim table into MySQL","prompt":"Create a workflow that reads rows from a Sim table and upserts each one into a MySQL table — updating the row when a matching key exists and inserting it otherwise — so the two stay in sync.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Nightly MySQL data-quality audit","prompt":"Build a scheduled workflow that runs MySQL queries checking for nulls, duplicates, and orphaned foreign keys, has an agent describe any issues found, and alerts the team in Slack when the counts are non-zero.","integrations":[{"id":"mysql","name":"MySQL"},{"id":"slack","name":"Slack"}]},{"title":"Scheduled MySQL cleanup job","prompt":"Create a scheduled workflow that deletes stale or soft-deleted rows from a MySQL table older than a retention window, reports the row count removed, and keeps the table lean over time.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Capture incoming records into MySQL","prompt":"Build a workflow that takes an incoming payload, validates the fields with an agent, and inserts a new row into the right MySQL table so submissions are persisted for later querying.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Export a MySQL query result to a file","prompt":"Create a scheduled workflow that runs a MySQL query for a snapshot of a table, writes the returned rows to a file, and keeps a dated export available for backups and downstream analysis.","integrations":[{"id":"mysql","name":"MySQL"}]},{"title":"Restore rehearsal","prompt":"Build a workflow. On a scheduled restore drill, select a successful backup, create a separate branch from it, and report the branch readiness. Run subsequent checks with the appropriate SQL integration.","integrations":[{"id":"mysql","name":"MySQL"},{"id":"planetscale","name":"PlanetScale"},{"id":"postgresql","name":"PostgreSQL"}]}]},{"id":"neo4j","type":"neo4j","slug":"neo4j","name":"Neo4j","description":"Connect to Neo4j graph database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/neo4j","authType":"none","connections":[],"operations":[{"name":"Query (MATCH)","description":"Execute MATCH queries to read nodes and relationships from Neo4j graph database. For best performance and to prevent large result sets, include LIMIT in your query (e.g., \\"MATCH (n:User) RETURN n LIMIT 100\\") or use LIMIT $limit with a limit parameter."},{"name":"Create Nodes/Relationships","description":"Execute CREATE statements to add new nodes and relationships to Neo4j graph database"},{"name":"Merge (Find or Create)","description":"Execute MERGE statements to find or create nodes and relationships in Neo4j (upsert operation)"},{"name":"Update Properties (SET)","description":"Execute SET statements to update properties of existing nodes and relationships in Neo4j"},{"name":"Delete Nodes/Relationships","description":"Execute DELETE or DETACH DELETE statements to remove nodes and relationships from Neo4j"},{"name":"Execute Cypher","description":"Execute arbitrary Cypher queries on Neo4j graph database for complex operations"},{"name":"Introspect Schema","description":"Introspect a Neo4j database to discover its schema including node labels, relationship types, properties, constraints, and indexes."}],"triggers":[],"skills":[{"name":"answer-graph-question","description":"Translate a plain-English question into Cypher, run it on Neo4j, and explain the result.","content":"# Answer Graph Question\\n\\nTurn a natural-language question into a Cypher query against the Neo4j graph.\\n\\n## Steps\\n1. Run Introspect Schema to learn the node labels, relationship types, and properties.\\n2. Translate the question into a Cypher MATCH that uses the real labels and relationships from the schema.\\n3. Run the Query operation and read the returned rows.\\n4. If the query returns nothing, relax the pattern and explain what was tried.\\n\\n## Output\\nA plain-language answer plus the Cypher used and the key matching nodes or paths."},{"name":"create-graph-relationship","description":"Create or merge nodes and connect them with a relationship in Neo4j.","content":"# Create Graph Relationship\\n\\nAdd nodes and a relationship between them without creating duplicates.\\n\\n## Steps\\n1. Introspect Schema to confirm the labels and relationship type to use.\\n2. Use Merge (Find or Create) for each node so existing nodes are reused rather than duplicated.\\n3. Create the relationship between them with the requested direction and any properties.\\n\\n## Output\\nConfirm the nodes involved and the relationship created, noting whether each node was found or newly created."},{"name":"find-connected-nodes","description":"Traverse the Neo4j graph from a starting node to find related entities.","content":"# Find Connected Nodes\\n\\nExplore the neighborhood of a node to find connected entities.\\n\\n## Steps\\n1. Introspect Schema to know the relationship types available.\\n2. Build a Cypher MATCH that starts at the given node and traverses the relevant relationships to the desired depth.\\n3. Run the Query operation and collect the connected nodes.\\n\\n## Output\\nA list of connected nodes grouped by relationship type, with the traversal path described in one line."}],"templates":[{"title":"ArXiv author-topic grapher","prompt":"Create a workflow that for a chosen ArXiv topic pulls papers and their authors, builds a co-authorship and topic graph in Neo4j, and exposes a visualization for the research team.","integrations":[{"id":"neo4j","name":"Neo4j"},{"id":"arxiv","name":"ArXiv"}]},{"title":"Dagster lineage map","prompt":"Create a workflow that exports Dagster asset lineage into a graph database for cross-pipeline impact analysis when an upstream source schema changes.","integrations":[{"id":"neo4j","name":"Neo4j"},{"id":"dagster","name":"Dagster"}]},{"title":"Neo4j relationship exporter","prompt":"Build a workflow that queries Neo4j for a chosen entity graph, writes the nodes and edges to a structured JSON adjacency file, and shares the file link for a downstream tool to visualize.","integrations":[{"id":"neo4j","name":"Neo4j"}]},{"title":"Neo4j fraud-ring detector","prompt":"Create a scheduled workflow that queries Neo4j for suspicious connection patterns — shared devices, overlapping addresses — writes risk-scored clusters to a fraud table, and pings Slack.","integrations":[{"id":"neo4j","name":"Neo4j"},{"id":"slack","name":"Slack"}]},{"title":"Neo4j org-chart sync","prompt":"Build a workflow that pulls Workday or Rippling worker data, upserts employees and reporting relationships into Neo4j, and exposes a queryable org graph for downstream tools.","integrations":[{"id":"neo4j","name":"Neo4j"},{"id":"workday","name":"Workday"},{"id":"rippling","name":"Rippling"}]},{"title":"Neo4j knowledge-graph builder","prompt":"Create a workflow that processes documents from a knowledge base, extracts entities and relationships with an agent, and writes the graph into Neo4j for cross-document insights.","integrations":[{"id":"neo4j","name":"Neo4j"}]},{"title":"Neo4j recommendation engine","prompt":"Build a workflow that runs Neo4j graph algorithms — collaborative filtering, PageRank — on product-purchase data and writes per-user recommendations to a personalization table.","integrations":[{"id":"neo4j","name":"Neo4j"}]},{"title":"Neo4j data lineage tracker","prompt":"Create a workflow that ingests dbt manifest metadata into Neo4j, tracks lineage across tables and pipelines, and queries impact when a source schema changes.","integrations":[{"id":"neo4j","name":"Neo4j"}]},{"title":"Neo4j natural-language graph explorer","prompt":"Build a chat agent that introspects the Neo4j schema, translates plain-English questions like “which customers share a support agent with churned accounts?” into Cypher queries, runs them, and returns a readable answer with the matching nodes.","integrations":[{"id":"neo4j","name":"Neo4j"}]},{"title":"Wikipedia related-topic graph","prompt":"Create a workflow that for a topic explores related Wikipedia pages, builds a topic graph in Neo4j, and surfaces adjacent themes.","integrations":[{"id":"neo4j","name":"Neo4j"},{"id":"wikipedia","name":"Wikipedia"}]}]},{"id":"neverbounce","type":"neverbounce","slug":"neverbounce","name":"NeverBounce","description":"Verify email deliverability and check account credits","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/neverbounce","authType":"api-key","connections":[],"operations":[{"name":"Verify Email","description":"Verify the deliverability of an email address. Uses one verification credit."},{"name":"Get Remaining Credits","description":"Retrieve the remaining paid and free verification credits for the account."}],"triggers":[],"skills":[],"templates":[]},{"id":"new_relic","type":"new_relic","slug":"new-relic","name":"New Relic","description":"Query observability data and record deployments in New Relic","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/new_relic","authType":"api-key","connections":[],"operations":[{"name":"Run NRQL Query","description":"Run a NRQL query against a New Relic account using NerdGraph."},{"name":"Search Entities","description":"Search New Relic entities by name, GUID, domain type, tags, or reporting state."},{"name":"Get Entity","description":"Fetch a New Relic entity by GUID."},{"name":"Create Deployment Event","description":"Record a deployment change event in New Relic change tracking."}],"triggers":[],"skills":[{"name":"query-golden-signals","description":"Run NRQL to pull latency, error rate, and throughput for a service over a time window.","content":"# Query Golden Signals\\n\\nUse New Relic NRQL to read the golden signals for a service.\\n\\n## Steps\\n1. Identify the service or application name, using Search Entities if it is unknown.\\n2. Build NRQL queries for throughput, average and p95 latency, and error rate over the requested window using SELECT ... FROM Transaction WHERE appName = ... SINCE ...\\n3. Run NRQL Query for each signal and collect the values.\\n\\n## Output\\nA short table of throughput, latency p50/p95, and error rate with the time window stated. Flag any signal that looks anomalous."},{"name":"investigate-error-spike","description":"Use NRQL to break down a New Relic error spike by type and impacted transaction.","content":"# Investigate Error Spike\\n\\nDrill into an error spike for a service in New Relic.\\n\\n## Steps\\n1. Run an NRQL query counting errors over time to confirm and bound the spike window.\\n2. Break the errors down by error.class, message, and transactionName using FACET.\\n3. Use Get Entity to add context such as the service health and recent alerts.\\n4. Check for a recent Create Deployment Event near the spike start to correlate with a release.\\n\\n## Output\\nThe top error types by count, the most impacted transactions, and whether a recent deployment lines up with the spike."},{"name":"record-deployment-marker","description":"Create a New Relic deployment event so releases line up with metric changes.","content":"# Record Deployment Marker\\n\\nMark a deployment in New Relic to correlate releases with performance.\\n\\n## Steps\\n1. Identify the target entity with Search Entities to get its GUID.\\n2. Run Create Deployment Event with the version, and include the commit or changelog and the user who deployed.\\n3. Confirm the marker is associated with the right entity.\\n\\n## Output\\nConfirm the deployment event created, with the entity name, version, and timestamp."}],"templates":[{"title":"New Relic health report","prompt":"Create a scheduled daily workflow that runs NRQL queries against New Relic for error rate, latency percentiles, and throughput, logs the results to a table for trend tracking, and Slacks a morning summary highlighting any degradations.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"slack","name":"Slack"}]},{"title":"New Relic deployment tracker","prompt":"Build a workflow that fires after each production release, records a New Relic deployment change event for the affected entity, and posts a Slack note linking the deployment to the dashboard for the on-call engineer.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"slack","name":"Slack"}]},{"title":"New Relic anomaly investigator","prompt":"Create a workflow triggered by an alert that runs targeted NRQL queries to pull the surrounding error and latency data, searches related New Relic entities for blast radius, summarizes likely causes, and opens a Linear ticket.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"linear","name":"Linear"}]},{"title":"New Relic entity inventory","prompt":"Build a scheduled weekly workflow that searches New Relic for all monitored entities, fetches details for each, logs them into an inventory table, and Slacks a diff of newly added or removed services.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"slack","name":"Slack"}]},{"title":"New Relic SLO weekly review","prompt":"Create a scheduled weekly workflow that runs NRQL queries to compute error budget burn for each service, writes a narrative review file for the SRE team, and links the supporting dashboards.","integrations":[{"id":"new_relic","name":"New Relic"}]},{"title":"New Relic cost-by-service breakdown","prompt":"Build a scheduled monthly workflow that runs NRQL queries to attribute data ingest and compute to each New Relic entity, writes a per-team cost breakdown to a table, and emails finance the services trending over budget.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"gmail","name":"Gmail"}]},{"title":"New Relic incident war-room kickoff","prompt":"Create a workflow triggered by a PagerDuty incident that runs NRQL queries for the impacted service, pulls the latest deployment change event from New Relic, and posts a war-room summary with golden-signal charts to the incident Slack channel.","integrations":[{"id":"new_relic","name":"New Relic"},{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]}]},{"id":"notion","type":"notion_v2","slug":"notion","name":"Notion","description":"Manage Notion pages","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/notion","authType":"oauth","connections":[{"id":"notion","kind":"oauth","label":"Connect with OAuth","providerId":"notion","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/notion","requiredScopes":[],"fields":[]},{"id":"notion-service-account","kind":"service_account","providerId":"notion-service-account","label":"Add integration secret","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/notion-service-account","fields":[{"id":"apiToken","label":"Internal integration secret","placeholder":"ntn_...","secret":true,"hint":"Notion integration secrets usually start with ntn_."}]}],"operations":[{"name":"Read Page","description":"Read content from a Notion page"},{"name":"Read Database","description":"Read database information and structure from Notion"},{"name":"Create Page","description":"Create a new page in Notion"},{"name":"Update Page Properties","description":"Update properties of a Notion page"},{"name":"Create Database","description":"Create a new database in Notion with custom properties"},{"name":"Add Database Row","description":"Add a new row to a Notion database with specified properties"},{"name":"Append Content","description":"Append content to a Notion page"},{"name":"Append Block Children","description":"Append new block children (content) to a Notion page or block"},{"name":"Retrieve Block","description":"Retrieve a single Notion block by its UUID, including its type-specific content"},{"name":"Retrieve Block Children","description":"Retrieve the block children (content) of a Notion page or block"},{"name":"Update Block","description":"Update the content or archived state of a single Notion block"},{"name":"Delete Block","description":"Delete (move to trash) a single Notion block"},{"name":"Create Comment","description":"Create a comment on a Notion page or within an existing discussion thread"},{"name":"List Comments","description":"List unresolved comments on a Notion page or block"},{"name":"List Users","description":"List all users (members and bots) in the Notion workspace"},{"name":"Retrieve User","description":"Retrieve a single Notion user by their UUID"},{"name":"Query Database","description":"Query and filter Notion database entries with advanced filtering"},{"name":"Search Workspace","description":"Search across all pages and databases in Notion workspace"}],"triggers":[{"id":"notion_page_created","name":"Notion Page Created","description":"Trigger workflow when a new page is created in Notion"},{"id":"notion_page_properties_updated","name":"Notion Page Properties Updated","description":"Trigger workflow when page properties are modified in Notion"},{"id":"notion_page_content_updated","name":"Notion Page Content Updated","description":"Trigger workflow when page content is changed in Notion"},{"id":"notion_page_deleted","name":"Notion Page Deleted","description":"Trigger workflow when a page is deleted in Notion"},{"id":"notion_database_created","name":"Notion Database Created","description":"Trigger workflow when a new database is created in Notion"},{"id":"notion_database_schema_updated","name":"Notion Database Schema Updated","description":"Trigger workflow when a database schema is modified in Notion"},{"id":"notion_database_deleted","name":"Notion Database Deleted","description":"Trigger workflow when a database is deleted in Notion"},{"id":"notion_comment_created","name":"Notion Comment Created","description":"Trigger workflow when a comment or suggested edit is added in Notion"},{"id":"notion_webhook","name":"Notion Webhook (All Events)","description":"Trigger workflow on any Notion webhook event"}],"skills":[{"name":"create-structured-page","description":"Create a Notion page under a parent with headings, bullets, and a clean layout.","content":"# Create Structured Page\\n\\nCreate a well-formatted Notion page, such as meeting notes or a project brief.\\n\\n## Steps\\n1. Identify the parent page or database, using Search Workspace if the destination is not known.\\n2. Run Create Page with the title and parent.\\n3. Use Append Content to add the body as Notion blocks: headings for sections, bulleted lists for items, and to-do blocks for action items.\\n\\n## Output\\nReturn the new page URL and id. Summarize the sections that were added."},{"name":"add-database-entry","description":"Add a row to a Notion database with the correct property values.","content":"# Add Database Entry\\n\\nInsert a new row into a Notion database with its properties set.\\n\\n## Steps\\n1. Run Read Database on the target database to learn its property names and types.\\n2. Map the requested values to the matching properties, formatting select, date, and relation fields correctly.\\n3. Run Add Database Row with the property values.\\n\\n## Output\\nConfirm the new row id and URL, and list the property values that were written."},{"name":"query-database","description":"Filter and sort a Notion database to return matching entries.","content":"# Query Database\\n\\nRetrieve entries from a Notion database that match a condition.\\n\\n## Steps\\n1. Read the database with Read Database to confirm the property to filter on.\\n2. Build a filter and optional sort for the requested condition (for example Status equals Done, sorted by date).\\n3. Run Query Database and collect the matching pages.\\n\\n## Output\\nA list of matching entries with their key properties and page links. Note the total count."},{"name":"search-and-summarize","description":"Search the Notion workspace for a topic and summarize the relevant pages.","content":"# Search and Summarize\\n\\nFind and summarize Notion content on a given topic.\\n\\n## Steps\\n1. Run Search Workspace with the topic keywords.\\n2. Read the most relevant pages with Read Page.\\n3. Synthesize the key points across the pages, citing each source page by title and link.\\n\\n## Output\\nA short synthesized answer with citations to the Notion pages used. Note if the workspace had no relevant content."}],"templates":[{"title":"Circleback notes to Notion","prompt":"Build a workflow that triggers when a meeting is processed in Circleback, pulls the notes, attendees, and transcript from the payload, and writes a structured meeting note to Notion with next steps.","integrations":[{"id":"notion","name":"Notion"},{"id":"circleback","name":"Circleback"}]},{"title":"PagerDuty incident coordinator","prompt":"Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.","integrations":[{"id":"notion","name":"Notion"},{"id":"confluence","name":"Confluence"},{"id":"pagerduty","name":"PagerDuty"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"Confluence multi-source knowledge hub","prompt":"Create a knowledge base and connect it to Confluence, Notion, and Google Drive so all my company documentation is automatically synced, chunked, and embedded. Then deploy a Q&A agent that can answer questions across all sources with citations.","integrations":[{"id":"notion","name":"Notion"},{"id":"confluence","name":"Confluence"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Discord community manager","prompt":"Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.","integrations":[{"id":"notion","name":"Notion"},{"id":"discord","name":"Discord"},{"id":"google_docs","name":"Google Docs"},{"id":"slack","name":"Slack"}]},{"title":"Dropbox to Notion publisher","prompt":"Create a scheduled workflow that lists Dropbox markdown files added since the last run, converts each to a Notion page in the right database, and writes a link back to the source file metadata.","integrations":[{"id":"notion","name":"Notion"},{"id":"dropbox","name":"Dropbox"}]},{"title":"Fathom transcript to Notion notes","prompt":"Create a workflow that triggers on a new Fathom meeting, pulls the transcript and summary, and writes a structured meeting note to Notion with attendees and next steps.","integrations":[{"id":"notion","name":"Notion"},{"id":"fathom","name":"Fathom"}]},{"title":"Fireflies + Notion meeting notes","prompt":"Create a workflow that watches Fireflies recordings, generates a polished meeting-notes page in Notion under the right team space, and links the recording.","integrations":[{"id":"notion","name":"Notion"},{"id":"fireflies","name":"Fireflies"}]},{"title":"GitHub docs auto-updater","prompt":"Create a knowledge base connected to my GitHub repository so code and docs stay synced. Then build a scheduled weekly workflow that detects API changes, compares them against the knowledge base to find outdated documentation, and either updates Notion pages directly or creates Linear tickets for the needed changes.","integrations":[{"id":"notion","name":"Notion"},{"id":"github","name":"GitHub"},{"id":"linear","name":"Linear"}]},{"title":"Gmail to Notion email capture","prompt":"Build a workflow that monitors Gmail for incoming emails, extracts structured data from each one, and stores it as a Notion database entry — useful for lead capture, support tickets, and meeting scheduling.","integrations":[{"id":"notion","name":"Notion"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Drive personal notes assistant","prompt":"Create a knowledge base and connect it to my Google Drive, Notion, or Obsidian so all my notes, docs, and articles are automatically synced and embedded. Then build an agent that I can ask anything — it should answer with citations and deploy as a chat endpoint.","integrations":[{"id":"notion","name":"Notion"},{"id":"google_drive","name":"Google Drive"},{"id":"obsidian","name":"Obsidian"}]},{"title":"Google Meet retro publisher","prompt":"Build a workflow that runs after a sprint-retro Google Meet, summarizes what went well, what to improve, and action items, and posts the retro to a Notion page tagged with the sprint number.","integrations":[{"id":"notion","name":"Notion"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Sync Google Sheets data into Notion","prompt":"Create an agent that reads rows from Google Sheets and transforms them into structured Notion database entries for richer documentation and cross-team project tracking.","integrations":[{"id":"notion","name":"Notion"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Grain + Notion knowledge sync","prompt":"Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.","integrations":[{"id":"notion","name":"Notion"},{"id":"grain","name":"Grain"}]},{"title":"Grain + Notion knowledge sync","prompt":"Create a workflow that processes Grain meeting recordings, extracts decisions and learnings, and writes them as Notion pages tagged by topic for the team knowledge base.","integrations":[{"id":"notion","name":"Notion"},{"id":"grain","name":"Grain"}]},{"title":"Granola + Notion publisher","prompt":"Build a scheduled workflow that polls Granola for new meeting notes, generates a polished meeting-notes page in Notion under the right team space, and links the original Granola note.","integrations":[{"id":"notion","name":"Notion"},{"id":"granola","name":"Granola"}]},{"title":"Intercom conversation summarizer","prompt":"Build a workflow triggered when an Intercom conversation is closed that summarizes the issue, resolution, and any follow-up actions, then appends the summary to a Notion knowledge log so the team can learn from past conversations.","integrations":[{"id":"notion","name":"Notion"},{"id":"intercom","name":"Intercom"}]},{"title":"Jina docs-to-Notion clipper","prompt":"Build a workflow that reads a submitted URL with Jina Reader, summarizes the content with an agent, and appends a clean clipped entry to a Notion research database.","integrations":[{"id":"notion","name":"Notion"},{"id":"jina","name":"Jina"}]},{"title":"Jotform applications into a hiring pipeline","prompt":"Build a workflow that pulls Jotform job application submissions, downloads the uploaded resume files from the form, has an agent summarize each candidate against the role requirements, and creates a Notion page per applicant.","integrations":[{"id":"notion","name":"Notion"},{"id":"jotform","name":"Jotform"}]},{"title":"Mem0 + Notion personal-knowledge agent","prompt":"Create an agent that uses Mem0 to recall personal context and Notion as the source-of-truth knowledge base, answering questions with citations plus user-specific memory.","integrations":[{"id":"notion","name":"Notion"},{"id":"mem0","name":"Mem0"}]},{"title":"Notion customer support bot","prompt":"Create a knowledge base and connect it to my Notion or Google Docs so it stays synced with my product documentation automatically. Then build an agent that answers customer questions using it with sourced citations and deploy it as a chat endpoint.","integrations":[{"id":"notion","name":"Notion"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Notion knowledge search","prompt":"Create a knowledge base connected to my Notion workspace so all pages, databases, meeting notes, and wikis are automatically synced and searchable. Then build an agent I can ask things like \\"what\'s our refund policy?\\" or \\"what was decided in the Q3 planning doc?\\" and get instant answers with page links.","integrations":[{"id":"notion","name":"Notion"}]},{"title":"Notify your team from Notion","prompt":"Build a workflow that watches Notion for new or updated pages and automatically posts a Slack message so your team stays aligned without manual check-ins.","integrations":[{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"Notion meeting-notes capture","prompt":"Build a workflow that runs after a Google Meet call, fetches the transcript, and creates a structured Notion page under the right project with attendees, decisions, and action items.","integrations":[{"id":"notion","name":"Notion"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Notion CRM enrichment","prompt":"Create a workflow that watches a Notion database of companies, researches each new entry for funding, headcount, and industry, and appends the enriched fields back to the Notion page so the pipeline stays current.","integrations":[{"id":"notion","name":"Notion"}]},{"title":"Notion content calendar publisher","prompt":"Build a scheduled workflow that queries a Notion content-calendar database for posts marked ready today, formats each one, and publishes it to the blog while updating the Notion page status to published.","integrations":[{"id":"notion","name":"Notion"},{"id":"wordpress","name":"WordPress"}]},{"title":"Notion weekly digest builder","prompt":"Create a scheduled weekly workflow that queries a Notion project database for items completed this week, appends a summary section to a Notion review page, and posts the highlights to Slack for the team.","integrations":[{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"Outlook newsletter clipper","prompt":"Create a workflow that reads newsletters arriving in Outlook, summarizes each one into key takeaways, and appends the digest to a daily Notion page so the inbox stays clean and the insights stay searchable.","integrations":[{"id":"notion","name":"Notion"},{"id":"outlook","name":"Outlook"}]},{"title":"Profound content-gap planner","prompt":"Build a workflow that pulls the prompts where Profound shows my brand is absent from AI answers, has an agent draft a prioritized content brief for each gap, and creates the briefs as Notion pages for the content team.","integrations":[{"id":"notion","name":"Notion"},{"id":"profound","name":"Profound"}]},{"title":"Slack Q&A bot","prompt":"Create a knowledge base connected to my Notion workspace so it stays synced with my company wiki. Then build a workflow that monitors Slack channels for questions and answers them using the knowledge base with source citations.","integrations":[{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"Archive Slack conversations to Notion","prompt":"Build a workflow that captures important Slack messages and threads and saves them as Notion pages or database entries, so meeting notes and decisions are always documented.","integrations":[{"id":"notion","name":"Notion"},{"id":"slack","name":"Slack"}]},{"title":"YouTube video recap to Notion","prompt":"Build a workflow that takes a YouTube video URL, pulls the video details, description, and top comments, summarizes the highlights and audience reaction, and saves a recap to a Notion page for the marketing team.","integrations":[{"id":"notion","name":"Notion"},{"id":"youtube","name":"YouTube"}]},{"title":"Zoom + Notion meeting notes","prompt":"Create a workflow that watches for Zoom recordings, transcribes, and writes a structured meeting-notes page to Notion under the right team space, with action items linked to owners.","integrations":[{"id":"notion","name":"Notion"},{"id":"zoom","name":"Zoom"}]}]},{"id":"obsidian","type":"obsidian","slug":"obsidian","name":"Obsidian","description":"Interact with your Obsidian vault via the Local REST API","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/obsidian","authType":"api-key","connections":[],"operations":[{"name":"List Files","description":"List files and directories in your Obsidian vault"},{"name":"Get Note","description":"Retrieve the content of a note from your Obsidian vault"},{"name":"Create Note","description":"Create or replace a note in your Obsidian vault"},{"name":"Append to Note","description":"Append content to an existing note in your Obsidian vault"},{"name":"Patch Note","description":"Insert or replace content at a specific heading, block reference, or frontmatter field in a note"},{"name":"Delete Note","description":"Delete a note from your Obsidian vault"},{"name":"Search","description":"Search for text across notes in your Obsidian vault"},{"name":"Get Active File","description":"Retrieve the content of the currently active file in Obsidian"},{"name":"Append to Active File","description":"Append content to the currently active file in Obsidian"},{"name":"Patch Active File","description":"Insert or replace content at a specific heading, block reference, or frontmatter field in the active file"},{"name":"Open File","description":"Open a file in the Obsidian UI (creates the file if it does not exist)"},{"name":"List Commands","description":"List all available commands in Obsidian"},{"name":"Execute Command","description":"Execute a command in Obsidian (e.g. open daily note, toggle sidebar)"},{"name":"Get Periodic Note","description":"Retrieve the current periodic note (daily, weekly, monthly, quarterly, or yearly)"},{"name":"Append to Periodic Note","description":"Append content to the current periodic note (daily, weekly, monthly, quarterly, or yearly). Creates the note if it does not exist."}],"triggers":[],"skills":[{"name":"capture-note","description":"Create a new Obsidian note with Markdown content at a chosen vault path.","content":"# Capture Note\\n\\nWrite a new note into the Obsidian vault.\\n\\n## Steps\\n1. Decide the vault path and filename for the note, keeping folder conventions consistent.\\n2. Compose the Markdown body with a clear title heading and any tags or frontmatter wanted.\\n3. Run Create Note with the path and content. If the note may already exist, use Append to Note instead to avoid overwriting.\\n\\n## Output\\nConfirm the note path created and summarize what was captured."},{"name":"append-to-daily-note","description":"Append an entry to the Obsidian periodic daily note.","content":"# Append to Daily Note\\n\\nAdd a timestamped entry to the current daily note.\\n\\n## Steps\\n1. Use Get Periodic Note to confirm the daily note exists and read its current content if needed.\\n2. Format the entry as a Markdown bullet or section, including a timestamp where useful.\\n3. Run Append to Periodic Note to add it to the day.\\n\\n## Output\\nConfirm the entry was appended to the daily note and quote the line added."},{"name":"search-vault","description":"Search the Obsidian vault for notes matching a query and summarize matches.","content":"# Search Vault\\n\\nFind notes in the Obsidian vault that mention a topic.\\n\\n## Steps\\n1. Run Search with the query terms.\\n2. Open the most relevant results with Get Note to read their content.\\n3. Summarize the findings, linking each note by its path.\\n\\n## Output\\nA short synthesis of what the vault says about the topic, with the source note paths listed."}],"templates":[{"title":"Google Drive personal notes assistant","prompt":"Create a knowledge base and connect it to my Google Drive, Notion, or Obsidian so all my notes, docs, and articles are automatically synced and embedded. Then build an agent that I can ask anything — it should answer with citations and deploy as a chat endpoint.","integrations":[{"id":"obsidian","name":"Obsidian"},{"id":"google_drive","name":"Google Drive"},{"id":"notion","name":"Notion"}]},{"title":"Obsidian daily journal agent","prompt":"Build a workflow that pulls calendar events, completed tasks, and journal prompts, and generates a daily Obsidian note draft for the user to review and annotate.","integrations":[{"id":"obsidian","name":"Obsidian"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Obsidian backlink builder","prompt":"Create a workflow that processes new Obsidian notes, identifies entities and concepts that should be wikilinks, and rewrites the note with proper backlinks plus a hub note for new tags.","integrations":[{"id":"obsidian","name":"Obsidian"}]},{"title":"Obsidian web clipper","prompt":"Build a workflow that accepts a URL from a form, scrapes the page with Firecrawl, summarizes with an agent, and writes the clip as a new Obsidian note with source metadata.","integrations":[{"id":"obsidian","name":"Obsidian"},{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Obsidian knowledge-base sync","prompt":"Create a workflow that mirrors an Obsidian vault into a Sim knowledge base so an agent can answer questions over personal notes with citations.","integrations":[{"id":"obsidian","name":"Obsidian"}]},{"title":"Obsidian smart review","prompt":"Build a scheduled weekly workflow that surfaces stale Obsidian notes due for spaced-repetition review, scores their freshness, and writes a review queue note for the user.","integrations":[{"id":"obsidian","name":"Obsidian"}]},{"title":"Obsidian meeting-note autopopulator","prompt":"Create a workflow that runs after a Google Meet meeting, fetches the transcript, and appends a structured meeting note to an Obsidian vault under the right project folder.","integrations":[{"id":"obsidian","name":"Obsidian"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Obsidian reading-list digester","prompt":"Build a scheduled workflow that reads the links saved in an Obsidian \\"to read\\" note, summarizes each article with an agent, and appends the key takeaways back into the vault as individual literature notes with source links.","integrations":[{"id":"obsidian","name":"Obsidian"}]}]},{"id":"okta","type":"okta","slug":"okta","name":"Okta","description":"Manage users, groups, apps, and MFA in Okta","category":"Security","docsUrl":"https://docs.sim.ai/integrations/okta","authType":"api-key","connections":[],"operations":[{"name":"List Users","description":"List users in your Okta organization with optional search and filtering. Users with a DEPROVISIONED status are omitted unless a search or filter expression selects them."},{"name":"Get User","description":"Get a specific user by ID or login from your Okta organization"},{"name":"Create User","description":"Create a new user in your Okta organization"},{"name":"Update User","description":"Update a user profile in your Okta organization"},{"name":"Activate User","description":"Activate a user in your Okta organization. Can only be performed on users with STAGED or DEPROVISIONED status. Optionally sends an activation email."},{"name":"Deactivate User","description":"Deactivate a user in your Okta organization. This transitions the user to DEPROVISIONED status."},{"name":"Suspend User","description":"Suspend a user in your Okta organization. Only users with ACTIVE status can be suspended. Suspended users cannot log in but retain group and app assignments."},{"name":"Unsuspend User","description":"Unsuspend a previously suspended user in your Okta organization. Returns the user to ACTIVE status."},{"name":"Reset Password","description":"Generate a one-time token to reset a user password. Can email the reset link to the user or return it directly. Transitions the user to RECOVERY status."},{"name":"Delete User","description":"Permanently delete a user from your Okta organization. Can only be performed on DEPROVISIONED users. If the user is active, this will first deactivate them and a second call is needed to delete."},{"name":"List Groups","description":"List all groups in your Okta organization with optional search and filtering"},{"name":"Get Group","description":"Get a specific group by ID from your Okta organization"},{"name":"Create Group","description":"Create a new group in your Okta organization"},{"name":"Update Group","description":"Update a group profile in your Okta organization. Only groups of OKTA_GROUP type can be updated. Fields left blank keep their stored value."},{"name":"Delete Group","description":"Delete a group from your Okta organization. Groups of OKTA_GROUP or APP_GROUP type can be removed."},{"name":"Add User to Group","description":"Add a user to a group in your Okta organization"},{"name":"Remove User from Group","description":"Remove a user from a group in your Okta organization"},{"name":"List Group Members","description":"List all members of a specific group in your Okta organization"},{"name":"List Group Rules","description":"List the group rules in your Okta organization. Each rule assigns users to groups automatically based on an expression over their profile, so this shows how group membership is being driven."},{"name":"Get Group Rule","description":"Retrieve a single Okta group rule by ID, including the expression that decides which users it matches and the groups those users are assigned to."},{"name":"Create Group Rule","description":"Create a group rule that automatically assigns users matching an Okta expression to one or more groups. New rules are created INACTIVE, so run Activate Group Rule afterwards to start applying it."},{"name":"Activate Group Rule","description":"Activate a group rule so Okta starts applying it, assigning every matching user to the target groups."},{"name":"Deactivate Group Rule","description":"Deactivate a group rule so Okta stops applying it. Existing memberships the rule created are left in place. A rule must be INACTIVE before it can be edited."},{"name":"Delete Group Rule","description":"Permanently delete a group rule. Destructive and irreversible. Optionally also removes the users that this rule had assigned from those groups, which revokes any access those groups grant."},{"name":"List Factors","description":"List the MFA factors a user has enrolled, with each factor type, provider, and enrollment status. Use this before resetting a factor to confirm which one to target."},{"name":"Get Factor","description":"Retrieve a single enrolled MFA factor for a user, including its type, provider, enrollment status, and factor-specific profile."},{"name":"Enroll Factor","description":"Enroll an MFA factor for a user. The profile fields required depend on the factor type: a phone number for sms and call, an email address for email, and a question and answer for question. Factors that enroll from the user device, such as webauthn and push, need no profile fields."},{"name":"Reset Factor","description":"Unenroll one specific MFA factor for a user so they can re-enroll it. Destructive and irreversible: the existing enrollment is removed. Unenrolling a push or signed_nonce factor also unenrolls the related Okta Verify factors. Factors cannot be unenrolled from a deactivated user."},{"name":"Reset All Factors","description":"Reset every MFA factor for a user, returning all enrollments to the unenrolled state. Destructive and irreversible: the user must re-enroll each factor before they can complete MFA again. The user status stays ACTIVE."},{"name":"Clear User Sessions","description":"Revoke every active Okta session for a user, signing them out of all devices immediately. Destructive and irreversible: the user must sign in again. Optionally also revokes their OAuth and OpenID Connect tokens, and clears remembered factors."},{"name":"Get Session","description":"Retrieve an Okta session by ID, including who it belongs to, when it expires, and which authentication methods were used to establish it."},{"name":"Revoke Session","description":"Revoke a single Okta session by ID, ending that sign-in immediately. Destructive and irreversible: the affected user must sign in again on that device."},{"name":"List Applications","description":"List the applications configured in your Okta organization, with optional name search, filtering, and cursor pagination."},{"name":"Get Application","description":"Retrieve a single Okta application by ID, including its sign-on mode, status, enabled provisioning features, and configuration objects."},{"name":"List Application Users","description":"List the users assigned to an Okta application, including how each assignment was made and its provisioning sync state. Use this to audit who has access to an app."},{"name":"Assign User to Application","description":"Assign a user to an Okta application, granting them access to it. Applications that require credentials also need the username the user signs in with."},{"name":"Remove User from Application","description":"Unassign a user from an Okta application, revoking their access. Destructive and irreversible: the app profile for that user is permanently removed, and if provisioning is enabled the downstream account is deactivated."},{"name":"List Application Groups","description":"List the groups assigned to an Okta application. Every member of an assigned group inherits access to the app, so this is the starting point for an app access review."},{"name":"Assign Group to Application","description":"Assign a group to an Okta application so every member of the group inherits access to it."},{"name":"Remove Group from Application","description":"Unassign a group from an Okta application. Destructive: every member who had access only through this group loses access to the app."},{"name":"List User Roles","description":"List the administrator roles assigned to a user. Returns both standard roles and custom role bindings, so you can review who holds privileged access."},{"name":"Assign User Role","description":"Grant a user an administrator role. Use a standard role type such as USER_ADMIN or HELP_DESK_ADMIN, or CUSTOM together with a custom role ID and a resource set ID. This grants privileged access, so confirm the role is the least privilege that fits."},{"name":"Remove User Role","description":"Revoke an administrator role from a user. Destructive: the user immediately loses the admin permissions that role granted. Takes the role assignment ID, not the role type, which List User Roles returns as the role id field."},{"name":"Get System Log Events","description":"Query the Okta System Log for sign-ins, admin changes, and security events. Supports a time window, SCIM filter expressions, keyword search, and cursor pagination for audit and investigation workflows."}],"triggers":[],"skills":[{"name":"onboard-user","description":"Create an Okta user, set their profile, and add them to the right groups.","content":"# Onboard User\\n\\nProvision a new user in Okta and grant their group access.\\n\\n## Steps\\n1. Run Create User with the profile fields: first name, last name, email, and login.\\n2. Determine the groups the role requires, using List Groups to resolve group ids.\\n3. Run Add User to Group for each required group.\\n4. Activate the user if it was created in a staged state.\\n\\n## Output\\nConfirm the new user id and login, and list the groups they were added to."},{"name":"offboard-user","description":"Deactivate an Okta user and remove their group memberships during offboarding.","content":"# Offboard User\\n\\nRevoke access for a departing user in Okta.\\n\\n## Steps\\n1. Find the user with List Users or Get User to confirm the user id.\\n2. Run Deactivate User (or Suspend User for a temporary hold) to block sign-in.\\n3. Remove the user from sensitive groups with Remove User from Group.\\n4. Only run Delete User when permanent removal is explicitly requested, since it is irreversible.\\n\\n## Output\\nConfirm the user status and the groups removed. State clearly whether the account was deactivated or deleted."},{"name":"audit-group-membership","description":"List Okta groups and their members to audit access for a security review.","content":"# Audit Group Membership\\n\\nReview who belongs to Okta groups, focusing on privileged access.\\n\\n## Steps\\n1. Run List Groups to enumerate the groups, or Get Group for a specific one.\\n2. For each group of interest, run List Group Members.\\n3. Highlight privileged or admin groups and call out any unexpected members.\\n\\n## Output\\nA per-group roster with member counts, and a short list of access concerns to review."},{"name":"reset-user-mfa","description":"Reset a locked-out user MFA enrollment so they can enroll a factor again.","content":"# Reset User MFA\\n\\nClear a stuck multifactor enrollment, the most common Okta help desk request.\\n\\n## Steps\\n1. Run List Factors for the user to see which factors are enrolled and their status.\\n2. Reset the narrowest thing that fixes it: Reset Factor for one factor id, or Reset All Factors when every enrollment must go.\\n3. Note that resetting push also unenrolls the related Okta Verify factors, and that factors cannot be reset on a deactivated user.\\n4. Run Clear User Sessions if the user must be signed out of existing sessions before re-enrolling.\\n\\n## Output\\nName the factors that were reset and state that the user must re-enroll before they can complete MFA again. Both resets are irreversible, so confirm the target user before running either."},{"name":"investigate-sign-in-failures","description":"Query the Okta System Log for failed sign-ins and suspicious authentication.","content":"# Investigate Sign-In Failures\\n\\nUse the System Log to explain why a user cannot sign in, or to review suspicious authentication.\\n\\n## Steps\\n1. Run Get System Log Events with a Since and Until that bracket the incident.\\n2. Filter to the events that matter, for example eventType eq \\"user.session.start\\" and outcome.result eq \\"FAILURE\\" for failed sign-ins.\\n3. Narrow to one person or origin by adding actor.alternateId or client.ipAddress to the filter, or use the keyword query for a free-text sweep.\\n4. Read outcomeReason, clientIpAddress, and the client geography on each event to separate a wrong password from an unexpected location.\\n5. Page with the returned cursor while hasMore is true when the window is wide.\\n\\n## Output\\nA short timeline of the matching events with actor, time, outcome, reason, and source IP, plus a plain statement of the likely cause."},{"name":"review-app-access","description":"Audit who can reach an Okta application through direct and group assignments.","content":"# Review Application Access\\n\\nEstablish who has access to an application and how they got it.\\n\\n## Steps\\n1. Run List Applications to resolve the application id, or Get Application when the id is known.\\n2. Run List Application Users and read the scope on each assignment: USER means a direct grant, GROUP means it was inherited.\\n3. Run List Application Groups to see which groups confer access, since every member of those groups reaches the app.\\n4. Expand any group of interest with List Group Members to get the real roster.\\n5. Revoke with Remove User from Application for a direct grant, or Remove Group from Application to cut the whole group.\\n\\n## Output\\nA roster split into direct and group-inherited access, naming the groups that grant it, and a list of assignments that look unjustified."},{"name":"reset-user-password","description":"Trigger an Okta password reset for a user who is locked out.","content":"# Reset User Password\\n\\nHelp a user regain access by resetting their Okta password.\\n\\n## Steps\\n1. Locate the user with Get User to confirm identity.\\n2. Run Reset Password to start the reset flow for that user.\\n3. If the account is suspended, run Unsuspend User first so the reset can proceed.\\n\\n## Output\\nConfirm the reset was initiated for the named user and note any prerequisite step that was taken."}],"templates":[{"title":"CrowdStrike + Okta coverage check","prompt":"Build a workflow that lists CrowdStrike Identity Protection sensors and cross-references them with Okta users and devices to find accounts active on endpoints that have no protected sensor, then writes the findings to a security table.","integrations":[{"id":"okta","name":"Okta"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"Okta quarterly access review","prompt":"Build a scheduled quarterly workflow that pulls Okta group memberships per app, posts an attestation thread to each owner in Slack, captures confirmations, and writes the audit log to a compliance table.","integrations":[{"id":"okta","name":"Okta"},{"id":"slack","name":"Slack"}]},{"title":"Okta orphan-account sweeper","prompt":"Create a scheduled workflow that compares Okta users against HRIS data, finds accounts for departed employees, disables them, and writes the sweep log to an audit table.","integrations":[{"id":"okta","name":"Okta"},{"id":"workday","name":"Workday"}]},{"title":"Okta new-hire provisioning","prompt":"Build a workflow that polls Workday for new hires, creates the matching Okta user, adds them to the right groups for their role, and emails IT a provisioning summary.","integrations":[{"id":"okta","name":"Okta"},{"id":"workday","name":"Workday"},{"id":"gmail","name":"Gmail"}]},{"title":"Okta compromised-account responder","prompt":"Create a workflow triggered by a CrowdStrike detection on a user that suspends the matching Okta account, resets their password, and pings the security Slack channel with the action taken.","integrations":[{"id":"okta","name":"Okta"},{"id":"crowdstrike","name":"CrowdStrike"},{"id":"slack","name":"Slack"}]},{"title":"Okta access-group provisioner","prompt":"Build a workflow that reads an access-request table, creates the Okta group if it is missing, adds the approved users to it, and writes the grant record back to the table.","integrations":[{"id":"okta","name":"Okta"}]},{"title":"Okta SSO group sync","prompt":"Create a scheduled workflow that mirrors org structure from Workday into Okta groups, ensuring group memberships stay in sync as employees change roles.","integrations":[{"id":"okta","name":"Okta"},{"id":"workday","name":"Workday"}]},{"title":"Okta group membership audit","prompt":"Build a scheduled monthly workflow that lists every Okta group and its members, flags privileged groups with unexpected membership, and writes a review report for the security team.","integrations":[{"id":"okta","name":"Okta"}]}]},{"id":"onedrive","type":"onedrive","slug":"onedrive","name":"OneDrive","description":"Create, upload, download, search, move, copy, share, and delete files","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/onedrive","authType":"oauth","connections":[{"id":"onedrive","kind":"oauth","label":"Connect with OAuth","providerId":"onedrive","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/onedrive","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Files.Read","label":"Read OneDrive files"},{"id":"Files.ReadWrite","label":"Read and write OneDrive files"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Create Folder","description":"Create a new folder in OneDrive"},{"name":"Create File","description":"Upload a file to OneDrive"},{"name":"Upload File","description":"Upload a file to OneDrive"},{"name":"Download File","description":"Download a file from OneDrive"},{"name":"List Files","description":"List files and folders in OneDrive"},{"name":"Search Files","description":"Search for files and folders across OneDrive by name, metadata, or content (recursive)"},{"name":"Get Item Info","description":"Get metadata for a specific OneDrive file or folder by ID, or the drive root"},{"name":"Get Drive Info","description":"Get information about the OneDrive drive, including storage quota"},{"name":"Move/Rename File","description":"Move a file or folder to a new parent folder, rename it, or both"},{"name":"Copy File","description":"Copy a file or folder to another location within OneDrive"},{"name":"Create Sharing Link","description":"Create a view or edit sharing link for a OneDrive file or folder"},{"name":"Delete File","description":"Delete a file or folder from OneDrive"}],"triggers":[],"skills":[{"name":"upload-file-to-folder","description":"Upload a file to a specific OneDrive folder, creating the folder if needed.","content":"# Upload File to Folder\\n\\nPlace a file into the right OneDrive folder.\\n\\n## Steps\\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\\n2. Run Upload File with the file content and the target folder.\\n3. Use a clear, consistent filename so the document is easy to find later.\\n\\n## Output\\nConfirm the uploaded file name, its folder, and the file id or link."},{"name":"find-and-download-file","description":"Locate a file in OneDrive by name and download its contents.","content":"# Find and Download File\\n\\nRetrieve a file from OneDrive for processing.\\n\\n## Steps\\n1. Run List Files in the likely folder to find the file and its id.\\n2. Run Download File with the matched file id.\\n3. Pass the downloaded content to the next step, such as a parser or summarizer.\\n\\n## Output\\nConfirm the file downloaded with its name and size, and hand off the content."},{"name":"save-generated-document","description":"Create a new text or document file in OneDrive from generated content, in the right folder.","content":"# Save Generated Document\\n\\nWrite generated content, such as a report or notes, into OneDrive as a new file.\\n\\n## Steps\\n1. Use List Files to confirm the destination folder exists; if not, run Create Folder.\\n2. Compose the document content and choose a clear filename and type.\\n3. Run Create File with the content, filename, and target folder.\\n\\n## Output\\nConfirm the created file name, its folder, and the file id or link."}],"templates":[{"title":"Word meeting-notes writer","prompt":"Build a workflow that takes a Fireflies meeting transcript, summarizes the decisions and action items, and creates a formatted Word document in the team OneDrive folder.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"fireflies","name":"Fireflies"}]},{"title":"OneDrive contract intake","prompt":"Create a scheduled workflow that polls a OneDrive intake folder for new contract PDFs, extracts clauses with Reducto, writes the structured terms to a table, and pings legal in Teams.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"reducto","name":"Reducto"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"OneDrive sharing audit","prompt":"Build a scheduled weekly workflow that lists OneDrive files shared externally, flags ones above a sensitivity score, and writes a security review report.","integrations":[{"id":"onedrive","name":"OneDrive"}]},{"title":"OneDrive to knowledge base sync","prompt":"Create a workflow that mirrors OneDrive folders into a knowledge base, chunks and embeds new content on change, and removes deleted files so retrieval stays accurate.","integrations":[{"id":"onedrive","name":"OneDrive"}]},{"title":"OneDrive backup verifier","prompt":"Build a scheduled workflow that verifies OneDrive backups by sampling files and comparing checksums against the originating SharePoint copy, writing the report to an SRE table.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"OneDrive retention cleaner","prompt":"Create a scheduled workflow that finds OneDrive files older than the retention horizon, requires manager approval through Teams, and archives or deletes per the policy.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"OneDrive Excel-pipeline opener","prompt":"Build a scheduled workflow that polls OneDrive for new Excel data drops, normalizes each, writes to a downstream table, and emails the analyst that the latest file is ready.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"gmail","name":"Gmail"}]},{"title":"OneDrive new-hire kit deployer","prompt":"Create a workflow triggered by a Workday new hire that creates a OneDrive new-hire folder, uploads the standard onboarding documents into it, and writes the folder link into the onboarding tracker.","integrations":[{"id":"onedrive","name":"OneDrive"},{"id":"workday","name":"Workday"}]}]},{"id":"oracledb","type":"oracledb","slug":"oracle-database","name":"Oracle Database","description":"Connect directly to an Oracle Database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/oracledb","authType":"api-key","connections":[{"id":"oracledb-service-account","kind":"service_account","providerId":"oracledb-service-account","label":"Add database connection","setup":"oracle-database","docsUrl":"https://docs.sim.ai/integrations/oracledb","fields":[{"id":"host","label":"Host","placeholder":"db.example.com"},{"id":"port","label":"Port","placeholder":"1521","defaultValue":"1521"},{"id":"protocol","label":"Protocol","defaultValue":"tcps","options":[{"value":"tcps","label":"TCPS (TLS)"},{"value":"tcp","label":"TCP"}]},{"id":"connectionType","label":"Connection identifier","defaultValue":"serviceName","options":[{"value":"serviceName","label":"Service name"},{"value":"sid","label":"SID"}]},{"id":"serviceName","label":"Service name","placeholder":"FREEPDB1","visibleWhen":{"field":"connectionType","values":["serviceName"]}},{"id":"sid","label":"SID","placeholder":"ORCL","visibleWhen":{"field":"connectionType","values":["sid"]}},{"id":"username","label":"Username","placeholder":"app_user"},{"id":"password","label":"Password","placeholder":"Enter the database password","secret":true},{"id":"walletContent","label":"PEM wallet","placeholder":"Paste ewallet.pem content","secret":true,"multiline":true,"optional":true,"visibleWhen":{"field":"protocol","values":["tcps"]}},{"id":"walletPassword","label":"Wallet password","placeholder":"Password for an encrypted PEM wallet","secret":true,"optional":true,"visibleWhen":{"field":"protocol","values":["tcps"]}}]}],"operations":[{"name":"Query (SELECT)","description":"Run one read-only Oracle SELECT statement or ordinary SELECT CTE with optional named IN binds"},{"name":"Insert Data","description":"Insert one JSON object as a row in an Oracle Database table using bound values"},{"name":"Update Data","description":"Update Oracle Database rows selected by a required WHERE expression, using bound values for changed columns"},{"name":"Delete Data","description":"Delete Oracle Database rows selected by a required WHERE expression"},{"name":"Execute SQL","description":"Execute one allowed Oracle SQL statement: SELECT, INSERT, UPDATE, DELETE, MERGE, CREATE, ALTER, DROP, or EXPLAIN PLAN"},{"name":"Introspect Schema","description":"Inspect accessible Oracle tables, columns, keys, non-primary-key indexes, and table-owning schemas using ALL_* dictionary views"}],"triggers":[],"skills":[{"name":"query-to-answer","description":"Answer a natural-language question with a bounded Oracle SELECT and its rows.","content":"# Query To Answer\\n\\nUse Oracle schema metadata and a read-only query to answer a factual question.\\n\\n## Steps\\n1. Run introspect for the relevant schema.\\n2. Generate one SELECT using real table and column names. Add deterministic ordering and `FETCH FIRST n ROWS ONLY`.\\n3. Put user-supplied values in named binds instead of concatenating them into SQL.\\n4. Run query and summarize `rows`, `rowCount`, and any truncation warning.\\n\\n## Output\\nReturn the plain-language answer, supporting rows, row count, and truncation status.\\n\\n## Reference\\n[Oracle SELECT](https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/SELECT.html)"},{"name":"merge-records","description":"Insert or update records atomically by key with an Oracle MERGE statement.","content":"# Merge Records\\n\\nKeep an Oracle table synchronized without a read-before-write race.\\n\\n## Steps\\n1. Introspect the target table and confirm the match key is unique.\\n2. Build one `MERGE INTO` statement whose `ON` clause uses the key.\\n3. Use named binds for source values and run the statement with execute.\\n4. Check `rowCount` and report failures without retrying blindly.\\n\\n## Output\\nReturn the number of rows affected and the match key used.\\n\\n## Reference\\n[Oracle MERGE](https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/MERGE.html)"},{"name":"document-schema","description":"Turn accessible Oracle dictionary metadata into readable schema documentation.","content":"# Document Schema\\n\\nDocument the objects visible to the connected Oracle account.\\n\\n## Steps\\n1. Run introspect for the target schema, or omit it for `CURRENT_SCHEMA`.\\n2. Explain each table from its columns and data types.\\n3. Describe relationships from primary and foreign keys.\\n4. Note indexes that reveal common lookup patterns.\\n5. Clearly label the result as privilege-scoped and potentially partial.\\n\\n## Output\\nReturn one section per table plus the raw introspection result.\\n\\n## Reference\\n[Oracle ALL_TABLES](https://docs.oracle.com/en/database/oracle/oracle-database/26/refrn/ALL_TABLES.html)"},{"name":"retention-cleanup","description":"Preview and delete Oracle rows older than an explicit retention cutoff.","content":"# Retention Cleanup\\n\\nRemove stale records with an auditable cutoff.\\n\\n## Steps\\n1. Compute and record the cutoff timestamp.\\n2. Run a bounded SELECT count using the same condition to preview impact.\\n3. Stop if the preview is unexpectedly large.\\n4. Run delete with a non-empty WHERE expression scoped to the cutoff.\\n5. Record `rowCount` and the cutoff.\\n\\n## Output\\nReturn preview count, deleted row count, cutoff, and status."},{"name":"monitor-thresholds","description":"Monitor an Oracle metric and alert only when an explicit threshold is crossed.","content":"# Monitor Thresholds\\n\\nTurn a bounded Oracle aggregate into a repeatable health check.\\n\\n## Steps\\n1. Define the metric, threshold, schedule, and alert destination.\\n2. Run one deterministic aggregate SELECT with named binds for any variable filters.\\n3. Treat truncation or query failure as an unknown state, not a healthy result.\\n4. Compare the returned metric with the threshold and alert only on a crossing or state change.\\n5. Include the measured value, threshold, and query time in the alert.\\n\\n## Output\\nReturn the current value, threshold, state, and whether an alert was sent.\\n\\n## Reference\\n[Oracle aggregate functions](https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/Aggregate-Functions.html)"},{"name":"audit-schema-design","description":"Audit visible Oracle keys and indexes for structural gaps and risky tables.","content":"# Audit Schema Design\\n\\nReview the schema structure visible to the integration account.\\n\\n## Steps\\n1. Run introspect for the target schema.\\n2. Flag tables with no primary key.\\n3. Use foreign-key metadata to nominate tables for index review. Treat coverage as provisional only when a foreign-key column leads a reported non-primary-key index or the primary key; composite constraints, function-based indexes, and omitted primary-key indexes require manual confirmation.\\n4. Identify duplicate reported indexes with the same ordered columns.\\n5. Separate confirmed metadata from review candidates; visibility is limited by account privileges.\\n\\n## Output\\nReturn confirmed missing keys, foreign-key index review candidates, duplicate reported indexes, and healthy tables.\\n\\n## Reference\\n[Oracle ALL_INDEXES](https://docs.oracle.com/en/database/oracle/oracle-database/26/refrn/ALL_INDEXES.html)"}],"templates":[{"title":"Ask Oracle in English","prompt":"Build a workflow that accepts a natural-language question, introspects the relevant Oracle schema, has an agent produce a bounded SELECT with named binds, runs it, and returns a readable answer with the supporting rows.","integrations":[{"id":"oracledb","name":"Oracle Database"}]},{"title":"Oracle KPI digest","prompt":"Create a scheduled workflow that queries key business metrics from Oracle Database each morning, has an agent summarize changes and anomalies, and posts the digest to Slack.","integrations":[{"id":"oracledb","name":"Oracle Database"},{"id":"slack","name":"Slack"}]},{"title":"Document Oracle schema","prompt":"Build a workflow that introspects an accessible Oracle schema, then has an agent turn its tables, columns, keys, and indexes into plain-English database documentation.","integrations":[{"id":"oracledb","name":"Oracle Database"}]},{"title":"Merge Oracle records","prompt":"Create a workflow that validates incoming records and executes an Oracle MERGE so matching rows are updated and new rows are inserted without a read-before-write race.","integrations":[{"id":"oracledb","name":"Oracle Database"}]},{"title":"Clean stale Oracle data","prompt":"Build a scheduled workflow that previews rows older than a retention cutoff, deletes only the matching Oracle records, and reports the affected row count.","integrations":[{"id":"oracledb","name":"Oracle Database"}]},{"title":"Sync Oracle to Sim","prompt":"Create a scheduled workflow that queries the latest Oracle records and writes each normalized row into a Sim table for downstream workflows and analysis.","integrations":[{"id":"oracledb","name":"Oracle Database"}]},{"title":"Alert on Oracle thresholds","prompt":"Build a scheduled workflow that runs an Oracle aggregate query, compares the result with a threshold, and sends a Slack alert only when the limit is crossed.","integrations":[{"id":"oracledb","name":"Oracle Database"},{"id":"slack","name":"Slack"}]},{"title":"Log webhooks in Oracle","prompt":"Create a workflow triggered by an incoming webhook that validates and reshapes the payload, then inserts one bound row into an Oracle audit or event table.","integrations":[{"id":"oracledb","name":"Oracle Database"}]}]},{"id":"oracle_fusion_financials","type":"oracle_fusion_financials","slug":"oracle-fusion-financials","name":"Oracle Fusion Financials","description":"Manage receivables and expenses, and report on payables and ledgers","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/oracle_fusion_financials","authType":"oauth","connections":[{"id":"oracle-fusion-service-account","kind":"service_account","providerId":"oracle-fusion-service-account","label":"Add integration user","setup":"fields","docsUrl":"https://docs.oracle.com/en/cloud/saas/applications-common/26b/farca/Quick_Start.html","fields":[{"id":"orgId","label":"Fusion Applications URL","placeholder":"https://your-environment.fa.ocs.oraclecloud.com","secret":false,"hint":"Expected the Oracle-assigned HTTPS application URL with no path, port, credentials, query, or fragment."},{"id":"clientId","label":"Integration username","placeholder":"Paste the integration username","secret":false},{"id":"clientSecret","label":"Password","placeholder":"Paste the password","secret":true}]}],"operations":[{"name":"Apply Receivables Receipt","description":"Apply a standard receipt to a Receivables invoice installment. An omitted amount applies the full open transaction balance."},{"name":"Approve Receivables Invoice","description":"Approve a pending-approval Oracle Fusion receivables invoice. Returns the action result, not a refreshed transaction."},{"name":"Create Expense Line","description":"Create an Oracle Fusion expense line."},{"name":"Create Expense Report","description":"Create an Oracle Fusion expense report."},{"name":"Create Receivables Credit Memo","description":"Create Oracle Fusion receivables credit memo."},{"name":"Create Receivables Invoice","description":"Create Oracle Fusion receivables invoice."},{"name":"Create Receivables Receipt","description":"Create Oracle Fusion receivables receipt."},{"name":"Get Expense Line","description":"Get an Oracle Fusion expense line."},{"name":"Get Expense Report","description":"Get an Oracle Fusion expense report."},{"name":"Get GL Journal Batch","description":"Get an Oracle Fusion gl journal batch."},{"name":"Get GL Ledger","description":"Get an Oracle Fusion gl ledger."},{"name":"Get Payables Invoice","description":"Get one Oracle Fusion Payables invoice by its opaque Oracle resource key."},{"name":"Get Payables Invoice Line","description":"Get one Oracle Fusion Payables invoice line by its Oracle-derived opaque key."},{"name":"Get Payables Payment","description":"Get one Oracle Fusion Payables payment by its CheckId."},{"name":"Get Receivables Credit Memo","description":"Get Oracle Fusion receivables credit memo."},{"name":"Get Receivables Invoice","description":"Get Oracle Fusion receivables invoice."},{"name":"Get Receivables Invoice Installment","description":"Get Oracle Fusion receivables invoice installment."},{"name":"Get Receivables Invoice Line","description":"Get Oracle Fusion receivables invoice line."},{"name":"Get Receivables Receipt","description":"Get Oracle Fusion receivables receipt."},{"name":"List Expense Lines","description":"List one bounded page of Oracle Fusion expense lines."},{"name":"List Expense Reports","description":"List one bounded page of Oracle Fusion expense reports."},{"name":"List GL Balances","description":"List one bounded page of Oracle Fusion gl balances."},{"name":"List GL Journal Batches","description":"List one bounded page of Oracle Fusion gl journal batches."},{"name":"List GL Ledgers","description":"List one bounded page of Oracle Fusion gl ledgers."},{"name":"List Payables Invoice Lines","description":"List one page of lines for an Oracle Fusion Payables invoice."},{"name":"List Payables Invoices","description":"List one page of Oracle Fusion Payables invoices using a fixed safe projection."},{"name":"List Payables Payments","description":"List one page of Oracle Fusion Payables payments using a fixed safe projection."},{"name":"List Receivables Credit Memos","description":"List one page of Oracle Fusion receivables credit memos."},{"name":"List Receivables Invoice Installments","description":"List one page of Oracle Fusion receivables invoice installments."},{"name":"List Receivables Invoice Lines","description":"List one page of Oracle Fusion receivables invoice lines."},{"name":"List Receivables Invoices","description":"List one page of Oracle Fusion receivables invoices."},{"name":"List Receivables Receipts","description":"List one page of Oracle Fusion receivables receipts."},{"name":"Submit Expense Report","description":"Submit an Oracle Fusion expense report. Only result S means submission without errors; other results are returned as business failures."},{"name":"Update Expense Line","description":"Update an Oracle Fusion expense line."},{"name":"Update Expense Report","description":"Update an Oracle Fusion expense report."},{"name":"Update Receivables Invoice","description":"Update Oracle Fusion receivables invoice."}],"triggers":[],"skills":[{"name":"review-fusion-payables","description":"Review invoice and payment status in Oracle Fusion.","content":"# Review Fusion Payables\\n\\n## Steps\\n1. List Payables Invoices with documented filters for the desired period or supplier.\\n2. Read selected invoices and their invoice lines using the returned opaque keys.\\n3. List Payables Payments with a documented filter when payment details are needed.\\n4. Continue only the bounded pages needed, advancing offset by the returned count while hasMore is true.\\n\\n## Output\\nReport supplier, invoice number, amounts, currencies, approval status, and payment status. Do not infer a payment-to-invoice relationship from matching amounts."},{"name":"apply-fusion-receipt","description":"Create and apply a standard receipt to a receivables installment.","content":"# Apply a Fusion Receipt\\n\\n## Steps\\n1. Get the target receivables invoice and list its installments to obtain the exact InstallmentId.\\n2. Create a receipt using the confirmed business unit, currency, receipt method, date, amount, and customer details.\\n3. Apply Receivables Receipt using its StandardReceiptId, the selected InstallmentId, and the approved amountApplied.\\n4. Read the receipt and invoice again to report the resulting balances.\\n\\n## Guidance\\nUse the correct customer and currency. Only SUCCESS means the action succeeded. A missing amountApplied requests the full open transaction balance; supply an amount when applying a partial receipt."},{"name":"submit-fusion-expenses","description":"Create and submit an expense report with its expense lines.","content":"# Submit Fusion Expenses\\n\\n## Steps\\n1. Create Expense Report with the authorized organization and employee details.\\n2. Use the returned expenseReportUniqId to create expense lines with their required assignment, organization, person, and ticket-class fields.\\n3. Read the report and lines and address validation errors.\\n4. Submit Expense Report and confirm the action result is S.\\n\\n## Output\\nReturn the report number, total, status, and validation errors. Submission does not mean approval or payment."},{"name":"report-fusion-ledger-balances","description":"Read ledger and accounting-period balances.","content":"# Report Fusion Ledger Balances\\n\\n## Steps\\n1. List GL Ledgers and select the correct ledger.\\n2. List GL Balances using the documented finder and accounting-period arguments for that ledger.\\n3. Page only as needed and retain the currency and accounting period alongside every amount.\\n4. Read journal batches separately when batch approval and posting status is relevant.\\n\\n## Output\\nReturn the ledger, period, currency, and documented balance values. Keep currencies separate and do not infer posting from the existence of a batch."}],"templates":[{"title":"Payables invoice review","prompt":"Build a scheduled workflow that lists a bounded page of Oracle Fusion payables invoices, reads the lines of selected invoices, and summarizes approval status, validation status, amounts, and supplier details.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Payables payment report","prompt":"Build a workflow that lists Oracle Fusion payables payments for a documented date filter and reports payment amounts, currencies, methods, and reconciliation flags.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Receivables invoice creation","prompt":"Build a workflow that creates an Oracle Fusion receivables invoice from approved billing details and line items, then reads the created invoice to report its number, balance, and status.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Receipt application","prompt":"Build a workflow that reads a receivables invoice and its installments, creates a standard receipt from approved payment details, and applies an explicitly supplied amount to the selected installment.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Credit memo creation","prompt":"Build a workflow that creates an Oracle Fusion receivables credit memo from approved customer, transaction, and line details, then reads the resulting memo.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Expense report submission","prompt":"Build a workflow that creates an Oracle Fusion expense report, adds validated expense lines with employee and business-unit identifiers, submits the report, and checks whether Oracle accepted submission without errors.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]},{"title":"Ledger balance report","prompt":"Build a workflow that lists Oracle Fusion ledgers and queries ledger balances using a documented finder, then summarizes the returned balance amounts for the selected accounting period.","integrations":[{"id":"oracle_fusion_financials","name":"Oracle Fusion Financials"}]}]},{"id":"netsuite","type":"netsuite","slug":"oracle-netsuite","name":"Oracle NetSuite","description":"Manage NetSuite records, queries, datasets, batches, and async jobs","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/netsuite","authType":"api-key","connections":[{"id":"netsuite-service-account","kind":"service_account","providerId":"netsuite-service-account","label":"Add OAuth certificate","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/netsuite-service-account","fields":[{"id":"orgId","label":"SuiteTalk URL","placeholder":"https://1234567-sb1.suitetalk.api.netsuite.com","secret":false,"hint":"Expected the HTTPS SuiteTalk Company URL with no path, port, query, or fragment."},{"id":"clientId","label":"Client ID","placeholder":"Paste the integration record client ID","secret":false},{"id":"certificateId","label":"Certificate ID","placeholder":"Paste the certificate mapping ID","secret":false},{"id":"privateKey","label":"Private key","placeholder":"-----BEGIN PRIVATE KEY-----","secret":true,"multiline":true,"hint":"Must match the certificate mapping in this NetSuite account and environment."}]}],"operations":[{"name":"List/Search Records","description":"List one page of a NetSuite record collection, optionally filtered with a q expression."},{"name":"Get Record","description":"Retrieve one NetSuite record by internal or external ID."},{"name":"Create Record","description":"Create a NetSuite record using the account-specific record metadata schema."},{"name":"Update Record","description":"Update fields on an existing NetSuite record with PATCH."},{"name":"Upsert Record","description":"Create or update a NetSuite record by external ID with PUT."},{"name":"Delete Record","description":"Delete one NetSuite record by internal or external ID."},{"name":"Get Subresource","description":"Retrieve a record sublist, subrecord, referenced record, or nested subresource."},{"name":"Get Record Form","description":"Return a prepopulated create form, or an edit form when a record ID is supplied."},{"name":"Get Select Options","description":"Retrieve valid select values for one or more fields on a new or existing record."},{"name":"Attach Record or File","description":"Attach a contact or file to another NetSuite record."},{"name":"Detach Record or File","description":"Detach a contact or file from another NetSuite record."},{"name":"Execute Record Action","description":"Execute a supported NetSuite record action such as approve, reject, or confirm."},{"name":"Transform Record","description":"Transform a supported source record into another NetSuite record type."},{"name":"Batch Get Records","description":"Submit an asynchronous request to retrieve up to 100 records of one type."},{"name":"Batch Create Records","description":"Submit an asynchronous batch that creates up to 100 records of one type."},{"name":"Batch Update Records","description":"Submit an asynchronous batch that updates up to 100 records of one type."},{"name":"Batch Upsert Records","description":"Submit an asynchronous batch that creates or updates up to 100 records by external ID."},{"name":"Batch Delete Records","description":"Submit an asynchronous request to delete up to 100 records of one type."},{"name":"Execute SuiteQL","description":"Execute one page of a SuiteQL query through SuiteTalk REST web services."},{"name":"List SuiteAnalytics Datasets","description":"List one page of SuiteAnalytics Workbook datasets available to the authenticated role."},{"name":"Execute SuiteAnalytics Dataset","description":"Execute one page of a standard or custom SuiteAnalytics Workbook dataset."},{"name":"List Record Types","description":"List record types exposed to the authenticated role by the REST metadata catalog."},{"name":"Get Record Metadata","description":"Retrieve account-specific metadata for one NetSuite record type."},{"name":"Get Async Status","description":"Retrieve job status, list job tasks, or retrieve one task status."},{"name":"Get Async Operation Result","description":"Retrieve the provider response for one task within a completed asynchronous job."},{"name":"Get Server Time","description":"Retrieve the current UTC time from the NetSuite server."},{"name":"Get Governance Limits","description":"Retrieve REST web-services concurrency limits for the NetSuite account and integration; NetSuite requires an Administrator role."}],"triggers":[],"skills":[{"name":"lookup-netsuite-records","description":"Find NetSuite records safely and retrieve the details needed by a workflow.","content":"# Look Up NetSuite Records\\n\\n## Steps\\n\\n1. Use List/Search Records with the exact record type and the narrowest supported q filter.\\n2. Keep limit at 100 unless the user requests another page; do not auto-fetch pages.\\n3. Use Get Record with the returned ID when full fields or subresources are needed.\\n\\n## Output\\n\\nReturn the record ID, requested business fields, and the page offset used."},{"name":"change-netsuite-records-with-metadata","description":"Use account metadata to prepare safe create, update, upsert, and transform bodies.","content":"# Change NetSuite Records with Metadata\\n\\n## Steps\\n\\n1. Get Record Metadata for the target record type, using JSON Schema when field structure is needed.\\n2. Construct only the documented fields required for the requested change.\\n3. Prefer Upsert Record with a stable external ID for synchronization.\\n4. Use Update Record for known internal IDs and include Replace Sublists only when replacement is intentional.\\n\\n## Output\\n\\nReport the HTTP status. Include Location for create and update when returned; retain the external ID for upserts and the source and target record context for transforms."},{"name":"query-netsuite-financial-data","description":"Run bounded, deterministic SuiteQL financial queries.","content":"# Query NetSuite Financial Data\\n\\n## Steps\\n\\n1. Write SuiteQL using NetSuite2.com record and field names.\\n2. Add a stable, unique ORDER BY clause whenever results may be paged.\\n3. Select only the fields needed for the report.\\n4. Execute one page with limit at most 1000 and an offset divisible by the limit.\\n\\n## Output\\n\\nState whether additional pages remain rather than fetching them automatically."},{"name":"synchronize-netsuite-records-in-batches","description":"Submit independent asynchronous record batches with idempotency keys.","content":"# Synchronize NetSuite Records in Batches\\n\\n## Steps\\n\\n1. Group only independent records by one NetSuite record type and operation.\\n2. Validate each record against NetSuite metadata and split input into batches of at most 100.\\n3. Use an idempotency key unique to each batch.\\n4. Submit the matching Batch Create, Update, Upsert, Get, or Delete operation.\\n\\n## Output\\n\\nPreserve the returned Location and job ID, inspect every task result, and report failures separately; do not treat submission as all-or-none success."},{"name":"monitor-netsuite-async-jobs","description":"Follow NetSuite asynchronous jobs through completion and retrieve task results.","content":"# Monitor NetSuite Async Jobs\\n\\n## Steps\\n\\n1. Use Get Async Status with the job ID parsed from the batch Location header and choose Job Status.\\n2. Wait until the documented completed state is true, then choose List Tasks and collect each task ID.\\n3. Choose Task Status to check each task separately.\\n4. Use Get Async Operation Result with both job ID and task ID.\\n\\n## Output\\n\\nReport failed task details separately and never resubmit without the original idempotency strategy."}],"templates":[{"title":"Synchronize NetSuite customers","prompt":"Build a scheduled workflow that queries customers changed since the last run, upserts them into the destination CRM by external ID, and stores the new NetSuite server time for the next sync.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Process NetSuite sales orders","prompt":"Create a workflow that looks up an approved NetSuite sales order, validates its lines, transforms it into an item fulfillment, and reports the completed transformation status.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Reconcile vendors and purchase orders","prompt":"Build a scheduled workflow that runs SuiteQL to compare open purchase orders with vendor records, flags missing or mismatched vendor details, and writes the reconciliation report to a table.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Monitor NetSuite inventory","prompt":"Create a scheduled workflow that uses SuiteQL to find inventory items below reorder point, enriches each item with its NetSuite record, and sends an operations digest.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Generate SuiteQL finance reports","prompt":"Build a workflow that accepts a reporting period, executes a bounded SuiteQL financial query with a stable ORDER BY clause, and stores the returned page in a table for review.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Export SuiteAnalytics datasets","prompt":"Create a scheduled workflow that lists available NetSuite SuiteAnalytics datasets, executes the selected dataset one page at a time, and writes each export page to a file.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]},{"title":"Import records with async batches","prompt":"Build a workflow that validates up to 100 homogeneous NetSuite records against metadata, submits an asynchronous batch upsert with an idempotency key, lists its tasks, checks each task, and retrieves every completed result.","integrations":[{"id":"netsuite","name":"Oracle NetSuite"}]}]},{"id":"otter","type":"otter","slug":"otter-ai","name":"Otter.ai","description":"Read Otter.ai meeting conversations, transcripts, and summaries","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/otter","authType":"api-key","connections":[],"operations":[{"name":"List Conversations","description":"List Otter conversations for the authenticated user, most recent first, optionally including shared conversations or filtering by channel."},{"name":"Get Conversation","description":"Get an Otter conversation with its summary and details, plus any requested action items, insights, outline, and transcript."},{"name":"Get Conversation Audio","description":"Get the MP3 audio download link for an Otter conversation."},{"name":"Import Recording","description":"Import an audio or video recording into Otter as a new conversation from a publicly reachable file URL."},{"name":"List Channels","description":"List the Otter channels available to the authenticated user, in alphabetical order."},{"name":"List Channel Members","description":"List the members of an Otter channel, in alphabetical order."},{"name":"Get Workspace","description":"Get the Otter workspace of the authenticated user, including its ID, name, owner, member count, handle, and type."},{"name":"List Workspace Conversations","description":"List every conversation in an Otter workspace, most recent first. Requires an Otter Super Admin API key in a workspace with Super Admin enabled."}],"triggers":[{"id":"otter_conversation_completed","name":"Otter Conversation Completed","description":"Trigger workflow when an Otter conversation shared to the webhook source finishes processing"},{"id":"otter_conversation_shared","name":"Otter Conversation Shared","description":"Trigger workflow when an existing Otter conversation is shared to the webhook source"},{"id":"otter_webhook","name":"Otter Webhook","description":"Trigger workflow on any Otter workspace webhook event"}],"skills":[{"name":"recap-otter-meeting","description":"Read an Otter conversation and write a recap with the summary, decisions, and action items with owners.","content":"# Recap Otter Meeting\\n\\nTurn one Otter conversation into a shareable recap.\\n\\n## Steps\\n1. If only a title is known, list conversations and match it to find the conversation ID.\\n2. Get the conversation, including action items, insights, and outline.\\n3. Use the abstract summary as the overview, the insights for decisions and risks, and the action items for follow-ups with their assignees.\\n\\n## Output\\nReturn the meeting title, a short overview, key decisions, and a list of action items with owners and completion status, plus the Otter link."},{"name":"sync-meeting-to-crm","description":"Prepare an Otter sales conversation for a CRM update, matching calendar guests to contacts.","content":"# Sync Meeting to CRM\\n\\nOtter recommends matching calendar guests to CRM contacts when syncing meetings.\\n\\n## Steps\\n1. Get the conversation with action items and insights.\\n2. Collect the calendar guest emails and the owner.\\n3. Draft a CRM note from the abstract summary and insights, and list next steps from the action items.\\n\\n## Output\\nReturn the guest emails to match, the CRM note text, and the next steps, ready to write to the CRM record."},{"name":"extract-otter-action-items","description":"Pull the action items from an Otter conversation into clean tasks for a project management tool.","content":"# Extract Otter Action Items\\n\\nConvert Otter action items into tasks.\\n\\n## Steps\\n1. Get the conversation, including action items.\\n2. Keep items that are not completed.\\n3. For each, write a task title from the text and use the assignee email as the owner.\\n\\n## Output\\nReturn a list of tasks with title, owner email, and a link back to the Otter conversation."},{"name":"audit-workspace-conversations","description":"As an Otter Super Admin, page through every conversation in the workspace and summarize activity.","content":"# Audit Workspace Conversations\\n\\nReview meeting activity across an Otter workspace (Super Admin only).\\n\\n## Steps\\n1. Get the workspace to find its ID.\\n2. List workspace conversations, following nextCursor while hasMore is true.\\n3. Group conversations by owner and note which have summaries finished.\\n\\n## Output\\nReturn conversation counts per owner, the most recent meetings, and any conversations still processing."}],"templates":[{"title":"Otter meeting recap to Slack","prompt":"Build a workflow that runs when an Otter conversation finishes processing, turns its summary, action items, and insights into a short recap, and posts it to the team Slack channel.","integrations":[{"id":"otter","name":"Otter.ai"},{"id":"slack","name":"Slack"}]},{"title":"Otter sales call to CRM","prompt":"Create a workflow triggered by an Otter conversation shared to the sales calls channel that matches calendar guests to HubSpot contacts and logs the meeting summary and next steps on the deal.","integrations":[{"id":"otter","name":"Otter.ai"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Otter action items to Linear","prompt":"Build a workflow that reads the action items of each completed Otter conversation and creates a Linear issue for every item, assigned to the matching teammate by email.","integrations":[{"id":"otter","name":"Otter.ai"},{"id":"linear","name":"Linear"}]},{"title":"Otter transcripts to knowledge base","prompt":"Create a scheduled workflow that lists new Otter conversations each day, fetches their transcripts and outlines, and adds them to a knowledge base so agents can answer questions about past meetings.","integrations":[{"id":"otter","name":"Otter.ai"}]},{"title":"Otter dialer call import","prompt":"Build a workflow that takes call recording URLs from a dialer export in a table and imports each one into Otter as a named conversation, recording the import status back in the table.","integrations":[{"id":"otter","name":"Otter.ai"}]},{"title":"Otter customer insight log","prompt":"Create a workflow that runs on every completed Otter customer call, extracts pain points, objections, and feature requests from the insights and transcript, and appends them to a research table.","integrations":[{"id":"otter","name":"Otter.ai"}]},{"title":"Otter weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists the week’s Otter conversations in a channel, summarizes recurring themes and decisions from their outlines, and emails the digest to the team.","integrations":[{"id":"otter","name":"Otter.ai"},{"id":"gmail","name":"Gmail"}]}]},{"id":"outlook","type":"outlook","slug":"outlook","name":"Outlook","description":"Send, read, search, reply, organize, and manage Outlook email and calendar","category":"Email","docsUrl":"https://docs.sim.ai/integrations/outlook","authType":"oauth","connections":[{"id":"outlook","kind":"oauth","label":"Connect with OAuth","providerId":"outlook","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/outlook","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Mail.ReadWrite","label":"Read, create, update, and delete your email"},{"id":"Mail.ReadBasic","label":"Read email properties, excluding body and attachments"},{"id":"Mail.Read","label":"Read your email"},{"id":"Mail.Send","label":"Send emails"},{"id":"Calendars.ReadWrite","label":"Read and manage Outlook calendar events"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Send Email","description":"Send emails using Outlook"},{"name":"Draft Email","description":"Draft emails using Outlook"},{"name":"Read Email","description":"Read emails from Outlook"},{"name":"Search Email","description":"Search Outlook messages using a free-text query (Microsoft Graph $search)"},{"name":"Reply to Email","description":"Reply to the sender of an Outlook message with a comment"},{"name":"Reply All","description":"Reply to all recipients of an Outlook message with a comment"},{"name":"Forward Email","description":"Forward an existing Outlook message to specified recipients"},{"name":"Move Email","description":"Move emails between Outlook folders"},{"name":"Copy Email","description":"Copy an Outlook message to another folder"},{"name":"Mark as Read","description":"Mark an Outlook message as read"},{"name":"Mark as Unread","description":"Mark an Outlook message as unread"},{"name":"Set Categories & Flag","description":"Set the categories, follow-up flag, and importance on an Outlook message"},{"name":"Delete Email","description":"Delete an Outlook message (move to Deleted Items)"},{"name":"List Folders","description":"List mail folders in the root of the Outlook mailbox"},{"name":"Create Folder","description":"Create a new mail folder in the root of the Outlook mailbox"},{"name":"List Attachments","description":"List the attachments on an Outlook message (metadata only, without contents)"},{"name":"Get Attachment","description":"Get a single attachment on an Outlook message, including its file contents"},{"name":"List Calendar Events","description":"List Outlook calendar events within a start/end time window"},{"name":"Get Calendar Event","description":"Get a single Outlook calendar event by ID"},{"name":"Create Event","description":"Create a new Outlook calendar event"},{"name":"Update Event","description":"Update an existing Outlook calendar event"},{"name":"Delete Event","description":"Delete an Outlook calendar event by ID"},{"name":"Respond to Invite","description":"Accept, tentatively accept, or decline an Outlook calendar event invitation"}],"triggers":[{"id":"outlook_poller","name":"Outlook Email Trigger","description":"Triggers when new emails are received in Outlook (requires Microsoft credentials)"}],"skills":[{"name":"send-email","description":"Compose and send an Outlook email to one or more recipients.","content":"# Send Email\\n\\nSend a message from the connected Outlook account.\\n\\n## Steps\\n1. Gather the recipients, subject, and the body content.\\n2. Write a clear subject and a concise, well-structured body.\\n3. Run Send Email with the recipients, subject, and body. Use Draft Email instead when the message should be reviewed before sending.\\n\\n## Output\\nConfirm the email was sent, listing recipients and subject. If drafted, note that it awaits review."},{"name":"triage-inbox","description":"Read recent Outlook emails and summarize which ones need a reply or action.","content":"# Triage Inbox\\n\\nTurn a noisy Outlook inbox into a short action list.\\n\\n## Steps\\n1. Run Read Email to pull recent unread messages.\\n2. Classify each as needs reply, needs action, FYI, or ignore.\\n3. For handled messages, run Mark as Read; leave items that still need a reply unread.\\n\\n## Output\\nA prioritized list of emails that need attention, each with sender, subject, and the suggested next action."},{"name":"forward-with-context","description":"Forward an Outlook email to the right person with an added note.","content":"# Forward with Context\\n\\nRoute an email to the correct owner with a short explanation.\\n\\n## Steps\\n1. Read the target email to capture its content with Read Email.\\n2. Identify the correct recipient for the topic.\\n3. Run Forward Email to that recipient, adding a brief note on why it is being forwarded and what is needed.\\n\\n## Output\\nConfirm the email was forwarded, to whom, and the note that was added."},{"name":"file-email-to-folder","description":"Move an Outlook email to the appropriate folder to keep the inbox clean.","content":"# File Email to Folder\\n\\nOrganize the inbox by moving a message into the right folder.\\n\\n## Steps\\n1. Identify the email and the destination folder.\\n2. Run Move Email to relocate the message.\\n3. Optionally run Mark as Read so it does not linger as unread.\\n\\n## Output\\nConfirm the email moved, naming the source and destination folders."},{"name":"schedule-meeting","description":"Create an Outlook calendar event and invite the right attendees.","content":"# Schedule Meeting\\n\\nPut a meeting on the calendar with the right people and context.\\n\\n## Steps\\n1. Gather the title, start and end times, attendees, and any agenda notes.\\n2. Run List Calendar Events over the proposed window to confirm the slot is free; pick another time if it is not.\\n3. Run Create Event with the subject, start, end, and attendee emails. Turn on Add Online Meeting when the attendees are remote (Teams; work or school accounts only).\\n\\n## Output\\nConfirm the event was created, naming the title, time, attendees, and the join link if one was added."},{"name":"summarize-agenda","description":"List Outlook calendar events for a time window and summarize the day.","content":"# Summarize Agenda\\n\\nTurn a calendar window into a short, readable agenda.\\n\\n## Steps\\n1. Determine the window (today, this week) as ISO 8601 start and end timestamps.\\n2. Run List Calendar Events for that window. Follow the returned nextLink if more pages are needed.\\n3. For each event, note the time, subject, organizer, attendees, and join link.\\n\\n## Output\\nA chronological agenda for the window, one line per meeting, calling out back-to-back blocks and any event with no agenda in its body."},{"name":"respond-to-invite","description":"Accept, tentatively accept, or decline an Outlook meeting invitation.","content":"# Respond to Invite\\n\\nDecide on a meeting invitation and reply to the organizer.\\n\\n## Steps\\n1. Run Get Calendar Event on the invite to read its time, organizer, and attendees.\\n2. Run List Calendar Events over the same window to check for conflicts.\\n3. Run Respond to Invite with accept, tentativelyAccept, or decline, adding a short comment when declining or proposing another time.\\n\\n## Output\\nState the response that was sent, the reason, and any conflicting meeting that drove the decision."},{"name":"reschedule-event","description":"Move an existing Outlook calendar event to a new time.","content":"# Reschedule Event\\n\\nShift a meeting and keep the attendees informed.\\n\\n## Steps\\n1. Run Get Calendar Event to read the current time, attendees, and body.\\n2. Run List Calendar Events over the proposed new window to confirm it is free.\\n3. Run Update Event with the new start and end. Send both bounds together so the window stays valid.\\n4. Optionally send the attendees a note explaining the change.\\n\\n## Output\\nConfirm the event moved, stating the old time, the new time, and who was notified."}],"templates":[{"title":"Dynamics stale deal follow-up","prompt":"Build a scheduled workflow that lists Dynamics 365 opportunities with old activity dates, retrieves customer context, drafts follow-up messages in Outlook, and updates the reviewed opportunities with your organization’s approved fields.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Dynamics case resolution","prompt":"Create a workflow that retrieves an approved Dynamics 365 case, records the resolution subject, notes, and time spent, resolves the case, and sends the customer a follow-up through Outlook.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Word proposal generator","prompt":"Create a workflow triggered by a closed-won HubSpot deal that generates a tailored proposal document in Word, exports it as PDF, and emails it to the customer contact.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Outlook auto-responder","prompt":"Build a workflow that monitors my Outlook inbox, drafts a contextual reply for every email that needs a response using my recent threads as tone reference, and saves each reply as an Outlook draft for me to review and send.","integrations":[{"id":"outlook","name":"Outlook"}]},{"title":"Outlook customer escalation to Zendesk","prompt":"Create a workflow that reads new Outlook emails from customers, classifies whether each one is a support issue, and when it is, creates a Zendesk ticket with the email body, attachments, and contact details, then replies from Outlook with the ticket number.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Outlook executive triage","prompt":"Build a scheduled workflow that scans Outlook every hour, ranks new emails by urgency, summarizes the top items, and posts a prioritized digest to a Slack channel so executives can act without opening the inbox.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"slack","name":"Slack"}]},{"title":"Outlook invoice extractor","prompt":"Build a workflow that monitors Outlook for invoice attachments, extracts vendor, amount, due date, and line items from each PDF, and logs the results to a tracking table while moving the original email to an Invoices folder.","integrations":[{"id":"outlook","name":"Outlook"}]},{"title":"Outlook follow-up reminder","prompt":"Create a workflow that scans Outlook for sent emails awaiting a reply older than three business days, drafts a polite follow-up email per thread, and saves each one as a draft in Outlook ready to send.","integrations":[{"id":"outlook","name":"Outlook"}]},{"title":"Outlook to JSM ticket router","prompt":"Build a workflow that reads support requests arriving in a shared Outlook mailbox, classifies the request type, and creates a Jira Service Management request in the correct service desk with the right request type, then replies from Outlook with the JSM portal link.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"Outlook newsletter clipper","prompt":"Create a workflow that reads newsletters arriving in Outlook, summarizes each one into key takeaways, and appends the digest to a daily Notion page so the inbox stays clean and the insights stay searchable.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"notion","name":"Notion"}]},{"title":"Outlook contract clause flagger","prompt":"Build a workflow that scans Outlook for inbound contracts and amendments, extracts key clauses (payment terms, liability, termination, renewal), flags deviations from my standard terms, and replies internally with a summary and red-flag list.","integrations":[{"id":"outlook","name":"Outlook"}]},{"title":"Outlook meeting scheduler","prompt":"Build a workflow that reads emails requesting a meeting, checks my Outlook calendar for the requested window, creates an Outlook calendar event with the sender as an attendee and a Teams link, and replies from Outlook confirming the time.","integrations":[{"id":"outlook","name":"Outlook"}]},{"title":"Outlook daily agenda digest","prompt":"Create a scheduled workflow that lists my Outlook calendar events for the day each morning, summarizes each meeting with its attendees and join link, and posts the agenda to a Slack DM before my first meeting.","integrations":[{"id":"outlook","name":"Outlook"},{"id":"slack","name":"Slack"}]},{"title":"Outlook invite auto-responder","prompt":"Build a workflow that reviews new Outlook meeting invitations, checks my calendar for conflicts in that time window, and accepts, tentatively accepts, or declines each invite with a short note to the organizer explaining the decision.","integrations":[{"id":"outlook","name":"Outlook"}]}]},{"id":"pagerduty","type":"pagerduty","slug":"pagerduty","name":"PagerDuty","description":"Manage incidents and on-call schedules with PagerDuty","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/pagerduty","authType":"api-key","connections":[],"operations":[{"name":"List Incidents","description":"List incidents from PagerDuty with optional filters."},{"name":"Get Incident","description":"Get a single incident from PagerDuty by ID."},{"name":"Create Incident","description":"Create a new incident in PagerDuty."},{"name":"Update Incident","description":"Update an incident in PagerDuty (acknowledge, resolve, change urgency, etc.)."},{"name":"Snooze Incident","description":"Snooze a triggered PagerDuty incident for a number of seconds, after which it returns to triggered."},{"name":"Merge Incidents","description":"Merge one or more source incidents into a target incident. Source incidents are resolved and their alerts move to the target."},{"name":"Add Note","description":"Add a note to an existing PagerDuty incident."},{"name":"List Incident Alerts","description":"List the individual alerts attached to a PagerDuty incident."},{"name":"List Services","description":"List services from PagerDuty with optional name filter."},{"name":"Get Service","description":"Get a single service from PagerDuty by ID."},{"name":"List On-Calls","description":"List current on-call entries from PagerDuty."},{"name":"List Escalation Policies","description":"List escalation policies from PagerDuty with an optional name filter."},{"name":"List Schedules","description":"List on-call schedules from PagerDuty with an optional name filter."},{"name":"List Users","description":"List users from PagerDuty with an optional name/email filter."},{"name":"Send Event","description":"Send a trigger, acknowledge, or resolve event to PagerDuty Events API v2 using a service integration key. Used to page from monitoring/alerting sources without a PagerDuty user account."}],"triggers":[{"id":"pagerduty_incident_triggered","name":"PagerDuty Incident Triggered","description":"Trigger workflow when a new incident is triggered in PagerDuty"},{"id":"pagerduty_incident_acknowledged","name":"PagerDuty Incident Acknowledged","description":"Trigger workflow when an incident is acknowledged in PagerDuty"},{"id":"pagerduty_incident_resolved","name":"PagerDuty Incident Resolved","description":"Trigger workflow when an incident is resolved in PagerDuty"},{"id":"pagerduty_incident_escalated","name":"PagerDuty Incident Escalated","description":"Trigger workflow when an incident is escalated in PagerDuty"},{"id":"pagerduty_incident_reassigned","name":"PagerDuty Incident Reassigned","description":"Trigger workflow when an incident is reassigned in PagerDuty"},{"id":"pagerduty_webhook","name":"PagerDuty Incident Event","description":"Trigger workflow from any PagerDuty incident event"}],"skills":[{"name":"open-incident","description":"Create a PagerDuty incident on a service with a title, urgency, and description so responders get paged.","content":"# Open Incident\\n\\nCreate a new PagerDuty incident and page the on-call responder.\\n\\n## Steps\\n1. Use the Create Incident operation with the target Service ID and a clear, specific Title summarizing the problem.\\n2. Set Urgency (high or low) based on customer impact and add a Description with affected systems, symptoms, and any error signatures.\\n3. Optionally set an Escalation Policy ID or Assignee User ID to route the page directly.\\n4. Capture the returned incident ID, number, and web URL for follow-up.\\n\\n## Output\\nReport the new incident number, urgency, assigned service, and the PagerDuty URL so the team can jump straight to the incident."},{"name":"triage-active-incidents","description":"List triggered and acknowledged PagerDuty incidents and produce a prioritized triage summary.","content":"# Triage Active Incidents\\n\\nReview what is currently on fire and summarize it for the team.\\n\\n## Steps\\n1. Use List Incidents filtered to Triggered then Acknowledged statuses, sorted by created at (newest first).\\n2. Optionally scope to specific Service IDs or a Since window to focus on a team or recent activity.\\n3. Group results by service and urgency, flagging high-urgency triggered incidents that are still unacknowledged.\\n4. For each, note title, age, status, and the responsible service.\\n\\n## Output\\nA prioritized list leading with unacknowledged high-urgency incidents, including incident number, service, age, and URL."},{"name":"resolve-and-note-incident","description":"Update a PagerDuty incident status and add a resolution note documenting what was done.","content":"# Resolve and Note Incident\\n\\nClose out an incident with a clear audit trail.\\n\\n## Steps\\n1. Use Update Incident with the Incident ID and set Status to acknowledged or resolved as appropriate.\\n2. Use Add Note on the same Incident ID to record the root cause, the fix applied, and any follow-up actions.\\n3. Provide a valid From Email (a real PagerDuty user) since these write operations require it.\\n4. Confirm the new status from the response.\\n\\n## Output\\nState the incident number, its new status, and a one-line summary of the note that was attached."},{"name":"check-whos-on-call","description":"List current PagerDuty on-call assignments for given schedules or escalation policies.","content":"# Check Who Is On Call\\n\\nFind the right person to reach right now.\\n\\n## Steps\\n1. Use List On-Calls, optionally scoped by Escalation Policy IDs or Schedule IDs.\\n2. Set a Since and Until window to look at the current or an upcoming shift.\\n3. Map each on-call entry to its escalation level so primary versus backup responders are clear.\\n\\n## Output\\nA concise roster: who is on call at level 1 (primary) and level 2 (backup) per schedule, with the time window covered."},{"name":"send-monitoring-event","description":"Trigger, acknowledge, or resolve a PagerDuty alert from a monitoring source using the Events API v2 integration key, without a PagerDuty user account.","content":"# Send Monitoring Event\\n\\nPage PagerDuty directly from a monitoring check or script.\\n\\n## Steps\\n1. Use Send Event with the target service\'s Integration Key and Event Action set to Trigger.\\n2. Provide a Summary, Source (the affected host/system), and Severity describing the problem.\\n3. Reuse the same De-duplication Key on later Acknowledge/Resolve events to update the same alert instead of opening a new one.\\n\\n## Output\\nReport the resulting status and the de-duplication key so follow-up events can reference the same alert."},{"name":"merge-duplicate-incidents","description":"Merge duplicate PagerDuty incidents from the same event into one target incident to reduce noise.","content":"# Merge Duplicate Incidents\\n\\nCollapse near-duplicate pages into a single incident.\\n\\n## Steps\\n1. Use List Incidents to identify incidents that describe the same underlying problem (same service, overlapping time window, similar title).\\n2. Pick the incident responders are already working as the Target Incident ID.\\n3. Use Merge Incidents with the Target Incident ID and the comma-separated Source Incident IDs to merge in; the sources are resolved automatically.\\n4. Provide a valid From Email since this is a write operation.\\n\\n## Output\\nConfirm the target incident number and status, and how many source incidents were merged into it."}],"templates":[{"title":"Kusto anomaly alerts","prompt":"Build a workflow that runs every 15 minutes, queries Azure Data Explorer for request failures grouped by endpoint, compares each endpoint against its own trailing baseline, and pages the on-call engineer through PagerDuty only when a real spike appears.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"CloudTrail trail health monitor","prompt":"Create a scheduled workflow that lists every AWS CloudTrail trail, checks each trail status for logging stopped or recent delivery errors, and opens a PagerDuty incident when a trail stops recording.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudWatch log triage","prompt":"Build a scheduled workflow that runs CloudWatch Logs Insights queries hourly for error patterns, clusters matches, writes top groups to a triage table, and pings the on-call engineer.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"CloudWatch SLO burn-rate watcher","prompt":"Create a workflow that monitors CloudWatch SLO burn rate every five minutes, classifies severity, and pages the on-call team via PagerDuty when burn exceeds fast-burn thresholds.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"CodePipeline flaky-stage retrier","prompt":"Build a scheduled workflow that finds failed CodePipeline executions, retries the failed stage once with failed-actions mode, and escalates to PagerDuty if the retry fails again.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"codepipeline","name":"CodePipeline"}]},{"title":"PagerDuty incident coordinator","prompt":"Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"CrowdStrike sensor coverage gaps","prompt":"Create a scheduled workflow that queries CrowdStrike Identity Protection sensors, identifies devices reporting an unprotected or degraded status, opens a PagerDuty incident for critical gaps, and posts the list to Slack.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"crowdstrike","name":"CrowdStrike"},{"id":"slack","name":"Slack"}]},{"title":"Databricks job runner","prompt":"Build a scheduled workflow that triggers a Databricks job daily, polls until completion, writes the run status and metrics to a control table, and pages on failure.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"databricks","name":"Databricks"}]},{"title":"Datadog deploy guardrail","prompt":"Build a workflow triggered after a deploy that creates a Datadog event marker, queries error-rate and latency timeseries over the next few minutes, and pages the team via PagerDuty if the metrics breach the rollback threshold.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"datadog","name":"Datadog"}]},{"title":"Dynatrace problem triage","prompt":"Build a scheduled workflow that polls Dynatrace every five minutes for open problems, pulls the root cause entity and recent logs for each one, summarizes the likely cause with an agent, and posts the enriched problem to Slack and PagerDuty.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"dynatrace","name":"Dynatrace"},{"id":"slack","name":"Slack"}]},{"title":"Elasticsearch log triage","prompt":"Build a scheduled workflow that runs saved Elasticsearch queries hourly for error patterns, clusters the matches, writes the top groups to a triage table, and pings on-call.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"Elasticsearch security event correlator","prompt":"Create a workflow that pulls Elasticsearch security events, correlates them across sources, and opens a CrowdStrike or PagerDuty incident on a confirmed pattern.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"elasticsearch","name":"Elasticsearch"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"BigQuery anomaly notifier","prompt":"Create a workflow that runs BigQuery anomaly-detection queries on key metrics hourly, writes any anomalies to a tracking table, and pages the on-call data team on severe deltas.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"PageSpeed CWV regression watcher","prompt":"Build a scheduled workflow that runs Google PageSpeed Insights daily for the top pages, captures Core Web Vitals, and pages on-call when LCP or CLS regress beyond threshold.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"Grafana alert auto-context","prompt":"Build a scheduled workflow that reads Grafana alert-state annotations to find rules that just started firing, queries the underlying data source for the current metric value, summarizes the two together with an agent, and posts the enriched alert to PagerDuty and Slack.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"grafana","name":"Grafana"},{"id":"slack","name":"Slack"}]},{"title":"Grafana incident annotator","prompt":"Build a scheduled workflow that polls PagerDuty for new incidents and adds Grafana annotations to relevant dashboards with the incident link, so engineers can see the context immediately on the timeline.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"grafana","name":"Grafana"}]},{"title":"incident.io commander","prompt":"Build a scheduled workflow that polls incident.io for newly declared incidents, opens a Slack war-room for each, invites responders from the on-call schedule, pulls related PagerDuty alerts, and pins the runbook.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"incidentio","name":"incident.io"},{"id":"slack","name":"Slack"}]},{"title":"JSM major incident broadcaster","prompt":"Build a workflow triggered when a major-incident request is created in Jira Service Management that pulls the affected service from PagerDuty, identifies the current on-call, posts a structured incident brief to a Slack war-room channel, and adds the responders as JSM request participants.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"jira_service_management","name":"Jira Service Management"},{"id":"slack","name":"Slack"}]},{"title":"Logfire latency watchdog","prompt":"Create a workflow that runs every 15 minutes, uses SQL against the Logfire records table to compute p95 duration per span_name over the window, compares it against the prior window stored in a table, and pages on-call through PagerDuty when latency regresses more than 50 percent.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"logfire","name":"Logfire"}]},{"title":"Teams incident war room","prompt":"Build a workflow triggered by a PagerDuty incident that creates a Microsoft Teams war-room channel, invites responders, posts the incident summary, and keeps the channel name in sync with incident state.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"New Relic incident war-room kickoff","prompt":"Create a workflow triggered by a PagerDuty incident that runs NRQL queries for the impacted service, pulls the latest deployment change event from New Relic, and posts a war-room summary with golden-signal charts to the incident Slack channel.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"new_relic","name":"New Relic"},{"id":"slack","name":"Slack"}]},{"title":"PagerDuty incident war room","prompt":"Build a scheduled workflow that polls PagerDuty for new severity-1 incidents, opens a Slack war-room channel, invites responders, posts the incident summary, and updates the channel topic with status.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"PagerDuty on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of PagerDuty incidents, MTTR, and on-call load by responder, and posts a Slack digest to the SRE channel.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"PagerDuty escalation auditor","prompt":"Build a scheduled weekly workflow that audits PagerDuty escalation policies, on-call schedules, and gaps in coverage, and writes a remediation backlog to a tracking table.","integrations":[{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PagerDuty postmortem starter","prompt":"Create a scheduled workflow that polls PagerDuty for newly resolved incidents and opens a postmortem doc for each with the timeline, responders, and Slack thread linked, ready for the team to fill in root cause.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"google_docs","name":"Google Docs"}]},{"title":"PagerDuty auto-triage enricher","prompt":"Build a scheduled workflow that polls PagerDuty for new incidents, pulls the affected service details, queries recent logs and the latest deploy, and posts an enriched triage summary with likely cause back as an incident note for the responder.","integrations":[{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PagerDuty customer-impact notifier","prompt":"Create a scheduled workflow that polls PagerDuty for incidents on customer-facing services, looks up affected accounts in Salesforce, and drafts a status-page update plus a Slack alert to the customer success team for high-impact outages.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"},{"id":"salesforce","name":"Salesforce"}]},{"title":"PagerDuty alert-to-ticket bridge","prompt":"Build a workflow that creates a PagerDuty incident from inbound monitoring alerts, opens a matching Linear issue with the same severity and links the two, and logs the pairing in a table so engineering can track alert-to-fix time.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"linear","name":"Linear"}]},{"title":"RabbitMQ queue depth alerting","prompt":"Create a scheduled workflow that lists RabbitMQ queues every five minutes, flags any queue whose depth exceeds its threshold or that has zero consumers, and opens a PagerDuty incident.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ cluster alarm watch","prompt":"Create a scheduled workflow that runs the RabbitMQ health checks every five minutes, lists cluster nodes for memory and disk alarms and network partitions, and pages on-call when an alarm fires.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"Reddit crisis-signal alerter","prompt":"Build a scheduled workflow that polls Reddit for sudden bursts of negative posts about the brand, classifies severity, and pages the PR team via Slack and PagerDuty when a real crisis emerges.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"reddit","name":"Reddit"},{"id":"slack","name":"Slack"}]},{"title":"Splunk alert to incident","prompt":"Create a scheduled workflow that polls Splunk fired alerts, deduplicates them by saved search, and opens a PagerDuty incident with the alert severity and the search ID attached.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"splunk","name":"Splunk"}]},{"title":"SQS alert enricher","prompt":"Create a workflow triggered by PagerDuty or Datadog alerts that classifies severity, decorates the payload with runbook context, and pushes the enriched alert to an Amazon SQS queue so multiple downstream notifiers and ticketing systems can consume it independently.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"sqs","name":"Amazon SQS"},{"id":"datadog","name":"Datadog"}]},{"title":"Telegram alert relay","prompt":"Build a workflow that listens for critical alerts from Sentry or PagerDuty and forwards a concise summary with severity, link, and the on-call person to a Telegram group.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"telegram","name":"Telegram"},{"id":"sentry","name":"Sentry"}]},{"title":"Temporal incident escalation bridge","prompt":"Create a workflow that signals a Temporal incident-response workflow with escalation details when a monitoring alert fires, using signal-with-start so a new incident workflow is created if one is not already running.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"temporal","name":"Temporal"}]},{"title":"Tinybird realtime metric watcher","prompt":"Build a workflow that polls a Tinybird pipe every minute for a realtime KPI, compares against a rolling baseline, and pages PagerDuty when the metric crosses a SLO threshold.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"tinybird","name":"Tinybird"}]},{"title":"Twilio incident escalation alerts","prompt":"Build a workflow triggered by a PagerDuty incident that sends a Twilio SMS to the on-call engineer with the service name and severity so critical alerts reach them even when they are away from Slack.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Twilio Voice incident dialer","prompt":"Create a workflow that on a PagerDuty severity-1 incident places a Twilio Voice call to the on-call engineer with an automated message, escalates to backup if no answer, and logs the cascade.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Upstash cache warmer","prompt":"Create a scheduled workflow that precomputes expensive query results and writes them into Upstash Redis with a TTL using SET, so hot paths stay warm and pages PagerDuty if a warm-up run fails.","integrations":[{"id":"pagerduty","name":"PagerDuty"},{"id":"upstash","name":"Upstash"}]}]},{"id":"parallel_ai","type":"parallel_ai","slug":"parallel-ai","name":"Parallel AI","description":"Web research with Parallel AI","category":"Search","docsUrl":"https://docs.sim.ai/integrations/parallel_ai","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search the web with Parallel AI and return matching pages with content excerpts."},{"name":"Extract from URLs","description":"Extract targeted information from specific URLs using Parallel AI. Processes provided URLs to pull relevant content based on your objective."},{"name":"Deep Research","description":"Research the web with Parallel AI and synthesize findings from multiple sources with citations. Can take up to 45 minutes to complete."}],"triggers":[],"skills":[{"name":"research-company-brief","description":"Run Parallel AI deep research on a company and produce a cited brief covering funding, leadership, and product.","content":"# Research Company Brief\\n\\nGenerate a sourced account brief for a target company.\\n\\n## Steps\\n1. Use the Deep Research operation with a Research Query naming the company and the angles to cover: recent funding, leadership changes, product launches, and notable news.\\n2. Choose an Output Format (Markdown report for prose, Structured JSON for fielded data), a processor tier (Pro for balance, Ultra for depth), and optionally constrain Include or Exclude Domains.\\n3. Read the content plus the basis field for citations and confidence per claim.\\n\\n## Output\\nA brief organized by topic, where every claim links to its source URL from the basis, and note any low-confidence items that need verification."},{"name":"web-search-with-objective","description":"Use Parallel AI search to answer a question across the web and return ranked, cited results.","content":"# Web Search With Objective\\n\\nAnswer a factual question grounded in fresh web sources.\\n\\n## Steps\\n1. Use the Search operation with one or more concise keyword Search Queries, and optionally an Objective describing what you want to know and which sources to prefer.\\n2. Optionally set a Search Mode (turbo, fast, basic, or advanced) and limit results with Include or Exclude Domains.\\n3. Tune Max Results and Max Chars Per Result for breadth versus depth.\\n\\n## Output\\nA direct answer to the objective followed by the supporting results, each with title, URL, and the relevant excerpt."},{"name":"extract-facts-from-urls","description":"Use Parallel AI extract to pull structured facts from a list of source URLs.","content":"# Extract Facts From URLs\\n\\nTurn a set of pages into structured data.\\n\\n## Steps\\n1. Use the Extract operation and provide the comma-separated URLs to read.\\n2. Set an Extract Objective describing exactly which fields to pull from each page.\\n3. Excerpts are always returned; enable Include Full Content only when the whole page text is needed.\\n\\n## Output\\nA normalized record per URL with the requested fields and an excerpt backing each value, plus a note on any URL that could not be parsed."},{"name":"monitor-competitor-news","description":"Search Parallel AI for recent announcements from named competitors and summarize the changes.","content":"# Monitor Competitor News\\n\\nTrack what rivals shipped or announced recently.\\n\\n## Steps\\n1. Use the Search operation with keyword Search Queries naming each competitor, plus an Objective describing the timeframe of interest.\\n2. Optionally restrict Include Domains to the competitors official sites and reputable news outlets.\\n3. For high-signal hits, follow up with the Extract operation to pull the specific details from each announcement URL.\\n\\n## Output\\nA dated digest grouped by competitor, each item a one-line summary with its source URL and why it matters."}],"templates":[{"title":"Parallel AI account research agent","prompt":"Build a workflow that takes a company name, runs Parallel AI deep research for recent funding, leadership changes, and product launches, and writes a structured account brief with citations back to the matching CRM record.","integrations":[{"id":"parallel_ai","name":"Parallel AI"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Parallel AI competitor monitor","prompt":"Create a scheduled workflow that uses Parallel AI search to find new announcements from a list of competitors, extracts the key details from each source URL, and posts a cited digest to Slack for the product team.","integrations":[{"id":"parallel_ai","name":"Parallel AI"},{"id":"slack","name":"Slack"}]},{"title":"Parallel AI URL fact extractor","prompt":"Build a workflow that reads a table of source URLs, uses Parallel AI extract to pull the structured facts requested for each page, and writes the normalized results back to the table for review.","integrations":[{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"Parallel AI market landscape report","prompt":"Create a workflow that runs Parallel AI deep research on a market category, synthesizes the players, pricing, and trends into a Markdown report file, and shares the link with the strategy team.","integrations":[{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"Parallel AI lead enrichment pipeline","prompt":"Build a workflow that runs Parallel AI search and extract on each new inbound lead to find company size, industry, and tech stack, scores fit against the ICP, and updates the lead record with the enriched profile.","integrations":[{"id":"parallel_ai","name":"Parallel AI"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Parallel AI due-diligence brief","prompt":"Create a workflow that runs Parallel AI deep research on a target company for litigation, leadership, and financial signals, extracts supporting detail from each cited source, and writes a due-diligence brief file for the deal team.","integrations":[{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"Parallel AI daily topic digest","prompt":"Build a scheduled daily workflow that uses Parallel AI search across the topics a team follows, extracts the key facts from the top results, and emails a concise cited digest each morning.","integrations":[{"id":"parallel_ai","name":"Parallel AI"},{"id":"gmail","name":"Gmail"}]}]},{"id":"peopledatalabs","type":"peopledatalabs","slug":"people-data-labs","name":"People Data Labs","description":"Enrich and search people and companies","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/peopledatalabs","authType":"api-key","connections":[],"operations":[{"name":"Person Enrich","description":"Enrich a single person profile using People Data Labs. Match by email, phone, LinkedIn URL, or name + company/location. Returns work history, contact details, location, and skills."},{"name":"Person Identify","description":"Return up to 20 candidate person matches with confidence scores. Useful when you want to see all plausible matches rather than the single best one. Reference: https://docs.peopledatalabs.com/docs/identify-api-quickstart"},{"name":"Person Search","description":"Search the People Data Labs person dataset using SQL or Elasticsearch DSL. Returns up to 100 matching records per call."},{"name":"Bulk Person Enrich","description":"Enrich up to 100 person records in a single call. Provide a JSON array of request objects, each with a `params` object (and optional `metadata` echoed back). Reference: https://docs.peopledatalabs.com/docs/bulk-person-enrichment-api"},{"name":"Company Enrich","description":"Enrich a single company using People Data Labs. Match by name, website, LinkedIn URL, ticker, or PDL ID."},{"name":"Company Search","description":"Search the People Data Labs company dataset using SQL or Elasticsearch DSL. Returns up to 100 matching companies per call."},{"name":"Bulk Company Enrich","description":"Enrich up to 100 companies in a single call. Provide a JSON array of request objects, each with a `params` object. Reference: https://docs.peopledatalabs.com/docs/bulk-company-enrichment-api"},{"name":"Company Cleaner","description":"Normalize a company string into a canonical company record. Provide at least one of name, website, or profile (LinkedIn URL)."},{"name":"Location Cleaner","description":"Normalize a freeform location string into a structured locality/region/country record with coordinates."},{"name":"School Cleaner","description":"Normalize a school string into a canonical school record. Provide at least one of name, website, or profile (LinkedIn URL)."},{"name":"Autocomplete","description":"Get autocomplete suggestions for a PDL field (title, skill, company, industry, location, school, major, role, sub_role)."}],"triggers":[],"skills":[{"name":"enrich-person","description":"Enrich a single person from an email, LinkedIn URL, or name plus company using People Data Labs.","content":"# Enrich Person\\n\\nFill in a full profile for one contact.\\n\\n## Steps\\n1. Use the Person Enrich operation and provide the strongest identifier available: Email or LinkedIn URL first, otherwise First and Last Name plus Company.\\n2. Set a Min Likelihood (for example 6) to avoid weak matches.\\n3. Read the matched person record for job title, seniority, company, location, and contact fields, and check the likelihood score.\\n\\n## Output\\nThe enriched profile (title, seniority, company, location, emails) plus the match likelihood; if not matched, say so and list which identifiers were tried."},{"name":"search-people-by-criteria","description":"Search the People Data Labs person dataset by role, location, or company using SQL or Elasticsearch DSL.","content":"# Search People By Criteria\\n\\nFind people matching a target profile.\\n\\n## Steps\\n1. Use the Person Search operation and write a SQL query (for example filter on job_title and location_country) or an Elasticsearch DSL query for finer control.\\n2. Set Result Size for the page, and optionally a Dataset filter (such as email or mobile_phone) to require certain coverage.\\n3. To page through more results, pass the returned scroll token on the next call.\\n\\n## Output\\nThe list of matched people with key fields, the total dataset match count, and the scroll token to fetch the next page."},{"name":"enrich-company","description":"Enrich a company from a name, website, or LinkedIn URL to get firmographics with People Data Labs.","content":"# Enrich Company\\n\\nBuild a firmographic profile for one company.\\n\\n## Steps\\n1. Use the Company Enrich operation and provide a Website (most reliable), Company Name, ticker, or LinkedIn URL.\\n2. Optionally add a Location or PDL Company ID to disambiguate common names, and set Min Likelihood.\\n3. Read the matched company record for industry, employee count, headquarters, and tech-related signals.\\n\\n## Output\\nThe company firmographics (industry, size, location, founded, website) with the match confidence noted."},{"name":"bulk-enrich-contacts","description":"Enrich many people or companies in one call with People Data Labs bulk enrichment.","content":"# Bulk Enrich Contacts\\n\\nEnrich a batch of records efficiently.\\n\\n## Steps\\n1. Use Bulk Person Enrich (or Bulk Company Enrich) and pass a JSON array of request objects, each with its own params such as a LinkedIn URL, email, or website.\\n2. Optionally set a Required Fields expression (for example emails AND job_title) so only records with that coverage are returned.\\n3. Iterate the results array in order, matching each result back to its input record.\\n\\n## Output\\nA per-record summary listing which inputs matched, the enriched fields returned, and which inputs had no match for follow-up."}],"templates":[{"title":"PDL person enricher","prompt":"Build a workflow that watches CRM contacts, enriches each via People Data Labs with role, seniority, and company signals, and writes the enriched data back.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"hubspot","name":"HubSpot"}]},{"title":"PDL company enricher","prompt":"Create a workflow that takes a list of company domains, runs People Data Labs company-search, and writes firmographics, employee count, and tech stack into a tables-based research base.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"PDL ICP scorer","prompt":"Build a workflow that scores inbound leads against the ICP using People Data Labs enrichment fields, routes high-fit leads to sales, and writes the score back to the CRM.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"salesforce","name":"Salesforce"}]},{"title":"PDL CRM gap-filler","prompt":"Create a scheduled workflow that finds CRM contacts missing key fields, runs People Data Labs to fill gaps, and writes coverage metrics to a hygiene table.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"hubspot","name":"HubSpot"}]},{"title":"PDL lookalike expander","prompt":"Build a workflow that derives firmographic attributes from a seed account list and uses People Data Labs company-search to find similar companies, expanding the TAM and writing the new prospects into Salesforce.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"salesforce","name":"Salesforce"}]},{"title":"PDL hiring-signal alerter","prompt":"Create a scheduled workflow that runs People Data Labs person-search for new hires in relevant roles at tracked accounts and posts a Slack alert when a match appears.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"slack","name":"Slack"}]},{"title":"PDL + Email Bison outbound","prompt":"Build a workflow that runs People Data Labs on prospects, drafts a personalized first-touch email based on enrichment fields, and sends via Email Bison.","integrations":[{"id":"peopledatalabs","name":"People Data Labs"},{"id":"emailbison","name":"Email Bison"}]}]},{"id":"perplexity","type":"perplexity","slug":"perplexity","name":"Perplexity","description":"Use Perplexity AI for chat and search","category":"AI","docsUrl":"https://docs.sim.ai/integrations/perplexity","authType":"api-key","connections":[],"operations":[{"name":"Chat","description":"Generate completions using Perplexity AI chat models"},{"name":"Search","description":"Get ranked search results from Perplexity\'s continuously refreshed index with advanced filtering and customization options"}],"triggers":[],"skills":[{"name":"answer-with-citations","description":"Ask Perplexity a question and get an answer grounded in current web sources with citations.","content":"# Answer With Citations\\n\\nGet a current, sourced answer to a question.\\n\\n## Steps\\n1. Use the Chat operation and write the question as the User Prompt. Add a System Prompt to set tone and require inline citations.\\n2. Pick a model: sonar for quick answers, sonar-pro for harder questions, or sonar-deep-research for thorough multi-source work.\\n3. Keep temperature low (around 0.2) for factual tasks and set Max Tokens to cap length.\\n\\n## Output\\nThe answer with its supporting sources, and a note flagging anything the model could not confirm."},{"name":"search-recent-news","description":"Use Perplexity search with a recency filter to find the latest results on a topic.","content":"# Search Recent News\\n\\nFind the freshest sources on a topic.\\n\\n## Steps\\n1. Use the Search operation and enter the topic as the Search Query.\\n2. Set a Recency Filter (hour, day, week, month, or year) or pin an After Date and Before Date window.\\n3. Optionally constrain a Domain Filter to trusted outlets and set a Country code for regional results.\\n4. Adjust Max Results for breadth.\\n\\n## Output\\nA dated list of results, each with title, URL, and a one-line summary, ordered by relevance and recency."},{"name":"domain-restricted-research","description":"Run a Perplexity search restricted to specific authoritative domains and summarize findings.","content":"# Domain-Restricted Research\\n\\nResearch a topic using only trusted sources.\\n\\n## Steps\\n1. Use the Search operation with a precise Search Query.\\n2. Set the Domain Filter to the allowed domains (comma-separated, up to twenty) such as official, academic, or .gov sites.\\n3. Tune Max Page Tokens to control how much text is pulled per source.\\n4. Synthesize the returned results into a short summary.\\n\\n## Output\\nA concise summary drawn only from the allowed domains, with each finding attributed to its source URL."}],"templates":[{"title":"DuckDuckGo agent fallback","prompt":"Create an agent that uses Perplexity for primary search and falls back to DuckDuckGo on rate-limit errors so research workflows remain reliable.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"Perplexity research briefer","prompt":"Build an agent that takes a topic or company name, runs deep web research via Perplexity with citations, and saves a structured brief file with sources, key findings, and open questions.","integrations":[{"id":"perplexity","name":"Perplexity"}]},{"title":"Daily news brief via Perplexity","prompt":"Create a scheduled daily workflow that queries Perplexity for the latest news on topics I follow, summarizes each thread with citations, and posts the digest to Slack.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"slack","name":"Slack"}]},{"title":"Perplexity multi-source research","prompt":"Create an agent that triangulates a topic across Perplexity, Exa, and Tavily, deduplicates findings, and produces a consensus brief with confidence scores per claim.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"exa","name":"Exa"},{"id":"tavily","name":"Tavily"}]},{"title":"Perplexity sales account refresh","prompt":"Create a scheduled workflow that walks accounts in my CRM, runs Perplexity research on each for new funding, headcount changes, or product launches, and writes the digest back to the account record.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Perplexity + DSPy structured-output evaluator","prompt":"Build a workflow that runs DSPy programs against a Perplexity-backed retrieval layer, evaluates outputs with Hugging Face and Mistral parsers, and writes regression scores to a tracking table.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"dspy","name":"DSPy"},{"id":"huggingface","name":"Hugging Face"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Perplexity + Hugging Face semantic dedup","prompt":"Build a workflow that runs Perplexity research, embeds findings with a Hugging Face encoder, deduplicates near-identical claims, and writes a clean research file.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"huggingface","name":"Hugging Face"}]},{"title":"Perplexity competitor-watch monitor","prompt":"Build a scheduled workflow that asks Perplexity for any new launches, pricing changes, or announcements from a list of competitors, summarizes what changed since last run, and posts a cited digest to a Slack channel for the product team.","integrations":[{"id":"perplexity","name":"Perplexity"},{"id":"slack","name":"Slack"}]}]},{"id":"persona","type":"persona","slug":"persona","name":"Persona","description":"Verify identities with Persona","category":"Security","docsUrl":"https://docs.sim.ai/integrations/persona","authType":"api-key","connections":[],"operations":[{"name":"Create Inquiry","description":"Create a new identity verification inquiry from an inquiry template. Returns the created inquiry, which can then be completed by the individual via a one-time link."},{"name":"Get Inquiry","description":"Retrieve a single identity verification inquiry by ID, including its status, collected fields, and decision timestamps."},{"name":"List Inquiries","description":"List identity verification inquiries, optionally filtered by status, account ID, reference ID, or creation date range. Results are cursor-paginated."},{"name":"Update Inquiry","description":"Update an inquiry’s note, fields, tags, or redirect URI. Only the provided values are changed."},{"name":"Approve Inquiry","description":"Approve an identity verification inquiry. Approving prevents further progress on the inquiry and triggers any associated workflows and webhooks."},{"name":"Decline Inquiry","description":"Decline an identity verification inquiry. Declining prevents further progress on the inquiry and triggers any associated workflows and webhooks."},{"name":"Mark Inquiry for Review","description":"Mark an identity verification inquiry for manual review, moving it to the needs_review status."},{"name":"Resume Inquiry","description":"Resume a pending or expired inquiry, creating a new session so the individual can continue verification. Returns a session token."},{"name":"Expire Inquiry","description":"Expire an in-progress inquiry, invalidating its sessions and one-time links so the individual can no longer continue it."},{"name":"Generate Inquiry Link","description":"Generate a one-time link for an inquiry that the individual can open to complete their identity verification."},{"name":"Print Inquiry PDF","description":"Download a PDF summary of an inquiry, including its collected information and verification results."},{"name":"Redact Inquiry","description":"Permanently delete all personally identifiable information collected by an inquiry, for example to honor a data deletion request. This cannot be undone."},{"name":"Create Account","description":"Create an account that represents an individual in Persona. Accounts consolidate inquiries, verifications, and reports for the same person."},{"name":"Get Account","description":"Retrieve a single account by ID, including its reference ID, fields, tags, and status."},{"name":"List Accounts","description":"List accounts in your Persona organization, optionally filtered by reference ID. Results are cursor-paginated."},{"name":"Update Account","description":"Update an account’s reference ID, country code, fields, or tags. Only the provided values are changed."},{"name":"Import Accounts (CSV)","description":"Bulk-import accounts into Persona from a CSV file. Returns an importer whose status can be polled until processing completes."},{"name":"Redact Account","description":"Permanently delete all personally identifiable information stored on an account, for example to honor a data deletion request. This cannot be undone."},{"name":"List Cases","description":"List manual review cases, optionally filtered by status, account ID, or reference ID. Results are cursor-paginated."},{"name":"Get Case","description":"Retrieve a single manual review case by ID, including its status, resolution, and assignee."},{"name":"Create Report","description":"Run a screening report (watchlist, adverse media, or politically exposed person) against an individual by name or search term."},{"name":"Get Report","description":"Retrieve a single screening report by ID, including its status, match results, and full type-specific attributes."},{"name":"List Reports","description":"List screening reports, optionally filtered by account ID or reference ID. Results are cursor-paginated."},{"name":"Get Verification","description":"Retrieve a single verification by ID (government ID, selfie, document, database, and more), including its status and the checks that ran."},{"name":"Get Document","description":"Retrieve a single document by ID (government ID, generic document, and more), including its processing status and uploaded files."},{"name":"List Inquiry Templates","description":"List the inquiry templates in your Persona organization, to discover template IDs for creating inquiries. Results are cursor-paginated."}],"triggers":[],"skills":[{"name":"verify-customer-identity","description":"Create a Persona inquiry for a customer and send them a one-time verification link.","content":"# Verify Customer Identity\\n\\nStart an identity verification for a customer using Persona.\\n\\n## Steps\\n1. Use the Create Inquiry operation with your inquiry template ID. Pass the customer reference ID so the inquiry links to an account in your user model, and pre-fill known fields (e.g. {\\"name-first\\": \\"Jane\\", \\"name-last\\": \\"Doe\\"}).\\n2. Use the Generate Inquiry Link operation with the new inquiry ID to mint a one-time verification link. Set a custom expiry only if the default (24 hours) does not fit.\\n3. Deliver the one-time link to the customer (email, SMS, or chat).\\n\\n## Output\\nReturn the inquiry ID, its status, and the one-time link. Note when the link expires so follow-ups can be scheduled."},{"name":"check-verification-status","description":"Look up a Persona inquiry and report whether the individual passed, failed, or needs review.","content":"# Check Verification Status\\n\\nRead the current state of an identity verification from Persona.\\n\\n## Steps\\n1. Use the Get Inquiry operation with the inquiry ID (or List Inquiries filtered by reference ID to find it).\\n2. Read the status: approved or completed means verified; needs_review means a human should look; failed, expired, or declined means not verified.\\n3. For deeper detail, use Get Verification with a verification ID to inspect the individual checks that ran.\\n\\n## Output\\nReturn the status, decision timestamps, and collected fields. Recommend the next action (proceed, route to review, or re-verify)."},{"name":"screen-against-watchlists","description":"Run a Persona watchlist, adverse media, or PEP report on a person and surface matches.","content":"# Screen Against Watchlists\\n\\nScreen an individual for sanctions, adverse media, or political exposure using Persona reports.\\n\\n## Steps\\n1. Use the Create Report operation with the report type (watchlist, adverse-media, or politically-exposed-person) and your report template ID. Provide the name parts or a full-name term, plus birthdate and country code when known to reduce false positives.\\n2. Reports run asynchronously: poll Get Report with the report ID until the status is ready.\\n3. Check hasMatch and the report attributes for matched lists and match details.\\n\\n## Output\\nReturn whether the screening found matches, the matched lists, and the report ID for the audit trail."},{"name":"triage-pending-reviews","description":"List Persona inquiries awaiting manual review and approve or decline them after assessment.","content":"# Triage Pending Reviews\\n\\nWork through identity verifications that need a manual decision in Persona.\\n\\n## Steps\\n1. Use the List Inquiries operation with status needs_review (optionally bounded by created-after/created-before).\\n2. For each inquiry, use Get Inquiry for collected fields and List Cases / Get Case to see any linked review case.\\n3. After assessment, use Approve Inquiry or Decline Inquiry. Both are final: they prevent further progress and trigger associated workflows and webhooks.\\n\\n## Output\\nReturn a summary of inquiries reviewed and the decision taken for each, with inquiry IDs for the audit trail."},{"name":"import-accounts-from-csv","description":"Bulk-import existing users into Persona as accounts from a CSV file.","content":"# Import Accounts from CSV\\n\\nMigrate an existing user base into Persona using the account importer.\\n\\n## Steps\\n1. Prepare a CSV of users (one row per account, with reference IDs and account fields).\\n2. Use the Import Accounts (CSV) operation with the file.\\n3. The importer runs asynchronously and returns pending at first; report the importer ID and counts once available.\\n\\n## Output\\nReturn the importer ID, status, and the successful, errored, and duplicate row counts."},{"name":"archive-verification-pdf","description":"Download the PDF summary of a Persona inquiry for compliance record-keeping.","content":"# Archive Verification PDF\\n\\nKeep a permanent record of an identity verification decision.\\n\\n## Steps\\n1. Use the Print Inquiry PDF operation with the inquiry ID.\\n2. The PDF lands in execution files; pass it to a storage integration (Google Drive, S3, SharePoint) named by customer reference ID and date.\\n\\n## Output\\nReturn the stored file and where it was archived."}],"templates":[{"title":"Persona onboarding verification","prompt":"Build a workflow triggered when a new customer signs up that creates a Persona inquiry from our KYC template with their name and email pre-filled, generates a one-time verification link, and emails it to the customer.","integrations":[{"id":"persona","name":"Persona"},{"id":"gmail","name":"Gmail"}]},{"title":"Persona decision router","prompt":"Build a workflow that takes an inquiry ID, fetches the inquiry from Persona, and routes on its status: approved customers get a welcome email, needs-review inquiries post to a compliance Slack channel with a summary, and declined inquiries update our CRM.","integrations":[{"id":"persona","name":"Persona"},{"id":"slack","name":"Slack"},{"id":"gmail","name":"Gmail"}]},{"title":"Persona pending-review digest","prompt":"Build a scheduled workflow that runs every morning, lists Persona inquiries with needs_review status from the last 24 hours, summarizes each one, and posts a digest to the compliance team in Slack.","integrations":[{"id":"persona","name":"Persona"},{"id":"slack","name":"Slack"}]},{"title":"Persona watchlist screening","prompt":"Build a workflow that takes a new user\'s name and birthdate, runs a Persona watchlist report against them, polls until the report is ready, and creates a case in our tracking table if the report has a match.","integrations":[{"id":"persona","name":"Persona"}]},{"title":"Persona bulk account import","prompt":"Build a workflow that takes an uploaded CSV export of customers, imports them into Persona as accounts using the account importer, polls the importer status, and reports how many rows succeeded, errored, or were duplicates.","integrations":[{"id":"persona","name":"Persona"}]},{"title":"Persona audit PDF archive","prompt":"Build a workflow that takes an approved inquiry ID, downloads the inquiry summary PDF from Persona, and uploads it to a compliance archive folder in Google Drive named by customer reference ID.","integrations":[{"id":"persona","name":"Persona"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Persona case triage agent","prompt":"Build an agent that lists open Persona cases, fetches the linked inquiry and verification details for each, drafts a recommended approve/decline decision with reasoning, and posts the triage summary to Slack for a human reviewer.","integrations":[{"id":"persona","name":"Persona"},{"id":"slack","name":"Slack"}]},{"title":"Persona re-verification campaign","prompt":"Build a scheduled workflow that lists Persona accounts, finds ones whose latest approved inquiry is older than a year, creates a new inquiry for each from our re-verification template, and emails customers a one-time verification link.","integrations":[{"id":"persona","name":"Persona"},{"id":"gmail","name":"Gmail"}]}]},{"id":"pinecone","type":"pinecone","slug":"pinecone","name":"Pinecone","description":"Use Pinecone vector database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/pinecone","authType":"api-key","connections":[],"operations":[{"name":"Generate Embeddings","description":"Generate embeddings from text using Pinecone\'s hosted models"},{"name":"Upsert Text","description":"Insert or update text records in a Pinecone index"},{"name":"Update Vector","description":"Update the values, sparse values, or metadata of a vector in a Pinecone namespace"},{"name":"Delete Vectors","description":"Delete vectors from a Pinecone namespace by IDs, by metadata filter, or delete all"},{"name":"Search With Text","description":"Search for similar text in a Pinecone index"},{"name":"Search With Vector","description":"Search for similar vectors in a Pinecone index"},{"name":"Fetch Vectors","description":"Fetch vectors by ID from a Pinecone index"},{"name":"List Vector IDs","description":"List vector IDs in a Pinecone namespace by prefix (serverless indexes only)"},{"name":"Describe Index Stats","description":"Get statistics about a Pinecone index, including per-namespace vector counts"},{"name":"List Indexes","description":"List all Pinecone indexes in the project"},{"name":"Describe Index","description":"Get the configuration and status of a Pinecone index by name"}],"triggers":[],"skills":[{"name":"upsert-text-records","description":"Embed and upsert text records into a Pinecone namespace using integrated embeddings.","content":"# Upsert Text Records\\n\\nLoad documents into a Pinecone index for retrieval.\\n\\n## Steps\\n1. Use the Upsert Text operation and provide the Index Host and target Namespace.\\n2. Pass newline-delimited JSON Records, each with a unique _id, a text or chunk_text field, and any metadata fields such as category for later filtering.\\n3. Keep chunks reasonably sized so each record carries one coherent idea.\\n4. Confirm the upsert status from the response.\\n\\n## Output\\nReport how many records were upserted into which namespace and surface any records that failed validation."},{"name":"semantic-search","description":"Run a text query against a Pinecone index with metadata filtering and optional reranking.","content":"# Semantic Search\\n\\nRetrieve the most relevant records for a query.\\n\\n## Steps\\n1. Use the Search With Text operation with the Index Host, Namespace, and a natural-language Search Query.\\n2. Set Top K for how many matches to return and list the Fields to Return.\\n3. Optionally apply a metadata Filter (operators like $eq, $in, $gte) to scope the search, and pass Rerank Options to reorder by a cross-encoder for higher precision.\\n\\n## Output\\nThe top matches with their scores, returned fields, and IDs, ordered by relevance after any reranking."},{"name":"generate-embeddings","description":"Generate vector embeddings for a set of texts with a Pinecone-hosted embedding model.","content":"# Generate Embeddings\\n\\nTurn text into vectors for storage or comparison.\\n\\n## Steps\\n1. Use the Generate Embeddings operation and choose a model such as multilingual-e5-large or llama-text-embed-v2.\\n2. Provide the Text Inputs as a JSON array of objects each with a text field.\\n3. Use the returned vectors for downstream upserts or similarity work.\\n\\n## Output\\nThe embedding vector per input, the model used, and the usage statistics for cost tracking."},{"name":"fetch-vectors-by-id","description":"Fetch specific vectors and their metadata from a Pinecone namespace by ID.","content":"# Fetch Vectors By ID\\n\\nLook up known records directly.\\n\\n## Steps\\n1. Use the Fetch Vectors operation with the Index Host and Namespace.\\n2. Provide the Vector IDs as a JSON array of the records to retrieve.\\n3. Inspect the returned values and metadata to confirm content or debug retrieval.\\n\\n## Output\\nThe requested records with their stored metadata, and a note listing any IDs that were not found."}],"templates":[{"title":"Document embedding pipeline","prompt":"Build a workflow that watches a files folder, chunks each new document, generates embeddings, and upserts vectors into Pinecone with rich metadata for retrieval.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Knowledge base re-embedder","prompt":"Create a scheduled workflow that finds documents whose embeddings are stale, regenerates them, and re-upserts the vectors into Pinecone so retrieval stays current.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Product catalog semantic search","prompt":"Create a workflow that embeds each product description from a table, upserts the vectors into Pinecone, and lets an incoming query return the closest matching products by similarity.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Semantic ticket deduplication","prompt":"Build a workflow that embeds each new support ticket, searches a Pinecone index of past tickets for near-duplicates, and links the new ticket to the matching thread instead of opening a fresh one.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"MongoDB to vector enrichment","prompt":"Build a scheduled workflow that polls a MongoDB collection for new documents, generates OpenAI embeddings, and upserts them into Pinecone with the source document ID for retrieval.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"mongodb","name":"MongoDB"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Document embedding pipeline","prompt":"Build a workflow that watches a files folder, chunks each new document, generates embeddings with OpenAI, and upserts vectors into Pinecone with rich metadata for retrieval.","integrations":[{"id":"pinecone","name":"Pinecone"}]},{"title":"Knowledge base re-embedder","prompt":"Create a scheduled workflow that finds documents whose embeddings are stale, regenerates them with OpenAI, and re-upserts the vectors into Pinecone so retrieval stays current.","integrations":[{"id":"pinecone","name":"Pinecone"}]},{"title":"Product catalog semantic search","prompt":"Create a workflow that embeds each product description from a table with OpenAI, upserts the vectors into Pinecone, and lets an incoming query return the closest matching products by similarity.","integrations":[{"id":"pinecone","name":"Pinecone"}]},{"title":"Semantic ticket deduplication","prompt":"Build a workflow that embeds each new support ticket with OpenAI, searches a Pinecone index of past tickets for near-duplicates, and links the new ticket to the matching thread instead of opening a fresh one.","integrations":[{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone reindex pipeline","prompt":"Build a scheduled workflow that regenerates embeddings with OpenAI for new or changed source documents and upserts the vectors into a Pinecone index so retrieval stays current.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Pinecone semantic search agent","prompt":"Create an agent that takes a natural-language query, embeds it with OpenAI, retrieves top-k matches from Pinecone, and answers with cited passages plus a confidence score.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Pinecone retrieval-quality monitor","prompt":"Build a scheduled weekly workflow that runs a fixed set of benchmark queries against a Pinecone index, records top-k similarity scores per namespace to a table, and pings Slack when retrieval quality regresses.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"slack","name":"Slack"}]},{"title":"Pinecone duplicate detector","prompt":"Create a workflow that reads a table of candidate records, embeds each with OpenAI, searches a Pinecone index for matches above a similarity threshold, and writes the near-duplicates to a cleanup queue.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Pinecone tenant isolation auditor","prompt":"Build a workflow that verifies Pinecone namespace isolation by sampling cross-namespace queries, ensuring no leakage, and writing a compliance audit report each week.","integrations":[{"id":"pinecone","name":"Pinecone"}]},{"title":"Pinecone FAQ deflection bot","prompt":"Create a workflow that embeds an incoming question with OpenAI, searches a Pinecone index of FAQ entries for the closest match, and returns the answer when similarity is high or escalates when it is not.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Pinecone support knowledge retriever","prompt":"Build a workflow that fetches each new Zendesk ticket, embeds the question with OpenAI, queries a Pinecone index of resolved tickets and docs, and drafts a suggested reply citing the most relevant matches for the agent to approve.","integrations":[{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"},{"id":"zendesk","name":"Zendesk"}]}]},{"id":"pipedrive","type":"pipedrive","slug":"pipedrive","name":"Pipedrive","description":"Manage Pipedrive deals, leads, activities, and projects","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/pipedrive","authType":"oauth","connections":[{"id":"pipedrive","kind":"oauth","label":"Connect with OAuth","providerId":"pipedrive","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/pipedrive","requiredScopes":[{"id":"base","label":"Basic access to Pipedrive account"},{"id":"deals:full","label":"Full access to manage Pipedrive deals"},{"id":"contacts:full","label":"Full access to manage Pipedrive contacts"},{"id":"leads:full","label":"Full access to manage Pipedrive leads"},{"id":"activities:full","label":"Full access to manage Pipedrive activities"},{"id":"mail:full","label":"Full access to manage Pipedrive emails"},{"id":"projects:full","label":"Full access to manage Pipedrive projects"}],"fields":[]},{"id":"pipedrive-service-account","kind":"service_account","providerId":"pipedrive-service-account","label":"Add API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/pipedrive-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste personal API token","secret":true}]}],"operations":[{"name":"Get All Deals","description":"Retrieve all deals from Pipedrive with optional filters"},{"name":"Get Deal","description":"Retrieve detailed information about a specific deal"},{"name":"Create Deal","description":"Create a new deal in Pipedrive"},{"name":"Update Deal","description":"Update an existing deal in Pipedrive"},{"name":"Get Files","description":"Retrieve files from Pipedrive with optional filters"},{"name":"Get Mail Threads","description":"Retrieve mail threads from Pipedrive mailbox"},{"name":"Get Mail Thread Messages","description":"Retrieve all messages from a specific mail thread"},{"name":"Get Pipelines","description":"Retrieve all pipelines from Pipedrive"},{"name":"Get Pipeline Deals","description":"Retrieve all deals in a specific pipeline"},{"name":"Get Projects","description":"Retrieve all projects or a specific project from Pipedrive"},{"name":"Create Project","description":"Create a new project in Pipedrive"},{"name":"Get Activities","description":"Retrieve activities (tasks) from Pipedrive with optional filters"},{"name":"Create Activity","description":"Create a new activity (task) in Pipedrive"},{"name":"Update Activity","description":"Update an existing activity (task) in Pipedrive"},{"name":"Get Leads","description":"Retrieve all leads or a specific lead from Pipedrive"},{"name":"Create Lead","description":"Create a new lead in Pipedrive"},{"name":"Update Lead","description":"Update an existing lead in Pipedrive"},{"name":"Delete Lead","description":"Delete a specific lead from Pipedrive"}],"triggers":[],"skills":[{"name":"create-deal","description":"Create a Pipedrive deal with a title, value, pipeline stage, and linked person or organization.","content":"# Create Deal\\n\\nAdd a new opportunity to the sales pipeline.\\n\\n## Steps\\n1. Use the Create Deal operation with a clear Title.\\n2. Set Value and Currency, the target Pipeline and Stage ID, and Status (open, won, or lost).\\n3. Link the deal to a Person ID or Organization ID, and set an Expected Close Date.\\n4. Capture the returned deal ID for follow-up activities.\\n\\n## Output\\nConfirm the new deal title, value, pipeline stage, and ID so it can be referenced in later steps."},{"name":"review-pipeline","description":"List Pipedrive deals in a pipeline and summarize stage distribution and deals at risk.","content":"# Review Pipeline\\n\\nGet a snapshot of the current sales pipeline.\\n\\n## Steps\\n1. Use Get All Deals (or Get Pipeline Deals for one pipeline) filtered to open status.\\n2. Optionally scope by Pipeline, Person ID, or Organization ID and set Updated Since to focus on recent movement.\\n3. Group deals by stage and total their value, flagging stale deals with no recent update.\\n4. Page with the cursor or start offset for large pipelines.\\n\\n## Output\\nA stage-by-stage breakdown with deal counts and total value, plus a short list of at-risk deals that have gone quiet."},{"name":"log-activity","description":"Create a Pipedrive activity such as a call, meeting, or task linked to a deal or contact.","content":"# Log Activity\\n\\nSchedule or record follow-up work against a record.\\n\\n## Steps\\n1. Use the Create Activity operation with a Subject and an activity Type (call, meeting, task, deadline, email, or lunch).\\n2. Set the Due Date and optional Due Time, Duration, and Notes.\\n3. Link the activity to the relevant Deal ID, Person ID, or Organization ID.\\n4. Use Update Activity later to mark it done.\\n\\n## Output\\nConfirm the activity subject, type, due date, and the record it is linked to."},{"name":"manage-leads","description":"Create or update Pipedrive leads with value, contacts, and expected close date.","content":"# Manage Leads\\n\\nCapture and maintain top-of-funnel leads.\\n\\n## Steps\\n1. Use Create Lead with a Title and link a Person ID or Organization ID and an Owner ID.\\n2. Set the Value Amount and Value Currency and an Expected Close Date.\\n3. Use Update Lead to revise details or archive a lead once it converts or goes cold.\\n4. Use Get Leads to review active or archived leads.\\n\\n## Output\\nThe lead title, linked contact, value, and current state (active or archived) with its ID."}],"templates":[{"title":"Pipedrive deal pipeline tracker","prompt":"Create a scheduled workflow that mirrors Pipedrive deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"slack","name":"Slack"}]},{"title":"Pipedrive lead enrichment pipeline","prompt":"Build a scheduled workflow that polls Pipedrive for new leads, enriches each via Apollo with role, seniority, and tech stack, and updates the lead with the enriched details.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"apollo","name":"Apollo"}]},{"title":"Pipedrive activity-from-email logger","prompt":"Create a workflow that watches Gmail for emails to or from Pipedrive contacts, logs each as an activity, and creates a follow-up task if next steps are mentioned.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"gmail","name":"Gmail"}]},{"title":"Pipedrive call-summary updater","prompt":"Build a workflow that runs after a Fireflies sales call, summarizes the transcript, and updates the matching Pipedrive deal with the call summary and next steps.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"fireflies","name":"Fireflies"}]},{"title":"Pipedrive win/loss analyzer","prompt":"Create a scheduled monthly workflow that pulls closed Pipedrive deals, analyzes patterns in wins vs losses, and writes an insights report file for the sales team.","integrations":[{"id":"pipedrive","name":"Pipedrive"}]},{"title":"Pipedrive renewal forecast","prompt":"Build a workflow that pulls Pipedrive customer renewals due in the next 90 days, generates a personalized renewal-prep brief, and emails the account owner.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"gmail","name":"Gmail"}]},{"title":"Pipedrive Slack channel-per-deal","prompt":"Create a workflow that for Pipedrive deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.","integrations":[{"id":"pipedrive","name":"Pipedrive"},{"id":"slack","name":"Slack"}]}]},{"id":"pitchbook","type":"pitchbook","slug":"pitchbook","name":"PitchBook","description":"Look up private market data on companies, deals, investors, funds, and people","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/pitchbook","authType":"api-key","connections":[],"operations":[{"name":"Search All Entities","description":"Search across every PitchBook entity type at once by name, PitchBook ID, website, or ticker. Use this to resolve a company, investor, or fund to its PitchBook ID before calling a profile operation."},{"name":"Shared Search","description":"Extract the names and PitchBook IDs behind an Advanced Search shared from the PitchBook platform, using the search ID and hash from the shared link"},{"name":"Get Entity People","description":"Retrieve the people at an entity: primary contact, current and former team, and current and former board members"},{"name":"Get Entity Locations","description":"Retrieve the headquarters and every alternate office on record for an entity"},{"name":"Get Entity Affiliates","description":"Retrieve the affiliated entities linked to an entity and how each is related"},{"name":"Get Entity News","description":"Retrieve recent news articles PitchBook has associated with an entity"},{"name":"Get Entity Updates","description":"Check which entity datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Companies","description":"Search PitchBook for companies by name, location, industry, funding, deal activity, and more"},{"name":"Get Company Bio","description":"Retrieve the core profile of a company: names, description, HQ, status, headcount, total raised, and social links"},{"name":"Get Company Industries","description":"Retrieve the industry classification, verticals, keywords, and emerging spaces assigned to a company"},{"name":"Get Company Investors","description":"Retrieve every investor in a company, current and former, with the type of investor and when they invested"},{"name":"Get Company Active Investors","description":"Retrieve only the investors currently holding a position in a company"},{"name":"Get Company Deals","description":"Retrieve every deal a company has been involved in, in chronological order with its deal type"},{"name":"Get Company Latest Financing","description":"Retrieve a company’s most recent financing round: date, size, type, and last known valuation"},{"name":"Get Company Latest Debt Financing","description":"Retrieve a company’s most recent debt financing, including each debt instrument raised"},{"name":"Get Company Latest Financials","description":"Retrieve the most recent reported financials for a private company: revenue, net income, EBITDA, assets, and debt"},{"name":"Get Company Financials History","description":"Retrieve reported financials for a private company across every available fiscal period. Annual data is returned by default."},{"name":"Get Similar Companies","description":"Retrieve companies PitchBook scores as similar to a given company, flagging which are direct competitors"},{"name":"Get VC Exit Predictions","description":"Retrieve PitchBook machine-learning exit predictions for a VC-backed company. Requires at least two funding rounds in the past six years."},{"name":"Get Company Social Analytics","description":"Retrieve web and social growth and size metrics for a company, with percentile ranks"},{"name":"Get Company Service Providers","description":"Retrieve the current and former general service providers engaged by a company"},{"name":"Get Company Deal Service Providers","description":"Retrieve the service providers that worked on a company’s deals, and what each was hired for"},{"name":"Get Company Updates","description":"Check which company datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Company Patents","description":"Search the patents held by a company by status, filing and publication date, authority, and CPC classification"},{"name":"Get Patent Detail","description":"Retrieve the full record for a single patent: title, status, dates, assignees, inventors, citations, and claim counts"},{"name":"Search Deals","description":"Search PitchBook for deals by company, investor, deal type, size, date, and valuation"},{"name":"Get Deal Bio","description":"Retrieve the summary of a deal: company, date, size, status, type, and which detail datasets are available for it"},{"name":"Get Deal Detail","description":"Retrieve the full detail of a deal: synopsis, percent acquired, round, invested capital, ownership, debt, and stock split"},{"name":"Get Deal Valuation","description":"Retrieve the pre-money and post-money valuation recorded for a deal"},{"name":"Get Deal Multiples","description":"Retrieve the valuation multiples for a deal against revenue, EBITDA, EBIT, cash flow, and net income"},{"name":"Get Deal Investors","description":"Retrieve the investors, sellers, and exiting investors on a deal, including who led it"},{"name":"Get Deal Stock Info","description":"Retrieve the share terms of a deal: price per share, shares acquired, and the preference, dividend, and voting rights attached"},{"name":"Get Deal Cap Table","description":"Retrieve the cap table as of a deal, one row per stock series with its terms and ownership"},{"name":"Get Deal Tranches","description":"Retrieve the tranches a deal was funded in, with each tranche’s date, size, and investors"},{"name":"Get Deal Debt and Lenders","description":"Retrieve the debt raised in a deal and the lenders behind it, with rate, maturity, seniority, and covenant terms"},{"name":"Get Deal Service Providers","description":"Retrieve the service providers that worked on a deal and which party each represented"},{"name":"Get Deal Updates","description":"Check which deal datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Investors","description":"Search PitchBook for investors by type, location, assets under management, fund profile, and deal activity"},{"name":"Get Investor Bio","description":"Retrieve the core profile of an investor: names, description, HQ, type, AUM, dry powder, and headcount"},{"name":"Get Investor Investments","description":"Retrieve every investment an investor has made, active and exited, with the deals that opened and closed each position"},{"name":"Get Investor Active Investments","description":"Retrieve only the positions an investor still holds"},{"name":"Get Investor Funds","description":"Retrieve the funds an investor manages, with open and closed counts and the min, median, and max fund size"},{"name":"Get Investor Last Closed Fund","description":"Retrieve the most recently closed fund raised by an investor, with its size, type, and vintage"},{"name":"Get Investor Preferences","description":"Retrieve what an investor targets: check size, deal size, valuation, revenue, geography, industry, and deal type preferences"},{"name":"Get Investor Board Seats","description":"Retrieve the board seats an investor holds and previously held across its portfolio"},{"name":"Get Investor Service Providers","description":"Retrieve the current and former general service providers engaged by an investor"},{"name":"Get Investor Deal Service Providers","description":"Retrieve the service providers that worked on an investor’s deals, and what each was hired for"},{"name":"Get Investor Updates","description":"Check which investor datasets changed in a window, so a sync only refetches what moved"},{"name":"Search People","description":"Search PitchBook for people by name, employer, position, education, and location"},{"name":"Get Person Bio","description":"Retrieve the profile of a person: name, biography, LinkedIn, primary employer, position, and office"},{"name":"Get Person Contact","description":"Retrieve the direct contact details on file for a person"},{"name":"Get Person History","description":"Retrieve a person’s full history: education, company roles, board seats, deal roles, and fund roles"},{"name":"Search Funds","description":"Search PitchBook for funds by manager, type, size, vintage, and performance"},{"name":"Get Fund Bio","description":"Retrieve the profile of a fund: managers, vintage, status, type, size, target, location, and team"},{"name":"Get Fund Performance","description":"Retrieve the most recent reported returns for a fund: IRR, DPI, RVPI, TVPI, NAV, and benchmark quartile"},{"name":"Get Fund Benchmark","description":"Retrieve the peer benchmark for a fund: benchmark IRR, DPI, TVPI, RVPI, and the funds it is drawn from"},{"name":"Get Fund Cash Flows","description":"Retrieve contributed, distributed, and remaining value for a fund as of a specific quarter"},{"name":"Get Fund Investments","description":"Retrieve every investment a fund has made, active and exited, with the deals that opened and closed each position"},{"name":"Get Fund Active Investments","description":"Retrieve only the portfolio positions a fund still holds"},{"name":"Get Fund Commitments","description":"Retrieve the limited partners committed to a fund, with commitment date, size, status, and type"},{"name":"Get Fund Preferences","description":"Retrieve what a fund targets: check size, valuation, geography, industry, vertical, and deal type preferences"},{"name":"Get Fund Team","description":"Retrieve the active and former people on a fund’s team"},{"name":"Get Fund Updates","description":"Check which fund datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Limited Partners","description":"Search PitchBook for limited partners by type, location, assets under management, and commitment activity"},{"name":"Get Limited Partner Bio","description":"Retrieve the profile of a limited partner: names, description, type, assets under management, and staff"},{"name":"Get LP Commitments","description":"Retrieve every fund commitment a limited partner has made, with date, size, status, and the managers behind each fund"},{"name":"Get LP Commitment Totals","description":"Retrieve a limited partner’s commitments rolled up by fund type, both active and all-time"},{"name":"Get LP Commitment Preferences","description":"Retrieve what a limited partner commits to: preferred commitment size, fund types, and geographies"},{"name":"Get LP Actual Allocations","description":"Retrieve a limited partner’s reported asset allocation across cash, equities, fixed income, private equity, real estate, and alternatives"},{"name":"Get LP Target Allocations","description":"Retrieve a limited partner’s target allocation ranges per asset class, in both value and percentage terms"},{"name":"Get LP Service Providers","description":"Retrieve the current and former service providers engaged by a limited partner"},{"name":"Get LP Updates","description":"Check which limited partner datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Service Providers","description":"Search PitchBook for service providers by type, location, and the deals they have worked on"},{"name":"Get Service Provider Bio","description":"Retrieve the profile of a service provider: names, types, description, and how many companies, deals, investors, funds, and limited partners it has serviced"},{"name":"Get Serviced Companies","description":"Retrieve the companies a service provider currently and formerly serves"},{"name":"Get Serviced Deals","description":"Retrieve the deals a service provider worked on and what it was hired for on each"},{"name":"Get Serviced Investors","description":"Retrieve the investors a service provider currently and formerly serves"},{"name":"Get Serviced Funds","description":"Retrieve the funds a service provider has worked with and the service provided to each"},{"name":"Get Serviced Limited Partners","description":"Retrieve the limited partners a service provider currently and formerly serves"},{"name":"Get Service Provider Updates","description":"Check which service provider datasets changed in a window, so a sync only refetches what moved"},{"name":"Search Credit News","description":"Search PitchBook credit analysis news by author, region, asset class, topic, issuer, lender, sponsor, and date"},{"name":"Get Recent Credit News","description":"Retrieve the most recently published credit analysis articles and their descriptions, without article bodies"},{"name":"Get Credit News Article","description":"Retrieve one credit analysis article in full, including its body text, authors, topics, and the issuer, lender, and sponsor it covers"},{"name":"Get Credit News Articles in Bulk","description":"Retrieve many credit analysis articles in full in a single call, reporting which IDs were found, missing, or duplicated"},{"name":"Get Contracts History","description":"Retrieve the API contracts on the account with their pricing model, term, and credit balances"},{"name":"Get Credit History","description":"Retrieve API credit usage and remaining balance per contract, for up to the last 90 days"},{"name":"Get Usage Report","description":"Retrieve how many API calls were made and how many credits they charged, for up to the last 90 days"},{"name":"Get Cost of Calls","description":"Retrieve the credit cost of every API endpoint under a given pricing model, for first-time and refresh calls"},{"name":"List Lookup Tables","description":"List the lookup tables backing the search endpoints. Use this to find which table holds the codes a search filter expects."},{"name":"Get Lookup Table Codes","description":"Retrieve the codes in one or more lookup tables. These are the codes the search filters expect, such as INDUSTRY or VERTICAL."},{"name":"List Sandbox Entities","description":"List the entities a sandbox API key is allowed to query, so test workflows have real IDs to run against"}],"triggers":[],"skills":[{"name":"company-diligence-brief","description":"Pull a full PitchBook picture of a company and write a diligence brief. Use before an investment, partnership, or competitive review.","content":"# Company Diligence Brief\\n\\nAssemble everything PitchBook holds on a company into one readable brief.\\n\\n## Steps\\n1. Resolve the company to a PitchBook ID with a general search — names, websites, and tickers all work.\\n2. Pull the bio for description, HQ, headcount, ownership status, and total raised.\\n3. Pull industries and verticals to place the company in its market.\\n4. Pull the full deal history and the latest financing round, then the latest reported financials.\\n5. Pull all investors to see who is on the cap table and who has exited.\\n6. Optionally pull similar companies to frame the competitive set.\\n\\n## Output\\nReport funding trajectory, current backers, latest valuation, and how the company compares to its peers. Call out any section PitchBook returned no data for rather than inferring it."},{"name":"investor-target-list","description":"Search PitchBook for investors whose stated preferences match a company, and rank them. Use for fundraising and outbound to capital partners.","content":"# Investor Target List\\n\\nFind the investors most likely to fund a given company.\\n\\n## Steps\\n1. Translate the company profile into search filters — deal type, deal size, industry, vertical, and geography.\\n2. Run an investor search, paging until enough candidates are collected.\\n3. For each candidate pull investment preferences and confirm the check size and stage actually match.\\n4. Pull recent investments to verify the investor is currently active, not dormant.\\n5. Rank by fit and write the list to a table with the evidence for each match.\\n\\n## Output\\nReport how many investors matched, the filters used, and why each top candidate fits. Flag any whose last investment is old enough to question whether they are still deploying."},{"name":"deal-flow-digest","description":"Search PitchBook for deals matching a thesis over a time window and summarize them. Use for recurring deal-flow and market monitoring.","content":"# Deal Flow Digest\\n\\nTurn a PitchBook deal search into a readable market update.\\n\\n## Steps\\n1. Express the thesis as deal search filters — deal type, size, date range, industry, vertical, and geography. Range filters carry their operator in the value, such as >2024-01-01 or 10^100.\\n2. Run the search and page through the results.\\n3. For notable deals pull the deal detail and the investor list to capture round size, valuation, and who led.\\n4. Group the results by theme and summarize what moved.\\n\\n## Output\\nReport the deal count, the total capital deployed, and the standout rounds with their lead investors. Note that each call spends PitchBook credits, so state how many were run."},{"name":"benchmark-fund-performance","description":"Compare a fund\'s returns against its PitchBook peer benchmark and report the quartile. Use for LP monitoring and manager due diligence.","content":"# Benchmark Fund Performance\\n\\nPlace a fund\'s returns in context against its peer set.\\n\\n## Steps\\n1. Resolve the fund to a PitchBook fund ID; fund IDs end in F.\\n2. Pull the fund bio for vintage, type, size, and managers - these define the peer set.\\n3. Pull the most recent performance for IRR, DPI, RVPI, TVPI, NAV, and quartile.\\n4. Pull the fund benchmark for the peer IRR, DPI, TVPI, and RVPI, and note how many funds it is drawn from.\\n5. Optionally pull cash flows for a specific quarter to show called capital, dry powder, and distributions.\\n\\n## Output\\nReport each metric next to its benchmark and state the quartile plainly. Name the benchmark\'s vintage, type, size bucket, and fund count, since a thin benchmark makes the quartile weak evidence. Say so when performance data is simply not reported rather than treating it as zero."},{"name":"screen-lp-allocations","description":"Compare a limited partner\'s actual asset allocation against its targets to find where it is under-allocated. Use to time a fundraising approach.","content":"# Screen LP Allocations\\n\\nFind limited partners with room to commit in your asset class.\\n\\n## Steps\\n1. Search limited partners matching the profile - type, geography, and AUM.\\n2. For each, pull actual allocations and target allocations.\\n3. Compare the two per asset class; a class sitting below its target minimum is where new commitments are most likely.\\n4. Pull commitment preferences to confirm preferred commitment size and fund types line up.\\n5. Pull commitment totals by fund type to see how much they have already deployed.\\n\\n## Output\\nRank the limited partners by the gap between actual and target allocation in your asset class, and give the evidence for each. Flag any where allocations are unreported so the gap cannot be computed."}],"templates":[{"title":"PitchBook deal flow monitor","prompt":"Build a scheduled workflow that runs a PitchBook company search for early-stage VC deals in my target verticals closed in the last week, pulls each deal size and lead investor, writes them to a deal-flow table, and posts a digest to the investment team Slack channel.","integrations":[{"id":"pitchbook","name":"PitchBook"},{"id":"slack","name":"Slack"}]},{"title":"PitchBook company diligence brief","prompt":"Create an agent that takes a company name, resolves it to a PitchBook ID, pulls the bio, industries, investors, full deal history, and latest financials, then writes a diligence brief covering funding trajectory, cap table participants, and comparable companies.","integrations":[{"id":"pitchbook","name":"PitchBook"}]},{"title":"PitchBook investor targeting","prompt":"Build a workflow that takes my company profile and stage, searches PitchBook for investors whose stated preferences match on deal type, check size, industry, and geography, enriches each with their recent investments, and ranks the resulting target list in a table.","integrations":[{"id":"pitchbook","name":"PitchBook"}]},{"title":"PitchBook fund performance tracker","prompt":"Create a scheduled workflow that pulls the latest IRR, TVPI, DPI, and benchmark quartile for each fund on my watchlist from PitchBook, appends the quarterly snapshot to a performance table, and flags any fund that has dropped a quartile.","integrations":[{"id":"pitchbook","name":"PitchBook"}]},{"title":"PitchBook competitor watch","prompt":"Build a scheduled workflow that fetches PitchBook similar companies for my main product, checks each one for new financing rounds and recent news, summarizes what changed with an agent, and emails the competitive brief to the product team every Monday.","integrations":[{"id":"pitchbook","name":"PitchBook"},{"id":"gmail","name":"Gmail"}]},{"title":"PitchBook LP commitment mapper","prompt":"Create a workflow that searches PitchBook limited partners matching a target profile, pulls their commitment history and preferences, and builds a table mapping which LPs back which fund types so the fundraising team knows who to approach.","integrations":[{"id":"pitchbook","name":"PitchBook"}]},{"title":"PitchBook buying committee lookup","prompt":"Build a workflow that takes a target account, resolves it in PitchBook, pulls the current team and board members with their titles, filters to the decision-makers for my product, and syncs the mapped contacts into HubSpot.","integrations":[{"id":"pitchbook","name":"PitchBook"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"plane","type":"plane","slug":"plane","name":"Plane","description":"Manage projects and work items in Plane","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/plane","authType":"api-key","connections":[],"operations":[{"name":"Add or remove cycle work items","description":"Add or remove cycle work items in Plane. Supports API v1 compatibility."},{"name":"Add or remove module work items","description":"Add or remove module work items in Plane. Supports API v1 compatibility."},{"name":"Archive a project","description":"Archive a project in Plane. Supports API v1 compatibility."},{"name":"Archive a work item","description":"Archive a work item in Plane. Requires API v2."},{"name":"Confirm a work item attachment upload","description":"Confirm a work item attachment upload in Plane. Supports API v1 compatibility."},{"name":"Create a comment","description":"Create a comment in Plane. Supports API v1 compatibility."},{"name":"Create a cycle","description":"Create a cycle in Plane. Supports API v1 compatibility."},{"name":"Create a label","description":"Create a label in Plane. Supports API v1 compatibility."},{"name":"Create a link","description":"Create a link in Plane. Supports API v1 compatibility."},{"name":"Create a module","description":"Create a module in Plane. Supports API v1 compatibility."},{"name":"Create a project","description":"Create a project in Plane. Supports API v1 compatibility."},{"name":"Create a project page","description":"Create a project page in Plane. Supports API v1 compatibility."},{"name":"Create a state","description":"Create a state in Plane. Supports API v1 compatibility."},{"name":"Create a webhook","description":"Create a webhook in Plane. Requires API v2."},{"name":"Create a work item","description":"Create a work item in Plane. Supports API v1 compatibility."},{"name":"Create a work item attachment upload","description":"Create a work item attachment upload in Plane. Supports API v1 compatibility."},{"name":"Delete a comment","description":"Delete a comment in Plane. Supports API v1 compatibility."},{"name":"Delete a cycle","description":"Delete a cycle in Plane. Supports API v1 compatibility."},{"name":"Delete a label","description":"Delete a label in Plane. Supports API v1 compatibility."},{"name":"Delete a link","description":"Delete a link in Plane. Supports API v1 compatibility."},{"name":"Delete a module","description":"Delete a module in Plane. Supports API v1 compatibility."},{"name":"Delete a project","description":"Delete a project in Plane. Supports API v1 compatibility."},{"name":"Delete a project page","description":"Delete a project page in Plane. Supports API v1 compatibility."},{"name":"Delete a state","description":"Delete a state in Plane. Supports API v1 compatibility."},{"name":"Delete a webhook","description":"Delete a webhook in Plane. Requires API v2."},{"name":"Delete a work item","description":"Delete a work item in Plane. Supports API v1 compatibility."},{"name":"Delete an attachment","description":"Delete an attachment in Plane. Supports API v1 compatibility."},{"name":"Get a comment","description":"Get a comment in Plane. Supports API v1 compatibility."},{"name":"Get a cycle","description":"Get a cycle in Plane. Supports API v1 compatibility."},{"name":"Get a label","description":"Get a label in Plane. Supports API v1 compatibility."},{"name":"Get a link","description":"Get a link in Plane. Supports API v1 compatibility."},{"name":"Get a module","description":"Get a module in Plane. Supports API v1 compatibility."},{"name":"Get a project","description":"Get a project in Plane. Supports API v1 compatibility."},{"name":"Get a project page","description":"Get a project page in Plane. Supports API v1 compatibility."},{"name":"Get a project summary","description":"Get a project summary in Plane. Supports API v1 compatibility."},{"name":"Get a state","description":"Get a state in Plane. Supports API v1 compatibility."},{"name":"Get a webhook","description":"Get a webhook in Plane. Requires API v2."},{"name":"Get a work item","description":"Get a work item in Plane. Supports API v1 compatibility."},{"name":"Get a work item by identifier","description":"Get a work item by identifier in Plane. Requires API v2."},{"name":"Get an attachment","description":"Get an attachment in Plane. Requires API v2."},{"name":"Get current user","description":"Get current user in Plane. Supports API v1 compatibility."},{"name":"List attachments","description":"List attachments in Plane. Supports API v1 compatibility."},{"name":"List comments","description":"List comments in Plane. Supports API v1 compatibility."},{"name":"List cycles","description":"List cycles in Plane. Supports API v1 compatibility."},{"name":"List labels","description":"List labels in Plane. Supports API v1 compatibility."},{"name":"List links","description":"List links in Plane. Supports API v1 compatibility."},{"name":"List modules","description":"List modules in Plane. Supports API v1 compatibility."},{"name":"List project pages","description":"List project pages in Plane. Supports API v1 compatibility."},{"name":"List projects","description":"List projects in Plane. Supports API v1 compatibility."},{"name":"List states","description":"List states in Plane. Supports API v1 compatibility."},{"name":"List webhooks","description":"List webhooks in Plane. Requires API v2."},{"name":"List work items","description":"List work items in Plane. Supports API v1 compatibility."},{"name":"List work items across a workspace","description":"List work items across a workspace in Plane. Requires API v2."},{"name":"Regenerate a webhook secret","description":"Regenerate a webhook secret in Plane. Requires API v2."},{"name":"Transfer work items between cycles","description":"Transfer work items between cycles in Plane. Supports API v1 compatibility."},{"name":"Unarchive a project","description":"Unarchive a project in Plane. Supports API v1 compatibility."},{"name":"Unarchive a work item","description":"Unarchive a work item in Plane. Requires API v2."},{"name":"Update a comment","description":"Update a comment in Plane. Supports API v1 compatibility."},{"name":"Update a cycle","description":"Update a cycle in Plane. Supports API v1 compatibility."},{"name":"Update a label","description":"Update a label in Plane. Supports API v1 compatibility."},{"name":"Update a link","description":"Update a link in Plane. Supports API v1 compatibility."},{"name":"Update a module","description":"Update a module in Plane. Supports API v1 compatibility."},{"name":"Update a project","description":"Update a project in Plane. Supports API v1 compatibility."},{"name":"Update a project page","description":"Update a project page in Plane. Supports API v1 compatibility."},{"name":"Update a state","description":"Update a state in Plane. Supports API v1 compatibility."},{"name":"Update a webhook","description":"Update a webhook in Plane. Requires API v2."},{"name":"Update a work item","description":"Update a work item in Plane. Supports API v1 compatibility."}],"triggers":[{"id":"plane_webhook","name":"Plane All Events","description":"Trigger a workflow for any signed Plane event."},{"id":"plane_project_created","name":"Plane Project Created","description":"Trigger a workflow for Plane project created events."},{"id":"plane_project_updated","name":"Plane Project Updated","description":"Trigger a workflow for Plane project updated events."},{"id":"plane_project_archived","name":"Plane Project Archived","description":"Trigger a workflow for Plane project archived events."},{"id":"plane_project_deleted","name":"Plane Project Deleted","description":"Trigger a workflow for Plane project deleted events."},{"id":"plane_cycle_created","name":"Plane Cycle Created","description":"Trigger a workflow for Plane cycle created events."},{"id":"plane_cycle_updated","name":"Plane Cycle Updated","description":"Trigger a workflow for Plane cycle updated events."},{"id":"plane_cycle_archived","name":"Plane Cycle Archived","description":"Trigger a workflow for Plane cycle archived events."},{"id":"plane_cycle_deleted","name":"Plane Cycle Deleted","description":"Trigger a workflow for Plane cycle deleted events."},{"id":"plane_module_created","name":"Plane Module Created","description":"Trigger a workflow for Plane module created events."},{"id":"plane_module_updated","name":"Plane Module Updated","description":"Trigger a workflow for Plane module updated events."},{"id":"plane_module_archived","name":"Plane Module Archived","description":"Trigger a workflow for Plane module archived events."},{"id":"plane_module_deleted","name":"Plane Module Deleted","description":"Trigger a workflow for Plane module deleted events."},{"id":"plane_milestone_created","name":"Plane Milestone Created","description":"Trigger a workflow for Plane milestone created events."},{"id":"plane_milestone_updated","name":"Plane Milestone Updated","description":"Trigger a workflow for Plane milestone updated events."},{"id":"plane_milestone_deleted","name":"Plane Milestone Deleted","description":"Trigger a workflow for Plane milestone deleted events."},{"id":"plane_page_created","name":"Plane Page Created","description":"Trigger a workflow for Plane page created events."},{"id":"plane_page_updated","name":"Plane Page Updated","description":"Trigger a workflow for Plane page updated events."},{"id":"plane_page_archived","name":"Plane Page Archived","description":"Trigger a workflow for Plane page archived events."},{"id":"plane_page_deleted","name":"Plane Page Deleted","description":"Trigger a workflow for Plane page deleted events."},{"id":"plane_page_comment_created","name":"Plane Page Comment Created","description":"Trigger a workflow for Plane page comment created events."},{"id":"plane_page_comment_updated","name":"Plane Page Comment Updated","description":"Trigger a workflow for Plane page comment updated events."},{"id":"plane_page_comment_deleted","name":"Plane Page Comment Deleted","description":"Trigger a workflow for Plane page comment deleted events."},{"id":"plane_workitem_created","name":"Plane Work Item Created","description":"Trigger a workflow for Plane work item created events."},{"id":"plane_workitem_updated","name":"Plane Work Item Updated","description":"Trigger a workflow for Plane work item updated events."},{"id":"plane_workitem_archived","name":"Plane Work Item Archived","description":"Trigger a workflow for Plane work item archived events."},{"id":"plane_workitem_deleted","name":"Plane Work Item Deleted","description":"Trigger a workflow for Plane work item deleted events."},{"id":"plane_workitem_comment_created","name":"Plane Work Item Comment Created","description":"Trigger a workflow for Plane work item comment created events."},{"id":"plane_workitem_comment_updated","name":"Plane Work Item Comment Updated","description":"Trigger a workflow for Plane work item comment updated events."},{"id":"plane_workitem_comment_deleted","name":"Plane Work Item Comment Deleted","description":"Trigger a workflow for Plane work item comment deleted events."},{"id":"plane_workitem_link_created","name":"Plane Work Item Link Created","description":"Trigger a workflow for Plane work item link created events."},{"id":"plane_workitem_link_updated","name":"Plane Work Item Link Updated","description":"Trigger a workflow for Plane work item link updated events."},{"id":"plane_workitem_link_deleted","name":"Plane Work Item Link Deleted","description":"Trigger a workflow for Plane work item link deleted events."},{"id":"plane_workitem_vote_created","name":"Plane Work Item Vote Created","description":"Trigger a workflow for Plane work item vote created events."},{"id":"plane_workitem_vote_deleted","name":"Plane Work Item Vote Deleted","description":"Trigger a workflow for Plane work item vote deleted events."},{"id":"plane_workitem_attachment_created","name":"Plane Work Item Attachment Created","description":"Trigger a workflow for Plane work item attachment created events."},{"id":"plane_workitem_attachment_updated","name":"Plane Work Item Attachment Updated","description":"Trigger a workflow for Plane work item attachment updated events."},{"id":"plane_workitem_attachment_deleted","name":"Plane Work Item Attachment Deleted","description":"Trigger a workflow for Plane work item attachment deleted events."},{"id":"plane_workitem_relation_created","name":"Plane Work Item Relation Created","description":"Trigger a workflow for Plane work item relation created events."},{"id":"plane_workitem_relation_deleted","name":"Plane Work Item Relation Deleted","description":"Trigger a workflow for Plane work item relation deleted events."},{"id":"plane_workitem_dependency_created","name":"Plane Work Item Dependency Created","description":"Trigger a workflow for Plane work item dependency created events."},{"id":"plane_workitem_dependency_deleted","name":"Plane Work Item Dependency Deleted","description":"Trigger a workflow for Plane work item dependency deleted events."},{"id":"plane_workitem_page_link_created","name":"Plane Work Item Page Link Created","description":"Trigger a workflow for Plane work item page link created events."},{"id":"plane_workitem_page_link_deleted","name":"Plane Work Item Page Link Deleted","description":"Trigger a workflow for Plane work item page link deleted events."}],"skills":[{"name":"plane-work-item-triage","description":"Triage incoming work items and assign their states, labels, and owners.","content":"# Plane Work Item Triage\\n\\nList project states and labels before creating or updating work items. Resolve names to IDs. Use description_html for formatted descriptions and assignee_ids/label_ids arrays for memberships. Set priority to none, low, medium, high, or urgent. Follow pagination cursors. Report each created or updated work item ID.\\n\\nReference: https://docs.plane.so/work-items/create-and-manage-work-items"},{"name":"plane-cycle-planning","description":"Plan and monitor a sprint using Plane cycles.","content":"# Plane Cycle Planning\\n\\nList project cycles and work items, resolve IDs, and create a cycle with matching start and end dates when requested. Add work items using their IDs. List project work items filtered by the cycle ID to verify membership. Transfer incomplete work items from a completed cycle only when requested, using the destination cycle ID. Report the cycle and work items included.\\n\\nReference: https://docs.plane.so/core-concepts/cycles"},{"name":"plane-module-tracking","description":"Track related work across a Plane module.","content":"# Plane Module Tracking\\n\\nList modules, then create or update a module with its lead, status, and dates. Add work items by ID. List project work items filtered by the module ID to confirm membership. Report work item states and module progress without changing work item states unless requested.\\n\\nReference: https://docs.plane.so/core-concepts/modules"},{"name":"plane-project-documentation","description":"Maintain project documentation alongside work items.","content":"# Plane Project Documentation\\n\\nList project pages, read the selected page, and create or update its name and HTML content. Link the documentation to work items using their link operations. Use comments for status notes. Verify the saved page and link IDs.\\n\\nReference: https://docs.plane.so/pages/overview"},{"name":"plane-project-digest","description":"Summarize project progress from paginated work items.","content":"# Plane Project Digest\\n\\nList projects, states, and work items. With API v2 offset pagination, follow result.next until null; with cursor pagination, follow result.next_cursor while result.has_more is true. With API v1, follow pagination.next_cursor while pagination.next_page_results is true. Group results by state, assignee, priority, and target date. Read cycles or modules when useful. Report overdue and blocked work with IDs and owners; treat missing fields as unavailable. Advanced features depend on the instance edition and version.\\n\\nReference: https://docs.plane.so/core-concepts/analytics"}],"templates":[{"title":"Plane backlog triage","prompt":"Build an agent that reads incoming Plane work items, resolves project states and labels, proposes triage decisions, and applies approved priority, ownership, and state changes.","integrations":[{"id":"plane","name":"Plane"}]},{"title":"Plane sprint planner","prompt":"Build an agent that selects ready Plane work items, creates a dated cycle, assigns those work items, and reports the resulting sprint scope.","integrations":[{"id":"plane","name":"Plane"}]},{"title":"Plane daily project digest","prompt":"Build a scheduled workflow that pages through Plane work items and sends a daily summary of overdue, blocked, and completed work to Slack.","integrations":[{"id":"plane","name":"Plane"},{"id":"slack","name":"Slack"}]},{"title":"Plane module progress report","prompt":"Build an agent that reads Plane modules and their work items, summarizes progress and overdue work, and reports the module lead and next steps.","integrations":[{"id":"plane","name":"Plane"}]},{"title":"Plane work item intake","prompt":"Build a workflow that receives requests, creates Plane work items with structured descriptions, and reports their IDs for triage.","integrations":[{"id":"plane","name":"Plane"}]},{"title":"Plane project documentation","prompt":"Build an agent that reads Plane project work items, summarizes decisions and progress, and updates a project page with the resulting documentation.","integrations":[{"id":"plane","name":"Plane"}]},{"title":"Plane self-hosted project sync","prompt":"Build a workflow that connects to my self-hosted Plane instance, pages through project work items, and syncs changed work items into a Sim table without losing the pagination cursor.","integrations":[{"id":"plane","name":"Plane"}]}]},{"id":"planetscale","type":"planetscale","slug":"planetscale","name":"PlanetScale","description":"Manage PlanetScale databases, branches, backups, and deploy requests","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/planetscale","authType":"api-key","connections":[],"operations":[{"name":"List Databases","description":"List databases"},{"name":"Get Database","description":"Get a database"},{"name":"List Branches","description":"List branches"},{"name":"Get Branch","description":"Get a branch"},{"name":"Create Branch","description":"Create a branch"},{"name":"Delete Branch","description":"Delete a branch"},{"name":"List Backups","description":"List backups"},{"name":"Get Backup","description":"Get a backup"},{"name":"Create Backup","description":"Create a backup"},{"name":"List Deploy Requests (Vitess)","description":"List deploy requests (Vitess only)"},{"name":"Get Deploy Request (Vitess)","description":"Get a deploy request (Vitess only)"},{"name":"Create Deploy Request (Vitess)","description":"Create a deploy request (Vitess only)"},{"name":"Review Deploy Request (Vitess)","description":"Review a deploy request (Vitess only)"},{"name":"Queue Deploy Request (Vitess)","description":"Queue a deploy request (Vitess only)"},{"name":"Close Deploy Request (Vitess)","description":"Close a deploy request (Vitess only)"}],"triggers":[],"skills":[{"name":"inspect-databases","description":"Inventory PlanetScale databases and branches before planning maintenance.","content":"# Inspect Databases\\n\\n## Steps\\nList databases in the organization. Get details for the selected database. List its branches and summarize readiness and safe-migration settings.\\n\\n## Output\\nReturn resource identifiers and current states.\\n\\n## Reference\\nhttps://planetscale.com/docs/api/reference/list_databases"},{"name":"prepare-schema-release","description":"Create and review a Vitess deploy request for a prepared schema change.","content":"# Prepare Schema Release\\n\\n## Steps\\nCreate a deploy request from the prepared source branch into the target branch. Get its state. Present the number and URL for approval. Only review or queue after explicit authorization.\\n\\n## Output\\nReturn resource identifiers and current states.\\n\\n## Reference\\nhttps://planetscale.com/docs/vitess/schema-changes/deploy-requests"},{"name":"check-backup-health","description":"Inspect branch backups and report their completion state.","content":"# Check Backup Health\\n\\n## Steps\\nList backups for the chosen branch. Get details for the selected backup. Report completion state, size, and expiration.\\n\\n## Output\\nReturn resource identifiers and current states.\\n\\n## Reference\\nhttps://planetscale.com/docs/vitess/backups"},{"name":"rehearse-backup-restore","description":"Restore a successful backup into a separate branch for a recovery drill.","content":"# Rehearse Backup Restore\\n\\n## Steps\\nList backups and choose a successful backup after confirming scope. Confirm a supported target cluster size, then create a new branch with the backup ID, parent branch, and cluster size. Get branch readiness. Do not delete the restored branch without authorization.\\n\\n## Output\\nReturn resource identifiers and current states.\\n\\n## Reference\\nhttps://planetscale.com/learn/courses/vitess/vitess-at-planetscale"},{"name":"track-schema-deployment","description":"Report the current state of queued Vitess schema deployments.","content":"# Track Schema Deployment\\n\\n## Steps\\nList deploy requests. Get the selected request. Report its current deployment state and URL. This skill does not wait for completion.\\n\\n## Output\\nReturn resource identifiers and current states.\\n\\n## Reference\\nhttps://planetscale.com/docs/vitess/schema-changes/deploy-requests"}],"templates":[{"title":"Database inventory","prompt":"Build a workflow. On a daily schedule, list PlanetScale databases and summarize their readiness and branch counts.","integrations":[{"id":"planetscale","name":"PlanetScale"}]},{"title":"Feature branch setup","prompt":"Build a workflow. When a GitHub pull request opens, create a PlanetScale development branch from its configured parent and report the new branch state.","integrations":[{"id":"planetscale","name":"PlanetScale"},{"id":"github","name":"GitHub"}]},{"title":"Pre-deployment backup","prompt":"Build a workflow. Before an approved release, create a backup of the selected PlanetScale branch and return its ID and current state.","integrations":[{"id":"planetscale","name":"PlanetScale"}]},{"title":"Backup health report","prompt":"Build a workflow. On a daily schedule, list backups for a PlanetScale branch and summarize successful and failed backups.","integrations":[{"id":"planetscale","name":"PlanetScale"}]},{"title":"Restore rehearsal","prompt":"Build a workflow. On a scheduled restore drill, select a successful backup, create a separate branch from it, and report the branch readiness. Run subsequent checks with the appropriate SQL integration.","integrations":[{"id":"planetscale","name":"PlanetScale"},{"id":"mysql","name":"MySQL"},{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Schema release request","prompt":"Build a workflow. When a release is ready for schema review, create a Vitess deploy request from the development branch into the target branch and return its number and URL.","integrations":[{"id":"planetscale","name":"PlanetScale"}]},{"title":"Deployment status report","prompt":"Build a workflow. On a schedule, list Vitess deploy requests and report their deployment states to Slack.","integrations":[{"id":"planetscale","name":"PlanetScale"},{"id":"slack","name":"Slack"}]},{"title":"Review and queue deployment","prompt":"Build a workflow. After explicit release approval, approve a Vitess deploy request, queue it, and report its current deployment state.","integrations":[{"id":"planetscale","name":"PlanetScale"}]}]},{"id":"polymarket","type":"polymarket","slug":"polymarket","name":"Polymarket","description":"Access prediction markets data from Polymarket","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/polymarket","authType":"none","connections":[],"operations":[{"name":"Get Markets","description":"Retrieve a list of prediction markets from Polymarket with optional filtering"},{"name":"Get Market","description":"Retrieve details of a specific prediction market by ID or slug"},{"name":"Get Events","description":"Retrieve a list of events from Polymarket with optional filtering"},{"name":"Get Event","description":"Retrieve details of a specific event by ID or slug"},{"name":"Get Tags","description":"Retrieve available tags for filtering markets from Polymarket"},{"name":"Search","description":"Search for markets, events, and profiles on Polymarket"},{"name":"Get Series","description":"Retrieve series (related market groups) from Polymarket"},{"name":"Get Series by ID","description":"Retrieve a specific series (related market group) by ID from Polymarket"},{"name":"Get Orderbook","description":"Retrieve the order book summary for a specific token"},{"name":"Get Price","description":"Retrieve the market price for a specific token and side"},{"name":"Get Midpoint","description":"Retrieve the midpoint price for a specific token"},{"name":"Get Price History","description":"Retrieve historical price data for a specific market token"},{"name":"Get Last Trade Price","description":"Retrieve the last trade price for a specific token"},{"name":"Get Spread","description":"Retrieve the bid-ask spread for a specific token"},{"name":"Get Tick Size","description":"Retrieve the minimum tick size for a specific token"},{"name":"Get Positions","description":"Retrieve user positions from Polymarket"},{"name":"Get Trades","description":"Retrieve trade history from Polymarket"},{"name":"Get Activity","description":"Retrieve on-chain activity for a user including trades, splits, merges, redemptions, rewards, and conversions"},{"name":"Get Leaderboard","description":"Retrieve trader leaderboard rankings by profit/loss or volume"},{"name":"Get Market Holders","description":"Retrieve top holders of a specific market token"}],"triggers":[],"skills":[{"name":"find-market-odds","description":"Look up a Polymarket market and report the current implied odds and price for each outcome.","content":"# Find Market Odds\\n\\nGet the live implied probability for a question.\\n\\n## Steps\\n1. Use Search or Get Markets to locate the market, or Get Market with a known market ID or slug.\\n2. Read the outcome token IDs from the market, then use Get Price or Get Midpoint per token to get the current price.\\n3. Treat the price (0 to 1) as the implied probability of that outcome.\\n\\n## Output\\nFor the market, list each outcome with its current price as a percentage probability, plus the market volume and whether it is still open."},{"name":"list-top-markets","description":"List the highest-volume or most-liquid Polymarket markets, optionally filtered by category tag.","content":"# List Top Markets\\n\\nSurface the markets attracting the most attention.\\n\\n## Steps\\n1. Use Get Markets (or Get Events) sorted by Volume or Liquidity in descending order.\\n2. Optionally filter by a Tag ID for a category and set Closed Status to open only.\\n3. Set a Limit and use the offset to page through results.\\n\\n## Output\\nA ranked list of markets with title, volume, liquidity, and current implied odds for the leading outcome."},{"name":"track-price-history","description":"Pull Polymarket price history for an outcome token over an interval and summarize the trend.","content":"# Track Price History\\n\\nSee how an outcome moved over time.\\n\\n## Steps\\n1. Identify the outcome token ID from the market.\\n2. Use Get Price History with that Token ID and either a preset Interval (1h, 6h, 1d, 1w, max) or a Start and End timestamp with a Fidelity in minutes.\\n3. Compare the latest price against the start of the window to compute the move.\\n\\n## Output\\nThe price at the start and end of the window, the net change, and a one-line read on the trend (rising, falling, or flat)."},{"name":"analyze-wallet-positions","description":"Fetch a Polymarket wallet\'s open positions and summarize value and profit and loss.","content":"# Analyze Wallet Positions\\n\\nReview what a trader holds and how it is performing.\\n\\n## Steps\\n1. Use Get Positions with the User Wallet Address, optionally sorted by Cash P&L or Current Value.\\n2. Filter with a Size Threshold or by redeemable status to focus on meaningful holdings.\\n3. Optionally use Get Activity for the same wallet to see recent trades and redemptions.\\n\\n## Output\\nA summary of the wallet positions: total current value, aggregate profit and loss, and the largest winners and losers by market."}],"templates":[{"title":"Kalshi + Polymarket arbitrage scanner","prompt":"Create a scheduled workflow that fetches comparable contracts on Kalshi and Polymarket, computes implied-probability spreads, writes the top arbitrage candidates to a table, and pings Slack on significant gaps.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"kalshi","name":"Kalshi"},{"id":"slack","name":"Slack"}]},{"title":"Polymarket position monitor","prompt":"Create a scheduled workflow that fetches Polymarket prices for tracked markets, computes price changes vs entry, writes the portfolio to a table, and pings Slack when any position swings beyond a threshold.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"slack","name":"Slack"}]},{"title":"Polymarket research digest","prompt":"Build a scheduled weekly workflow that pulls top-volume Polymarket markets, summarizes the implied odds and recent moves, and writes a markdown research file for the trading group.","integrations":[{"id":"polymarket","name":"Polymarket"}]},{"title":"Polymarket price-move alerter","prompt":"Build a scheduled workflow that polls Polymarket prices for tracked markets, detects sharp moves since the last run, and writes the price reactions to a research table.","integrations":[{"id":"polymarket","name":"Polymarket"}]},{"title":"Polymarket + Similarweb event volume tracker","prompt":"Create a workflow that overlays Polymarket market activity with Similarweb traffic for the involved entities, identifies volume-driving news, and writes the analysis.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"similarweb","name":"Similarweb"}]},{"title":"Polymarket large-order tracker","prompt":"Build a scheduled workflow that pulls Polymarket order book activity, identifies unusually large orders on tracked markets, and pings Slack on whale activity.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"slack","name":"Slack"}]},{"title":"Polymarket position digest","prompt":"Create a scheduled daily workflow that summarizes Polymarket holdings, PnL per market, and notable movements, and emails the report to the trading team.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"gmail","name":"Gmail"}]},{"title":"Polymarket arbitrage scanner","prompt":"Build a scheduled workflow that fetches prices for related Polymarket markets, detects when complementary outcomes sum away from fair value, writes the mispriced pairs to a table, and pings Slack with the implied edge for each opportunity.","integrations":[{"id":"polymarket","name":"Polymarket"},{"id":"slack","name":"Slack"}]}]},{"id":"postgresql","type":"postgresql","slug":"postgresql","name":"PostgreSQL","description":"Connect to PostgreSQL database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/postgresql","authType":"none","connections":[],"operations":[{"name":"Query (SELECT)","description":"Execute a SELECT query on PostgreSQL database"},{"name":"Insert Data","description":"Insert data into PostgreSQL database"},{"name":"Update Data","description":"Update data in PostgreSQL database"},{"name":"Delete Data","description":"Delete data from PostgreSQL database"},{"name":"Execute Raw SQL","description":"Execute raw SQL query on PostgreSQL database"},{"name":"Introspect Schema","description":"Introspect PostgreSQL database schema to retrieve table structures, columns, and relationships"}],"triggers":[],"skills":[{"name":"query-to-answer","description":"Turn a natural-language question into a PostgreSQL SELECT and return the rows.","content":"# Query To Answer\\n\\nAnswer a question by generating and running a PostgreSQL SELECT.\\n\\n## Steps\\n1. Introspect the relevant schema first so the agent knows the real table and column names.\\n2. Have the agent write a single SELECT with an explicit LIMIT for large result sets.\\n3. Run the query and inspect rows and rowCount.\\n4. Summarize the rows back to the caller in plain language.\\n\\n## Output\\nReturn the answer text, the underlying rows, and the rowCount."},{"name":"upsert-records","description":"Insert new rows or update existing ones by key so a table stays deduplicated.","content":"# Upsert Records\\n\\nKeep a table in sync by inserting new rows or updating existing ones on a key.\\n\\n## Preferred: atomic upsert with execute\\nUse the execute operation to run a single `INSERT ... ON CONFLICT ... DO UPDATE`, which is atomic and avoids the race between a separate read and write. This requires a unique or primary-key constraint on the conflict target.\\n\\n```sql\\nINSERT INTO users (id, name, email)\\nVALUES (\'u1\', \'Jane\', \'jane@example.com\')\\nON CONFLICT (id)\\nDO UPDATE SET name = EXCLUDED.name, email = EXCLUDED.email;\\n```\\n\\n`EXCLUDED` refers to the row proposed for insertion, so `DO UPDATE SET col = EXCLUDED.col` applies the incoming values.\\n\\n## Fallback: read then write\\nIf the key has no unique constraint, query the table for an existing row by key, then run insert when none exists or update with a WHERE condition on the key when one does.\\n\\n## Steps\\n1. Ensure the conflict target has a unique or primary-key constraint.\\n2. Run execute with `INSERT ... ON CONFLICT (key) DO UPDATE SET ... = EXCLUDED. ...` for each record.\\n3. Inspect rowCount to confirm the write landed.\\n\\n## Output\\nReport how many records were upserted and the total rowCount changed."},{"name":"document-schema","description":"Introspect a schema and produce plain-English documentation of its tables.","content":"# Document Schema\\n\\nDescribe a PostgreSQL schema in readable terms.\\n\\n## Steps\\n1. Run introspect on the target schema to get tables, columns, keys, and indexes.\\n2. Have an agent describe what each table stores and how they relate via foreign keys.\\n3. Note primary keys and indexes that hint at common access patterns.\\n4. Assemble the descriptions into a single document.\\n\\n## Output\\nReturn the list of tables with a short description of each and the raw introspection result."},{"name":"retention-cleanup","description":"Delete rows older than a retention cutoff and report the count removed.","content":"# Retention Cleanup\\n\\nRemove stale rows on a schedule.\\n\\n## Steps\\n1. Compute the retention cutoff timestamp for the run.\\n2. Optionally query a count of rows older than the cutoff to preview the impact.\\n3. Run delete with a WHERE condition comparing the timestamp column to the cutoff.\\n4. Capture the rowCount removed for the run.\\n\\n## Output\\nReport how many rows were deleted and the cutoff that was applied."}],"templates":[{"title":"Restore rehearsal","prompt":"Build a workflow. On a scheduled restore drill, select a successful backup, create a separate branch from it, and report the branch readiness. Run subsequent checks with the appropriate SQL integration.","integrations":[{"id":"postgresql","name":"PostgreSQL"},{"id":"planetscale","name":"PlanetScale"},{"id":"mysql","name":"MySQL"}]},{"title":"Ask Postgres in plain English","prompt":"Build a workflow that takes a natural-language question, has an agent turn it into a PostgreSQL SELECT query, runs it against the database, and returns the resulting rows as a readable answer.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Postgres metrics digest to Slack","prompt":"Create a scheduled workflow that queries key business metrics from PostgreSQL each morning, has an agent summarize the numbers and notable changes, and posts the digest to a Slack channel.","integrations":[{"id":"postgresql","name":"PostgreSQL"},{"id":"slack","name":"Slack"}]},{"title":"Document your Postgres schema","prompt":"Build a workflow that introspects a PostgreSQL schema to list its tables, columns, keys, and indexes, then has an agent write plain-English documentation describing what each table holds.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Upsert records into Postgres","prompt":"Create a workflow that takes incoming records, checks PostgreSQL for an existing row by key, then inserts a new row or updates the existing one so the table stays in sync without duplicates.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Nightly Postgres data cleanup","prompt":"Build a scheduled workflow that deletes rows in PostgreSQL older than a retention cutoff and reports how many rows were removed, so tables stay lean on an interval.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Postgres results to Sim table","prompt":"Create a scheduled workflow that runs a PostgreSQL query for the latest records and writes each row into a Sim table, so the data is available for downstream blocks without a live database call.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Postgres threshold breach alert","prompt":"Build a scheduled workflow that queries a PostgreSQL count or aggregate, compares it to a threshold, and posts a Slack alert only when the value crosses the limit so the team hears about problems early.","integrations":[{"id":"postgresql","name":"PostgreSQL"},{"id":"slack","name":"Slack"}]},{"title":"Log form submissions to Postgres","prompt":"Create a workflow that takes an incoming payload, validates the fields, and inserts a new row into a PostgreSQL table so every submission is durably recorded.","integrations":[{"id":"postgresql","name":"PostgreSQL"}]}]},{"id":"posthog","type":"posthog","slug":"posthog","name":"PostHog","description":"Product analytics and feature management","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/posthog","authType":"api-key","connections":[],"operations":[{"name":"Capture Event","description":"Capture a single event in PostHog. Use this to track user actions, page views, or custom events."},{"name":"Batch Events","description":"Capture multiple events at once in PostHog. Use this for bulk event ingestion to improve performance."},{"name":"List Persons","description":"List persons (users) in PostHog. Returns user profiles with their properties and distinct IDs."},{"name":"Get Person","description":"Get detailed information about a specific person in PostHog by their ID or UUID."},{"name":"Delete Person","description":"Request deletion of one PostHog person. Associated event and recording deletion is not requested. Deletion can be queued asynchronously even when the current result reports no person deleted."},{"name":"Run Query (HogQL)","description":"Execute a HogQL query in PostHog. HogQL is PostHog\'s SQL-like query language for analytics. Use this for advanced data retrieval and analysis."},{"name":"List Insights","description":"List all insights in a PostHog project. Returns insight configurations and metadata."},{"name":"Get Insight","description":"Get a specific insight by ID from PostHog. Returns detailed insight configuration and metadata."},{"name":"Create Insight","description":"Create a new insight in PostHog. Requires insight name and a query configuration."},{"name":"Update Insight","description":"Update an existing insight in PostHog. Can modify name, description, query, dashboards, tags, and favorited status."},{"name":"List Dashboards","description":"List all dashboards in a PostHog project. Returns dashboard configurations, tiles, and metadata."},{"name":"Get Dashboard","description":"Get a specific dashboard by ID from PostHog. Returns detailed dashboard configuration, tiles, and metadata."},{"name":"Create Dashboard","description":"Create a new dashboard in PostHog. Optionally seed it from a built-in template, then attach insights to it afterward."},{"name":"List Actions","description":"List all actions in a PostHog project. Returns action definitions, steps, and metadata."},{"name":"List Cohorts","description":"List all cohorts in a PostHog project. Returns cohort definitions, filters, and user counts."},{"name":"Get Cohort","description":"Get a specific cohort by ID from PostHog. Returns detailed cohort definition, filters, and user count."},{"name":"Create Cohort","description":"Create a new cohort in PostHog. Requires cohort name and filter or query configuration."},{"name":"Update Cohort","description":"Update an existing cohort in PostHog. Can modify name, description, filters, query, static membership, and deleted status."},{"name":"List Annotations","description":"List all annotations in a PostHog project. Returns annotation content, timestamps, and associated insights."},{"name":"Create Annotation","description":"Create a new annotation in PostHog. Mark important events on your graphs with date and description."},{"name":"List Feature Flags","description":"List all feature flags in a PostHog project"},{"name":"Get Feature Flag","description":"Get details of a specific feature flag"},{"name":"Create Feature Flag","description":"Create a new feature flag in PostHog"},{"name":"Update Feature Flag","description":"Update an existing feature flag in PostHog"},{"name":"Delete Feature Flag","description":"Delete a feature flag from PostHog"},{"name":"Evaluate Flags","description":"Evaluate feature flags for a specific user or group. This is a public endpoint that uses the project API key."},{"name":"List Experiments","description":"List all experiments in a PostHog project"},{"name":"Get Experiment","description":"Get details of a specific experiment"},{"name":"Create Experiment","description":"Create a new experiment in PostHog"},{"name":"Update Experiment","description":"Update an existing experiment in PostHog. Use this to change dates, archive an experiment, or adjust its parameters and filters."},{"name":"List Surveys","description":"List all surveys in a PostHog project. Surveys allow you to collect feedback from users."},{"name":"Get Survey","description":"Get details of a specific survey in PostHog by ID."},{"name":"Create Survey","description":"Create a new survey in PostHog. Supports question types: Basic (open), Link, Rating, and Multiple Choice."},{"name":"Update Survey","description":"Update an existing survey in PostHog. Can modify questions, appearance, conditions, and other settings."},{"name":"Delete Survey","description":"Delete a survey from PostHog. Use this to remove expired or unused surveys."},{"name":"List Session Recordings","description":"List session recordings in a PostHog project. Session recordings capture user interactions with your application."},{"name":"Get Session Recording","description":"Get details of a specific session recording in PostHog by ID."},{"name":"List Recording Playlists","description":"List session recording playlists in a PostHog project. Playlists allow you to organize and curate session recordings."},{"name":"List Event Definitions","description":"List all event definitions in a PostHog project. Event definitions represent tracked events with metadata like descriptions, tags, and usage statistics."},{"name":"Get Event Definition","description":"Get a PostHog event definition, including its metadata, last-seen timestamp, and verification status."},{"name":"Update Event Definition","description":"Update an event definition in PostHog. Can modify description, tags, and verification status to maintain clean event schemas."},{"name":"List Property Definitions","description":"List all property definitions in a PostHog project. Property definitions represent tracked properties with metadata like descriptions, tags, types, and usage statistics."},{"name":"Get Property Definition","description":"Get a PostHog property definition, including its metadata, type, and verification status."},{"name":"Update Property Definition","description":"Update a property definition in PostHog. Can modify description, tags, property type, and verification status to maintain clean property schemas."},{"name":"List Projects","description":"List all projects in the organization. Returns project details including IDs, names, API tokens, and settings. Useful for getting project IDs needed by other endpoints."},{"name":"Get Project","description":"Get a PostHog project by ID, including its configuration and capture settings."},{"name":"List Organizations","description":"List all organizations the user has access to. Returns organization details including name, slug, membership level, and available product features."},{"name":"Get Organization","description":"Get a PostHog organization by ID, including its settings, features, usage, and teams."}],"triggers":[],"skills":[{"name":"capture-event","description":"Send a product analytics event to PostHog for a user with custom properties.","content":"# Capture Event\\n\\nRecord a user action in PostHog.\\n\\n## Steps\\n1. Use the Capture Event operation with the Project API Key and Project ID.\\n2. Set the Event Name (for example purchase_completed) and the Distinct ID identifying the user.\\n3. Add Properties as a JSON object with relevant context such as plan, price, or page, and optionally a Timestamp.\\n4. For many events at once, use Batch Events with a JSON array instead.\\n\\n## Output\\nConfirm the event name and user it was captured for, and report success or any validation error returned."},{"name":"query-product-data","description":"Run a HogQL query against PostHog to answer a product analytics question.","content":"# Query Product Data\\n\\nPull custom analytics with HogQL.\\n\\n## Steps\\n1. Use the Run Query operation with your Personal API Key, Project ID, and Region.\\n2. Write the HogQL Query (SQL-like) to compute the metric, for example daily active users or top events over a window.\\n3. Pass Query Values for any parameters.\\n4. Aggregate or format the returned rows for the answer.\\n\\n## Output\\nThe query result rows summarized into a direct answer, noting the time window and any assumptions in the query."},{"name":"manage-feature-flag","description":"Create, update, or toggle a PostHog feature flag and control its rollout.","content":"# Manage Feature Flag\\n\\nControl a feature rollout in PostHog.\\n\\n## Steps\\n1. Use Create Feature Flag with a Flag Key, Name, and a Rollout Percentage, or Update Feature Flag by Feature Flag ID to change state.\\n2. Set Active on or off and supply Filters as JSON to target specific cohorts or person properties.\\n3. Provide the Personal API Key, Project ID, and Region.\\n4. Use List Feature Flags to confirm the current state.\\n\\n## Output\\nReport the flag key, whether it is active, and the rollout percentage or targeting now in effect."},{"name":"analyze-survey-responses","description":"List PostHog surveys and pull responses to summarize themes and satisfaction.","content":"# Analyze Survey Responses\\n\\nTurn survey feedback into insight.\\n\\n## Steps\\n1. Use List Surveys to find the active survey, then Get Survey for its definition.\\n2. Use Run Query (HogQL) to pull the survey response events for that survey over a date window.\\n3. Group open-text answers by theme and compute the rating or NPS distribution.\\n\\n## Output\\nA short summary of the top themes from open responses plus the rating or NPS breakdown and any notable movement."},{"name":"add-release-annotation","description":"Create a PostHog annotation marking a deploy or release on the analytics timeline.","content":"# Add Release Annotation\\n\\nMark an event on the PostHog timeline for context.\\n\\n## Steps\\n1. Use the Create Annotation operation with the Personal API Key, Project ID, and Region.\\n2. Provide the Content describing what happened (for example a deploy or campaign launch) and a Date Marker timestamp.\\n3. Set the Scope to project or dashboard item.\\n\\n## Output\\nConfirm the annotation content and the date it was placed on so charts show the marker."}],"templates":[{"title":"Amplitude + PostHog cross-tool dashboard","prompt":"Build a scheduled workflow that aggregates equivalent active-user and event metrics from both Amplitude and PostHog, writes a side-by-side comparison to a table, and surfaces discrepancies to the product team in Slack.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"amplitude","name":"Amplitude"},{"id":"slack","name":"Slack"}]},{"title":"Athena + PostHog data-warehouse join","prompt":"Create a scheduled workflow that joins PostHog event exports with Athena historical data, computes funnel conversion across the join, and writes a daily report.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"athena","name":"Athena"}]},{"title":"PostHog insight digest","prompt":"Create a scheduled daily workflow that pulls key PostHog insights — DAU, top events, funnels — and posts a digest to Slack with week-over-week deltas and emoji indicators.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"slack","name":"Slack"}]},{"title":"PostHog feature flag flip notifier","prompt":"Build a scheduled workflow that polls PostHog feature flags, detects status changes since the last run, and posts a Slack notification with the old and new state for each changed flag.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"slack","name":"Slack"}]},{"title":"PostHog session replay triage","prompt":"Create a scheduled workflow that lists PostHog session recordings with rage clicks or dead clicks, scores each for severity, and creates a Linear ticket for the worst sessions.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"linear","name":"Linear"}]},{"title":"PostHog event taxonomy enforcer","prompt":"Build a workflow that scans PostHog events daily, flags any new event names that violate the naming convention, and opens a Linear ticket for the engineer to clean up tracking debt.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"linear","name":"Linear"}]},{"title":"PostHog cohort enrichment","prompt":"Create a workflow that pulls a PostHog cohort, enriches each user with HubSpot lifecycle stage and Stripe LTV, and writes the enriched cohort to a tables-based targeting view.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"hubspot","name":"HubSpot"},{"id":"stripe","name":"Stripe"}]},{"title":"PostHog + Profound user-journey enricher","prompt":"Build a scheduled weekly workflow that joins PostHog user journeys with Profound AI brand signal to identify how AI-driven discovery converts, and writes a report.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"profound","name":"Profound"}]},{"title":"PostHog survey response analyzer","prompt":"Create a scheduled workflow that lists active PostHog surveys, pulls their responses with a query, runs sentiment and theme analysis across the open-text answers, and posts a summary of top themes and NPS movement to Slack.","integrations":[{"id":"posthog","name":"PostHog"},{"id":"slack","name":"Slack"}]}]},{"id":"powerbi","type":"powerbi","slug":"power-bi","name":"Power BI","description":"Query semantic models and manage reports and refreshes","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/powerbi","authType":"oauth","connections":[{"id":"microsoft-powerbi","kind":"oauth","label":"Connect with OAuth","providerId":"microsoft-powerbi","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/powerbi","requiredScopes":[{"id":"https://analysis.windows.net/powerbi/api/Workspace.Read.All","label":"View Power BI workspaces"},{"id":"https://analysis.windows.net/powerbi/api/Report.Read.All","label":"View Power BI reports"},{"id":"https://analysis.windows.net/powerbi/api/Dataset.ReadWrite.All","label":"Read, create, update, refresh, and delete Power BI semantic models within your account’s permissions"},{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"List Workspaces","description":"List accessible Power BI workspaces with optional OData filtering and pagination."},{"name":"List Reports","description":"List reports in a Power BI workspace, including paginated reports."},{"name":"Get Report","description":"Get report metadata from a Power BI workspace."},{"name":"List Semantic Models","description":"List semantic models in a Power BI workspace; available metadata depends on permissions."},{"name":"Get Semantic Model","description":"Get semantic model metadata from a Power BI workspace."},{"name":"Execute DAX Query","description":"Execute one DAX query returning one table. Requires workspace access, Read/Build permissions, and the tenant Execute Queries setting. Reported errors fail the action even with HTTP 200. Direct tool responses retain partial rows and typed errors; failed workflows expose only the standard error output. Sim limits workflow tool responses to 10 MiB; use summaries or TOPN for larger results."},{"name":"Refresh Semantic Model","description":"Request a standard asynchronous semantic model refresh and return acceptance immediately. Acceptance does not mean completion; use Get Refresh History separately to inspect status. Shared capacity allows eight refresh requests per day, including scheduled refreshes."},{"name":"Get Refresh History","description":"Get recent semantic model refresh history; requires Write permission on the model. Unknown can mean a refresh is in progress or its completion state is unknown."}],"triggers":[],"skills":[{"name":"summarize-semantic-model-kpis","description":"Run an approved DAX query and turn complete semantic model results into a KPI summary.","content":"# Summarize Semantic Model KPIs\\n\\n## Steps\\n1. Select an accessible workspace and semantic model. Ask for known measure names or an approved query; these actions do not discover the model schema.\\n2. Use Execute DAX Query with one EVALUATE query returning one table. Keep the result small and include nulls when blanks matter.\\n3. Summarize only successful query results. Connect the query block\'s error port to a failure notification using its error output; partial rows are unavailable on the workflow error path.\\n\\n## Output\\nKPI values and their model context on success, or a separate query failure notification.\\n\\n## Sources\\n[Microsoft DAX queries](https://learn.microsoft.com/en-us/dax/dax-queries) · [Execute Queries API](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/execute-queries-in-group)"},{"name":"inventory-workspace-reports","description":"Catalog accessible workspace reports and links without assuming every report has a semantic model.","content":"# Inventory Workspace Reports\\n\\n## Steps\\n1. Use List Workspaces for the connected user, advancing the numeric offset for subsequent pages when needed.\\n2. Use List Reports in each selected workspace. Use Get Report for a specific report.\\n3. Record IDs, names, report types, and available URLs. Paginated reports may have no semantic model ID; keep that value null.\\n\\n## Output\\nA catalog limited to the workspaces the account can access.\\n\\n## Sources\\n[Get Groups](https://learn.microsoft.com/en-us/rest/api/power-bi/groups/get-groups) · [Get Reports in Group](https://learn.microsoft.com/en-us/rest/api/power-bi/reports/get-reports-in-group)"},{"name":"inventory-semantic-models","description":"List semantic models and describe only the metadata available to the connected account.","content":"# Inventory Semantic Models\\n\\n## Steps\\n1. Select an accessible workspace and use List Semantic Models.\\n2. Use Get Semantic Model for details of a chosen model.\\n3. Record model identity and available metadata. A read-only response can contain only ID and name; missing fields do not mean false. The refreshability flag does not prove permission to refresh.\\n\\n## Output\\nA model inventory with explicit unknown metadata.\\n\\n## Source\\n[Get Datasets in Group](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/get-datasets-in-group)"},{"name":"request-semantic-model-refresh","description":"Request a standard semantic model refresh and record acceptance for later monitoring.","content":"# Request Semantic Model Refresh\\n\\n## Steps\\n1. Confirm the workspace and semantic model to refresh.\\n2. Use Refresh Semantic Model with the selected notification option. No Notification is the default.\\n3. Record accepted, requestId, and location. Acceptance is not completion; use Get Refresh History later. Do not automatically resubmit an ambiguous request failure.\\n\\n## Output\\nRefresh acceptance and the provider request ID when supplied.\\n\\n## Source\\n[Refresh Dataset in Group](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/refresh-dataset-in-group)"},{"name":"monitor-refresh-health","description":"Inspect refresh history for failed requests and summarize their attempts and errors.","content":"# Monitor Refresh Health\\n\\n## Steps\\n1. Use Get Refresh History for a selected semantic model with model Write permission.\\n2. Inspect request IDs, statuses, timestamps, service exceptions, and refresh attempts. Unknown does not confirm completion.\\n3. Report failed requests with available error details and avoid duplicate alerts by retaining previously reported request IDs.\\n\\n## Output\\nA refresh health summary with failed requests and unresolved statuses.\\n\\n## Sources\\n[Get Refresh History](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/get-refresh-history-in-group) · [Microsoft refresh monitoring guidance](https://learn.microsoft.com/en-us/power-bi/guidance/powerbi-implementation-planning-auditing-monitoring-data-level-auditing)"},{"name":"check-data-freshness","description":"Compare completed refresh history with a freshness deadline before distributing a KPI report.","content":"# Check Data Freshness\\n\\n## Steps\\n1. Retrieve enough recent refresh history for the chosen semantic model.\\n2. Find the most recent completed refresh with an end time and compare it with the agreed freshness deadline.\\n3. Report stale or unknown freshness before publishing a KPI briefing. Refresh history does not include OneDrive refreshes or all refresh warnings.\\n\\n## Output\\nThe last observed completed refresh and whether it meets the deadline.\\n\\n## Source\\n[Microsoft data refresh guidance](https://learn.microsoft.com/en-us/power-bi/connect-data/refresh-data)"}],"templates":[{"title":"Power BI KPI briefing","prompt":"Build a scheduled workflow that runs an approved DAX query for daily KPIs in a Power BI semantic model, summarizes successful results, and posts the briefing to Microsoft Teams. Connect the query block\'s error port to a separate failure notification.","integrations":[{"id":"powerbi","name":"Power BI"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Power BI sales target alert","prompt":"Create a scheduled workflow that queries approved sales and target measures from a Power BI semantic model, compares complete results with a configured threshold, and alerts the sales team in Slack when the target is missed.","integrations":[{"id":"powerbi","name":"Power BI"},{"id":"slack","name":"Slack"}]},{"title":"Power BI report catalog","prompt":"Build a scheduled workflow that lists accessible Power BI workspaces and their reports, collects report links and semantic model IDs when available, and updates a Sim table as a searchable report catalog.","integrations":[{"id":"powerbi","name":"Power BI"}]},{"title":"Power BI model inventory","prompt":"Create a scheduled workflow that inventories semantic models in selected accessible workspaces, records names and available owner and refresh metadata in a Sim table, and summarizes missing metadata without assuming read-only responses are complete.","integrations":[{"id":"powerbi","name":"Power BI"}]},{"title":"Power BI pipeline refresh","prompt":"Build a workflow started by an upstream pipeline completion request that asks Power BI to refresh a selected semantic model and records the acceptance and request ID in a Sim table. Notify Microsoft Teams that the refresh was requested, then use a separate scheduled history check to observe completion.","integrations":[{"id":"powerbi","name":"Power BI"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Power BI refresh failure monitor","prompt":"Create a scheduled workflow that retrieves refresh history for critical Power BI semantic models, identifies failed requests and their error details, and notifies an operations Slack channel once per request ID using a Sim table to track previously reported failures.","integrations":[{"id":"powerbi","name":"Power BI"},{"id":"slack","name":"Slack"}]},{"title":"Power BI freshness watch","prompt":"Build a scheduled workflow that reads semantic model refresh history, compares the most recent completed refresh with an agreed freshness deadline, and sends Microsoft Teams a stale-data warning when the deadline is missed. Report Unknown statuses separately without claiming a refresh has completed.","integrations":[{"id":"powerbi","name":"Power BI"},{"id":"microsoft_teams","name":"Microsoft Teams"}]}]},{"id":"profound","type":"profound","slug":"profound","name":"Profound","description":"AI visibility and analytics with Profound","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/profound","authType":"api-key","connections":[],"operations":[{"name":"List Categories","description":"List all organization categories in Profound"},{"name":"List Regions","description":"List all organization regions in Profound"},{"name":"List Models","description":"List all AI models/platforms tracked in Profound"},{"name":"List Domains","description":"List all organization domains in Profound"},{"name":"List Assets","description":"List all organization assets (companies/brands) across all categories in Profound"},{"name":"List Personas","description":"List all organization personas across all categories in Profound"},{"name":"Category Topics","description":"List topics for a specific category in Profound"},{"name":"Category Tags","description":"List tags for a specific category in Profound"},{"name":"Category Prompts","description":"List prompts for a specific category in Profound"},{"name":"Category Assets","description":"List assets (companies/brands) for a specific category in Profound"},{"name":"Category Personas","description":"List personas for a specific category in Profound"},{"name":"Visibility Report","description":"Query AI visibility report for a category in Profound"},{"name":"Sentiment Report","description":"Query sentiment report for a category in Profound"},{"name":"Citations Report","description":"Query citations report for a category in Profound"},{"name":"Query Fanouts","description":"Query fanout report showing how AI models expand prompts into sub-queries in Profound"},{"name":"Prompt Answers","description":"Get raw prompt answers data for a category in Profound"},{"name":"Bots Report","description":"Query bot traffic report with hourly granularity for a domain in Profound"},{"name":"Referrals Report","description":"Query human referral traffic report with hourly granularity for a domain in Profound"},{"name":"Raw Logs","description":"Get raw traffic logs with filters for a domain in Profound"},{"name":"Bot Logs","description":"Get identified bot visit logs with filters for a domain in Profound"},{"name":"List Optimizations","description":"List content optimization entries for an asset in Profound"},{"name":"Optimization Analysis","description":"Get detailed content optimization analysis for a specific content item in Profound"},{"name":"Prompt Volume","description":"Query prompt volume data to understand search demand across AI platforms in Profound"},{"name":"Citation Prompts","description":"Get prompts that cite a specific domain across AI platforms in Profound"}],"triggers":[],"skills":[{"name":"check-brand-visibility","description":"Pull a Profound visibility report to see how a brand surfaces in AI answers for tracked prompts.","content":"# Check Brand Visibility\\n\\nMeasure how often a brand appears in AI engine answers.\\n\\n## Steps\\n1. Use the Visibility Report operation with the Category ID and a Start Date and End Date.\\n2. Set Metrics such as share_of_voice, visibility_score, and mentions_count.\\n3. Optionally break the data out by Dimensions (date, model) and set a Date Interval.\\n4. Compare the latest period against the prior one.\\n\\n## Output\\nThe visibility and share-of-voice scores for the period, broken down by model where requested, with the change versus the previous window."},{"name":"track-citation-sources","description":"Pull a Profound citations report to see which sources AI engines cite for brand prompts.","content":"# Track Citation Sources\\n\\nFind the sources AI engines cite when answering about a brand.\\n\\n## Steps\\n1. Use the Citations Report operation with the Category ID, Start Date, and End Date, and set Metrics such as count and citation_share.\\n2. For a specific domain, use Citation Prompts with the Domain to see which prompts cite it.\\n3. Optionally add Dimensions to group by source domain or page.\\n\\n## Output\\nA ranked list of citing domains and pages with their citation share, highlighting any new sources the content team should target."},{"name":"compare-competitor-share","description":"Use Profound visibility metrics to compare a brand against competitors in AI answers.","content":"# Compare Competitor Share\\n\\nBenchmark share-of-voice across competitors.\\n\\n## Steps\\n1. Use the Visibility Report operation for the Category ID over a date window with the share_of_voice metric.\\n2. Add Dimensions to break results out by asset or brand name, and apply Filters as JSON to scope to the competitor set.\\n3. Rank the brands by share-of-voice.\\n\\n## Output\\nA leaderboard of brands by share-of-voice in AI answers, flagging any competitor that gained or lost notable ground."},{"name":"find-content-gaps","description":"Use Profound prompt and answer data to find prompts where the brand is absent from AI answers.","content":"# Find Content Gaps\\n\\nSurface prompts where the brand is missing from AI answers.\\n\\n## Steps\\n1. Use Category Prompts with the Category ID to list tracked prompts, paging with the cursor.\\n2. Use Prompt Answers over a date window to see how the brand appears (or does not) for each prompt.\\n3. Flag prompts with low or zero visibility as content gaps.\\n\\n## Output\\nA prioritized list of prompts where the brand is absent or weak in AI answers, ready to drive content briefs."}],"templates":[{"title":"Ahrefs + Profound combined visibility","prompt":"Create a scheduled weekly workflow that combines Ahrefs SEO rankings with Profound AI-visibility scores, writes a combined visibility report, and surfaces gaps to Slack.","integrations":[{"id":"profound","name":"Profound"},{"id":"ahrefs","name":"Ahrefs"},{"id":"slack","name":"Slack"}]},{"title":"Google Ads + Profound brand comparison","prompt":"Build a scheduled workflow that joins Google Ads spend per campaign with Profound AI brand-visibility scores, writes a comparison table without claiming causal attribution, and posts findings to Slack.","integrations":[{"id":"profound","name":"Profound"},{"id":"google_ads","name":"Google Ads"},{"id":"slack","name":"Slack"}]},{"title":"Kalshi + Profound macro signal","prompt":"Build a scheduled workflow that combines Kalshi event-contract prices with Profound AI signal to forecast macro events and writes a thesis file weekly.","integrations":[{"id":"profound","name":"Profound"},{"id":"kalshi","name":"Kalshi"}]},{"title":"PostHog + Profound user-journey enricher","prompt":"Build a scheduled weekly workflow that joins PostHog user journeys with Profound AI brand signal to identify how AI-driven discovery converts, and writes a report.","integrations":[{"id":"profound","name":"Profound"},{"id":"posthog","name":"PostHog"}]},{"title":"Profound AI-visibility tracker","prompt":"Create a scheduled weekly workflow that pulls Profound brand-visibility scores across AI search engines, tracks how my brand surfaces in answers for tracked prompts, and reports week-over-week shifts to Slack.","integrations":[{"id":"profound","name":"Profound"},{"id":"slack","name":"Slack"}]},{"title":"Profound competitor share-of-voice","prompt":"Build a workflow that pulls Profound competitor share-of-voice across AI engines, writes the leaderboard to a tracking table, and flags when a competitor jumps more than two positions.","integrations":[{"id":"profound","name":"Profound"}]},{"title":"Profound prompt-coverage audit","prompt":"Build a scheduled weekly workflow that reads Profound\'s tracked-prompt coverage and prompt answers to monitor how my brand surfaces in AI answers across engines, and writes the coverage scorecard to a tables-based report.","integrations":[{"id":"profound","name":"Profound"}]},{"title":"Profound citation-source tracker","prompt":"Build a scheduled workflow that pulls the sources Profound reports AI engines cite when answering brand prompts, logs the citing domains and pages to a table, and flags new sources the content team should target.","integrations":[{"id":"profound","name":"Profound"}]},{"title":"Profound visibility-drop alerter","prompt":"Create a workflow that checks Profound brand-visibility scores daily, compares each tracked prompt against its baseline, and immediately pages the marketing on-call in Slack when visibility drops sharply on a high-priority prompt.","integrations":[{"id":"profound","name":"Profound"},{"id":"slack","name":"Slack"}]},{"title":"Profound content-gap planner","prompt":"Build a workflow that pulls the prompts where Profound shows my brand is absent from AI answers, has an agent draft a prioritized content brief for each gap, and creates the briefs as Notion pages for the content team.","integrations":[{"id":"profound","name":"Profound"},{"id":"notion","name":"Notion"}]},{"title":"Profound executive AI-search digest","prompt":"Create a scheduled monthly workflow that aggregates Profound visibility, share-of-voice, and citation trends into a Markdown report file with commentary, and emails the AI-search performance digest to leadership.","integrations":[{"id":"profound","name":"Profound"},{"id":"gmail","name":"Gmail"}]}]},{"id":"prospeo","type":"prospeo","slug":"prospeo","name":"Prospeo","description":"Enrich and search B2B contacts and companies","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/prospeo","authType":"api-key","connections":[],"operations":[{"name":"Enrich Person","description":"Enrich a person with complete B2B profile data, email address and mobile."},{"name":"Enrich Company","description":"Enrich a company with complete B2B data."},{"name":"Bulk Enrich Person","description":"Enrich up to 50 person records at once."},{"name":"Bulk Enrich Company","description":"Enrich up to 50 company records at once."},{"name":"Search Person","description":"Search for leads using 20+ filters to build targeted contact lists."},{"name":"Search Company","description":"Search for companies using 20+ filters to build account lists."},{"name":"Search Suggestions","description":"Free endpoint to retrieve valid location or job title values for use in Search filters. Provide exactly one of location_search or job_title_search."},{"name":"Account Information","description":"Retrieve the current plan, remaining credits, and renewal date of your Prospeo account."}],"triggers":[],"skills":[{"name":"find-work-email","description":"Find and verify a prospect\'s work email and optional mobile number with Prospeo.","content":"# Find Work Email\\n\\nGet a deliverable work email for a prospect.\\n\\n## Steps\\n1. Use the Enrich Person operation and provide the strongest match key: a LinkedIn URL, or First and Last Name plus Company Name or Company Website.\\n2. Set Only Verified Email to Yes when deliverability matters, and Enrich Mobile to also reveal a phone number.\\n3. Read the enriched person object for the email, its verification status, and the mobile if requested.\\n\\n## Output\\nThe verified work email (and mobile if requested) with its status, or a clear note that no match was found and which keys were tried."},{"name":"search-prospects","description":"Search Prospeo for people matching an ICP using seniority, title, industry, and company filters.","content":"# Search Prospects\\n\\nBuild a targeted prospect list from the B2B database.\\n\\n## Steps\\n1. Use the Search Person operation and supply a Filters JSON object using documented keys such as person_seniority, person_job_title, company_industry, and company_headcount_range with include or exclude lists.\\n2. Avoid using only exclude filters; always include at least one positive filter.\\n3. Page through results with the Page field.\\n\\n## Output\\nThe matching prospects with names, titles, and companies, plus the pagination details so the list can be fully retrieved."},{"name":"enrich-company","description":"Enrich a company from its website or LinkedIn URL to get Prospeo firmographics.","content":"# Enrich Company\\n\\nPull firmographics for a target account.\\n\\n## Steps\\n1. Use the Enrich Company operation and provide the Company Website or Company LinkedIn URL (most reliable), or a Company Name.\\n2. Read the returned company object for size, industry, location, and other firmographic fields.\\n3. For many accounts, use Bulk Enrich Company with a JSON array of records, each with an identifier and a match key.\\n\\n## Output\\nThe company firmographics (size, industry, location) for the account, or the matched and not-matched breakdown when running in bulk."},{"name":"bulk-enrich-list","description":"Enrich a list of people or companies in batches with Prospeo bulk enrichment.","content":"# Bulk Enrich List\\n\\nEnrich up to fifty records per call efficiently.\\n\\n## Steps\\n1. Use Bulk Enrich Person (or Bulk Enrich Company) and pass a JSON array of records, each with a unique identifier and one valid match key set.\\n2. Set Only Verified Email or Enrich Mobile as needed for the person variant.\\n3. Map results back to inputs using the identifier, and check the not-matched and invalid-datapoints lists.\\n\\n## Output\\nA per-identifier summary of matched records with their enriched fields, the total credit cost, and the identifiers that did not match for retry."}],"templates":[{"title":"Prospeo email finder","prompt":"Build a workflow that takes a prospect name and company from a table, runs Prospeo to find and verify their work email, and writes the deliverable contact back to the row.","integrations":[{"id":"prospeo","name":"Prospeo"}]},{"title":"Prospeo person enricher","prompt":"Create a workflow that watches CRM contacts, runs Prospeo enrichment to fill in title, company, and verified contact details, and writes the enriched fields back.","integrations":[{"id":"prospeo","name":"Prospeo"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Prospeo ICP search","prompt":"Build a workflow that runs a Prospeo people search against my ICP filters, reveals verified emails and mobile numbers, and writes the prospect list into a sender table.","integrations":[{"id":"prospeo","name":"Prospeo"}]},{"title":"Prospeo + Email Bison outbound","prompt":"Create a workflow that uses Prospeo to find and verify prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.","integrations":[{"id":"prospeo","name":"Prospeo"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Prospeo CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing email addresses, runs Prospeo to find and verify them, and updates each contact record.","integrations":[{"id":"prospeo","name":"Prospeo"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Prospeo bulk list enrichment","prompt":"Build a workflow that reads a large prospect list from a table, runs Prospeo bulk person enrichment in batches to reveal verified emails and titles, and writes the enriched results back row by row with a status column for any that could not be matched.","integrations":[{"id":"prospeo","name":"Prospeo"}]},{"title":"Prospeo company enrichment","prompt":"Create a workflow that takes a list of target company domains, runs Prospeo company enrichment to pull firmographics like size, industry, and location, and writes the structured company profiles into an account table for territory planning.","integrations":[{"id":"prospeo","name":"Prospeo"}]}]},{"id":"pulse","type":"pulse_v2","slug":"pulse","name":"Pulse","description":"Extract text from documents using Pulse OCR","category":"AI","docsUrl":"https://docs.sim.ai/integrations/pulse","authType":"api-key","connections":[],"operations":[{"name":"Pulse Document Parser","description":"Parse documents (PDF, images, Office docs) using Pulse OCR API"}],"triggers":[],"skills":[{"name":"extract-document-text","description":"Run a PDF, image, or Office file through Pulse OCR and return clean markdown.","content":"# Extract Document Text\\n\\nTurn a document into structured markdown text.\\n\\n## Steps\\n1. Upload the Document (PDF, image, DOCX, PPTX, or XLSX) or provide a file reference.\\n2. Optionally set Specific Pages (for example 1-3,5) to limit extraction to part of the document.\\n3. Provide the Pulse API Key.\\n4. Use the returned markdown as the source for downstream summarization or parsing.\\n\\n## Output\\nThe extracted markdown text and the page count, plus any bounding-box or figure data when available."},{"name":"extract-structured-fields","description":"Use Pulse OCR output to pull structured fields like vendor, totals, or dates from a document.","content":"# Extract Structured Fields\\n\\nPull specific data points out of a scanned document.\\n\\n## Steps\\n1. Run the document through Pulse OCR to get the markdown text.\\n2. In a following agent step, map the markdown to the target fields (for example invoice vendor, line items, totals, or contract parties and renewal dates).\\n3. Validate the parsed values against the source text before using them.\\n\\n## Output\\nA structured record of the requested fields, with a note on any field that could not be confidently extracted from the document."},{"name":"chunk-for-knowledge-base","description":"Extract and chunk a document with Pulse OCR so it can be indexed for retrieval.","content":"# Chunk For Knowledge Base\\n\\nPrepare a document for vector indexing.\\n\\n## Steps\\n1. Upload the Document and provide the Pulse API Key.\\n2. Set a Chunking Strategy (semantic, header, page, or recursive) and a Chunk Size in characters.\\n3. Use the returned chunks as the units to embed and index into a knowledge base.\\n\\n## Output\\nThe chunked content ready for embedding, with each chunk sized per the strategy, plus the total page count for reference."}],"templates":[{"title":"ElevenLabs + Pulse meeting voice digest","prompt":"Build a workflow that takes Pulse meeting insights, narrates them with an ElevenLabs voice, and emails the audio digest to the team for asynchronous review.","integrations":[{"id":"pulse","name":"Pulse"},{"id":"elevenlabs","name":"ElevenLabs"},{"id":"gmail","name":"Gmail"}]},{"title":"Pulse invoice extractor","prompt":"Create a workflow that runs each uploaded invoice PDF through Pulse OCR, extracts vendor, line items, and totals into structured fields, and writes the parsed records to an accounts-payable table.","integrations":[{"id":"pulse","name":"Pulse"}]},{"title":"Pulse contract clause extractor","prompt":"Build a workflow that extracts the full text of uploaded contract PDFs with Pulse OCR, has an agent pull out key clauses, parties, and renewal dates, and writes a structured summary to a table.","integrations":[{"id":"pulse","name":"Pulse"}]},{"title":"Pulse scanned-document indexer","prompt":"Create a workflow that runs each scanned image or PDF through Pulse OCR, chunks the extracted markdown, and indexes the cleaned content into a knowledge base so agents can search across every document.","integrations":[{"id":"pulse","name":"Pulse"}]},{"title":"Pulse form data extractor","prompt":"Build a workflow that extracts text from uploaded form PDFs and images with Pulse OCR, maps the values into structured fields with an agent, and writes each submission to a table.","integrations":[{"id":"pulse","name":"Pulse"}]},{"title":"Pulse table-to-spreadsheet extractor","prompt":"Create a workflow that runs uploaded reports through Pulse OCR, pulls the embedded tables into structured rows, and writes the consolidated data to a tracking table.","integrations":[{"id":"pulse","name":"Pulse"}]},{"title":"Pulse document summarizer","prompt":"Build a workflow that extracts the text of an uploaded PDF or Office file with Pulse OCR, has an agent write a concise summary, and posts it to Slack.","integrations":[{"id":"pulse","name":"Pulse"},{"id":"slack","name":"Slack"}]},{"title":"Pulse document OCR pipeline","prompt":"Build a workflow that runs each uploaded PDF, image, or Office file through Pulse OCR, extracts the text into structured rows in a table, and indexes the cleaned content into a knowledge base so agents can search across every scanned document.","integrations":[{"id":"pulse","name":"Pulse"}]}]},{"id":"qdrant","type":"qdrant","slug":"qdrant","name":"Qdrant","description":"Use Qdrant vector database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/qdrant","authType":"api-key","connections":[],"operations":[{"name":"Upsert","description":"Insert or update points in a Qdrant collection"},{"name":"Search","description":"Search for similar vectors in a Qdrant collection"},{"name":"Fetch","description":"Fetch points by ID from a Qdrant collection"}],"triggers":[],"skills":[{"name":"upsert-points","description":"Insert or update vector points with payload metadata into a Qdrant collection.","content":"# Upsert Points\\n\\nLoad vectors into a Qdrant collection.\\n\\n## Steps\\n1. Use the Upsert operation with the Qdrant URL, Collection name, and API Key.\\n2. Provide Points as a JSON array, each with an id, a vector matching the collection dimension, and an optional payload of metadata for later filtering.\\n3. Confirm the upserted count from the response.\\n\\n## Output\\nReport how many points were upserted into which collection and surface any payload validation issues."},{"name":"search-vectors","description":"Run a vector similarity search in Qdrant with optional payload filters.","content":"# Search Vectors\\n\\nFind the nearest points to a query vector.\\n\\n## Steps\\n1. Use the Search operation with the Qdrant URL, Collection, and the Query Vector.\\n2. Set the Limit for how many matches to return and choose what Return Data you need (payload only, vector only, both, or none).\\n3. Optionally pass a Filter JSON object using must, should, or must_not conditions to scope the search by payload fields.\\n\\n## Output\\nThe top matches with their scores and requested payload or vector data, ordered by similarity."},{"name":"fetch-points-by-id","description":"Retrieve specific Qdrant points and their payloads by ID.","content":"# Fetch Points By ID\\n\\nLook up known points directly.\\n\\n## Steps\\n1. Use the Fetch operation with the Qdrant URL, Collection, and API Key.\\n2. Provide the IDs as a JSON array of the points to retrieve.\\n3. Choose the Return Data option to control whether payloads and vectors are included.\\n\\n## Output\\nThe requested points with their payloads (and vectors if requested), plus a note on any IDs that were not found."}],"templates":[{"title":"Qdrant document ingestion","prompt":"Build a workflow that watches a Google Drive folder for new docs, chunks each, generates embeddings, and upserts the vectors into a Qdrant collection with rich metadata.","integrations":[{"id":"qdrant","name":"Qdrant"},{"id":"google_drive","name":"Google Drive"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Qdrant retrieval agent","prompt":"Create an agent that performs hybrid search against a Qdrant collection — semantic + filter conditions — and answers user questions with the matched documents cited.","integrations":[{"id":"qdrant","name":"Qdrant"}]},{"title":"Qdrant payload schema migrator","prompt":"Build a workflow that scans a Qdrant collection, migrates payload schema to a new version with backfilled fields, and writes the migration plan and outcome to an audit table.","integrations":[{"id":"qdrant","name":"Qdrant"}]},{"title":"Qdrant + knowledge base sync","prompt":"Create a workflow that mirrors a Sim knowledge base into a Qdrant collection so downstream applications outside Sim can perform retrieval against the same vectors.","integrations":[{"id":"qdrant","name":"Qdrant"}]},{"title":"Qdrant snapshot manager","prompt":"Build a scheduled workflow that takes a Qdrant collection snapshot each night, uploads it to S3 with retention rotation, and writes the snapshot manifest to a tracking table.","integrations":[{"id":"qdrant","name":"Qdrant"},{"id":"s3","name":"S3"}]},{"title":"Qdrant abandoned-document detector","prompt":"Create a workflow that scans a Qdrant collection for vectors whose source document no longer exists, deletes the orphans, and writes a hygiene report each week.","integrations":[{"id":"qdrant","name":"Qdrant"}]},{"title":"Qdrant support-answer retriever","prompt":"Build a workflow that embeds each new Zendesk ticket with OpenAI, runs a filtered Qdrant search scoped to the customer’s product, and drafts a cited reply from the closest matching resolved tickets for the agent to approve.","integrations":[{"id":"qdrant","name":"Qdrant"},{"id":"embeddings","name":"Embeddings"},{"id":"zendesk","name":"Zendesk"}]}]},{"id":"quartr","type":"quartr","slug":"quartr","name":"Quartr","description":"Access earnings calls, transcripts, filings, and slides","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/quartr","authType":"api-key","connections":[],"operations":[{"name":"List Companies","description":"List companies covered by Quartr, filterable by ticker, ISIN, CIK, OpenFIGI, country, and exchange."},{"name":"Get Company","description":"Retrieve a single company from Quartr by its company ID."},{"name":"List Events","description":"List corporate events (earnings calls, capital markets days, etc.) from Quartr, filterable by company, event type, and date range."},{"name":"Get Event","description":"Retrieve a single corporate event from Quartr by its event ID."},{"name":"Get Event Summary","description":"Retrieve the AI-generated summary of a corporate event from Quartr, with selectable length and optional plain-text formatting."},{"name":"List Event Types","description":"List the event types available in Quartr (e.g., earnings calls), useful for filtering events by type ID."},{"name":"List Documents","description":"List documents of all kinds (reports, slide decks, and transcripts) from Quartr, filterable by company, event, document type, document group, and date range."},{"name":"List Document Types","description":"List the document types available in Quartr (e.g., 10-Q quarterly reports), useful for filtering documents by type ID."},{"name":"List Reports","description":"List filings and reports (10-K, 10-Q, earnings releases, etc.) from Quartr, filterable by company, event, document type, document group, and date range."},{"name":"Get Report","description":"Retrieve a filing or report (10-K, 10-Q, earnings release, etc.) from Quartr by its document ID and download the PDF file."},{"name":"List Slide Decks","description":"List slide presentations from Quartr, filterable by company, event, document type, document group, and date range."},{"name":"Get Slide Deck","description":"Retrieve a slide presentation from Quartr by its document ID and download the PDF file."},{"name":"List Transcripts","description":"List event transcripts from Quartr, filterable by company, event, document type, document group, and date range."},{"name":"Get Transcript","description":"Retrieve an event transcript from Quartr by its document ID and download the transcript JSON file (paragraphs, sentences, timestamps, and speaker identification)."},{"name":"List Audio","description":"List archived event audio recordings from Quartr, filterable by company, event, and date range. Returns download (MPEG) and streaming (M3U8) URLs."},{"name":"Get Audio","description":"Retrieve an archived event audio recording from Quartr by its audio ID. Returns download (MPEG) and streaming (M3U8) URLs."},{"name":"List Live Events","description":"List live and upcoming events from Quartr with live audio and transcript stream URLs, filterable by company, live state, and date range."}],"triggers":[],"skills":[{"name":"summarize-earnings-call","description":"Find a company’s latest earnings call on Quartr and return its AI-generated summary with sources.","content":"# Summarize an Earnings Call\\n\\nTurn a ticker into a sourced summary of the company’s most recent earnings call.\\n\\n## Steps\\n1. Use the List Companies operation with the ticker in Tickers to resolve the Quartr company ID.\\n2. Use List Events with that ID in Company IDs, Sort By set to Date, and Sort Direction set to Descending to find the latest earnings event.\\n3. Use Get Event Summary with the event ID. Pick Summary Length: One Line for a headline, Short for a digest, or Long for full detail.\\n4. Keep Plain Text Summary off if you want the embedded source tags, and use the sources output to cite documents.\\n\\n## Output\\nReturn the summary text followed by the event title, date, and the source document IDs it references."},{"name":"download-earnings-transcript","description":"Download the structured transcript JSON for a company’s earnings call for downstream analysis.","content":"# Download an Earnings Call Transcript\\n\\nFetch a transcript with timestamps and speaker identification as a workflow file.\\n\\n## Steps\\n1. Resolve the company with List Companies (ticker, ISIN, or CIK).\\n2. Use List Transcripts with the company ID in Company IDs and a date range to find the right transcript document.\\n3. Use Get Transcript with that document ID. The transcript JSON is downloaded and stored as an execution file.\\n4. Pass the file to an agent or knowledge base to analyze paragraphs, sentences, timestamps, and speakers.\\n\\n## Output\\nReturn the transcript file plus the document metadata (event title, fiscal period, and date)."},{"name":"fetch-latest-filings","description":"List a company’s recent filings and reports on Quartr and download the report PDFs.","content":"# Fetch the Latest Filings and Reports\\n\\nPull recent 10-Ks, 10-Qs, earnings releases, or annual reports for a company.\\n\\n## Steps\\n1. Resolve the company with List Companies using its ticker or CIK.\\n2. Use List Reports with the company ID in Company IDs. Narrow with Document Group IDs (1 = Earnings Release, 3 = Interim Report, 4 = Annual Report) or a date range.\\n3. Use Get Report with each document ID to download the PDF into execution files.\\n4. Optionally use List Document Types to map type IDs to filing forms like 10-Q.\\n\\n## Output\\nReturn the report files with each document’s type, event, and filing date."},{"name":"monitor-live-earnings","description":"Check which companies are live on Quartr right now and surface their audio and transcript streams.","content":"# Monitor Live Earnings Calls\\n\\nWatch for companies going live and grab their stream URLs.\\n\\n## Steps\\n1. Use List Live Events with Live States set to live (or willBeLive to see what is coming up).\\n2. Filter to your watchlist with Company IDs or Tickers.\\n3. Read each live event’s state, audio stream URL, and transcript stream URL from the output.\\n4. Run the workflow on a schedule and alert when a watched company’s state changes to live.\\n\\n## Output\\nReturn the live companies with their event IDs, states, and audio/transcript stream URLs."},{"name":"analyze-investor-slides","description":"Download a company’s latest investor presentation from Quartr and extract key takeaways.","content":"# Analyze an Investor Slide Deck\\n\\nGet the latest presentation PDF and have an agent extract what matters.\\n\\n## Steps\\n1. Resolve the company with List Companies and find the relevant event with List Events.\\n2. Use List Slide Decks with the event ID in Event IDs (or the company ID and a date range) to find the deck.\\n3. Use Get Slide Deck with the document ID to download the PDF into execution files.\\n4. Pass the file to an agent to extract guidance, KPIs, and notable changes.\\n\\n## Output\\nReturn the slide deck file plus the extracted highlights."}],"templates":[{"title":"Quartr earnings call digest","prompt":"Create a scheduled workflow that lists yesterday’s Quartr events for my watchlist tickers, fetches the AI-generated summary for each event, and posts a digest with source links to Slack.","integrations":[{"id":"quartr","name":"Quartr"},{"id":"slack","name":"Slack"}]},{"title":"Quartr transcript knowledge base","prompt":"Build a scheduled workflow that lists new Quartr earnings call transcripts for companies I follow, downloads each transcript file, and indexes the content into a knowledge base so agents can answer questions about past calls.","integrations":[{"id":"quartr","name":"Quartr"}]},{"title":"Quartr filing watcher","prompt":"Create a scheduled workflow that checks Quartr daily for new annual and interim reports from my portfolio companies, downloads each report PDF to Files, and emails me a summary of what was filed.","integrations":[{"id":"quartr","name":"Quartr"},{"id":"gmail","name":"Gmail"}]},{"title":"Quartr slide deck analyst","prompt":"Build a workflow that fetches the latest Quartr slide deck for a given ticker, has an agent extract guidance, KPIs, and notable changes from the deck, and writes the analysis to a table.","integrations":[{"id":"quartr","name":"Quartr"}]},{"title":"Quartr live earnings monitor","prompt":"Create a scheduled workflow that polls Quartr live events for my watchlist, and when a company goes live, posts the live audio and transcript stream links to a Slack channel.","integrations":[{"id":"quartr","name":"Quartr"},{"id":"slack","name":"Slack"}]},{"title":"Quartr competitor earnings tracker","prompt":"Build a workflow that reads competitor tickers from a table, lists each company’s recent Quartr events and event summaries, and logs revenue and guidance highlights back to the table for quarter-over-quarter comparison.","integrations":[{"id":"quartr","name":"Quartr"}]},{"title":"Quartr earnings Q&A agent","prompt":"Create an agent that answers questions about a company’s earnings by looking up the company on Quartr, finding its latest earnings call event, and grounding answers in the event summary and transcript.","integrations":[{"id":"quartr","name":"Quartr"}]}]},{"id":"quickbooks","type":"quickbooks","slug":"quickbooks","name":"QuickBooks","description":"Manage QuickBooks Online company, transactions, reports, emails, PDFs, and attachments","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/quickbooks","authType":"oauth","connections":[{"id":"quickbooks","kind":"oauth","label":"Connect with OAuth","providerId":"quickbooks","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/quickbooks","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"com.intuit.quickbooks.accounting","label":"Access and manage accounting data in the connected QuickBooks Online company"}],"fields":[{"id":"clientId","label":"Client ID","placeholder":"Enter your Intuit app client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Enter your Intuit app client secret","secret":true},{"id":"environment","label":"Environment","placeholder":"Select an Intuit environment","secret":false,"options":[{"value":"sandbox","label":"Sandbox"},{"value":"production","label":"Production"}],"hint":"Use the environment that matches the credentials in your Intuit app."},{"id":"webhookVerifierToken","label":"Webhook verifier token","placeholder":"Enter your Intuit app webhook verifier token","secret":true,"hint":"Used only to authenticate QuickBooks webhook triggers for this Intuit app."}]}],"operations":[{"name":"Get Company Info","description":"Get information about the connected QuickBooks Online company"},{"name":"Read Master Data","description":"List or read one account, class, customer, department, employee, item, or vendor"},{"name":"Create Customer","description":"Create a customer in the connected QuickBooks Online company"},{"name":"Update Customer","description":"Sparse-update a customer in the connected QuickBooks Online company"},{"name":"Create Employee","description":"Create a non-payroll employee profile in the connected QuickBooks Online company"},{"name":"Update Employee","description":"Read, merge, and full-update a non-payroll employee profile"},{"name":"Create Vendor","description":"Create a vendor in the connected QuickBooks Online company"},{"name":"Update Vendor","description":"Read, merge, and full-update a vendor in QuickBooks Online"},{"name":"Create Item","description":"Create a Service or Non-inventory item in QuickBooks Online"},{"name":"Update Item","description":"Read, merge, and full-update a Service or Non-inventory item without changing its type"},{"name":"Read Sales Transactions","description":"List or read one estimate, invoice, sales receipt, payment, credit memo, or refund receipt"},{"name":"Create Estimate","description":"Create an estimate with bounded item and description lines"},{"name":"Update Estimate","description":"Sparse-update an estimate using its current sync token"},{"name":"Create Invoice","description":"Create an invoice without emailing or collecting payment"},{"name":"Update Invoice","description":"Sparse-update an invoice using its current sync token"},{"name":"Void Invoice","description":"Void an invoice after explicit confirmation"},{"name":"Create Sales Receipt","description":"Create a sales receipt for a completed customer sale"},{"name":"Update Sales Receipt","description":"Sparse-update a sales receipt using its current sync token"},{"name":"Void Sales Receipt","description":"Void a sales receipt after explicit confirmation"},{"name":"Create Customer Payment","description":"Record a customer payment with optional bounded invoice allocations"},{"name":"Update Customer Payment","description":"Read, merge, and full-update a customer payment using its current sync token"},{"name":"Void Customer Payment","description":"Void a customer payment after explicit confirmation"},{"name":"Create Credit Memo","description":"Create a customer credit memo with bounded sales lines"},{"name":"Update Credit Memo","description":"Read, merge, and full-update a credit memo using its current sync token"},{"name":"Create Refund Receipt","description":"Create a customer refund receipt against a required deposit account"},{"name":"Update Refund Receipt","description":"Sparse-update a refund receipt using its current sync token"},{"name":"Read Purchasing Transactions","description":"List or read one purchase order, bill, bill payment, vendor credit, or purchase"},{"name":"Create Purchase Order","description":"Create a purchase order with bounded expense lines"},{"name":"Update Purchase Order","description":"Read, merge, and full-update purchase-order header fields"},{"name":"Create Bill","description":"Create a vendor bill with optional Purchase Order line links without paying it"},{"name":"Update Bill","description":"Read, merge, and full-update bill header fields using its current sync token"},{"name":"Create Bill Payment","description":"Record a check or credit-card payment allocated to one or more bills"},{"name":"Update Bill Payment","description":"Read, merge, and full-update a BillPayment without changing allocations"},{"name":"Void Bill Payment","description":"Void a bill payment after explicit confirmation"},{"name":"Create Vendor Credit","description":"Create a vendor credit without applying it to a bill"},{"name":"Update Vendor Credit","description":"Read, merge, and full-update vendor-credit header fields"},{"name":"Create Purchase or Expense","description":"Record a cash, check, or credit-card purchase with bounded expense lines"},{"name":"Update Purchase or Expense","description":"Read, merge, and full-update purchase header fields without changing lines"},{"name":"Read Accounting Transactions","description":"List or read one journal entry, deposit, or transfer"},{"name":"Create Journal Entry","description":"Post a balanced journal entry after explicit confirmation"},{"name":"Update Journal Entry","description":"Sparse-update journal-entry header fields after explicit confirmation"},{"name":"Create Deposit","description":"Create a deposit with bounded account lines"},{"name":"Update Deposit","description":"Sparse-update deposit header fields using the current sync token and destination account"},{"name":"Run Financial Report","description":"Run a fixed QuickBooks financial report with verified accountant-focused filters"},{"name":"Email Transaction","description":"Send a supported QuickBooks transaction by email. This causes an external email and Intuit limits sandbox email delivery."},{"name":"Download Transaction PDF","description":"Download a supported QuickBooks transaction as a bounded PDF file"},{"name":"Read Attachments","description":"List attachment metadata for a fixed QuickBooks entity or read one attachment by ID"},{"name":"Add Attachment","description":"Attach one supported file or one note to a fixed QuickBooks entity"},{"name":"Download Attachment","description":"Download a QuickBooks file attachment as a stored Sim file"}],"triggers":[{"id":"quickbooks_invoice_events","name":"QuickBooks Invoice Events","description":"Trigger when selected Invoice events occur in QuickBooks"},{"id":"quickbooks_customer_events","name":"QuickBooks Customer Events","description":"Trigger when selected Customer events occur in QuickBooks"},{"id":"quickbooks_estimate_events","name":"QuickBooks Estimate Events","description":"Trigger when selected Estimate events occur in QuickBooks"},{"id":"quickbooks_payment_events","name":"QuickBooks Payment Events","description":"Trigger when selected Payment events occur in QuickBooks"},{"id":"quickbooks_credit_memo_events","name":"QuickBooks Credit Memo Events","description":"Trigger when selected Credit Memo events occur in QuickBooks"},{"id":"quickbooks_refund_receipt_events","name":"QuickBooks Refund Receipt Events","description":"Trigger when selected Refund Receipt events occur in QuickBooks"},{"id":"quickbooks_sales_receipt_events","name":"QuickBooks Sales Receipt Events","description":"Trigger when selected Sales Receipt events occur in QuickBooks"},{"id":"quickbooks_vendor_events","name":"QuickBooks Vendor Events","description":"Trigger when selected Vendor events occur in QuickBooks"},{"id":"quickbooks_bill_events","name":"QuickBooks Bill Events","description":"Trigger when selected Bill events occur in QuickBooks"},{"id":"quickbooks_bill_payment_events","name":"QuickBooks Bill Payment Events","description":"Trigger when selected Bill Payment events occur in QuickBooks"},{"id":"quickbooks_purchase_order_events","name":"QuickBooks Purchase Order Events","description":"Trigger when selected Purchase Order events occur in QuickBooks"},{"id":"quickbooks_purchase_events","name":"QuickBooks Purchase Events","description":"Trigger when selected Purchase events occur in QuickBooks"},{"id":"quickbooks_vendor_credit_events","name":"QuickBooks Vendor Credit Events","description":"Trigger when selected Vendor Credit events occur in QuickBooks"},{"id":"quickbooks_deposit_events","name":"QuickBooks Deposit Events","description":"Trigger when selected Deposit events occur in QuickBooks"},{"id":"quickbooks_journal_entry_events","name":"QuickBooks Journal Entry Events","description":"Trigger when selected Journal Entry events occur in QuickBooks"},{"id":"quickbooks_transfer_events","name":"QuickBooks Transfer Events","description":"Trigger when selected Transfer events occur in QuickBooks"},{"id":"quickbooks_item_events","name":"QuickBooks Item Events","description":"Trigger when selected Item events occur in QuickBooks"},{"id":"quickbooks_employee_events","name":"QuickBooks Employee Events","description":"Trigger when selected Employee events occur in QuickBooks"},{"id":"quickbooks_time_activity_events","name":"QuickBooks Time Activity Events","description":"Trigger when selected Time Activity events occur in QuickBooks"},{"id":"quickbooks_account_events","name":"QuickBooks Account Events","description":"Trigger when selected Account events occur in QuickBooks"},{"id":"quickbooks_budget_events","name":"QuickBooks Budget Events","description":"Trigger when selected Budget events occur in QuickBooks"},{"id":"quickbooks_class_events","name":"QuickBooks Class Events","description":"Trigger when selected Class events occur in QuickBooks"},{"id":"quickbooks_currency_events","name":"QuickBooks Currency Events","description":"Trigger when selected Currency events occur in QuickBooks"},{"id":"quickbooks_department_events","name":"QuickBooks Department Events","description":"Trigger when selected Department events occur in QuickBooks"},{"id":"quickbooks_journal_code_events","name":"QuickBooks Journal Code Events","description":"Trigger when selected Journal Code events occur in QuickBooks"},{"id":"quickbooks_payment_method_events","name":"QuickBooks Payment Method Events","description":"Trigger when selected Payment Method events occur in QuickBooks"},{"id":"quickbooks_preferences_updated","name":"QuickBooks Preferences Updated","description":"Trigger when QuickBooks Preferences are updated"},{"id":"quickbooks_tax_agency_events","name":"QuickBooks Tax Agency Events","description":"Trigger when selected Tax Agency events occur in QuickBooks"},{"id":"quickbooks_term_events","name":"QuickBooks Term Events","description":"Trigger when selected Term events occur in QuickBooks"}],"skills":[{"name":"onboard-quickbooks-customers","description":"Create approved QuickBooks customers and retain their IDs and record versions.","content":"# Onboard QuickBooks Customers\\n\\n## Steps\\n1. Validate the approved customer identity and contact details.\\n2. Use Create Customer with a unique display name.\\n3. Store the returned `recordId` and `recordVersion`; connect `recordVersion` to the Sync Token input for later updates.\\n\\n## Output\\nReturn the created customer, ID, and record version. Report duplicate-name faults for human review."},{"name":"onboard-quickbooks-vendors","description":"Create approved QuickBooks vendors with bounded contact and 1099 fields.","content":"# Onboard QuickBooks Vendors\\n\\n## Steps\\n1. Validate the approved vendor identity, contact, address, and optional 1099 status.\\n2. Use Create Vendor.\\n3. Store the returned `recordId` and `recordVersion`; connect `recordVersion` to the Sync Token input for later updates.\\n\\n## Output\\nReturn the created vendor and identifiers. Do not claim to merge vendors or administer tax identifiers."},{"name":"maintain-products-and-services","description":"Create supported items or update exposed item fields without changing types.","content":"# Maintain QuickBooks Products and Services\\n\\n## Steps\\n1. Read Account master data to obtain approved account IDs.\\n2. Create a Service or Non-inventory Item, or update exposed basic fields without changing the existing item Type.\\n3. Store the latest item ID and record version; connect the record version to the Sync Token input for updates.\\n\\n## Output\\nReturn the native Item record and record version. Do not claim to create Inventory, Category, or Group items or manage their specialized fields."},{"name":"record-quickbooks-accounting-adjustments","description":"Post approved balanced journal entries, record deposits, and review transfers.","content":"# Record QuickBooks Accounting Adjustments\\n\\n## Steps\\n1. Read the approved account IDs from Master Data.\\n2. For a journal entry, verify that positive debit and credit lines balance and require explicit posting confirmation; for a deposit, verify the destination and source account IDs.\\n3. Store the returned `recordId` and `recordVersion`; connect `recordVersion` to the Sync Token input for later updates, and use Read Accounting Transactions to review journal entries, deposits, or read-only transfers.\\n4. Run an approved Trial Balance or financial statement on cash or accrual basis when an accountant requests post-adjustment review.\\n\\n## Output\\nReturn the native accounting transaction and identifiers plus the native report hierarchy when requested. Do not claim to create transfers, replace transaction lines, or administer currencies."},{"name":"prepare-quickbooks-estimates","description":"Create and revise bounded QuickBooks estimates from approved quote details.","content":"# Prepare QuickBooks Estimates\\n\\n## Steps\\n1. Validate the customer, item IDs, amounts, and dates.\\n2. Use Create Estimate with bounded item or description lines.\\n3. For a revision, use the estimate ID and latest `recordVersion` as the Update Estimate Sync Token input.\\n\\n## Output\\nReturn the native Estimate, ID, and latest record version. Do not claim to email or accept the estimate."},{"name":"create-quickbooks-invoices","description":"Create approved QuickBooks invoices and explicitly deliver or archive their documents.","content":"# Create and Deliver QuickBooks Invoices\\n\\n## Steps\\n1. Validate the approved customer, item IDs, positive amounts, and optional dates.\\n2. Use Create Invoice with at least one bounded line.\\n3. Store the returned `recordId` and `recordVersion`; connect `recordVersion` to the Sync Token input for later updates.\\n4. Only after explicit approval, use Email Transaction for one recipient or Download Transaction PDF for controlled archiving.\\n5. Use Add Attachment for one approved receipt or audit note when needed, and Read Attachments to verify the metadata.\\n\\n## Output\\nReturn the native Invoice and identifiers plus any sent status, downloaded file, or attachment ID. Do not claim bulk email, automatic resend, attachment deletion, or automatic payment collection."},{"name":"record-quickbooks-payables","description":"Create standalone or PO-linked bills and record bounded payments to approved Bill IDs.","content":"# Record QuickBooks Payables\\n\\n## Steps\\n1. Validate the vendor, expense lines, and optional A/P account.\\n2. For PO-linked billing, use Read Purchasing Transactions by ID and copy each approved Purchase Order `Line[].Id` into the matching Create Bill line with its PO ID.\\n3. Use Create Bill, store its ID and record version, and inspect `linkingSucceeded` and `missingLinks`; QuickBooks may create the Bill while omitting an invalid or unavailable link.\\n4. When payment is separately approved, use Create Bill Payment with bounded Bill allocations whose amounts equal the payment total.\\n5. Run A/P Aging Summary or Detail with supported vendor, department, date, and aging controls for accountant review.\\n\\n## Output\\nAlways return the created Bill ID, record version, and linkage result. Preserve the native aging report when requested. Never imply that a missing link prevented Bill creation, and never create a payment implicitly."},{"name":"analyze-quickbooks-financial-reports","description":"Run verified financial, balance, aging, sales, and expense reports with supported filters.","content":"# Analyze QuickBooks Financial Reports\\n\\n## Steps\\n1. Choose a verified report and an accountant-approved date or as-of period.\\n2. Use Read Master Data to discover customer, vendor, account, item, class, or department IDs required by supported filters.\\n3. Run Financial Report with only the controls shown for that report; compare cash and accrual basis or time summaries when requested.\\n4. Preserve the native Header, Columns, nested Rows, and summaries for review.\\n\\n## Output\\nReturn the report hierarchy and applied report context. Do not claim to export spreadsheets, email reports, customize columns, schedule delivery in QuickBooks, or mutate accounting records from a report."}],"templates":[{"title":"QuickBooks customer onboarding","prompt":"Build a workflow that receives an approved customer profile, creates the QuickBooks customer, and stores its ID and record version in a Sim table.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks vendor onboarding","prompt":"Create a workflow that receives approved vendor identity, contact, address, and 1099 details, creates the QuickBooks vendor, and stores the returned ID and record version.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks catalogue maintenance","prompt":"Build a workflow that reads filtered QuickBooks master data, creates approved non-payroll employees or Service and Non-inventory items, and safely updates exposed fields while retaining returned IDs and record versions.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks monthly and year-end reporting","prompt":"Build a scheduled workflow that runs monthly and year-end Balance Sheet, Profit and Loss, Trial Balance, and Cash Flow reports, preserves their native rows and summaries, and stores review results in a Sim table.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks estimate preparation","prompt":"Build a workflow that receives an approved customer quote and line items, creates a QuickBooks estimate, and stores its ID and record version for controlled revisions.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks invoice creation and delivery","prompt":"Create a workflow that validates approved customer and item IDs, creates a QuickBooks invoice, stores its ID and record version, then—after explicit approval—emails it or downloads its PDF for controlled delivery and archiving.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks partial-payment application","prompt":"Build a workflow that records a customer payment, applies bounded amounts to approved QuickBooks invoice IDs, and reports any unapplied remainder.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks journal adjustments and deposits","prompt":"Build a controlled workflow that posts an explicitly approved, balanced QuickBooks journal entry or records a bounded deposit, then runs cash- and accrual-basis reports to support the accounting review.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks receivables and payables aging","prompt":"Create a scheduled workflow that runs A/R and A/P aging summaries and details with approved aging controls, optionally filters by customer or vendor, and flags balances requiring accountant review without changing records.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks bill entry and payment","prompt":"Build a controlled workflow that reads an approved Purchase Order by ID, captures its Line IDs, creates a QuickBooks Bill with explicit PO-line mappings, checks linkingSucceeded and missingLinks, attaches one approved receipt or audit note, and records a separately approved payment only after reviewing the created Bill.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]},{"title":"QuickBooks customer, vendor, and expense analysis","prompt":"Create a workflow that runs customer and vendor balance reports, expenses by vendor, or the Transaction List with bounded date, entity, paid-status, cleared-status, document-number, grouping, and source-account filters for accountant review.","integrations":[{"id":"quickbooks","name":"QuickBooks"}]}]},{"id":"quiver","type":"quiver_v2","slug":"quiver","name":"Quiver","description":"Generate and vectorize SVGs","category":"AI","docsUrl":"https://docs.sim.ai/integrations/quiver","authType":"api-key","connections":[],"operations":[{"name":"Text to SVG","description":"Generate SVG images from text prompts using QuiverAI"},{"name":"Image to SVG","description":"Convert raster images into vector SVG format using QuiverAI"},{"name":"List Models","description":"List all available QuiverAI models"}],"triggers":[],"skills":[{"name":"generate-brand-icon","description":"Generate a clean SVG icon from a text prompt and save it to the files store.","content":"# Generate Brand Icon\\n\\nTurn a text description into a production-ready SVG icon using Quiver text-to-SVG.\\n\\n## Steps\\n1. Collect the icon concept (for example, a product name plus a brand color and style cues).\\n2. Run the text_to_svg operation with a focused prompt that names the subject, color palette, and visual style (flat, line, filled).\\n3. Optionally set n greater than 1 to generate several variations to choose from.\\n4. Save the returned SVG file to the files store, or pass the file downstream.\\n\\n## Output\\nReport the saved file location and the request id. When multiple variations are generated, list each so the user can pick one."},{"name":"vectorize-raster-image","description":"Convert an uploaded raster image (PNG or JPG) into a clean editable SVG.","content":"# Vectorize Raster Image\\n\\nConvert a bitmap logo or graphic into a scalable SVG with Quiver image-to-SVG.\\n\\n## Steps\\n1. Accept the raster image upload and pass it as the image input.\\n2. Run the image_to_svg operation, optionally setting auto_crop and a target_size to tighten the output.\\n3. Inspect the generated SVG file for fidelity; rerun with adjusted instructions if details are lost.\\n4. Save the SVG file for use in presentations, exports, or the web.\\n\\n## Output\\nReturn the vectorized SVG file and confirm dimensions. Note any visual elements that did not vectorize cleanly."},{"name":"create-data-diagram","description":"Generate an SVG diagram that visualizes structured data, then share it.","content":"# Create Data Diagram\\n\\nProduce a clean SVG diagram from structured data and attach it to a message.\\n\\n## Steps\\n1. Read the structured data (for example, rows from a table) that should be visualized.\\n2. Summarize the data into a precise prompt describing the diagram type and relationships.\\n3. Run the text_to_svg operation to generate the diagram.\\n4. Save the SVG file and attach it to the target channel or document.\\n\\n## Output\\nShare the generated diagram file and a one-line description of what it depicts."}],"templates":[{"title":"Quiver SVG icon generator","prompt":"Build a workflow that takes a product name and brand color as inputs, generates a matching SVG icon with Quiver, and saves it to the files store.","integrations":[{"id":"quiver","name":"Quiver"}]},{"title":"Quiver diagram creator","prompt":"Create a workflow that reads structured data from a table and uses Quiver to generate a clean SVG diagram visualizing the data, then attaches it to a Slack message.","integrations":[{"id":"quiver","name":"Quiver"}]},{"title":"Quiver image vectorizer","prompt":"Build a workflow that accepts a raster image upload, vectorizes it to SVG with Quiver, and returns the clean SVG for use in presentations or exports.","integrations":[{"id":"quiver","name":"Quiver"}]}]},{"id":"rabbitmq","type":"rabbitmq","slug":"rabbitmq","name":"RabbitMQ","description":"Publish and read messages and manage queues in RabbitMQ","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/rabbitmq","authType":"api-key","connections":[],"operations":[{"name":"Publish Message","description":"Publish a message to a RabbitMQ exchange with a routing key. Reports whether the message was routed to at least one queue."},{"name":"Get Messages","description":"Retrieve messages from a RabbitMQ queue. Defaults to requeueing the messages so they stay available to real consumers."},{"name":"List Queues","description":"List queues in a RabbitMQ virtual host with their depth, consumer count, and configuration."},{"name":"Get Queue","description":"Read a single RabbitMQ queue, including its depth, consumer count, and declaration settings."},{"name":"Create Queue","description":"Declare a RabbitMQ queue. Declaring a queue that already exists with the same settings succeeds without changing it."},{"name":"Delete Queue","description":"Delete a RabbitMQ queue and every message still in it. Can be guarded so the delete only happens when the queue is unused or empty."},{"name":"Purge Queue","description":"Discard every ready message in a RabbitMQ queue while leaving the queue itself in place."},{"name":"List Exchanges","description":"List exchanges in a RabbitMQ virtual host with their type and declaration settings."},{"name":"Get Exchange","description":"Read a single RabbitMQ exchange and the settings it was declared with."},{"name":"Create Exchange","description":"Declare a RabbitMQ exchange. Declaring an exchange that already exists with the same settings succeeds without changing it."},{"name":"Delete Exchange","description":"Delete a RabbitMQ exchange and every binding attached to it. Publishers targeting it will fail afterwards."},{"name":"List Queue Bindings","description":"List the bindings that route messages into a RabbitMQ queue, including the implicit default-exchange binding."},{"name":"List Exchange Bindings","description":"List everything an exchange routes to, so you can see which routing keys reach which queues."},{"name":"Create Binding","description":"Bind a queue or another exchange to a RabbitMQ exchange so messages matching a routing key are routed to it."},{"name":"Delete Binding","description":"Remove a binding so an exchange stops routing its matching messages to that destination."},{"name":"Get Overview","description":"Read broker-wide RabbitMQ status: version, cluster name, object totals, queue depth totals, and message rates."},{"name":"Health Check","description":"Run one of the broker health checks and report whether it passed. A failing check is a normal result, not a tool error."},{"name":"List Nodes","description":"List the cluster nodes with memory, disk, file-descriptor, and alarm state. A fired alarm blocks publishers broker-wide."},{"name":"List Virtual Hosts","description":"List the virtual hosts on the broker with their message totals, so you can discover which scopes exist."},{"name":"List Connections","description":"List client connections to the broker with their user, state, and channel count. Connections are cluster-wide, not scoped to one virtual host."},{"name":"List Channels","description":"List open channels with their prefetch limit and unacknowledged message count, which is where stalled consumers show up. Channels are cluster-wide, not scoped to one virtual host."},{"name":"List Consumers","description":"List the consumers subscribed in a virtual host. An empty result for a queue with a backlog means nothing is processing it."},{"name":"List Policies","description":"List the policies in a virtual host. Policies are how dead-lettering, TTLs, and length limits get applied to matching queues and exchanges."},{"name":"Create Policy","description":"Create or replace a RabbitMQ policy, applying settings such as dead-lettering, TTLs, or length limits to every queue or exchange whose name matches a pattern."},{"name":"Delete Policy","description":"Delete a RabbitMQ policy. Every queue and exchange it matched immediately loses the settings it applied."}],"triggers":[],"skills":[{"name":"publish-rabbitmq-message","description":"Publish a message to a RabbitMQ exchange and confirm it was routed.","content":"# Publish RabbitMQ Message\\n\\nSend a message into a RabbitMQ topology.\\n\\n## Steps\\n1. Confirm the management URL, credentials, and virtual host.\\n2. Choose the Publish Message operation. Set the exchange and routing key — to target a queue directly, leave the exchange empty and set the routing key to the queue name.\\n3. Put the body in the message field. For JSON, set content_type to application/json in the message properties, and set delivery_mode to 2 so the message survives a broker restart.\\n4. Add headers when downstream consumers or a headers exchange route on them.\\n\\n## Output\\nReport whether the message was routed. A routed value of false means no binding matched the routing key and the broker dropped the message — check the exchange bindings before retrying."},{"name":"drain-rabbitmq-queue","description":"Read messages off a RabbitMQ queue for inspection or reprocessing.","content":"# Drain RabbitMQ Queue\\n\\nRetrieve messages from a queue so they can be inspected or reprocessed.\\n\\n## Steps\\n1. Confirm the management URL, credentials, virtual host, and queue name.\\n2. Choose the Get Messages operation and set the count. Leave the acknowledgement mode at \\"Ack, requeue\\" to inspect messages without consuming them; switch to \\"Ack, discard\\" only when the messages should be removed.\\n3. Raise the truncate limit if payloads are being cut short.\\n\\n## Output\\nReturn the retrieved messages with their routing key, headers, and body, plus how many remain in the queue. Note explicitly whether the messages were left in place or removed."},{"name":"audit-rabbitmq-queues","description":"Review RabbitMQ queue depth, consumers, and broker health.","content":"# Audit RabbitMQ Queues\\n\\nAssess the state of a RabbitMQ broker.\\n\\n## Steps\\n1. Confirm the management URL and credentials.\\n2. Run Get Overview for broker version, node, and aggregate queue totals.\\n3. Run List Queues for the virtual host. Use the name filter to narrow to a service prefix.\\n4. Flag queues where messages are growing, consumers is zero, or state is not running. Queue statistics are null until the broker has collected them, which is normal for a freshly declared queue.\\n\\n## Output\\nReport the broker version and totals, then the problem queues with their depth and consumer count and what each symptom implies — a backlog with no consumers means nothing is processing, a backlog with consumers means processing is too slow."},{"name":"triage-rabbitmq-alarms","description":"Check RabbitMQ broker health and explain what a fired alarm means.","content":"# Triage RabbitMQ Alarms\\n\\nDetermine whether the broker is healthy and what to do if it is not.\\n\\n## Steps\\n1. Confirm the management URL and credentials.\\n2. Run Health Check with the alarms check for a cluster-wide answer. A failing check is a normal result — read the healthy flag and reason rather than treating it as an error.\\n3. Run List Nodes and inspect memory and disk alarms, the free-versus-limit figures, file-descriptor usage, and partitions. A non-empty partitions list means the cluster is split-brained and needs manual recovery.\\n4. For a cluster, also run the quorum-critical check to confirm quorum queues would survive losing the node, and the virtual-hosts check to confirm every vhost is running.\\n\\n## Output\\nState whether the broker is healthy. When a resource alarm has fired, say plainly that publishers are currently blocked broker-wide until the resource is reclaimed, name the node and the resource, and give the free-versus-limit numbers. Recommend consuming the backlog or raising the watermark rather than restarting the node."},{"name":"find-stalled-rabbitmq-consumers","description":"Work out why a RabbitMQ queue has a backlog that is not draining.","content":"# Find Stalled RabbitMQ Consumers\\n\\nDistinguish \\"nothing is consuming\\" from \\"consuming too slowly\\" from \\"consumers are stuck\\".\\n\\n## Steps\\n1. Confirm the management URL, credentials, and virtual host.\\n2. Run Get Queue on the affected queue and note messages, messagesReady, and messagesUnacknowledged. Null values mean the broker has not collected statistics yet, not that the queue is empty.\\n3. Run List Consumers. No consumers on a queue with a backlog means nothing is processing it — the application is down or never subscribed.\\n4. If consumers exist, check their active flag and activityStatus, then run List Channels and compare messagesUnacknowledged against prefetchCount. A channel pinned at its prefetch limit is a consumer that received messages and never acknowledged them.\\n5. Run List Connections to confirm the client is still connected and its state is running rather than blocked or flow — blocked means a resource alarm is throttling it.\\n\\n## Output\\nName which of the three cases applies and the evidence for it. For no consumers, say the application is not subscribed. For unacknowledged messages stuck at the prefetch limit, say consumers are hung mid-processing and those messages will be redelivered when the connection drops. For flow or blocked connection state, point at the resource alarm instead."},{"name":"configure-rabbitmq-dead-lettering","description":"Apply dead-lettering to a family of RabbitMQ queues with a policy.","content":"# Configure RabbitMQ Dead-Lettering\\n\\nRoute rejected and expired messages somewhere you can inspect them.\\n\\n## Steps\\n1. Confirm the management URL, credentials, and virtual host.\\n2. Create the dead-letter exchange and the queue that will hold the failures, then bind them.\\n3. Use Create Policy with a pattern matching the queues to protect and a definition setting dead-letter-exchange, plus message-ttl, max-length, or delivery-limit as needed. A policy is the right tool here because it applies to matching queues that already exist — queue arguments only take effect at declaration time, so setting them on a live queue means deleting and redeclaring it.\\n4. Run List Policies and confirm the priority. Only the single highest-priority matching policy applies to a resource; policies do not merge, so a higher-priority policy elsewhere will silently override this one.\\n5. Verify with Get Queue that the queue reports the expected policy.\\n\\n## Output\\nReport the policy name, pattern, definition, and priority, and which queues it now governs. Warn about any existing policy at equal or higher priority whose pattern also matches, since that one wins."},{"name":"diagnose-unrouted-messages","description":"Work out why a published RabbitMQ message was not routed to any queue.","content":"# Diagnose Unrouted Messages\\n\\nFind why a publish reported `routed: false`.\\n\\n## Steps\\n1. Confirm the management URL, credentials, and virtual host — a message published to the wrong vhost cannot match any binding.\\n2. Run List Exchanges and confirm the target exchange exists and note its type. The type decides how matching works: direct requires the routing key to equal the binding key exactly, topic matches wildcard patterns, fanout ignores the routing key, and headers ignores it entirely in favour of binding arguments.\\n3. Run List Bindings on the queue that should have received the message and compare each binding routing key against the key that was published. Watch for the common causes: a typo, a topic pattern that uses `*` (exactly one word) where `#` (zero or more words) was needed, or a queue bound to a different exchange.\\n4. If no binding matches, use Create Binding to add the missing one, then republish and confirm `routed` is true.\\n\\n## Output\\nState the exchange type, the routing key that was published, and every binding that could have matched. Name the specific mismatch, then the exact binding needed to fix it. An unrouted message is gone — the broker drops it unless the exchange has an alternate exchange configured, so re-publishing after the fix is required."},{"name":"purge-queue-safely","description":"Clear a RabbitMQ queue after confirming what would be lost.","content":"# Purge Queue Safely\\n\\nDiscard a queue backlog without throwing away messages that still matter.\\n\\n## Steps\\n1. Confirm the management URL, credentials, virtual host, and queue name.\\n2. Run Get Queue first and report the current depth. If message counts come back null the broker has not collected statistics yet — wait and re-read rather than assuming the queue is empty.\\n3. Sample the backlog with Get Messages at the default requeue acknowledgement mode so nothing is consumed, and summarize what the messages are.\\n4. Only after the user confirms, run Purge Queue. It discards every ready message and cannot be undone. To remove the queue itself instead, use Delete Queue with the only-if-empty guard so the call fails rather than destroying unread messages.\\n\\n## Output\\nReport the depth before purging, a summary of what the sampled messages contained, and the depth afterwards. If the queue is a dead-letter queue, say so explicitly and recommend replaying or archiving the messages before discarding them."},{"name":"set-up-rabbitmq-topology","description":"Declare RabbitMQ queues and bind them to an exchange.","content":"# Set Up RabbitMQ Topology\\n\\nCreate the queues and bindings a pipeline needs.\\n\\n## Steps\\n1. Confirm the management URL, credentials, and virtual host.\\n2. Use Create Queue for each queue. Keep durable on so queues survive a restart. Set arguments for a quorum queue, a message TTL, a length limit, or dead lettering.\\n3. Use Create Binding to attach each queue to its exchange with the routing key it should receive. Topic exchanges accept wildcards such as orders.* for one segment and orders.# for many.\\n4. Verify with List Bindings on each queue.\\n\\n## Output\\nList the queues declared and the bindings created with their routing keys. Note that every queue also has an implicit default-exchange binding on its own name, which appears with an empty source."}],"templates":[{"title":"RabbitMQ dead-letter triage","prompt":"Build a scheduled workflow that reads messages off the RabbitMQ dead-letter queue every 15 minutes, groups them by failure reason, writes the groups to a table, and posts a summary to Slack.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"slack","name":"Slack"}]},{"title":"RabbitMQ queue depth alerting","prompt":"Create a scheduled workflow that lists RabbitMQ queues every five minutes, flags any queue whose depth exceeds its threshold or that has zero consumers, and opens a PagerDuty incident.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Publish enriched events to RabbitMQ","prompt":"Build a workflow that receives an inbound webhook, enriches the payload with an agent, and publishes the result to a RabbitMQ topic exchange with a routing key derived from the event type.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ to Slack incident relay","prompt":"Create a scheduled workflow that drains a RabbitMQ alerts queue, summarizes each message with an agent, and posts the summary to the on-call Slack channel with a severity label.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"slack","name":"Slack"}]},{"title":"RabbitMQ order pipeline bootstrap","prompt":"Build a workflow that declares the RabbitMQ queues and exchange bindings an order pipeline needs, verifies each binding, and records the resulting topology in a table.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ broker health digest","prompt":"Create a scheduled daily workflow that reads the RabbitMQ broker overview and queue list, compares depth and consumer counts against yesterday, and emails the platform team a health digest.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"gmail","name":"Gmail"}]},{"title":"RabbitMQ replay after an outage","prompt":"Build a workflow that reads messages from a RabbitMQ parking queue, has an agent decide which are safe to replay, republishes those to the live exchange, and logs every skipped message with its reason.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ capacity review","prompt":"Create a scheduled weekly workflow that lists every RabbitMQ queue and exchange, identifies unused queues and queues with no bindings, and posts a cleanup proposal to a Linear issue.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"linear","name":"Linear"}]},{"title":"RabbitMQ cluster alarm watch","prompt":"Create a scheduled workflow that runs the RabbitMQ health checks every five minutes, lists cluster nodes for memory and disk alarms and network partitions, and pages on-call when an alarm fires.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"RabbitMQ stalled consumer detector","prompt":"Build a scheduled workflow that cross-references RabbitMQ queue depth with consumers and channels, flags queues whose consumers are inactive or whose unacknowledged counts are stuck at the prefetch limit, and posts the findings to Slack.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"slack","name":"Slack"}]},{"title":"RabbitMQ dead-letter policy rollout","prompt":"Create a workflow that audits RabbitMQ policies across virtual hosts, finds queue families with no dead-letter exchange configured, and applies a standard dead-lettering policy after posting the plan for approval.","integrations":[{"id":"rabbitmq","name":"RabbitMQ"},{"id":"slack","name":"Slack"}]}]},{"id":"railway","type":"railway","slug":"railway","name":"Railway","description":"Manage Railway projects, services, deployments, and variables","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/railway","authType":"api-key","connections":[],"operations":[{"name":"List Projects","description":"List Railway projects visible to the provided token"},{"name":"Get Project","description":"Get a Railway project with its services and environments"},{"name":"Create Project","description":"Create a Railway project"},{"name":"Update Project","description":"Update a Railway project name or description"},{"name":"Delete Project","description":"Delete a Railway project"},{"name":"Transfer Project","description":"Transfer a Railway project to another workspace"},{"name":"List Project Members","description":"List members for a Railway project"},{"name":"Create Environment","description":"Create a Railway project environment"},{"name":"Delete Environment","description":"Delete a Railway project environment"},{"name":"Create Service","description":"Create a Railway service from a GitHub repo or Docker image"},{"name":"Delete Service","description":"Delete a Railway service and all of its deployments"},{"name":"List Deployments","description":"List deployments for a Railway service in an environment"},{"name":"Get Deployment","description":"Get details for a single Railway deployment"},{"name":"Deploy Service","description":"Trigger a deployment for a Railway service in an environment"},{"name":"Restart Deployment","description":"Restart a running Railway deployment without rebuilding"},{"name":"Rollback Deployment","description":"Roll a Railway service back to a previous deployment"},{"name":"Get Deployment Logs","description":"Retrieve runtime logs for a Railway deployment"},{"name":"List Variables","description":"List Railway environment variables for a service or shared environment"},{"name":"Upsert Variable","description":"Create or update a Railway environment variable"},{"name":"Delete Variable","description":"Delete a Railway environment variable"}],"triggers":[],"skills":[{"name":"monitor-failed-deployments","description":"List recent Railway deployments, detect failures, and alert with a summary.","content":"# Monitor Failed Deployments\\n\\nWatch Railway deployments and surface failures fast.\\n\\n## Steps\\n1. Run list_deployments for the target project, service, and environment.\\n2. Identify deployments with a failed or crashed status from the returned list.\\n3. For each failure, run get_deployment_logs to pull the runtime logs and determine the likely cause.\\n4. Summarize each failure: service, environment, status, and the diagnosed cause.\\n5. Post an actionable alert (for example to Slack) with a link to the affected service.\\n\\n## Output\\nReturn the count of failed deployments and a concise summary of each. If all healthy, report a clean status."},{"name":"deploy-service","description":"Trigger a Railway service deployment for a given environment and commit.","content":"# Deploy Service\\n\\nTrigger a deployment of a Railway service.\\n\\n## Steps\\n1. Identify the service id and environment id to deploy (use get_project to look them up if needed).\\n2. Run deploy_service, optionally pinning a specific commitSha.\\n3. Capture the returned deploymentId.\\n4. Optionally poll list_deployments to confirm the deployment reaches a success state.\\n\\n## Output\\nReport the deploymentId, target environment, and final status."},{"name":"sync-environment-variables","description":"Upsert Railway environment variables from a reference source and report changes.","content":"# Sync Environment Variables\\n\\nKeep Railway environment variables aligned with a reference list.\\n\\n## Steps\\n1. Read the desired variable set (for example from a table) for each service.\\n2. Run list_variables to capture the current state for the project, environment, and service.\\n3. For each variable that is missing or differs, run upsert_variable. Use skipDeploys when batching multiple changes.\\n4. Trigger a single deploy at the end if needed.\\n\\n## Output\\nReturn a summary of every variable created or changed, grouped by service."},{"name":"provision-preview-environment","description":"Create an ephemeral Railway environment, seed variables, and deploy it.","content":"# Provision Preview Environment\\n\\nSpin up a fresh Railway environment for a branch or pull request.\\n\\n## Steps\\n1. Run create_environment for the project, optionally cloning from a source environment and marking it ephemeral.\\n2. Upsert the required environment variables for the new environment.\\n3. Run deploy_service to bring the preview online.\\n4. Capture the deployment status and the preview URL.\\n\\n## Output\\nReturn the new environment id and the live preview URL so it can be shared on the PR."},{"name":"audit-project-inventory","description":"List every Railway project with services and environments for tracking.","content":"# Audit Project Inventory\\n\\nBuild a current inventory of Railway resources.\\n\\n## Steps\\n1. Run list_projects, paginating with first and after until complete.\\n2. For each project, run get_project to capture its services and environments.\\n3. Optionally run list_project_members to record access.\\n4. Compare against a prior snapshot to detect added or removed resources.\\n\\n## Output\\nReturn the full inventory and a diff of any changes since the last run."},{"name":"rollback-failed-deployment","description":"Detect a bad Railway deployment and roll back or restart to recover.","content":"# Roll Back Failed Deployment\\n\\nRecover a Railway service automatically when a deployment goes bad.\\n\\n## Steps\\n1. Run list_deployments for the service and environment to find the most recent deployment and its status.\\n2. If the latest deployment failed or crashed, optionally run get_deployment_logs to confirm and capture the cause.\\n3. To revert: pick the most recent healthy deployment with canRollback true (from list_deployments) and run rollback_deployment with its id.\\n4. To recover a locked-up but otherwise healthy deployment instead, run restart_deployment with the deployment id.\\n5. Run get_deployment on the resulting deployment to confirm it reaches a healthy status.\\n\\n## Output\\nReport whether a rollback or restart was performed, the target deployment id, and the final status."}],"templates":[{"title":"Railway deployment monitor","prompt":"Build a scheduled workflow that lists the latest Railway deployments across my services every few minutes, detects failed or crashed deployments, summarizes the failure with an agent, and posts an actionable Slack alert with a link to the service.","integrations":[{"id":"railway","name":"Railway"},{"id":"slack","name":"Slack"}]},{"title":"Railway deploy on merge","prompt":"Create a workflow that watches GitHub for merges to the main branch, triggers a Railway service deployment for the matching environment, and posts the deployment status back as a Slack notification.","integrations":[{"id":"railway","name":"Railway"},{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]},{"title":"Railway environment variable auditor","prompt":"Build a scheduled weekly workflow that lists environment variables across every Railway project, compares them to a reference list in a table, flags drift and missing keys, and emails a remediation report to the platform team.","integrations":[{"id":"railway","name":"Railway"}]},{"title":"Railway project inventory","prompt":"Create a scheduled workflow that lists every Railway project, its services, and environments weekly, logs them into a tracking table, and Slacks a diff of any added or removed resources so infrastructure changes never go unnoticed.","integrations":[{"id":"railway","name":"Railway"},{"id":"slack","name":"Slack"}]},{"title":"Railway config sync","prompt":"Build a workflow that reads service configuration from a table and upserts the matching Railway environment variables for each service, then posts a Slack summary of every variable that was created or changed.","integrations":[{"id":"railway","name":"Railway"},{"id":"slack","name":"Slack"}]},{"title":"Railway preview environment provisioner","prompt":"Create a workflow that watches GitHub for new pull requests, creates a fresh Railway environment for the branch, upserts the required environment variables, deploys the service, and comments the live preview URL back on the PR.","integrations":[{"id":"railway","name":"Railway"},{"id":"github","name":"GitHub"}]},{"title":"Railway project onboarding kit","prompt":"Build a workflow that takes a new service name, creates a Railway project, sets up staging and production environments, seeds baseline environment variables from a table, and posts the project members and access summary to Slack for the team.","integrations":[{"id":"railway","name":"Railway"},{"id":"slack","name":"Slack"}]}]},{"id":"ramp","type":"ramp","slug":"ramp","name":"Ramp","description":"Read spend, bills, cards, and reimbursements, and add transaction memos in Ramp","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/ramp","authType":"oauth","connections":[{"id":"ramp","kind":"oauth","label":"Connect with OAuth","providerId":"ramp","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/ramp","requiredScopes":[{"id":"business:read","label":"View Ramp business details and balances"},{"id":"users:read","label":"View Ramp users and roles"},{"id":"transactions:read","label":"View Ramp transactions"},{"id":"cards:read","label":"View Ramp physical and virtual card details"},{"id":"vendors:read","label":"View Ramp vendors"},{"id":"bills:read","label":"View Ramp bills"},{"id":"reimbursements:read","label":"View Ramp reimbursements"},{"id":"memos:read","label":"View Ramp transaction memos"},{"id":"memos:write","label":"Create and update Ramp transaction memos"}],"fields":[]},{"id":"ramp-service-account","kind":"service_account","providerId":"ramp-service-account","label":"Add application","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/ramp","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true}]}],"operations":[{"name":"Get Business","description":"Fetch the company information in Ramp"},{"name":"Get Balance","description":"Fetch the company balance information in Ramp"},{"name":"List Users","description":"List users in one page in Ramp"},{"name":"Get User","description":"Fetch a user in Ramp"},{"name":"List Transactions","description":"List transactions in one page in Ramp"},{"name":"Get Transaction","description":"Fetch a transaction in Ramp"},{"name":"List Physical Cards","description":"List physical cards in one page in Ramp"},{"name":"Get Physical Card","description":"Fetch a physical card in Ramp"},{"name":"List Virtual Cards","description":"List virtual cards in one page in Ramp"},{"name":"Get Virtual Card","description":"Fetch a virtual card in Ramp"},{"name":"List Vendors","description":"List vendors in one page in Ramp"},{"name":"Get Vendor","description":"Fetch a vendor in Ramp"},{"name":"List Bills","description":"List bills in one page in Ramp"},{"name":"Get Bill","description":"Fetch a bill in Ramp"},{"name":"List Reimbursements","description":"List reimbursements in one page in Ramp"},{"name":"Get Reimbursement","description":"Fetch a reimbursement in Ramp"},{"name":"Get Memo","description":"Fetch a transaction memo in Ramp"},{"name":"Create Memo","description":"Upload a new memo for a transaction in Ramp"}],"triggers":[],"skills":[{"name":"summarize-card-spend","description":"Summarize card spending by merchant and currency for a requested time window.","content":"# Summarize Card Spend\\n\\nSummarize card spending by merchant and currency for a requested time window.\\n\\n## Steps\\n1. Use list_transactions with from_date and to_date for the requested time window.\\n2. Read additional pages only within an explicit page budget, passing nextCursor as start.\\n3. Group entity_amount.value by entity_amount.currency and merchant; keep refunds signed.\\n\\n## Output\\nReturn totals per currency, covered dates, transaction IDs for exceptions, and whether more pages remain."},{"name":"review-pending-reimbursements","description":"Prepare a reimbursement review queue with employee and expense context.","content":"# Review Pending Reimbursements\\n\\nPrepare a reimbursement review queue with employee and expense context.\\n\\n## Steps\\n1. Use list_reimbursements with reimbursement_state PENDING.\\n2. Fetch selected reimbursement details and corresponding users when more context is needed.\\n3. Summarize employee, merchant, memo, submitted date, and entity_amount.\\n\\n## Output\\nReturn a review queue with reimbursement IDs and currency-aware amounts; retain unknown values as unknown."},{"name":"review-upcoming-bills","description":"Identify unpaid vendor bills due within a specified time window.","content":"# Review Upcoming Bills\\n\\nIdentify unpaid vendor bills due within a specified time window.\\n\\n## Steps\\n1. Use list_bills with payment_status OPEN and the requested from_due_date and to_due_date.\\n2. Read selected bill details and vendor details when additional context is needed.\\n3. Group bills by vendor and approval_status while keeping currencies separate.\\n\\n## Output\\nReturn due dates, invoice numbers, bill IDs, approval status, and amounts for review."},{"name":"analyze-vendor-spend","description":"Compare vendor spend over the last 30 days and year to date.","content":"# Analyze Vendor Spend\\n\\nCompare vendor spend over the last 30 days and year to date.\\n\\n## Steps\\n1. List vendors using a bounded page budget.\\n2. Read vendor details for vendors requiring investigation.\\n3. Compare total_spend_last_30_days and total_spend_ytd using their currency codes.\\n\\n## Output\\nReturn a ranked report with vendor IDs, time periods, currencies, and any incomplete pagination."},{"name":"inventory-employee-cards","description":"Inspect the physical and virtual cards assigned to an employee.","content":"# Inventory Employee Cards\\n\\nInspect the physical and virtual cards assigned to an employee.\\n\\n## Steps\\n1. Look up the employee with list_users filtered by email.\\n2. List physical and virtual cards using the employee user_id.\\n3. Read selected card details and summarize each suspension flag and physical-card state.\\n\\n## Output\\nReturn card IDs, physical-card last four digits, and suspension status without implying a card was changed."},{"name":"document-transaction-purpose","description":"Attach a supplied business purpose to a card transaction.","content":"# Document Transaction Purpose\\n\\nAttach a supplied business purpose to a card transaction.\\n\\n## Steps\\n1. Read the transaction and current memo for the supplied transaction ID.\\n2. Use the user-provided business purpose; obtain missing facts instead of inventing them.\\n3. Call create_memo with the supplied purpose and recurring behavior only when requested.\\n\\n## Output\\nReturn the transaction ID and saved memo."},{"name":"inspect-credit-availability","description":"Summarize the business card balance and remaining spending capacity.","content":"# Inspect Credit Availability\\n\\nSummarize the business card balance and remaining spending capacity.\\n\\n## Steps\\n1. Fetch the business identity and balance.\\n2. Compare card_limit_amount and available_card_limit_amount, respecting currency codes and minor_unit_conversion_rate.\\n3. Include statement_balance_amount and next_billing_date in the summary.\\n\\n## Output\\nReturn a dated balance snapshot, retaining null amounts as unavailable."}],"templates":[{"title":"Weekly Spend Review","prompt":"Every week, read Ramp transactions for the previous week, group spending by merchant and currency, and produce a summary with unusually large expenses and transaction IDs.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Reimbursement Review Queue","prompt":"Each morning, list pending Ramp reimbursements, read the details needed for review, and produce a queue with employee names, amounts, merchants, and submission dates.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Upcoming Bill Report","prompt":"Each day, list open Ramp bills due in the next seven days and produce a report grouped by vendor, currency, approval status, and due date.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Vendor Spend Summary","prompt":"At month end, list Ramp vendors and compare their last 30 days and year-to-date spend. Produce a ranked vendor report with vendor IDs and currencies.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Employee Card Inventory","prompt":"When given an employee email, find the Ramp user, list their physical and virtual cards, and return an inventory with card status and suspension flags.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Transaction Memo Assistant","prompt":"When a finance reviewer supplies a transaction ID and approved business purpose, read the transaction and its memo, add the supplied memo in Ramp, and return the saved memo.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Available Credit Snapshot","prompt":"Each business morning, read the Ramp business and balance, and produce a snapshot of the card limit, available card spending, statement balance, and next billing date.","integrations":[{"id":"ramp","name":"Ramp"}]},{"title":"Accounting Close Review","prompt":"Before month end, list Ramp transactions with accounting sync status SYNC_READY and reimbursements ready to sync, and produce a checklist with IDs and amounts for the accounting team.","integrations":[{"id":"ramp","name":"Ramp"}]}]},{"id":"rb2b","type":"rb2b","slug":"rb2b","name":"RB2B","description":"Identify and enrich website visitors","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/rb2b","authType":"api-key","connections":[],"operations":[{"name":"Credit Check","description":"Check the number of API credits remaining on your RB2B account."},{"name":"IP to HEM","description":"Convert an IP address (and optional user agent) into hashed email addresses (HEM) with accuracy scores."},{"name":"IP to MAID","description":"Resolve an IP address (and optional user agent) into mobile advertising identifiers (MAIDs) observed over the last 60 days."},{"name":"IP to Company","description":"Identify the company domains associated with an IP address, ranked by confidence."},{"name":"Email/HEM to Business Profile","description":"Return a full business profile (name, title, company, industry, seniority and more) for an email address or MD5-hashed email."},{"name":"Email/HEM to Best LinkedIn URL","description":"Return the most recently active LinkedIn profile URL for an email address or MD5-hashed email."},{"name":"Email/HEM to LinkedIn Slug","description":"Return the LinkedIn slug (the profile identifier portion of the URL) for an email address or MD5-hashed email."},{"name":"Email/HEM to MAID","description":"Return up to five mobile advertising identifiers (MAIDs) associated with an email address or MD5-hashed email."},{"name":"Email to Last Active Date","description":"Return the last known active date for an email address."},{"name":"LinkedIn to Business Profile","description":"Return a full business profile (name, title, company, emails and more) for a LinkedIn profile."},{"name":"LinkedIn to Best Personal Email","description":"Return the personal email with the most recent known network activity for a LinkedIn profile."},{"name":"LinkedIn to Personal Email","description":"Return the personal email addresses associated with a LinkedIn profile."},{"name":"LinkedIn to Hashed Emails","description":"Return the business and personal hashed emails (MD5 and SHA-256) associated with a LinkedIn profile."},{"name":"LinkedIn to Mobile Phone","description":"Return the mobile phone number with the most recent known network activity for a LinkedIn profile."},{"name":"LinkedIn Slug Search","description":"Find a LinkedIn profile URL from a first name, last name, and company domain."}],"triggers":[],"skills":[{"name":"identify-website-visitor","description":"Resolve a visitor IP into a person and company profile for sales follow-up.","content":"# Identify Website Visitor\\n\\nTurn an anonymous visit into a named, enrichable lead.\\n\\n## Steps\\n1. Take the visitor ip_address and run ip_to_company to resolve the firmographic match.\\n2. Run ip_to_hem to obtain the hashed email identifier for the person.\\n3. Run hem_to_business_profile and hem_to_best_linkedin to build a full contact profile.\\n4. Score the lead by company fit and route high-intent matches to sales.\\n\\n## Output\\nReturn the resolved company, person name, title, and LinkedIn. Flag whether the match clears your fit threshold."},{"name":"enrich-linkedin-contact","description":"Enrich a LinkedIn profile with business email and phone for outreach.","content":"# Enrich LinkedIn Contact\\n\\nTurn a LinkedIn profile into reachable contact details.\\n\\n## Steps\\n1. Provide the LinkedIn URL or slug; use linkedin_slug_search first if you only have a name.\\n2. Run linkedin_to_business_profile to capture role and company.\\n3. Run linkedin_to_best_personal_email and linkedin_to_mobile_phone for direct contact points.\\n4. Push the enriched record into the CRM or an outreach sequence.\\n\\n## Output\\nReturn the contact name, company, best email, and phone. Note any field that could not be resolved."},{"name":"check-credit-balance","description":"Check the RB2B credit balance before running a batch of enrichment lookups.","content":"# Check Credit Balance\\n\\nVerify enrichment credits remain before a batch run.\\n\\n## Steps\\n1. Run credit_check to read the current balance.\\n2. Estimate the credits needed for the planned lookups.\\n3. If the balance is insufficient, alert the team rather than starting a partial run.\\n\\n## Output\\nReturn the remaining credit balance and whether the planned batch can proceed."}],"templates":[{"title":"RB2B visitor de-anonymizer","prompt":"Build a workflow that takes the IP addresses of anonymous website visitors, uses RB2B to resolve each IP to a hashed email and company domain, and writes the identified visitors into a table for the sales team.","integrations":[{"id":"rb2b","name":"RB2B"}]},{"title":"RB2B IP to LinkedIn profile","prompt":"Create a workflow that resolves a visitor IP to a hashed email with RB2B, then enriches that hashed email into a LinkedIn profile and business profile so reps know exactly who visited.","integrations":[{"id":"rb2b","name":"RB2B"}]},{"title":"RB2B hashed-email enrichment","prompt":"Build a workflow that reads hashed emails from a table, uses RB2B to enrich each into a full business profile with name, title, seniority, and company details, and writes the enriched records back to the row.","integrations":[{"id":"rb2b","name":"RB2B"}]},{"title":"RB2B LinkedIn phone finder","prompt":"Create a workflow that takes a list of LinkedIn profile slugs, uses RB2B to look up each prospect\'s mobile phone and best personal email, and writes a ready-to-contact table for outbound calling.","integrations":[{"id":"rb2b","name":"RB2B"}]},{"title":"RB2B visitor-to-HubSpot sync","prompt":"Build a workflow that resolves visitor IPs to company domains with RB2B, enriches the matched person into a business profile, and creates or updates the matching contact and company in HubSpot.","integrations":[{"id":"rb2b","name":"RB2B"},{"id":"hubspot","name":"HubSpot"}]},{"title":"RB2B visitor Slack alerts","prompt":"Create a workflow that reads a list of website visitor IPs, uses RB2B to resolve each person and their company, and posts an alert with the identified LinkedIn profile and company to the sales Slack channel.","integrations":[{"id":"rb2b","name":"RB2B"},{"id":"slack","name":"Slack"}]},{"title":"RB2B LinkedIn slug resolver","prompt":"Build a workflow that takes a first name, last name, and company domain, uses RB2B LinkedIn slug search to resolve the matching profile, and enriches it into a business profile written to a prospect table.","integrations":[{"id":"rb2b","name":"RB2B"}]},{"title":"RB2B engagement freshness sweep","prompt":"Create a scheduled workflow that runs my list of prospect emails through RB2B email-to-last-active-date lookups, flags recently active contacts, and logs the engagement snapshot to a table for prioritized follow-up.","integrations":[{"id":"rb2b","name":"RB2B"}]}]},{"id":"reddit","type":"reddit","slug":"reddit","name":"Reddit","description":"Access Reddit data and content","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/reddit","authType":"oauth","connections":[{"id":"reddit","kind":"oauth","label":"Connect with OAuth","providerId":"reddit","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/reddit","requiredScopes":[{"id":"identity","label":"View your Reddit username and signup date"},{"id":"read","label":"Read posts and comments through your account"},{"id":"submit","label":"Submit posts and comments"},{"id":"vote","label":"Vote on posts and comments"},{"id":"save","label":"Save and unsave posts and comments"},{"id":"edit","label":"Edit and delete your posts and comments"},{"id":"subscribe","label":"Subscribe and unsubscribe from subreddits"},{"id":"history","label":"View your voting history and saved or hidden posts"},{"id":"privatemessages","label":"Access inbox and send private messages"},{"id":"account","label":"Update account preferences and settings"},{"id":"mysubreddits","label":"Access subscribed and moderated subreddits"},{"id":"flair","label":"Select your user flair and change flair on your posts"},{"id":"report","label":"Report content and hide or show posts"},{"id":"modposts","label":"Approve, remove, and moderate posts in moderated subreddits"},{"id":"modflair","label":"Manage flair in moderated subreddits"},{"id":"modmail","label":"Access and respond to moderator mail"}],"fields":[]}],"operations":[{"name":"Get Posts","description":"Fetch posts from a subreddit with different sorting options"},{"name":"Get Comments","description":"Fetch comments from a specific Reddit post"},{"name":"Get Controversial Posts","description":"Fetch controversial posts from a subreddit"},{"name":"Search Subreddit","description":"Search for posts within a subreddit"},{"name":"Submit Post","description":"Submit a new post to a subreddit (text or link)"},{"name":"Vote","description":"Upvote, downvote, or unvote a Reddit post or comment"},{"name":"Save","description":"Save a Reddit post or comment to your saved items"},{"name":"Unsave","description":"Remove a Reddit post or comment from your saved items"},{"name":"Reply","description":"Add a comment reply to a Reddit post or comment"},{"name":"Edit","description":"Edit the text of your own Reddit post or comment"},{"name":"Delete","description":"Delete your own Reddit post or comment"},{"name":"Subscribe","description":"Subscribe or unsubscribe from a subreddit"},{"name":"Get My Profile","description":"Get information about the authenticated Reddit user"},{"name":"Get User Profile","description":"Get public profile information about any Reddit user by username"},{"name":"Send Message","description":"Send a private message to a Reddit user"},{"name":"Get Messages","description":"Retrieve private messages from your Reddit inbox"},{"name":"Get Subreddit Info","description":"Get metadata and information about a subreddit"},{"name":"Get Subreddit Rules","description":"Get the rules and site-wide rules that apply to a subreddit"},{"name":"Get User Posts","description":"Fetch submitted posts (t3) from a Reddit user profile"},{"name":"Get User Comments","description":"Fetch comments (t1) made by a Reddit user"},{"name":"Get Saved Items","description":"Fetch your own saved posts (t3) and comments (t1). You can only read your own saved items"},{"name":"Get Info by ID","description":"Fetch information about one or more Reddit things (posts, comments, or subreddits) by their fullnames"},{"name":"Search Subreddits","description":"Search for subreddits by name and description"},{"name":"List My Subreddits","description":"List the subreddits the authenticated user is subscribed to"},{"name":"Report","description":"Report a Reddit post or comment to subreddit moderators for a rules violation"},{"name":"Hide","description":"Hide one or more Reddit posts from your listings"},{"name":"Unhide","description":"Unhide one or more previously hidden Reddit posts"},{"name":"Mark NSFW","description":"Mark a Reddit post as NSFW (not safe for work)"},{"name":"Unmark NSFW","description":"Remove the NSFW (not safe for work) mark from a Reddit post"},{"name":"Mark Messages Read","description":"Mark one or more private messages as read"},{"name":"Mark All Messages Read","description":"Mark all private messages in the inbox as read"},{"name":"Approve (Mod)","description":"Approve a reported or removed Reddit post or comment as a moderator"},{"name":"Remove (Mod)","description":"Remove a Reddit post or comment as a moderator, optionally marking it as spam"},{"name":"Distinguish (Mod)","description":"Distinguish or un-distinguish a Reddit post or comment as a moderator"},{"name":"Lock (Mod)","description":"Lock a Reddit post or comment to prevent further replies (moderator action)"},{"name":"Unlock (Mod)","description":"Unlock a Reddit post or comment to allow replies again (moderator action)"},{"name":"Sticky (Mod)","description":"Sticky or unsticky a Reddit post to the top of a subreddit (moderator action)"}],"triggers":[],"skills":[{"name":"monitor-subreddit-mentions","description":"Search a subreddit for brand or keyword mentions and summarize what people say.","content":"# Monitor Subreddit Mentions\\n\\nTrack what people say about a topic on Reddit.\\n\\n## Steps\\n1. Run search with the brand or keyword query, scoped to the relevant subreddit when appropriate.\\n2. For high-signal threads, run get_comments to pull the discussion.\\n3. Summarize sentiment, recurring themes, and notable complaints or praise.\\n4. Route urgent or negative threads to the right channel.\\n\\n## Output\\nReturn a digest of top mentions with links, sentiment, and key takeaways."},{"name":"surface-trending-posts","description":"Pull top and controversial posts from a subreddit for a content or research brief.","content":"# Surface Trending Posts\\n\\nFind what is rising and contentious in a community.\\n\\n## Steps\\n1. Run get_posts for the subreddit using a hot or top sort to capture momentum.\\n2. Run get_controversial to surface divisive discussions.\\n3. Read get_comments on the standouts for context.\\n4. Cluster the posts into themes.\\n\\n## Output\\nReturn a ranked brief of trending and controversial posts with titles, links, and a one-line takeaway each."},{"name":"reply-to-mention","description":"Draft and post a helpful, on-brand reply to a Reddit post or comment.","content":"# Reply To Mention\\n\\nRespond to a relevant Reddit thread.\\n\\n## Steps\\n1. Read the target post or comment with get_posts or get_comments for full context.\\n2. Draft a concise, non-promotional reply that adds genuine value.\\n3. Run reply to post it on the chosen thread.\\n4. Optionally save the thread for later follow-up.\\n\\n## Output\\nReturn the posted reply text and a link to the comment. Respect subreddit rules and avoid spammy self-promotion."},{"name":"submit-announcement-post","description":"Submit a new post to a target subreddit for an announcement or launch.","content":"# Submit Announcement Post\\n\\nShare an announcement on Reddit.\\n\\n## Steps\\n1. Run get_subreddit_rules to confirm the target subreddit allows the post type and self-promotion.\\n2. Run submit_post with a clear title and body tailored to the community.\\n3. Capture the returned post id and link.\\n4. Monitor early get_comments and respond to questions.\\n\\n## Output\\nReturn the new post link and an initial engagement check."},{"name":"research-a-redditor","description":"Profile a Reddit user from their public posts, comments, and karma.","content":"# Research A Redditor\\n\\nBuild a picture of a Reddit user for vetting or community research.\\n\\n## Steps\\n1. Run get_user to pull profile, karma, and account age.\\n2. Run get_user_posts and get_user_comments to sample their recent activity.\\n3. Identify the subreddits, topics, and tone they engage with most.\\n4. Flag anything notable (expertise, affiliations, red flags).\\n\\n## Output\\nReturn a short profile: account summary, top communities, themes, and a sample of representative posts/comments with links."},{"name":"discover-communities","description":"Find the most relevant subreddits for a topic before posting or monitoring.","content":"# Discover Communities\\n\\nLocate the right subreddits for a topic or campaign.\\n\\n## Steps\\n1. Run search_subreddits with the topic keywords to find candidate communities.\\n2. Run get_subreddit_info on the strongest matches to compare size and activity.\\n3. Run get_subreddit_rules to check posting and self-promotion rules.\\n4. Optionally run list_my_subreddits to see which you already follow.\\n\\n## Output\\nReturn a ranked shortlist of subreddits with subscriber counts, activity, fit, and key rules."},{"name":"manage-saved-research","description":"Curate a research reading list from saved Reddit posts and comments.","content":"# Manage Saved Research\\n\\nTurn saved Reddit items into an organized research list.\\n\\n## Steps\\n1. Run get_saved to pull your saved posts and comments.\\n2. Run get_info to re-hydrate any specific fullnames you are tracking.\\n3. Summarize and cluster the items by theme.\\n4. Use save / unsave to keep the list current.\\n\\n## Output\\nReturn a themed reading list with titles, links, and one-line summaries."},{"name":"triage-mod-queue","description":"Moderate a subreddit: review reported content and act on it against the rules.","content":"# Triage Mod Queue\\n\\nReview and action content in a subreddit you moderate.\\n\\n## Steps\\n1. Run get_posts / get_comments to pull the content under review.\\n2. Run get_subreddit_rules and evaluate each item against them.\\n3. Take action: mod_approve to keep, mod_remove (optionally as spam) to remove, lock to stop replies, mod_distinguish or mod_sticky to highlight official posts.\\n4. Log each decision and the rule it maps to.\\n\\n## Output\\nReturn a decision list: item link, action taken, and the rule or reason. Only act on subreddits you moderate."}],"templates":[{"title":"Reddit mention tracker","prompt":"Create a scheduled workflow that monitors Reddit and X for mentions of my brand and competitors, scores each mention by sentiment and reach, logs them to a table, and sends a daily Slack digest of notable mentions.","integrations":[{"id":"reddit","name":"Reddit"},{"id":"x","name":"X"},{"id":"slack","name":"Slack"}]},{"title":"Reddit subreddit monitor","prompt":"Build a scheduled workflow that uses Reddit to watch target subreddits for posts matching brand or product keywords, scores each for relevance and sentiment, and posts notable hits to Slack with the original link.","integrations":[{"id":"reddit","name":"Reddit"},{"id":"slack","name":"Slack"}]},{"title":"Reddit user-question knowledge mining","prompt":"Create a workflow that pulls top questions from Reddit industry subreddits weekly, classifies by theme, and writes a content-opportunity table the marketing team can prioritize.","integrations":[{"id":"reddit","name":"Reddit"}]},{"title":"Reddit AMA preparer","prompt":"Build a workflow that aggregates top Reddit AMA-style questions for a topic, clusters them, drafts polished answers using a knowledge base, and posts a Q&A document for review.","integrations":[{"id":"reddit","name":"Reddit"}]},{"title":"Reddit competitor watch","prompt":"Create a scheduled workflow that monitors Reddit threads mentioning competitors weekly, summarizes sentiment and pain points, and writes a competitive intelligence note to a tracking table.","integrations":[{"id":"reddit","name":"Reddit"}]},{"title":"Reddit crisis-signal alerter","prompt":"Build a scheduled workflow that polls Reddit for sudden bursts of negative posts about the brand, classifies severity, and pages the PR team via Slack and PagerDuty when a real crisis emerges.","integrations":[{"id":"reddit","name":"Reddit"},{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Reddit content-idea collector","prompt":"Create a scheduled workflow that polls marketing-relevant Reddit subreddits, captures upvoted long-form posts, summarizes each, and adds them to a content-ideas table with effort and impact scores.","integrations":[{"id":"reddit","name":"Reddit"}]}]},{"id":"redis","type":"redis","slug":"redis","name":"Redis","description":"Key-value operations with Redis","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/redis","authType":"api-key","connections":[],"operations":[{"name":"Get","description":"Get the value of a key from Redis."},{"name":"Set","description":"Set the value of a key in Redis with an optional expiration time in seconds."},{"name":"Delete","description":"Delete a key from Redis."},{"name":"List Keys","description":"List all keys matching a pattern in Redis. Avoid using on large databases in production; use the Redis Command tool with SCAN for large key spaces."},{"name":"HSET","description":"Set a field in a hash stored at a key in Redis."},{"name":"HGET","description":"Get the value of a field in a hash stored at a key in Redis."},{"name":"HGETALL","description":"Get all fields and values of a hash stored at a key in Redis."},{"name":"HDEL","description":"Delete a field from a hash stored at a key in Redis."},{"name":"INCR","description":"Increment the integer value of a key by one in Redis."},{"name":"INCRBY","description":"Increment the integer value of a key by a given amount in Redis."},{"name":"EXISTS","description":"Check if a key exists in Redis."},{"name":"SETNX","description":"Set the value of a key in Redis only if the key does not already exist."},{"name":"LPUSH","description":"Prepend a value to a list stored at a key in Redis."},{"name":"RPUSH","description":"Append a value to the end of a list stored at a key in Redis."},{"name":"LPOP","description":"Remove and return the first element of a list stored at a key in Redis."},{"name":"RPOP","description":"Remove and return the last element of a list stored at a key in Redis."},{"name":"LLEN","description":"Get the length of a list stored at a key in Redis."},{"name":"LRANGE","description":"Get a range of elements from a list stored at a key in Redis."},{"name":"EXPIRE","description":"Set an expiration time (in seconds) on a key in Redis."},{"name":"PERSIST","description":"Remove the expiration from a key in Redis, making it persist indefinitely."},{"name":"TTL","description":"Get the remaining time to live (in seconds) of a key in Redis."},{"name":"Command","description":"Execute a raw Redis command as a JSON array (e.g. [\\"HSET\\", \\"key\\", \\"field\\", \\"value\\"])."}],"triggers":[],"skills":[{"name":"cache-with-expiry","description":"Cache a computed value in Redis with a TTL and read it back on later runs.","content":"# Cache With Expiry\\n\\nStore an expensive result in Redis so later runs reuse it.\\n\\n## Steps\\n1. Run get on the cache key first; if a value is returned, use it and stop.\\n2. On a miss, compute the value, then run set with an ex expiry in seconds.\\n3. Use setnx instead of set when only the first writer should win.\\n4. Return the value to the caller.\\n\\n## Output\\nReport whether the result was a cache hit or a fresh computation, and the key TTL."},{"name":"rate-limit-counter","description":"Track per-key request counts in Redis with a sliding expiry to enforce limits.","content":"# Rate Limit Counter\\n\\nEnforce a request budget using a Redis counter.\\n\\n## Steps\\n1. Run incr on a counter key derived from the user or client id.\\n2. If the returned count is 1, run expire to start the window.\\n3. Compare the count to the allowed limit.\\n4. Allow or reject the request based on the result.\\n\\n## Output\\nReturn the current count, the limit, and whether the request is allowed. Include ttl for the reset time."},{"name":"manage-session-data","description":"Store and refresh session context in a Redis hash keyed by token.","content":"# Manage Session Data\\n\\nKeep session state in a Redis hash and keep active sessions alive.\\n\\n## Steps\\n1. On write, run hset to store session fields under the session key.\\n2. On read, run hgetall by token to return the full session context.\\n3. Run expire to refresh the TTL so active sessions do not lapse.\\n4. Run delete on logout to clear the session.\\n\\n## Output\\nReturn the session context and confirm the refreshed expiry, or confirm deletion on logout."},{"name":"manage-work-queue","description":"Push jobs onto a Redis list and pop them for processing in order.","content":"# Manage Work Queue\\n\\nUse a Redis list as a simple job queue.\\n\\n## Steps\\n1. Run rpush to enqueue a job payload onto the queue key.\\n2. Run lpop to dequeue the next job for processing (FIFO).\\n3. Check llen to monitor backlog depth.\\n4. Use lrange to inspect pending jobs without removing them.\\n\\n## Output\\nReturn the dequeued job, the remaining queue length, and processing status."}],"templates":[{"title":"Redis response cache","prompt":"Build a workflow that checks Redis for a cached result by key before running an expensive step, and writes the computed result back with a TTL when there is a miss so repeat requests stay fast.","integrations":[{"id":"redis","name":"Redis"}]},{"title":"Redis rate limiter","prompt":"Create a workflow that increments a per-user Redis counter on each request, sets an expiry on the first hit, and blocks the request when the counter passes the allowed threshold within the window.","integrations":[{"id":"redis","name":"Redis"}]},{"title":"Redis feature-flag reader","prompt":"Build a workflow that reads feature-flag values from a Redis hash, branches downstream logic on whether each flag is enabled, and falls back to a default when a flag key is missing.","integrations":[{"id":"redis","name":"Redis"}]},{"title":"Redis job queue worker","prompt":"Create a scheduled workflow that pops the next job off a Redis list, processes it with an agent, and writes the outcome to a table so a backlog of work is drained on an interval.","integrations":[{"id":"redis","name":"Redis"}]},{"title":"Redis cache warmer","prompt":"Build a scheduled workflow that reads a list of hot keys from a table and sets each one in Redis with fresh values and a TTL, so popular lookups stay warm.","integrations":[{"id":"redis","name":"Redis"}]},{"title":"Redis daily counter digest","prompt":"Create a scheduled workflow that reads the day’s Redis counters by key pattern, builds a summary of the totals with an agent, and posts the digest to Slack.","integrations":[{"id":"redis","name":"Redis"},{"id":"slack","name":"Slack"}]},{"title":"Redis session lookup","prompt":"Build a workflow that reads a session hash from Redis by token, returns the stored user context to the caller, and refreshes the key’s expiry so active sessions stay alive.","integrations":[{"id":"redis","name":"Redis"}]}]},{"id":"reducto","type":"reducto_v2","slug":"reducto","name":"Reducto","description":"Extract text from PDF documents","category":"AI","docsUrl":"https://docs.sim.ai/integrations/reducto","authType":"api-key","connections":[],"operations":[{"name":"Reducto PDF Parser","description":"Parse PDF documents using Reducto OCR API"}],"triggers":[],"skills":[{"name":"extract-document-text","description":"Parse an uploaded PDF into clean text for downstream summarizing or search.","content":"# Extract Document Text\\n\\nTurn a PDF into clean, structured text with Reducto.\\n\\n## Steps\\n1. Pass the uploaded document (file or file path) to the parser.\\n2. Optionally limit to specific pages by passing a comma-separated page list.\\n3. Capture the extracted text and structure from the result.\\n4. Pass the text downstream for summarizing, classification, or indexing.\\n\\n## Output\\nReturn the extracted text and a brief note of the page count processed."},{"name":"extract-form-fields","description":"Parse an intake form PDF and pull structured fields into a table or record.","content":"# Extract Form Fields\\n\\nLift structured fields out of a form PDF.\\n\\n## Steps\\n1. Run the parser on the uploaded form document.\\n2. From the parsed text, identify the target fields (for example name, date, amount, form type).\\n3. Map the fields into a structured record and write them to a table.\\n4. Route the record to the right reviewer based on form type.\\n\\n## Output\\nReturn the extracted field record and confirm where it was stored or routed. Flag any field that could not be located."},{"name":"extract-invoice-tables","description":"Parse an invoice or financial PDF into structured line-item tables for AP automation.","content":"# Extract Invoice Tables\\n\\nPull line-item tables out of invoices, receipts, or statements with Reducto.\\n\\n## Steps\\n1. Run the parser on the uploaded invoice or financial document.\\n2. Set the table output format so tables come back in a structured, machine-readable shape.\\n3. Limit to the relevant pages with a comma-separated page list when the document is long.\\n4. Map header fields and line items into a record and write the rows to a table.\\n\\n## Output\\nReturn the parsed line items and invoice totals. Flag any row or amount that could not be confidently extracted."}],"templates":[{"title":"Google Drive contract intake","prompt":"Create a workflow that watches a Google Drive intake folder for new contract PDFs, extracts clauses with Reducto, writes structured terms to a table, and pings legal in Slack.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"google_drive","name":"Google Drive"},{"id":"slack","name":"Slack"}]},{"title":"OneDrive contract intake","prompt":"Create a scheduled workflow that polls a OneDrive intake folder for new contract PDFs, extracts clauses with Reducto, writes the structured terms to a table, and pings legal in Teams.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"onedrive","name":"OneDrive"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Reducto contract parser","prompt":"Create a workflow that uses Reducto to parse uploaded contract PDFs into structured clauses, writes payment terms, liability caps, and termination conditions to a table, and flags non-standard clauses.","integrations":[{"id":"reducto","name":"Reducto"}]},{"title":"Reducto + knowledge base loader","prompt":"Build a workflow that parses every PDF in a Drive folder with Reducto, normalizes the structure, and upserts chunks into a knowledge base with section-aware metadata so retrieval returns the right passage.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Reducto medical-record digester","prompt":"Build a workflow that parses medical record PDFs with Reducto, extracts diagnoses, medications, and visit summaries to structured rows, and produces a patient-facing one-pager file.","integrations":[{"id":"reducto","name":"Reducto"}]},{"title":"Reducto + Mem0 contract memory","prompt":"Create a workflow that parses contracts with Reducto and writes the key terms into Mem0 per counterparty, so future interactions reference the real contract terms.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"mem0","name":"Mem0"}]},{"title":"Reducto invoice line-item extractor","prompt":"Build a workflow that parses incoming invoice PDFs with Reducto, extracts vendor, line items, tax, and totals into an accounts-payable table, and flags any invoice that fails to reconcile against its purchase order.","integrations":[{"id":"reducto","name":"Reducto"}]},{"title":"Reducto financial-statement digitizer","prompt":"Create a workflow that parses quarterly financial-statement PDFs with Reducto, extracts the balance sheet and income statement figures into structured rows, and writes a normalized table the finance team can chart over time.","integrations":[{"id":"reducto","name":"Reducto"}]},{"title":"Reducto form-intake router","prompt":"Build a workflow that runs each uploaded intake form through Reducto, extracts the applicant fields into a table, and routes the parsed submission to the right reviewer in Slack based on the form type.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"slack","name":"Slack"}]},{"title":"Textract + Reducto cross-format extractor","prompt":"Create a workflow that ingests mixed PDF and image files, routes images through AWS Textract and dense PDFs through Reducto, normalizes fields, and writes rows to a table.","integrations":[{"id":"reducto","name":"Reducto"},{"id":"textract","name":"AWS Textract"}]}]},{"id":"resend","type":"resend","slug":"resend","name":"Resend","description":"Send emails and manage contacts with Resend.","category":"Email","docsUrl":"https://docs.sim.ai/integrations/resend","authType":"api-key","connections":[],"operations":[{"name":"Send Email","description":"Send an email using your own Resend API key and from address"},{"name":"Get Email","description":"Retrieve details of a previously sent email by its ID"},{"name":"Cancel Email","description":"Cancel a scheduled email before it is sent"},{"name":"Create Contact","description":"Create a new contact in Resend"},{"name":"List Contacts","description":"List all contacts in Resend"},{"name":"Get Contact","description":"Retrieve details of a contact by ID or email"},{"name":"Update Contact","description":"Update an existing contact in Resend"},{"name":"Delete Contact","description":"Delete a contact from Resend by ID or email"},{"name":"Create Audience","description":"Create a new audience in Resend"},{"name":"Get Audience","description":"Retrieve details of an audience by ID"},{"name":"List Audiences","description":"List all audiences in Resend"},{"name":"Delete Audience","description":"Delete an audience from Resend by ID"},{"name":"Create Broadcast","description":"Create a broadcast email for an audience in Resend"},{"name":"Send Broadcast","description":"Send a broadcast immediately or schedule it for later"},{"name":"Get Broadcast","description":"Retrieve details of a broadcast by ID"},{"name":"List Domains","description":"List all verified domains in your Resend account"}],"triggers":[{"id":"resend_email_sent","name":"Resend Email Sent","description":"Trigger workflow when an email is sent"},{"id":"resend_email_delivered","name":"Resend Email Delivered","description":"Trigger workflow when an email is delivered"},{"id":"resend_email_bounced","name":"Resend Email Bounced","description":"Trigger workflow when an email bounces"},{"id":"resend_email_complained","name":"Resend Email Complained","description":"Trigger workflow when an email is marked as spam"},{"id":"resend_email_opened","name":"Resend Email Opened","description":"Trigger workflow when an email is opened"},{"id":"resend_email_clicked","name":"Resend Email Clicked","description":"Trigger workflow when a link in an email is clicked"},{"id":"resend_email_failed","name":"Resend Email Failed","description":"Trigger workflow when an email fails to send"},{"id":"resend_webhook","name":"Resend Webhook (All Events)","description":"Start a workflow for subscribed Resend email, contact, and domain events. Flattened email fields may be null for non-email events; use `data` for the full payload."}],"skills":[{"name":"send-transactional-email","description":"Send a personalized transactional email and confirm delivery via Resend.","content":"# Send Transactional Email\\n\\nSend a one-off transactional email through Resend.\\n\\n## Steps\\n1. Compose the recipient, from address, subject, and HTML or text body, filling in personalization fields.\\n2. Run the send operation.\\n3. Capture the returned email id.\\n4. Optionally run get_email with the id to confirm the delivery status.\\n\\n## Output\\nReturn the email id and delivery status. If sending fails, report the error reason."},{"name":"add-contact-to-audience","description":"Create or update a Resend contact in an audience for marketing sends.","content":"# Add Contact To Audience\\n\\nKeep a Resend audience in sync with new contacts.\\n\\n## Steps\\n1. Run list_contacts or get_contact to check whether the person already exists.\\n2. If new, run create_contact with email and name fields and the subscribed state.\\n3. If existing, run update_contact to refresh fields.\\n4. Confirm the contact is in the correct audience.\\n\\n## Output\\nReturn the contact id and whether it was created or updated."},{"name":"handle-unsubscribe","description":"Mark a Resend contact as unsubscribed and send a confirmation email.","content":"# Handle Unsubscribe\\n\\nProcess an opt-out request cleanly.\\n\\n## Steps\\n1. Run get_contact to look up the matching contact by email.\\n2. Run update_contact to set unsubscribed to true.\\n3. Log the opt-out reason for compliance records.\\n4. Run the send operation to deliver a brief confirmation acknowledging the change.\\n\\n## Output\\nConfirm the contact is unsubscribed and the acknowledgement email id."}],"templates":[{"title":"Mailgun + Resend transactional fallback","prompt":"Build a workflow that sends transactional emails through Mailgun by default and automatically falls back to Resend when Mailgun returns a send error or rate-limit response, normalizing the payload and writing every send and the provider used to a delivery table.","integrations":[{"id":"resend","name":"Resend"},{"id":"mailgun","name":"Mailgun"}]},{"title":"Resend + Loops onboarding emails","prompt":"Build a workflow that listens for new signups, creates a Loops contact with the right user group, and sends the welcome email through Resend with a personalized subject and body so the first impression is on-brand and fast.","integrations":[{"id":"resend","name":"Resend"},{"id":"loops","name":"Loops"}]},{"title":"Resend domain monitor","prompt":"Create a scheduled workflow that lists Resend domains, checks DNS verification status for each, and posts a Slack alert the moment any domain shows a verification or DKIM problem so we never silently lose deliverability.","integrations":[{"id":"resend","name":"Resend"},{"id":"slack","name":"Slack"}]},{"title":"Resend transactional flow","prompt":"Build a workflow that listens for product events, renders the right transactional email body, sends it through Resend, then retrieves the message status after a short delay and writes delivery, open, and click events to a per-user activity table.","integrations":[{"id":"resend","name":"Resend"}]},{"title":"Resend + AgentMail reply handler","prompt":"Create a workflow that sends outbound messages through Resend but routes replies into a per-customer AgentMail inbox, threads them with the original send, and posts unread inbox digests to the support owner.","integrations":[{"id":"resend","name":"Resend"},{"id":"agentmail","name":"AgentMail"}]},{"title":"Resend marketing broadcast","prompt":"Build a workflow that takes a marketing message and a Resend audience, splits the recipient list into safe-volume batches, sends each batch through Resend with rate-limit pacing, and logs per-batch send results to a table.","integrations":[{"id":"resend","name":"Resend"}]},{"title":"Resend audience sync","prompt":"Create a workflow that reads my subscriber list from a table, creates or updates each Resend contact in the matching audience, and removes contacts that have unsubscribed by deleting them so the Resend audience stays in sync with my source of truth.","integrations":[{"id":"resend","name":"Resend"}]},{"title":"Resend unsubscribe handler","prompt":"Build a workflow that listens for unsubscribe events, looks up the matching Resend contact, updates it to unsubscribed, logs the opt-out reason to a table, and sends a confirmation email through Resend acknowledging the change.","integrations":[{"id":"resend","name":"Resend"}]},{"title":"SendGrid + Resend failover","prompt":"Build a workflow that sends transactional emails through SendGrid by default and automatically falls back to Resend when the primary send fails or rate limits, logging every send and the provider used to a delivery table.","integrations":[{"id":"resend","name":"Resend"},{"id":"sendgrid","name":"SendGrid"}]}]},{"id":"revenuecat","type":"revenuecat","slug":"revenuecat","name":"RevenueCat","description":"Manage in-app subscriptions and entitlements","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/revenuecat","authType":"api-key","connections":[],"operations":[{"name":"Get Customer","description":"Retrieve subscriber information by app user ID"},{"name":"Delete Customer","description":"Permanently delete a subscriber and all associated data"},{"name":"Create Purchase","description":"Record a purchase (receipt) for a subscriber via the REST API"},{"name":"Grant Entitlement","description":"Grant a promotional entitlement to a subscriber"},{"name":"Revoke Entitlement","description":"Revoke all promotional entitlements for a specific entitlement identifier"},{"name":"List Offerings","description":"List all offerings configured for the project"},{"name":"Update Subscriber Attributes","description":"Update custom subscriber attributes (e.g., $email, $displayName, or custom key-value pairs)"},{"name":"Defer Google Subscription","description":"Defer a Google Play subscription by extending its billing date by a number of days (Google Play only)"},{"name":"Refund Google Subscription","description":"Refund a specific store transaction by its store transaction identifier and revoke access (subscription or non-subscription, last 365 days)"},{"name":"Revoke Google Subscription","description":"Immediately revoke access to a Google Play subscription and issue a refund (Google Play only)"}],"triggers":[{"id":"revenuecat_initial_purchase","name":"RevenueCat Initial Purchase","description":"Trigger workflow when a subscriber makes their first purchase in RevenueCat"},{"id":"revenuecat_renewal","name":"RevenueCat Renewal","description":"Trigger workflow when a RevenueCat subscription renews"},{"id":"revenuecat_cancellation","name":"RevenueCat Cancellation","description":"Trigger workflow when a subscriber cancels a RevenueCat subscription"},{"id":"revenuecat_expiration","name":"RevenueCat Expiration","description":"Trigger workflow when a RevenueCat subscription expires"},{"id":"revenuecat_non_renewing_purchase","name":"RevenueCat Non-Renewing Purchase","description":"Trigger workflow when a subscriber makes a non-renewing purchase in RevenueCat"},{"id":"revenuecat_product_change","name":"RevenueCat Product Change","description":"Trigger workflow when a subscriber changes their RevenueCat subscription product"}],"skills":[{"name":"check-subscription-status","description":"Look up a customer in RevenueCat and report their active entitlements.","content":"# Check Subscription Status\\n\\nDetermine what a customer is entitled to right now.\\n\\n## Steps\\n1. Run get_customer with the app user id.\\n2. Inspect the returned entitlements for active grants and expiration dates.\\n3. Determine whether the customer has the entitlement you are gating on.\\n4. Return a clear allow or deny decision.\\n\\n## Output\\nReturn the active entitlements, their expiration dates, and whether the gated feature should be unlocked."},{"name":"grant-promotional-access","description":"Grant a promotional entitlement to a customer for support or a campaign.","content":"# Grant Promotional Access\\n\\nGive a customer temporary access via a promotional entitlement.\\n\\n## Steps\\n1. Confirm the target app user id with get_customer.\\n2. Run grant_entitlement with the entitlement identifier and duration.\\n3. Verify the grant by re-checking get_customer.\\n4. To reverse a grant later, run revoke_entitlement.\\n\\n## Output\\nConfirm the granted entitlement, its duration, and the customer it was applied to."},{"name":"process-subscription-refund","description":"Refund and revoke a Google Play subscription for a customer support request.","content":"# Process Subscription Refund\\n\\nHandle a refund request for a store subscription.\\n\\n## Steps\\n1. Look up the customer with get_customer to find the relevant subscription.\\n2. For Google Play, run refund_google_subscription with the store transaction id.\\n3. If access should end immediately, run revoke_google_subscription.\\n4. Log the action for the support record.\\n\\n## Output\\nConfirm the refund and revocation status, and the affected customer and product."},{"name":"sync-subscriber-attributes","description":"Update RevenueCat subscriber attributes to power targeting and analytics.","content":"# Sync Subscriber Attributes\\n\\nKeep RevenueCat subscriber attributes current.\\n\\n## Steps\\n1. Gather the attributes to set (for example email, plan tier, or campaign source).\\n2. Run update_subscriber_attributes for the app user id with the attribute map.\\n3. Confirm the update with get_customer.\\n\\n## Output\\nReturn the updated attributes and confirm they were applied to the subscriber."}],"templates":[{"title":"RevenueCat MRR dashboard","prompt":"Build a scheduled daily workflow that pulls RevenueCat subscriber and offering data, calculates MRR, ARPU, and trial-to-paid conversion, logs the metrics to a tracking table with historical trends, and posts a daily Slack summary for the growth team.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"slack","name":"Slack"}]},{"title":"RevenueCat entitlement granter","prompt":"Create a workflow that listens for a customer-success approval — for example a Slack reaction or a row in a table — looks up the RevenueCat subscriber, grants a promotional entitlement with the right expiry, and logs the grant in an audit table for compliance.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"slack","name":"Slack"}]},{"title":"RevenueCat renewal recovery","prompt":"Build a scheduled workflow that lists RevenueCat subscribers with failed renewals, segments them by plan and tenure, drafts a tailored win-back email, sends it via Gmail, and tracks recovery outcomes in a table with retry cadence rules.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"gmail","name":"Gmail"}]},{"title":"RevenueCat attribute sync","prompt":"Create a workflow that listens for changes in your customer table — like email, display name, or company — and updates the matching RevenueCat subscriber attributes so analytics and targeted offers always reflect the latest customer state.","integrations":[{"id":"revenuecat","name":"RevenueCat"}]},{"title":"RevenueCat trial expiry digest","prompt":"Build a scheduled daily workflow that lists RevenueCat subscribers whose trials expire in the next three days, ranks them by engagement, drafts a personalized conversion nudge, and emails the success team a prioritized list to call.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"gmail","name":"Gmail"}]},{"title":"RevenueCat Google Play refund","prompt":"Create a workflow that takes a refund approval from a support ticket, calls the RevenueCat Google Play refund operation with the right transaction identifier, revokes access, posts the outcome back on the ticket, and logs the action in a compliance table.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"zendesk","name":"Zendesk"}]},{"title":"RevenueCat offering report","prompt":"Build a scheduled weekly workflow that pulls RevenueCat offerings and recent purchases, computes conversion rate per offering and per package, writes a narrative analysis file with recommendations, and Slacks growth leadership the top findings.","integrations":[{"id":"revenuecat","name":"RevenueCat"},{"id":"slack","name":"Slack"}]}]},{"id":"rippling","type":"rippling","slug":"rippling","name":"Rippling","description":"Manage workers, departments, custom objects, and company data in Rippling","category":"HR","docsUrl":"https://docs.sim.ai/integrations/rippling","authType":"api-key","connections":[],"operations":[{"name":"List Workers","description":"List all workers with optional filtering and pagination"},{"name":"Get Worker","description":"Get a specific worker by ID"},{"name":"List Users","description":"List all users with optional pagination"},{"name":"Get User","description":"Get a specific user by ID"},{"name":"List Companies","description":"List all companies"},{"name":"Get Current User","description":"Get SSO information for the current user"},{"name":"List Entitlements","description":"List all entitlements"},{"name":"List Departments","description":"List all departments"},{"name":"Get Department","description":"Get a specific department by ID"},{"name":"Create Department","description":"Create a new department"},{"name":"Update Department","description":"Update an existing department"},{"name":"List Teams","description":"List all teams"},{"name":"Get Team","description":"Get a specific team by ID"},{"name":"List Employment Types","description":"List all employment types"},{"name":"Get Employment Type","description":"Get a specific employment type by ID"},{"name":"List Titles","description":"List all titles"},{"name":"Get Title","description":"Get a specific title by ID"},{"name":"Create Title","description":"Create a new title"},{"name":"Update Title","description":"Update an existing title"},{"name":"Delete Title","description":"Delete a title"},{"name":"List Custom Fields","description":"List all custom fields"},{"name":"List Job Functions","description":"List all job functions"},{"name":"Get Job Function","description":"Get a specific job function by ID"},{"name":"List Work Locations","description":"List all work locations"},{"name":"Get Work Location","description":"Get a specific work location by ID"},{"name":"Create Work Location","description":"Create a new work location"},{"name":"Update Work Location","description":"Update a work location"},{"name":"Delete Work Location","description":"Delete a work location"},{"name":"List Business Partners","description":"List all business partners"},{"name":"Get Business Partner","description":"Get a specific business partner by ID"},{"name":"Create Business Partner","description":"Create a new business partner"},{"name":"Delete Business Partner","description":"Delete a business partner"},{"name":"List Business Partner Groups","description":"List all business partner groups"},{"name":"Get Business Partner Group","description":"Get a specific business partner group by ID"},{"name":"Create Business Partner Group","description":"Create a new business partner group"},{"name":"Delete Business Partner Group","description":"Delete a business partner group"},{"name":"List Supergroups","description":"List all supergroups"},{"name":"Get Supergroup","description":"Get a specific supergroup by ID"},{"name":"List Supergroup Members","description":"List members of a supergroup"},{"name":"List Supergroup Inclusion Members","description":"List inclusion members of a supergroup"},{"name":"List Supergroup Exclusion Members","description":"List exclusion members of a supergroup"},{"name":"Update Supergroup Inclusion Members","description":"Update inclusion members of a supergroup"},{"name":"Update Supergroup Exclusion Members","description":"Update exclusion members of a supergroup"},{"name":"List Custom Objects","description":"List all custom objects"},{"name":"Get Custom Object","description":"Get a custom object by API name"},{"name":"Create Custom Object","description":"Create a new custom object"},{"name":"Update Custom Object","description":"Update a custom object"},{"name":"Delete Custom Object","description":"Delete a custom object"},{"name":"List Custom Object Fields","description":"List all fields for a custom object"},{"name":"Get Custom Object Field","description":"Get a specific field of a custom object"},{"name":"Create Custom Object Field","description":"Create a field on a custom object"},{"name":"Update Custom Object Field","description":"Update a field on a custom object"},{"name":"Delete Custom Object Field","description":"Delete a field from a custom object"},{"name":"List Custom Object Records","description":"List all records for a custom object"},{"name":"Get Custom Object Record","description":"Get a specific custom object record"},{"name":"Get Custom Object Record by External ID","description":"Get a custom object record by external ID"},{"name":"Query Custom Object Records","description":"Query custom object records with filters"},{"name":"Create Custom Object Record","description":"Create a custom object record"},{"name":"Update Custom Object Record","description":"Update a custom object record"},{"name":"Delete Custom Object Record","description":"Delete a custom object record"},{"name":"Bulk Create Custom Object Records","description":"Bulk create custom object records"},{"name":"Bulk Update Custom Object Records","description":"Bulk update custom object records"},{"name":"Bulk Delete Custom Object Records","description":"Bulk delete custom object records"},{"name":"List Custom Apps","description":"List all custom apps"},{"name":"Get Custom App","description":"Get a specific custom app"},{"name":"Create Custom App","description":"Create a new custom app"},{"name":"Update Custom App","description":"Update a custom app"},{"name":"Delete Custom App","description":"Delete a custom app"},{"name":"List Custom Pages","description":"List all custom pages"},{"name":"Get Custom Page","description":"Get a specific custom page"},{"name":"Create Custom Page","description":"Create a new custom page"},{"name":"Update Custom Page","description":"Update a custom page"},{"name":"Delete Custom Page","description":"Delete a custom page"},{"name":"List Custom Settings","description":"List all custom settings"},{"name":"Get Custom Setting","description":"Get a specific custom setting"},{"name":"Create Custom Setting","description":"Create a new custom setting"},{"name":"Update Custom Setting","description":"Update a custom setting"},{"name":"Delete Custom Setting","description":"Delete a custom setting"},{"name":"List Object Categories","description":"List all object categories"},{"name":"Get Object Category","description":"Get a specific object category"},{"name":"Create Object Category","description":"Create a new object category"},{"name":"Update Object Category","description":"Update an object category"},{"name":"Delete Object Category","description":"Delete an object category"},{"name":"Get Report Run","description":"Get a report run by ID"},{"name":"Trigger Report Run","description":"Trigger a new report run"},{"name":"Create Draft Hires","description":"Create bulk draft hires"}],"triggers":[],"skills":[{"name":"lookup-employee-profile","description":"Find a Rippling worker and return their role, department, and team details.","content":"# Lookup Employee Profile\\n\\nRetrieve a complete profile for an employee.\\n\\n## Steps\\n1. Run list_workers filtered by name or attributes to find the worker, or list_users if you have a user id.\\n2. Run get_worker for the full record once identified.\\n3. Enrich with get_department, get_team, and get_title as needed for context.\\n4. Assemble the profile.\\n\\n## Output\\nReturn the worker name, title, department, team, and employment type. Note any field that is unavailable."},{"name":"department-headcount-report","description":"Group Rippling workers by department and employment type to report headcount.","content":"# Department Headcount Report\\n\\nBuild a headcount snapshot across the org.\\n\\n## Steps\\n1. Run list_departments to enumerate departments.\\n2. Run list_workers and group by department and employment type.\\n3. Compute headcount per group and compare against a prior snapshot for growth.\\n4. Write a narrative summary of the changes.\\n\\n## Output\\nReturn headcount per department and employment type, plus week-over-week change where available."},{"name":"manage-department","description":"Create or update a department record in Rippling for an org change.","content":"# Manage Department\\n\\nKeep the Rippling org structure current.\\n\\n## Steps\\n1. Run list_departments to check whether the department already exists.\\n2. If new, run create_department with the name and parent details.\\n3. If it exists, run update_department to adjust the record.\\n4. Confirm with get_department.\\n\\n## Output\\nReturn the department id and whether it was created or updated."},{"name":"sync-custom-object-records","description":"Push external data (training, licenses, assets) onto Rippling custom object records.","content":"# Sync Custom Object Records\\n\\nWrite product data onto Rippling profiles via custom objects.\\n\\n## Steps\\n1. Run list_custom_objects to find the target object, then list_custom_object_fields to confirm its schema.\\n2. Build the records to write (for example training completion dates, license assignments, or asset ids).\\n3. Use create_custom_object_record or update_custom_object_record for single writes, or bulk_create_custom_object_records and bulk_update_custom_object_records for batches.\\n4. Verify with query_custom_object_records or get_custom_object_record_by_external_id.\\n\\n## Output\\nReturn the count of records created or updated and flag any that failed validation."},{"name":"run-rippling-report","description":"Trigger a Rippling report run and retrieve the completed results.","content":"# Run Rippling Report\\n\\nGenerate and collect a Rippling report for downstream analysis.\\n\\n## Steps\\n1. Run trigger_report_run for the target report id to start a run.\\n2. Capture the returned run id.\\n3. Poll get_report_run until the run completes.\\n4. Pass the results downstream to a table or summary.\\n\\n## Output\\nReturn the report run id, completion status, and a summary of the returned rows."}],"templates":[{"title":"Google Groups onboarding sync","prompt":"Create a workflow that watches Rippling or Greenhouse for new hires, adds them to the right Google Groups based on team and department, and emails the new hire a list of the groups joined.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"google_groups","name":"Google Groups"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Google Groups departure cleanup","prompt":"Create a workflow that watches Workday or Rippling for terminations and removes the departing user from every Google Group they belonged to, writing the change to a security audit log.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"google_groups","name":"Google Groups"},{"id":"workday","name":"Workday"}]},{"title":"Neo4j org-chart sync","prompt":"Build a workflow that pulls Workday or Rippling worker data, upserts employees and reporting relationships into Neo4j, and exposes a queryable org graph for downstream tools.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"neo4j","name":"Neo4j"},{"id":"workday","name":"Workday"}]},{"title":"Rippling new-hire provisioning","prompt":"Build a scheduled workflow that polls Rippling for new workers, creates accounts in the matching downstream tools, drops each new hire into the right Slack channels, books day-one onboarding via Google Calendar, and writes provisioning status to a tracking table.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"slack","name":"Slack"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Rippling departure offboarder","prompt":"Create a scheduled workflow that polls Rippling for workers transitioning out, gathers their owned resources, deactivates downstream accounts, schedules data handoff meetings, posts a structured offboarding checklist to a table, and notifies the people team in Slack.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"slack","name":"Slack"}]},{"title":"Rippling org chart export","prompt":"Build a scheduled weekly workflow that pulls Rippling workers, departments, teams, and titles, writes an updated org chart file, diffs against last week to find structural changes, and Slacks people operations any unexpected moves for review.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"slack","name":"Slack"}]},{"title":"Rippling custom object sync","prompt":"Create a workflow that reads rows from a Sim table representing custom Rippling objects — perks, equipment, allowances — and upserts them into Rippling so HR can manage company-specific data with the same governance as core worker records.","integrations":[{"id":"rippling","name":"Rippling"}]},{"title":"Rippling team and title audit","prompt":"Build a scheduled monthly workflow that lists Rippling teams, titles, and job functions, flags duplicates, unused values, and inconsistent naming, writes a cleanup report file, and opens a Linear task for the people operations owner of each issue.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"linear","name":"Linear"}]},{"title":"Rippling manager change alerts","prompt":"Create a scheduled workflow that polls Rippling workers for manager reassignments, notifies the worker and the new manager via email, schedules a thirty-minute intro on Google Calendar, and logs the transition in a tracking table for HR visibility.","integrations":[{"id":"rippling","name":"Rippling"},{"id":"gmail","name":"Gmail"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Rippling headcount digest","prompt":"Build a scheduled weekly workflow that pulls Rippling workers grouped by department and employment type, computes headcount, open requisitions, and growth versus the prior week, writes a narrative summary, and emails it to department heads.","integrations":[{"id":"rippling","name":"Rippling"}]}]},{"id":"rocketlane","type":"rocketlane","slug":"rocketlane","name":"Rocketlane","description":"Manage client onboarding projects, tasks, time tracking, and invoices","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/rocketlane","authType":"api-key","connections":[],"operations":[{"name":"Create Project","description":"Create a new Rocketlane project with a customer, owner, dates, team members, templates, financials, and custom fields"},{"name":"Get Project","description":"Retrieve a Rocketlane project by its unique identifier"},{"name":"List Projects","description":"List Rocketlane projects with optional filters, sorting, and token-based pagination"},{"name":"Update Project","description":"Update a Rocketlane project by ID, including name, dates, visibility, owner, status, and custom fields"},{"name":"Archive Project","description":"Archive a Rocketlane project by ID, making it dormant while preserving its details and history"},{"name":"Delete Project","description":"Permanently delete a Rocketlane project by ID (irreversible; only Admins, Super Users, and Project Owners can delete)"},{"name":"Add Project Members","description":"Add team members and customer stakeholders to a Rocketlane project"},{"name":"Remove Project Members","description":"Remove team members from a Rocketlane project"},{"name":"Import Template","description":"Import a project template into an existing Rocketlane project"},{"name":"List Placeholders","description":"List the placeholders of a Rocketlane project"},{"name":"Assign Placeholder","description":"Assign a placeholder in a Rocketlane project to a user"},{"name":"Unassign Placeholder","description":"Unassign a placeholder from its user in a Rocketlane project"},{"name":"Create Task","description":"Create a new task in a Rocketlane project"},{"name":"Get Task","description":"Retrieve detailed information about a Rocketlane task by its unique identifier"},{"name":"List Tasks","description":"Retrieve all Rocketlane tasks with optional filters, sorting, and pagination"},{"name":"Update Task","description":"Update the properties of an existing Rocketlane task by its unique identifier"},{"name":"Delete Task","description":"Permanently delete a Rocketlane task by its unique identifier"},{"name":"Move Task to Phase","description":"Move a Rocketlane task to a given phase, associating the task with that phase"},{"name":"Add Task Assignees","description":"Add members as assignees to a Rocketlane task"},{"name":"Remove Task Assignees","description":"Remove assignees from a Rocketlane task"},{"name":"Add Task Followers","description":"Add members as followers to a Rocketlane task"},{"name":"Remove Task Followers","description":"Remove followers from a Rocketlane task"},{"name":"Add Task Dependencies","description":"Add finish-to-start dependencies between a Rocketlane task and other tasks"},{"name":"Remove Task Dependencies","description":"Remove dependencies from a Rocketlane task"},{"name":"Create Phase","description":"Create a new phase in a Rocketlane project"},{"name":"Get Phase","description":"Retrieve a single Rocketlane phase by ID"},{"name":"List Phases","description":"List phases of a Rocketlane project, with optional filters, sorting, and pagination"},{"name":"Update Phase","description":"Update the name, dates, status, or privacy of an existing Rocketlane phase"},{"name":"Delete Phase","description":"Permanently delete a Rocketlane phase by ID"},{"name":"Create Field","description":"Create a custom field in your Rocketlane account, with options for SINGLE_CHOICE and MULTIPLE_CHOICE field types"},{"name":"Get Field","description":"Retrieve a single Rocketlane field by ID"},{"name":"List Fields","description":"List fields in your Rocketlane account, with optional filters, sorting, and pagination"},{"name":"Update Field","description":"Update the label, description, enabled state, or privacy of an existing Rocketlane field"},{"name":"Delete Field","description":"Permanently delete a Rocketlane field by ID"},{"name":"Add Field Option","description":"Add a new option to an existing SINGLE_CHOICE or MULTIPLE_CHOICE Rocketlane field"},{"name":"Update Field Option","description":"Update the label or color of an existing option on a SINGLE_CHOICE or MULTIPLE_CHOICE Rocketlane field"},{"name":"Create Time Entry","description":"Create a time entry in Rocketlane against an adhoc activity, task, project phase, or project"},{"name":"Get Time Entry","description":"Get a single Rocketlane time entry by ID"},{"name":"List Time Entries","description":"List Rocketlane time entries with optional filters, sorting, and cursor-based pagination"},{"name":"Search Time Entries","description":"Search Rocketlane time entries with filters, sorting, and pagination (deprecated by Rocketlane in favor of listing time entries with filters)"},{"name":"Update Time Entry","description":"Update a Rocketlane time entry by ID. The activityName, notes, billable, and minutes properties can be updated"},{"name":"Delete Time Entry","description":"Permanently delete a Rocketlane time entry by ID"},{"name":"List Time Entry Categories","description":"List the time entry categories configured in Rocketlane"},{"name":"Create Time-Off","description":"Create a time-off for a team member in Rocketlane. Holidays and weekends within the date range are automatically excluded from the duration."},{"name":"Get Time-Off","description":"Retrieve a Rocketlane time-off by its ID"},{"name":"List Time-Offs","description":"List time-offs in Rocketlane with optional date, type, and user filters, sorting, and pagination"},{"name":"Delete Time-Off","description":"Permanently delete a Rocketlane time-off by its ID"},{"name":"Get User","description":"Retrieve a Rocketlane user by their ID"},{"name":"List Users","description":"List users in your Rocketlane account, with optional filters, sorting, and pagination"},{"name":"Create Space","description":"Create a new space in a Rocketlane project"},{"name":"Get Space","description":"Retrieve a Rocketlane space by its ID"},{"name":"List Spaces","description":"List spaces in a Rocketlane project, with optional filters, sorting, and pagination"},{"name":"Update Space","description":"Update a Rocketlane space by its ID"},{"name":"Delete Space","description":"Permanently delete a Rocketlane space by its ID"},{"name":"Create Space Document","description":"Create a new space document in a Rocketlane space"},{"name":"Get Space Document","description":"Retrieve a Rocketlane space document by its ID"},{"name":"List Space Documents","description":"List space documents in a Rocketlane project, with optional filters, sorting, and pagination"},{"name":"Update Space Document","description":"Update a Rocketlane space document by its ID"},{"name":"Delete Space Document","description":"Permanently delete a Rocketlane space document by its ID"},{"name":"List Resource Allocations","description":"List resource allocations in Rocketlane within a date range, with optional member, project, and placeholder filters, sorting, and pagination"},{"name":"Get Invoice","description":"Retrieve a Rocketlane invoice by its ID"},{"name":"List Invoices","description":"Search invoices in Rocketlane with date, amount, company, invoice-number, and status filters, sorting, and pagination"},{"name":"Get Invoice Line Items","description":"List line items of a Rocketlane invoice"},{"name":"Get Invoice Payments","description":"List payments recorded against a Rocketlane invoice"}],"triggers":[],"skills":[{"name":"kickoff-onboarding-project","description":"Spin up a Rocketlane onboarding project from a template when a deal closes — create the project, apply the template, assign placeholders, and add the account team. Use for CRM-triggered kickoffs.","content":"# Kickoff Onboarding Project\\n\\nLaunch a client onboarding project in Rocketlane from a closed-won deal or intake request.\\n\\n## Steps\\n1. Extract the customer company name, project name, owner, start date, and any template to apply from the request.\\n2. Create the project with `create_project`, passing the customer company (enable auto-create if the company may not exist yet) and template sources so phases and tasks are scaffolded automatically. For an existing project, apply a plan with `import_template` instead.\\n3. List the project placeholders with `list_placeholders` and map each one to a real person using `assign_placeholders` (by user ID or email).\\n4. Add the delivery and account team with `add_project_members`, resolving people via `list_users` when only names are given.\\n\\n## Output\\nReport the created project ID and name, which template was applied, placeholder assignments made, and the members added."},{"name":"project-status-report","description":"Compile a delivery status report across Rocketlane projects — phases, task progress, overdue work, and at-risk items. Use for weekly digests and exec updates.","content":"# Project Status Report\\n\\nSummarize the health of one or more Rocketlane projects.\\n\\n## Steps\\n1. Resolve the scope: a single project via `get_project`, or all active projects via `list_projects` (filter by status, customer, or due-date window; page with the returned page token until done or a sensible cap).\\n2. For each project, pull `list_phases` for stage-level progress and `list_tasks` for task status, using due-date filters to isolate overdue or due-soon work.\\n3. Group findings per project: current phase, tasks completed vs open, overdue tasks with assignees, and anything flagged at risk.\\n\\n## Output\\nA per-project status summary — phase, progress counts, overdue items called out by name and owner — with an overall headline of projects on track vs slipping."},{"name":"escalate-overdue-tasks","description":"Find overdue or slipping Rocketlane tasks, mark them at risk, and loop in the right people. Use for daily delivery hygiene automations.","content":"# Escalate Overdue Tasks\\n\\nCatch slipping work before it derails a project.\\n\\n## Steps\\n1. Query `list_tasks` with a due-date-to filter of today (optionally scoped to a project or phase) to find tasks past their due date that are not complete.\\n2. For each overdue task, set the at-risk flag with `update_task` so it is visible on the project plan.\\n3. Add the project owner or delivery lead as a follower with `add_task_followers` so they get notified of further changes.\\n4. Reassign stalled tasks when instructed, using `add_task_assignees` / `remove_task_assignees`.\\n\\n## Output\\nList each escalated task with its project, assignees, days overdue, and the action taken (flagged, follower added, reassigned)."},{"name":"log-time-entry","description":"Record time in Rocketlane against a task, phase, project, or ad-hoc activity with the right category and billable flag. Use to log work from chat or other systems.","content":"# Log Time Entry\\n\\nCreate an accurate Rocketlane time entry from a natural-language description of work done.\\n\\n## Steps\\n1. Extract the date, duration in minutes, what the time was spent on, and whether it is billable.\\n2. Resolve the target: find the task with `list_tasks` (or the project/phase with `list_projects`/`list_phases`); for non-project work use an ad-hoc activity name instead.\\n3. Match a category with `list_time_entry_categories` when the team uses categories.\\n4. Create the entry with `create_time_entry` against exactly one source (task, project, phase, or activity), including notes and the billable flag. Fix mistakes with `update_time_entry`.\\n\\n## Output\\nConfirm the logged entry: date, minutes, target, category, and billable state."},{"name":"utilization-rollup","description":"Roll up Rocketlane time entries, allocations, and time-offs into a utilization picture per person or project. Use for capacity planning and weekly utilization reviews.","content":"# Utilization Rollup\\n\\nBuild a utilization and capacity snapshot for a date range.\\n\\n## Steps\\n1. Pull logged time for the period with `search_time_entries` (filter by date range; page through results with the page token, keeping a sensible page cap).\\n2. Total billable vs non-billable minutes per user and per project.\\n3. Fetch planned capacity with `list_resource_allocations` for the same window and subtract `list_time_offs` to get true availability.\\n4. Compare logged time against allocation to flag under-logged members and over-allocated ones.\\n\\n## Output\\nA table-style rollup per person: allocated minutes, logged billable/non-billable minutes, time off, and a utilization percentage, plus any members flagged for follow-up."},{"name":"overdue-invoice-followup","description":"Track Rocketlane invoices with outstanding balances past their due date and assemble follow-up details. Use for finance and collections automations.","content":"# Overdue Invoice Follow-up\\n\\nFind unpaid invoices and prepare a collections summary.\\n\\n## Steps\\n1. Query `list_invoices` filtered to invoices with an outstanding amount greater than zero and a due date in the past.\\n2. For each hit, fetch `get_invoice_payments` to confirm what has already been paid and `get_invoice_line_items` when the follow-up needs a breakdown.\\n3. Sort by amount outstanding and days overdue so the largest, oldest balances lead.\\n\\n## Output\\nA prioritized list of overdue invoices: invoice number, customer company, amount outstanding, days overdue, and payments received to date."}],"templates":[{"title":"Rocketlane onboarding kickoff","prompt":"Build a workflow that creates a Rocketlane project from an onboarding template for a new customer, assigns the implementation manager placeholder, adds the account team as members, and posts a kickoff summary with the project details to Slack.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"slack","name":"Slack"}]},{"title":"Rocketlane status digest","prompt":"Create a scheduled weekly workflow that lists active Rocketlane projects with their status and due dates, summarizes progress and anything overdue per customer, and emails the digest to the delivery team every Monday morning.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"gmail","name":"Gmail"}]},{"title":"Rocketlane task escalation","prompt":"Build a scheduled daily workflow that lists Rocketlane tasks with a due date before today that are not complete, marks them at risk, and posts an escalation to Slack tagging each task name, project, and assignees.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"slack","name":"Slack"}]},{"title":"Rocketlane time rollup","prompt":"Create a scheduled weekly workflow that searches Rocketlane time entries for the past week, totals billable and non-billable minutes per project, and posts a formatted utilization rollup to Slack.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"slack","name":"Slack"}]},{"title":"Rocketlane invoice monitor","prompt":"Build a scheduled workflow that lists Rocketlane invoices with an outstanding amount greater than zero and a due date in the past, pulls their payments, and emails the finance team a list of overdue invoices with amounts outstanding.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"gmail","name":"Gmail"}]},{"title":"Rocketlane allocation report","prompt":"Create a workflow that lists Rocketlane resource allocations for the next two weeks, writes each member, project, and allocation range into a table, and flags team members who appear in overlapping allocations.","integrations":[{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rocketlane timesheet reminder","prompt":"Build a scheduled Friday workflow that lists active Rocketlane team members, searches this week’s time entries per user, and sends a Slack reminder to anyone who has logged less than their expected hours.","integrations":[{"id":"rocketlane","name":"Rocketlane"},{"id":"slack","name":"Slack"}]},{"title":"Rocketlane project scaffolding","prompt":"Create a workflow that scaffolds a delivery project in Rocketlane: create the project, add Discovery, Implementation, and Go-live phases with dates, create kickoff tasks in each phase with assignees, and set up a shared space with a kickoff document.","integrations":[{"id":"rocketlane","name":"Rocketlane"}]}]},{"id":"rootly","type":"rootly","slug":"rootly","name":"Rootly","description":"Manage incidents, alerts, and on-call with Rootly","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/rootly","authType":"api-key","connections":[],"operations":[{"name":"Create Incident","description":"Create a new incident in Rootly with optional severity, services, and teams."},{"name":"Get Incident","description":"Retrieve a single incident by ID from Rootly."},{"name":"Update Incident","description":"Update an existing incident in Rootly (status, severity, summary, etc.)."},{"name":"List Incidents","description":"List incidents from Rootly with optional filtering by status, severity, and more."},{"name":"Create Alert","description":"Create a new alert in Rootly for on-call notification and routing."},{"name":"List Alerts","description":"List alerts from Rootly with optional filtering by status, source, and services."},{"name":"Add Incident Event","description":"Add a timeline event to an existing incident in Rootly."},{"name":"List Services","description":"List services from Rootly with optional search filtering."},{"name":"List Severities","description":"List severity levels configured in Rootly."},{"name":"List Teams","description":"List teams (groups) configured in Rootly."},{"name":"List Environments","description":"List environments configured in Rootly."},{"name":"List Incident Types","description":"List incident types configured in Rootly."},{"name":"List Functionalities","description":"List functionalities configured in Rootly."},{"name":"List Retrospectives","description":"List incident retrospectives (post-mortems) from Rootly."},{"name":"Delete Incident","description":"Delete an incident by ID from Rootly."},{"name":"Get Alert","description":"Retrieve a single alert by ID from Rootly."},{"name":"Update Alert","description":"Update an existing alert in Rootly."},{"name":"Acknowledge Alert","description":"Acknowledge an alert in Rootly."},{"name":"Resolve Alert","description":"Resolve an alert in Rootly."},{"name":"Create Action Item","description":"Create a new action item for an incident in Rootly."},{"name":"List Action Items","description":"List action items for an incident in Rootly."},{"name":"List Users","description":"List users from Rootly with optional search and email filtering."},{"name":"List On-Calls","description":"List current on-call entries from Rootly with optional filtering."},{"name":"List Schedules","description":"List on-call schedules from Rootly with optional search filtering."},{"name":"List Escalation Policies","description":"List escalation policies from Rootly with optional search filtering."},{"name":"List Causes","description":"List causes from Rootly with optional search filtering."},{"name":"List Playbooks","description":"List playbooks from Rootly with pagination support."},{"name":"Mitigate Incident","description":"Transition a Rootly incident to the mitigated state."},{"name":"Resolve Incident","description":"Transition a Rootly incident to the resolved state."},{"name":"Assign Incident Role","description":"Assign an incident role (e.g. commander) to a user on a Rootly incident."},{"name":"Unassign Incident Role","description":"Remove an incident role assignment from a user on a Rootly incident."},{"name":"Add Subscribers","description":"Subscribe users to a Rootly incident so they receive updates."},{"name":"Remove Subscribers","description":"Unsubscribe users from a Rootly incident."},{"name":"Create Status Page Event","description":"Post a public status page update for a Rootly incident."},{"name":"Update Action Item","description":"Update a Rootly incident action item (status, priority, assignee, etc.)."},{"name":"Delete Action Item","description":"Delete a Rootly incident action item."},{"name":"Snooze Alert","description":"Snooze a Rootly alert for a set number of minutes."},{"name":"Escalate Alert","description":"Escalate a Rootly alert, optionally to a specific escalation policy or level."},{"name":"List Incident Events","description":"List the timeline events for a Rootly incident."},{"name":"Run Workflow","description":"Trigger a Rootly automation workflow, optionally scoped to an incident or alert."},{"name":"List Incident Roles","description":"List incident roles configured in Rootly (e.g. commander, scribe)."}],"triggers":[{"id":"rootly_incident_created","name":"Rootly Incident Created","description":"Trigger workflow when a new incident is created in Rootly"},{"id":"rootly_incident_updated","name":"Rootly Incident Updated","description":"Trigger workflow when an incident is updated in Rootly"},{"id":"rootly_incident_resolved","name":"Rootly Incident Resolved","description":"Trigger workflow when an incident is resolved in Rootly"},{"id":"rootly_alert_created","name":"Rootly Alert Created","description":"Trigger workflow when a new alert is created in Rootly"}],"skills":[{"name":"declare-incident","description":"Open a Rootly incident with the right severity, service, and team assigned.","content":"# Declare Incident\\n\\nSpin up a structured Rootly incident from an alert or report.\\n\\n## Steps\\n1. Run list_severities, list_services, and list_teams to resolve the correct ids.\\n2. Run create_incident with a clear title, summary, severity, affected service, and owning team.\\n3. Capture the returned incident id.\\n4. Add an opening timeline note with add_incident_event.\\n\\n## Output\\nReturn the incident id, severity, assigned team, and a link. Confirm the opening event was logged."},{"name":"post-incident-update","description":"Append a status update event to an active Rootly incident timeline.","content":"# Post Incident Update\\n\\nKeep an incident timeline current.\\n\\n## Steps\\n1. Run get_incident to confirm the current state.\\n2. Run add_incident_event with the update text (mitigation steps, customer impact, next checkpoint).\\n3. Run update_incident if the severity or status has changed.\\n\\n## Output\\nReturn the appended event and the current incident status."},{"name":"triage-alerts","description":"List open Rootly alerts, acknowledge them, and escalate to an incident if needed.","content":"# Triage Alerts\\n\\nWork through the open alert queue.\\n\\n## Steps\\n1. Run list_alerts to pull open alerts.\\n2. For each, run get_alert for detail and run acknowledge_alert to claim it.\\n3. If an alert warrants response, run create_incident and link it.\\n4. Run resolve_alert once the alert is handled.\\n\\n## Output\\nReturn how many alerts were acknowledged, resolved, and escalated to incidents."},{"name":"check-on-call","description":"Look up who is currently on call across Rootly schedules and escalation policies.","content":"# Check On Call\\n\\nFind the right person to page right now.\\n\\n## Steps\\n1. Run list_schedules to enumerate on-call schedules.\\n2. Run list_on_calls to read the current rotation members.\\n3. Cross-reference list_escalation_policies for the escalation path.\\n\\n## Output\\nReturn the current on-call person per schedule and the escalation order."},{"name":"track-action-items","description":"Create and list retrospective action items tied to a Rootly incident.","content":"# Track Action Items\\n\\nCapture and follow up on postmortem action items.\\n\\n## Steps\\n1. Run get_incident to confirm the incident context.\\n2. Run create_action_item for each follow-up with a clear owner and description.\\n3. Run list_action_items to review open items for the incident.\\n\\n## Output\\nReturn the created action items and the list of outstanding follow-ups."}],"templates":[{"title":"Rootly incident war-room","prompt":"Build a scheduled workflow that polls Rootly for newly opened incidents, creates a Slack war-room channel for each, invites responders, posts the incident summary, and keeps the channel topic in sync with severity.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"slack","name":"Slack"}]},{"title":"Rootly retro generator","prompt":"Create a scheduled workflow that polls Rootly for recently closed incidents, drafts the retrospective doc, pulls the Slack thread and timeline, and assigns owners for follow-up actions in Linear.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"slack","name":"Slack"},{"id":"linear","name":"Linear"}]},{"title":"Rootly weekly digest","prompt":"Build a scheduled weekly workflow that summarizes Rootly incident counts, MTTR, top affected services, and outstanding action items, and posts a digest to leadership Slack.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"slack","name":"Slack"}]},{"title":"Rootly customer-comms drafter","prompt":"Create a workflow that drafts and queues customer-facing status updates during a Rootly incident based on severity and impacted services, holding for approval before publishing.","integrations":[{"id":"rootly","name":"Rootly"}]},{"title":"Rootly action-item tracker","prompt":"Build a workflow that tracks Rootly follow-up actions across incidents, opens Linear tickets, and writes a tables-based dashboard that flags overdue items by owner.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"linear","name":"Linear"}]},{"title":"Rootly on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of Rootly pages, the on-call responder load by person, and writes a digest to the SRE Slack channel.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"slack","name":"Slack"}]},{"title":"Rootly + LangSmith agent-incident tracker","prompt":"Build a workflow that for each Rootly incident involving an AI agent attaches the LangSmith trace, captures the failure mode, and writes the agent-quality regression analysis.","integrations":[{"id":"rootly","name":"Rootly"},{"id":"langsmith","name":"LangSmith"}]}]},{"id":"s3","type":"s3","slug":"s3","name":"S3","description":"Upload, download, list, and manage S3 files and buckets","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/s3","authType":"api-key","connections":[],"operations":[{"name":"Download File","description":"Retrieve an object from an AWS S3 bucket"},{"name":"Upload File","description":"Upload a file to an AWS S3 bucket"},{"name":"List Objects","description":"List objects in an AWS S3 bucket"},{"name":"Delete Object","description":"Delete an object from an AWS S3 bucket"},{"name":"Delete Objects (Batch)","description":"Delete multiple objects from an AWS S3 bucket in a single batch request"},{"name":"Copy Object","description":"Copy an object within or between AWS S3 buckets"},{"name":"Head Object (Metadata)","description":"Retrieve metadata for an S3 object without downloading its body"},{"name":"Presigned URL","description":"Generate a time-limited presigned URL to download or upload an S3 object"},{"name":"List Buckets","description":"List the S3 buckets owned by the authenticated AWS account"},{"name":"Create Bucket","description":"Create a new AWS S3 bucket in the specified region"},{"name":"Delete Bucket","description":"Delete an empty AWS S3 bucket"}],"triggers":[],"skills":[{"name":"upload-and-share-asset","description":"Upload a generated file to an S3 bucket and return its object URL.","content":"# Upload And Share Asset\\n\\nPublish a file to S3 and hand back a usable link.\\n\\n## Steps\\n1. Take the generated image or document as the object body.\\n2. Run put_object with the bucket, key, and content type.\\n3. Construct or capture the resulting object URL.\\n4. Write the link back to the originating record (for example a table row).\\n\\n## Output\\nReturn the object key and URL. Note the bucket and whether the object is publicly accessible."},{"name":"fetch-object-contents","description":"Download an object from S3 and pass its contents to downstream steps.","content":"# Fetch Object Contents\\n\\nRetrieve a file from S3 for processing.\\n\\n## Steps\\n1. Identify the bucket and object key.\\n2. Run get_object to download the file.\\n3. Pass the contents downstream for parsing, summarizing, or transformation.\\n\\n## Output\\nReturn the object contents (or a file reference) and confirm the source key."},{"name":"list-bucket-objects","description":"List objects in an S3 bucket under a prefix for inventory or cleanup.","content":"# List Bucket Objects\\n\\nEnumerate what lives under an S3 prefix.\\n\\n## Steps\\n1. Run list_objects with the bucket and an optional prefix to scope the listing.\\n2. Page through results if the listing is truncated.\\n3. Filter the keys by name, date, or size as needed.\\n\\n## Output\\nReturn the matching object keys with sizes and last-modified dates."},{"name":"archive-object","description":"Copy an S3 object to an archive location and delete the original.","content":"# Archive Object\\n\\nMove an object to an archive prefix or bucket.\\n\\n## Steps\\n1. Run copy_object from the source key to the archive destination key.\\n2. Verify the copy succeeded.\\n3. Run delete_object on the original to complete the move.\\n\\n## Output\\nConfirm the archived destination key and that the original was removed."},{"name":"share-file-via-presigned-url","description":"Generate a time-limited presigned URL so others can download an S3 object.","content":"# Share File Via Presigned URL\\n\\nHand someone a temporary download link without making the object public.\\n\\n## Steps\\n1. Identify the bucket and object key to share.\\n2. Run presigned_url with method get and an expiry window in seconds.\\n3. Deliver the returned URL to the recipient (for example via email or Slack).\\n\\n## Output\\nReturn the presigned URL and note when it expires."}],"templates":[{"title":"Athena S3 access audit","prompt":"Build a workflow that runs Athena queries against S3 access logs weekly, identifies unusual access patterns or new principals, and writes findings to a security audit table.","integrations":[{"id":"s3","name":"S3"},{"id":"athena","name":"Athena"}]},{"title":"Box to S3 backup","prompt":"Create a scheduled workflow that mirrors a Box folder tree into S3 nightly with incremental sync, captures the manifest, and pings Slack on any failed files.","integrations":[{"id":"s3","name":"S3"},{"id":"box","name":"Box"}]},{"title":"Clerk user roster archiver","prompt":"Build a scheduled workflow that exports the full Clerk user and organization roster to S3 on a retention schedule, and writes the snapshot manifest to a compliance table.","integrations":[{"id":"s3","name":"S3"},{"id":"clerk","name":"Clerk"}]},{"title":"CloudTrail data-event coverage audit","prompt":"Create a weekly workflow that reads the event selectors of every AWS CloudTrail trail, reports which trails are missing management event logging or S3 data events, and writes the gaps to a compliance table.","integrations":[{"id":"s3","name":"S3"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudWatch metric archiver","prompt":"Build a scheduled workflow that exports CloudWatch metric snapshots into S3 long-term storage, preserving granularity for compliance, and writing a manifest table.","integrations":[{"id":"s3","name":"S3"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"Convex nightly backup to S3","prompt":"Create a scheduled workflow that runs each night, pages through every Convex table with List Documents, writes the exported JSON to S3 with date partitions, and records the run in an audit table.","integrations":[{"id":"s3","name":"S3"},{"id":"convex","name":"Convex"}]},{"title":"Datadog monitor config backup","prompt":"Create a scheduled workflow that lists every Datadog monitor nightly, fetches each monitor’s full configuration, exports the definitions as JSON to S3 with version history, and writes a manifest to a tracking table for restore drills.","integrations":[{"id":"s3","name":"S3"},{"id":"datadog","name":"Datadog"}]},{"title":"DynamoDB to S3 archive","prompt":"Build a scheduled workflow that exports DynamoDB items older than the retention horizon to S3 with Parquet partitioning and removes the rows from the table, writing the archive manifest.","integrations":[{"id":"s3","name":"S3"},{"id":"dynamodb","name":"Amazon DynamoDB"}]},{"title":"Google Vault export archiver","prompt":"Create a scheduled workflow that creates Google Vault matter exports, downloads the export files, archives them to S3 long-term storage, and writes the manifest to a compliance table.","integrations":[{"id":"s3","name":"S3"},{"id":"google_vault","name":"Google Vault"}]},{"title":"Infisical secret-inventory snapshot","prompt":"Build a scheduled workflow that lists Infisical secrets across environments, writes a redacted inventory snapshot to S3 for long-term retention, and tracks secret count trends in a table.","integrations":[{"id":"s3","name":"S3"},{"id":"infisical","name":"Infisical"}]},{"title":"MongoDB to data lake export","prompt":"Build a scheduled workflow that runs each night, exports MongoDB collections to S3 with partitioned Parquet files, and registers them in an Athena-queryable catalog.","integrations":[{"id":"s3","name":"S3"},{"id":"mongodb","name":"MongoDB"}]},{"title":"Qdrant snapshot manager","prompt":"Build a scheduled workflow that takes a Qdrant collection snapshot each night, uploads it to S3 with retention rotation, and writes the snapshot manifest to a tracking table.","integrations":[{"id":"s3","name":"S3"},{"id":"qdrant","name":"Qdrant"}]},{"title":"S3 report archiver","prompt":"Build a scheduled workflow that generates a daily report file, uploads it to an S3 bucket under a dated prefix, and posts the object link to Slack so the team always has the latest archived copy.","integrations":[{"id":"s3","name":"S3"},{"id":"slack","name":"Slack"}]},{"title":"S3 document ingestion to knowledge base","prompt":"Create a workflow that lists objects in an S3 bucket, downloads each new document, and indexes it into a Sim knowledge base so agents can answer questions over files stored in S3.","integrations":[{"id":"s3","name":"S3"}]},{"title":"S3 incoming-file processor","prompt":"Build a workflow that downloads a newly uploaded S3 object, parses its contents, writes the extracted rows to a table, and deletes the source object once processing succeeds.","integrations":[{"id":"s3","name":"S3"}]},{"title":"S3 backup retention sweeper","prompt":"Create a scheduled workflow that lists objects in an S3 backup bucket, identifies files older than the retention window, deletes the expired objects, and writes a deletion manifest to a table for audit.","integrations":[{"id":"s3","name":"S3"}]},{"title":"S3 export-to-customer flow","prompt":"Build a workflow that generates a per-customer data export file, uploads it to a customer-scoped S3 prefix, and emails the customer a download link once the upload completes.","integrations":[{"id":"s3","name":"S3"},{"id":"gmail","name":"Gmail"}]},{"title":"S3 bucket inventory dashboard","prompt":"Create a scheduled workflow that lists objects across an S3 bucket, aggregates object count and total size by prefix, and writes a daily inventory snapshot to a table for cost and growth tracking.","integrations":[{"id":"s3","name":"S3"}]},{"title":"S3 media-asset publisher","prompt":"Build a workflow that takes a generated image or document, uploads it to a public S3 bucket, retrieves the object URL, and writes the link back to the originating row in a table.","integrations":[{"id":"s3","name":"S3"}]},{"title":"Supabase nightly export to S3","prompt":"Create a scheduled workflow that runs each night, exports key Supabase tables to compressed JSON in S3 with date partitions, and writes the manifest to an audit table.","integrations":[{"id":"s3","name":"S3"},{"id":"supabase","name":"Supabase"}]},{"title":"Textract invoice extractor","prompt":"Create a scheduled workflow that polls an S3 folder for new PDFs, runs AWS Textract to extract line items and totals, writes the structured fields to a table, and flags invoices that fail validation.","integrations":[{"id":"s3","name":"S3"},{"id":"textract","name":"AWS Textract"}]},{"title":"Webflow CMS backup","prompt":"Build a scheduled workflow that exports every item from a Webflow CMS collection to S3 nightly with versioning, and writes the backup manifest to a tracking table.","integrations":[{"id":"s3","name":"S3"},{"id":"webflow","name":"Webflow"}]}]},{"id":"sailpoint","type":"sailpoint","slug":"sailpoint","name":"SailPoint","description":"Govern identities and access in SailPoint Identity Security Cloud","category":"Security","docsUrl":"https://docs.sim.ai/integrations/sailpoint","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search current SailPoint indices with every documented search query mode."},{"name":"Search Count","description":"Count documents matching a complete SailPoint search body."},{"name":"Search Aggregate","description":"Run an Elasticsearch DSL or SailPoint aggregation over current search indices."},{"name":"List Identities","description":"List identities with documented filtering, sorting, and pagination."},{"name":"Get Identity","description":"Get an identity from the current /identities/v1 service by ID."},{"name":"List Accounts","description":"List accounts with documented filtering, sorting, detail, and pagination."},{"name":"Get Account","description":"Get an account from the current /accounts/v1 service by ID."},{"name":"Get Account Entitlements","description":"List entitlements granted to one account."},{"name":"Get Account Selections","description":"Resolve eligible source accounts before submitting a machine or multi-account access request."},{"name":"List Entitlements","description":"List entitlements with current segmentation, cursor, filter, and page controls."},{"name":"Get Entitlement","description":"Get an entitlement by ID."},{"name":"Get Entitlement Request Config","description":"Get grant, revocation, duration, approval, and form settings for an entitlement."},{"name":"List Identity Entitlements","description":"List tagged entitlement references held by one identity."},{"name":"List Roles","description":"List roles with current visibility, segmentation, filtering, and pagination controls."},{"name":"Get Role","description":"Get a role by ID."},{"name":"Get Role Entitlements","description":"List entitlements in one role using the current non-experimental roles service."},{"name":"List Access Profiles","description":"List access profiles with current visibility and segmentation controls."},{"name":"Get Access Profile","description":"Get an access profile by ID."},{"name":"Get Access Profile Entitlements","description":"List entitlements in one access profile."},{"name":"Get Access Request Config","description":"Get tenant access-request, request-on-behalf-of, and machine-identity configuration."},{"name":"List Sources","description":"List identity sources with visibility, filtering, sorting, and pagination controls."},{"name":"Get Source","description":"Get an identity source by ID."},{"name":"List Account Activities","description":"List provisioning activities with identity, filter, sort, and page controls."},{"name":"Get Account Activity","description":"Get an account activity by ID."},{"name":"List Campaigns","description":"List certification campaigns with detail, filtering, sorting, and pagination."},{"name":"Get Campaign","description":"Get a certification campaign by ID."},{"name":"List Certifications","description":"List identity certifications assigned to a reviewer."},{"name":"Get Certification","description":"Get an identity certification by ID."},{"name":"List Certification Review Items","description":"List access-review items in one identity certification."},{"name":"Decide Certification Review Items","description":"Approve or revoke 1-250 review items in an identity certification."},{"name":"Sign Off Certification","description":"Sign off a completed identity certification."},{"name":"Request Access","description":"Submit a current human or machine identity access request."},{"name":"Cancel Access Request","description":"Cancel an access request that has not passed approval."},{"name":"Get Access Request Status","description":"List requested-item status records for access requests."},{"name":"List Pending Access Request Approvals","description":"List pending access-request approvals visible to the caller."},{"name":"Approve Access Request","description":"Approve one pending access-request approval."},{"name":"Reject Access Request","description":"Reject one pending access-request approval with a reviewer comment."},{"name":"Load Accounts (CSV)","description":"Start account aggregation for a source, optionally using a CSV file."},{"name":"Load Entitlements (CSV)","description":"Start entitlement aggregation for a source, optionally using a CSV file."},{"name":"Get Task Status","description":"Get the current status of a SailPoint background task by ID."}],"triggers":[],"skills":[{"name":"review-identity-access","description":"Search a SailPoint identity and summarize its entitlements, roles, and access profiles for an access review.","content":"# Review SailPoint Identity Access\\n\\nBuild a complete picture of what an identity can access.\\n\\n## Steps\\n1. Search identities (with nested objects) to find the target identity and its access array.\\n2. Expand roles and access profiles into their underlying entitlements.\\n3. Note directly-assigned versus role- or birthright-granted access (only directly-assigned access can be revoked via access request).\\n\\n## Output\\nA per-identity access summary highlighting privileged or unusual grants for reviewer attention."},{"name":"request-and-track-access","description":"Submit a SailPoint access request and track it to completion via account activities and request status.","content":"# Request and Track SailPoint Access\\n\\nDrive an access request from submission to fulfillment.\\n\\n## Steps\\n1. Search entitlements, roles, or access profiles to resolve the exact item IDs and confirm the identity does not already hold the access.\\n2. Submit a GRANT_ACCESS request using the flat human shape or the structured per-identity shape when account selection or a machine identity is required.\\n3. Record accessRequestIds from newRequests and use access-request status plus account activities to follow fulfillment, cancelling only when authorized and necessary.\\n\\n## Output\\nThe new or existing request IDs, requested items, and current fulfillment status."},{"name":"review-pending-access-requests","description":"Review pending SailPoint access-request approvals and approve or reject each item with an auditable comment.","content":"# Review Pending SailPoint Access Requests\\n\\nProcess the approval queue with the context needed for a defensible decision.\\n\\n## Steps\\n1. List pending access-request approvals for the current approver or an authorized owner.\\n2. Inspect the requester, target identity, requested object, dates, account selections, prior reviewer comments, and any separation-of-duties context.\\n3. Approve justified requests; reject requests that should not proceed and include the required reason.\\n\\n## Output\\nA decision log containing each approval ID, requested access, decision, comment, and provider acceptance status."},{"name":"complete-certification-review","description":"Review SailPoint certification items, record approve or revoke decisions, and sign off the completed certification.","content":"# Complete a SailPoint Certification Review\\n\\nWork through an assigned identity certification without losing review context.\\n\\n## Steps\\n1. List certifications for the reviewer and open the target certification.\\n2. Page through its access-review items, filtering by entitlement, access profile, or role when needed.\\n3. Submit decisions in batches of no more than 250 review items, including comments and proposed end dates for revoke decisions where appropriate.\\n4. Re-read the certification and sign it off only after every required item is complete.\\n\\n## Output\\nThe certification status, decision summary, unresolved items, and final sign-off result."},{"name":"monitor-aggregation-task","description":"Start a SailPoint source aggregation and monitor its task status through completion.","content":"# Monitor a SailPoint Aggregation Task\\n\\nRun a source import and surface its terminal result.\\n\\n## Steps\\n1. Start an account or entitlement aggregation for the intended source, attaching a CSV only for a compatible delimited-file source.\\n2. Capture the returned task ID.\\n3. Poll task status until completionStatus is populated, retaining progress, percentComplete, messages, and return values.\\n4. Report warnings or errors without treating task submission as successful completion.\\n\\n## Output\\nThe source and task IDs, progress history, completion status, messages, and returned task details."},{"name":"audit-orphan-accounts","description":"Find uncorrelated SailPoint accounts and prepare a source-grouped orphan-account inventory.","content":"# Audit SailPoint Orphan Accounts\\n\\nIdentify accounts that are not correlated to an identity.\\n\\n## Steps\\n1. List accounts with the documented uncorrelated filter and request full detail when the audit needs source and attribute context.\\n2. Page through all results using limit, offset, and totalCount when requested.\\n3. Group accounts by source and preserve account ID, native identity, account name, source, creation and modification timestamps, and entitlement context.\\n4. Write the normalized inventory to a table for governance follow-up.\\n\\n## Output\\nA source-grouped orphan-account inventory with stable account identifiers and the evidence needed for review."}],"templates":[{"title":"SailPoint joiner access review","prompt":"Create a scheduled workflow that lists recent SailPoint account activities for joiners, summarizes their granted access and time-to-access, and posts a digest to Slack for the identity team.","integrations":[{"id":"sailpoint","name":"SailPoint"},{"id":"slack","name":"Slack"}]},{"title":"SailPoint access request bot","prompt":"Build a Slack bot where a user describes the access they need, the agent searches SailPoint entitlements and access profiles, and submits a SailPoint access request on their behalf with a correlation note in client metadata.","integrations":[{"id":"sailpoint","name":"SailPoint"},{"id":"slack","name":"Slack"}]},{"title":"SailPoint orphan account finder","prompt":"Create a scheduled workflow that lists SailPoint accounts using the uncorrelated filter, groups the orphaned accounts by source, and writes the review-ready inventory to a table.","integrations":[{"id":"sailpoint","name":"SailPoint"}]},{"title":"SailPoint certification progress digest","prompt":"Build a scheduled workflow that lists active SailPoint campaigns and certifications, computes completion percentages, and emails a progress digest to certification owners.","integrations":[{"id":"sailpoint","name":"SailPoint"},{"id":"gmail","name":"Gmail"}]},{"title":"SailPoint leaver access revocation","prompt":"Create a workflow that, given a departing employee, searches their SailPoint identity access, and submits revoke access requests for each directly-assigned entitlement with a comment referencing the offboarding ticket in Jira.","integrations":[{"id":"sailpoint","name":"SailPoint"},{"id":"jira","name":"Jira"}]},{"title":"SailPoint entitlement catalog export","prompt":"Build a scheduled workflow that lists SailPoint entitlements and their owning sources, and writes the catalog to a table for access-governance reporting.","integrations":[{"id":"sailpoint","name":"SailPoint"}]},{"title":"SailPoint privileged access watch","prompt":"Create a scheduled workflow that searches SailPoint identities holding privileged roles, cross-references recent account activities, and flags any new privileged grants to a security review channel.","integrations":[{"id":"sailpoint","name":"SailPoint"},{"id":"slack","name":"Slack"}]}]},{"id":"salesforce","type":"salesforce","slug":"salesforce","name":"Salesforce","description":"Interact with Salesforce CRM","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/salesforce","authType":"oauth","connections":[{"id":"salesforce","kind":"oauth","label":"Production or Developer Edition","providerId":"salesforce","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/salesforce","requiredScopes":[{"id":"api","label":"Access Salesforce API"},{"id":"refresh_token","label":"Maintain long-term access to Salesforce account"},{"id":"openid","label":"Standard authentication"}],"fields":[]},{"id":"salesforce-sandbox","kind":"oauth","label":"Sandbox","providerId":"salesforce-sandbox","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/salesforce","requiredScopes":[{"id":"api","label":"Access Salesforce API"},{"id":"refresh_token","label":"Maintain long-term access to Salesforce account"},{"id":"openid","label":"Standard authentication"}],"fields":[]},{"id":"salesforce-service-account","kind":"service_account","providerId":"salesforce-service-account","label":"Add integration user app","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/salesforce-service-account","fields":[{"id":"authMethod","label":"Authentication method","placeholder":"Select a method","secret":false,"optional":true,"options":[{"value":"client_credentials","label":"Client credentials (consumer secret)"},{"value":"jwt_bearer","label":"JWT bearer (private key)"}],"defaultValue":"client_credentials"},{"id":"clientId","label":"Consumer key","placeholder":"Paste the consumer key","secret":false},{"id":"clientSecret","label":"Consumer secret","placeholder":"Paste the consumer secret","secret":true,"visibleWhen":{"field":"authMethod","values":["client_credentials"]}},{"id":"privateKey","label":"Private key","placeholder":"-----BEGIN PRIVATE KEY-----","secret":true,"multiline":true,"visibleWhen":{"field":"authMethod","values":["jwt_bearer"]},"hint":"Must match the certificate uploaded to the app."},{"id":"username","label":"Run as username","placeholder":"integration.user@yourorg.com","secret":false,"visibleWhen":{"field":"authMethod","values":["jwt_bearer"]},"hint":"Expected a Salesforce username, which is email-shaped (user@example.com)."},{"id":"orgId","label":"My Domain host","placeholder":"yourorg.my.salesforce.com","secret":false,"hint":"Expected a My Domain host like yourorg.my.salesforce.com, yourorg--sbx.sandbox.my.salesforce.com, or yourorg-dev-ed.develop.my.salesforce.com — not the my.salesforce-setup.com or lightning.force.com host."}]}],"operations":[{"name":"Get Accounts","description":"Retrieve accounts from Salesforce CRM"},{"name":"Create Account","description":"Create a new account in Salesforce CRM"},{"name":"Update Account","description":"Update an existing account in Salesforce CRM"},{"name":"Delete Account","description":"Delete an account from Salesforce CRM"},{"name":"Get Contacts","description":"Get contact(s) from Salesforce - single contact if ID provided, or list if not"},{"name":"Create Contact","description":"Create a new contact in Salesforce CRM"},{"name":"Update Contact","description":"Update an existing contact in Salesforce CRM"},{"name":"Delete Contact","description":"Delete a contact from Salesforce CRM"},{"name":"Get Leads","description":"Retrieve lead(s) from Salesforce CRM"},{"name":"Create Lead","description":"Create a new lead"},{"name":"Update Lead","description":"Update an existing lead"},{"name":"Delete Lead","description":"Delete a lead"},{"name":"Get Opportunities","description":"Get opportunity(ies) from Salesforce"},{"name":"Create Opportunity","description":"Create a new opportunity"},{"name":"Update Opportunity","description":"Update an existing opportunity"},{"name":"Delete Opportunity","description":"Delete an opportunity"},{"name":"Get Cases","description":"Get case(s) from Salesforce"},{"name":"Create Case","description":"Create a new case"},{"name":"Update Case","description":"Update an existing case"},{"name":"Delete Case","description":"Delete a case"},{"name":"Get Tasks","description":"Get task(s) from Salesforce"},{"name":"Create Task","description":"Create a new task"},{"name":"Update Task","description":"Update an existing task"},{"name":"Delete Task","description":"Delete a task"},{"name":"List Reports","description":"Get a list of up to 200 recently viewed reports for the current user"},{"name":"Get Report","description":"Get the describe (definition and metadata) for a specific report"},{"name":"Run Report","description":"Execute a report and retrieve the results"},{"name":"List Report Types","description":"Get a list of available report types"},{"name":"List Dashboards","description":"Get a list of recently used dashboards for the current user"},{"name":"Get Dashboard","description":"Get details and results for a specific dashboard"},{"name":"Refresh Dashboard","description":"Refresh a dashboard to get the latest data"},{"name":"Run SOQL Query","description":"Execute a custom SOQL query to retrieve data from Salesforce"},{"name":"Get More Query Results","description":"Retrieve additional query results using the nextRecordsUrl from a previous query"},{"name":"Describe Object","description":"Get metadata and field information for a Salesforce object"},{"name":"List Objects","description":"Get a list of all available Salesforce objects"},{"name":"Create Custom Field","description":"Create a custom field on a Salesforce object (e.g., Account) using the Tooling API"},{"name":"Update Custom Field","description":"Update an existing custom field on a Salesforce object using the Tooling API"},{"name":"Delete Custom Field","description":"Delete a custom field from a Salesforce object using the Tooling API"},{"name":"Create Custom Object","description":"Create a custom object in Salesforce using the Tooling API"},{"name":"Run Tooling Query","description":"Execute a SOQL query against the Tooling API to inspect metadata objects"}],"triggers":[{"id":"salesforce_record_created","name":"Salesforce Record Created","description":"Trigger workflow when a Salesforce record is created"},{"id":"salesforce_record_updated","name":"Salesforce Record Updated","description":"Trigger workflow when a Salesforce record is updated"},{"id":"salesforce_record_deleted","name":"Salesforce Record Deleted","description":"Trigger workflow when a Salesforce record is deleted"},{"id":"salesforce_opportunity_stage_changed","name":"Salesforce Opportunity Stage Changed","description":"Trigger workflow when an opportunity stage changes"},{"id":"salesforce_case_status_changed","name":"Salesforce Case Status Changed","description":"Trigger workflow when a case status changes"},{"id":"salesforce_webhook","name":"Salesforce Webhook (All Events)","description":"Trigger workflow on any Salesforce webhook event"}],"skills":[{"name":"capture-inbound-lead","description":"Create or update a Salesforce lead from an inbound signal and assign follow-up.","content":"# Capture Inbound Lead\\n\\nGet an inbound lead into Salesforce cleanly.\\n\\n## Steps\\n1. Run get_leads to check for an existing lead with the same email.\\n2. If new, run create_lead with name, company, email, and source; otherwise run update_lead to enrich it.\\n3. Run create_task to assign a follow-up to the owner.\\n\\n## Output\\nReturn the lead id, whether it was created or updated, and the follow-up task id."},{"name":"log-opportunity-update","description":"Advance a Salesforce opportunity stage and record the change for the account.","content":"# Log Opportunity Update\\n\\nKeep a deal current in Salesforce.\\n\\n## Steps\\n1. Run get_opportunities to locate the deal.\\n2. Run update_opportunity to set the new stage, amount, or close date.\\n3. Run create_task to capture the next action.\\n\\n## Output\\nReturn the opportunity id, its new stage, and the next-step task. Note if the stage moved to closed-won or closed-lost."},{"name":"sync-account-contacts","description":"Pull a Salesforce account with its contacts for a 360 view.","content":"# Sync Account Contacts\\n\\nAssemble a full picture of an account.\\n\\n## Steps\\n1. Run get_accounts to resolve the target account.\\n2. Run get_contacts filtered to the account to list its people.\\n3. Optionally run get_opportunities and get_cases for active deals and support context.\\n\\n## Output\\nReturn the account, its contacts with roles, and a summary of open opportunities and cases."},{"name":"create-support-case","description":"Open a Salesforce case for a customer issue and assign the owner.","content":"# Create Support Case\\n\\nFile a support case in Salesforce.\\n\\n## Steps\\n1. Run get_contacts or get_accounts to link the case to the right record.\\n2. Run create_case with subject, description, priority, and origin.\\n3. Run create_task for the assigned owner if a follow-up is required.\\n\\n## Output\\nReturn the case id, priority, and linked account or contact."},{"name":"run-sales-report","description":"Run a Salesforce report and summarize the results for a stakeholder.","content":"# Run Sales Report\\n\\nPull live numbers from a Salesforce report.\\n\\n## Steps\\n1. Run list_reports to find the report, or use a known report id.\\n2. Run run_report to execute it and capture the result set.\\n3. Summarize the key metrics and notable changes.\\n\\n## Output\\nReturn the headline metrics and a short narrative of what the report shows."}],"templates":[{"title":"AgentPhone post-call summary","prompt":"Create a workflow that runs after every AgentPhone call, summarizes the transcript with action items, and updates the linked Salesforce or HubSpot record with next steps.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"agentphone","name":"AgentPhone"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Agiloft contract launcher","prompt":"Build a workflow that on a closed-won Salesforce opportunity creates an Agiloft contract record from the right template, fills key fields from the opportunity, and routes for legal review.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"agiloft","name":"Agiloft"}]},{"title":"Agiloft renewal tracker","prompt":"Build a scheduled workflow that finds Agiloft contracts with renewals due in the next 90 days, creates a renewal-prep task in the CRM, and emails the account owner.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"agiloft","name":"Agiloft"},{"id":"gmail","name":"Gmail"}]},{"title":"Asana onboarding task launcher","prompt":"Create a workflow that on a new Salesforce opportunity creates a customer-onboarding Asana task with the right assignee and due date, and writes the task link back to the opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"asana","name":"Asana"}]},{"title":"Box new-vendor folder setup","prompt":"Build a workflow triggered when a new vendor is created in a CRM that provisions a standard Box folder structure for that vendor, invites the right users, and writes the folder link to the vendor record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"box","name":"Box"}]},{"title":"Brandfetch deck personalizer","prompt":"Build a workflow that on a new opportunity pulls the prospect’s brand assets from Brandfetch, generates a personalized pitch deck with their logo and colors, and attaches it.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"brandfetch","name":"Brandfetch"},{"id":"gamma","name":"Gamma"}]},{"title":"Cal.com post-meeting recap","prompt":"Create a workflow that runs after a Cal.com meeting ends, summarizes the meeting notes, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"calcom","name":"Cal.com"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Calendly post-meeting recap","prompt":"Create a workflow that runs after a Calendly meeting ends, pulls the meeting notes from the calendar, writes a CRM-ready summary, and updates the linked Salesforce opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"calendly","name":"Calendly"}]},{"title":"Circleback CRM updater","prompt":"Build a workflow that runs after a Circleback sales meeting, gets the full meeting with notes and insights, summarizes it into a deal-ready update, and writes it to the matching HubSpot or Salesforce record using the attendee company domain.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"circleback","name":"Circleback"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Clay TAM seeder","prompt":"Build a workflow that reads a seed account list from Salesforce and pushes each account to a Clay table via the populate webhook, so Clay runs its lookalike and enrichment waterfall to expand the TAM.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"clay","name":"Clay"}]},{"title":"ClickUp customer onboarding launcher","prompt":"Create a workflow that on a closed-won Salesforce opportunity creates a ClickUp onboarding task with the right assignees and due date, attaches the signed order form, and writes the task link back to the opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"clickup","name":"ClickUp"}]},{"title":"DocuSign envelope sender","prompt":"Build a workflow that takes a deal from Salesforce above a threshold, pre-fills a DocuSign envelope from a template, sends it, and writes the envelope ID back to the opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"docusign","name":"DocuSign"}]},{"title":"DocuSign renewal tracker","prompt":"Build a scheduled workflow that reads a DocuSign contracts table, finds renewals due in the next 60 days, and creates a renewal-prep task in Salesforce for each.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"docusign","name":"DocuSign"}]},{"title":"Enrich CRM hydrator","prompt":"Build a workflow that watches new Salesforce leads, enriches each with Enrich.so contact data, and writes role, company size, and email to the lead record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"enrich","name":"Enrich"}]},{"title":"Fireflies CRM updater","prompt":"Create a workflow that runs after a Fireflies sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"fireflies","name":"Fireflies"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Gamma sales pitch personalizer","prompt":"Build a workflow triggered by a Salesforce opportunity that generates a Gamma sales pitch deck personalized to the account, embeds the deck link in the opportunity, and notifies the rep.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"gamma","name":"Gamma"}]},{"title":"Gong CRM auto-updater","prompt":"Build a workflow that runs after a Gong sales call, summarizes objections and next steps, and updates the linked Salesforce or HubSpot opportunity with notes.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"gong","name":"Gong"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Google Books due-diligence helper","prompt":"Create a workflow that for a tracked person or company searches Google Books for prior publications and citations, and writes the findings to a CRM intel record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_books","name":"Google Books"}]},{"title":"Google Contacts deal-mapper","prompt":"Create a workflow that maps Google Contacts to active Salesforce opportunities by email domain, tagging contacts as deal-relevant for fast follow-ups.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Maps territory builder","prompt":"Create a workflow that takes a list of CRM accounts, geocodes them via Google Maps, clusters into territories, and writes the assignment to a tables-based territory plan.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_maps","name":"Google Maps"}]},{"title":"Google Meet auto-invite from CRM","prompt":"Create a workflow that watches Salesforce for new meetings logged on opportunities, creates a matching Google Meet event, invites the right attendees, and writes the meeting link back to the opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_meet","name":"Google Meet"}]},{"title":"Google Sheets CRM updater","prompt":"Build a scheduled workflow that pulls Salesforce opportunities, refreshes the Google Sheets spreadsheet that ops uses for weekly forecasting, and notes the last-updated timestamp.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Google Slides pitch personalizer","prompt":"Create a workflow that takes a Salesforce opportunity, generates a Google Slides pitch deck personalized to the account, and attaches it to the opportunity record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_slides","name":"Google Slides"}]},{"title":"Google Slides win-loss recap","prompt":"Build a workflow that aggregates closed-won and closed-lost deals from Salesforce monthly, generates a Google Slides recap with patterns and insights, and emails it to the sales team.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_slides","name":"Google Slides"},{"id":"gmail","name":"Gmail"}]},{"title":"Google Vault legal hold automator","prompt":"Build a scheduled workflow that polls Salesforce for new legal-hold instructions, creates a Google Vault matter and hold for the named custodians, and notifies legal with the hold details.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"google_vault","name":"Google Vault"}]},{"title":"Grain highlight to CRM","prompt":"Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"grain","name":"Grain"}]},{"title":"Grain highlight to CRM","prompt":"Build a workflow that watches Grain meeting highlights, extracts customer quotes, and writes them to the linked Salesforce opportunity for deal context.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"grain","name":"Grain"}]},{"title":"Granola CRM updater","prompt":"Build a workflow that runs after a Granola sales meeting, summarizes the meeting notes into a deal-ready summary, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"granola","name":"Granola"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Harmonic CRM prospect route","prompt":"Build a workflow that searches Harmonic Scout for technical buyers at target accounts, filters contacts with a usable email or LinkedIn URL, deduplicates them by person URN, and writes qualified prospects to Salesforce.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"harmonic","name":"Harmonic"}]},{"title":"Linkup CRM account refresh","prompt":"Create a scheduled workflow that for accounts in the CRM runs Linkup research on each weekly, surfaces new signals, and writes the digest into the account record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"linkup","name":"Linkup"}]},{"title":"Dataverse legacy CRM bridge","prompt":"Build a workflow that mirrors Salesforce contacts into Microsoft Dataverse and back, mapping fields and resolving conflicts deterministically so both CRMs stay in sync during migration.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Excel commission calculator","prompt":"Build a workflow that pulls closed Salesforce deals each month, computes commission per rep using a Microsoft Excel commission model, and emails the per-rep statements.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"gmail","name":"Gmail"}]},{"title":"Teams sales-deal channel","prompt":"Create a workflow that listens for new Salesforce opportunities above a threshold, creates a Microsoft Teams channel for the deal, invites the account team, and pins the opportunity link.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Monday + CRM sync","prompt":"Create a workflow that mirrors Monday CRM board items into Salesforce as opportunities, keeps stage and amount synced, and writes the Salesforce ID back to the Monday item.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"monday","name":"Monday"}]},{"title":"PagerDuty customer-impact notifier","prompt":"Create a scheduled workflow that polls PagerDuty for incidents on customer-facing services, looks up affected accounts in Salesforce, and drafts a status-page update plus a Slack alert to the customer success team for high-impact outages.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"pagerduty","name":"PagerDuty"},{"id":"slack","name":"Slack"}]},{"title":"Parallel AI account research agent","prompt":"Build a workflow that takes a company name, runs Parallel AI deep research for recent funding, leadership changes, and product launches, and writes a structured account brief with citations back to the matching CRM record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"PDL ICP scorer","prompt":"Build a workflow that scores inbound leads against the ICP using People Data Labs enrichment fields, routes high-fit leads to sales, and writes the score back to the CRM.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"PDL lookalike expander","prompt":"Build a workflow that derives firmographic attributes from a seed account list and uses People Data Labs company-search to find similar companies, expanding the TAM and writing the new prospects into Salesforce.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"Perplexity sales account refresh","prompt":"Create a scheduled workflow that walks accounts in my CRM, runs Perplexity research on each for new funding, headcount changes, or product launches, and writes the digest back to the account record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"perplexity","name":"Perplexity"}]},{"title":"Prospeo CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing email addresses, runs Prospeo to find and verify them, and updates each contact record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"prospeo","name":"Prospeo"}]},{"title":"Salesforce knowledge search","prompt":"Create a knowledge base connected to my Salesforce account so all deals, contacts, notes, and activities are automatically synced and searchable. Then build an agent I can ask things like \\"what\'s the history with Acme Corp?\\" or \\"who was involved in the last enterprise deal?\\" and get instant answers with CRM record citations.","integrations":[{"id":"salesforce","name":"Salesforce"}]},{"title":"Salesforce pipeline tracker","prompt":"Create a table with columns for deal name, stage, amount, close date, and next steps. Build a workflow that syncs open deals from Salesforce into this table daily, and sends me a Slack summary each morning of deals that need attention or are at risk of slipping.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"slack","name":"Slack"}]},{"title":"Push Salesforce pipeline updates to Slack","prompt":"Build a workflow that monitors Salesforce opportunities and posts a Slack notification to your sales team whenever a deal advances, closes, or needs immediate attention.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"slack","name":"Slack"}]},{"title":"Salesforce lead router","prompt":"Build a workflow that triggers on new inbound form submissions, creates a Salesforce lead with the captured fields, runs a SOQL query to check for an existing account match, assigns the lead to the right owner, and posts the new lead with its score to Slack.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"slack","name":"Slack"}]},{"title":"Salesforce case escalation","prompt":"Create a scheduled workflow that queries open Salesforce cases past their SLA, escalates each by updating its priority and owner, creates a follow-up task on the account, and Slacks the support lead a summary of everything that breached.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"slack","name":"Slack"}]},{"title":"Salesforce report digest","prompt":"Build a scheduled workflow that runs a saved Salesforce report each morning, refreshes the linked dashboard, summarizes the key metrics and biggest movers with an agent, and emails the leadership team a written narrative of what changed.","integrations":[{"id":"salesforce","name":"Salesforce"}]},{"title":"Salesforce onboarding kickoff","prompt":"Create a workflow that watches Salesforce opportunities for stage changes to closed-won, pulls the related account and contacts, creates onboarding tasks for the CS owner, and writes a kickoff record into a tables-based project tracker.","integrations":[{"id":"salesforce","name":"Salesforce"}]},{"title":"Similarweb account intel sync","prompt":"Create a workflow that watches my CRM for new accounts, pulls Similarweb data on each account domain, writes traffic estimates, rankings, and engagement signals back to the account record for sales context.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"similarweb","name":"Similarweb"}]},{"title":"Sixtyfour CRM enricher","prompt":"Create a scheduled workflow that finds CRM accounts missing deep-research signals, runs Sixtyfour, and writes the structured findings back to the account record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Tavily account refresher","prompt":"Build a workflow that walks accounts in the CRM, runs Tavily research on each for new funding, hiring, or product launches, and writes the digest back to the account record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"tavily","name":"Tavily"}]},{"title":"Twilio Voice transcript-to-CRM","prompt":"Build a workflow that runs after a Twilio Voice call ends, transcribes the recording, summarizes the conversation, and writes the summary plus action items to the linked Salesforce account.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Typeform lead enricher","prompt":"Create a workflow that watches Typeform lead-gen submissions, enriches each lead with company size and tech stack via Apollo, and pushes the enriched lead into Salesforce.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"typeform","name":"Typeform"},{"id":"apollo","name":"Apollo"}]},{"title":"WhatsApp lead qualifier","prompt":"Create a workflow that engages new leads via WhatsApp with a guided qualification script, scores them based on responses, and pushes qualified leads into Salesforce with the conversation log attached.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"whatsapp","name":"WhatsApp"}]},{"title":"Wiza CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing verified phone numbers, runs a Wiza reveal to fill the gaps, and updates each contact record.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"wiza","name":"Wiza"}]},{"title":"X engagement digest","prompt":"Create a scheduled daily workflow that summarizes top X engagement on the brand account, identifies high-influence engagers, and writes them to a sales-prospect table.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"x","name":"X"}]},{"title":"Zendesk customer record sync","prompt":"Build a workflow that watches my CRM for new or updated accounts, searches Zendesk for the matching user and organization, and creates or updates them in bulk so support agents always see the latest company, plan, and contact details on every ticket.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Zep + Salesforce account memory","prompt":"Build a workflow that for each Salesforce account writes meeting and email context into Zep keyed by account, so any future agent interaction has full history.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"zep","name":"Zep"}]},{"title":"Zoom sales-call deal updater","prompt":"Build a workflow that runs after a Zoom sales call, summarizes objections, next steps, and stage signals from the transcript, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"zoom","name":"Zoom"},{"id":"hubspot","name":"HubSpot"}]},{"title":"ZoomInfo contact enricher","prompt":"Build a workflow that watches CRM contacts, enriches each via ZoomInfo with title, seniority, and verified contact details, and writes the enriched data back.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"zoominfo","name":"ZoomInfo"}]},{"title":"ZoomInfo CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing firmographic or contact fields, runs ZoomInfo enrichment to fill the gaps, and writes coverage metrics to a hygiene table.","integrations":[{"id":"salesforce","name":"Salesforce"},{"id":"zoominfo","name":"ZoomInfo"}]}]},{"id":"sap_concur","type":"sap_concur","slug":"sap-concur","name":"SAP Concur","description":"Manage expense reports, travel requests, cash advances, and more in SAP Concur","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/sap_concur","authType":"api-key","connections":[],"operations":[{"name":"List Expense Reports","description":"List expense reports (GET /api/v3.0/expense/reports). Returns a v3 envelope with Items and NextPage."},{"name":"Get Expense Report","description":"Retrieve a single expense report header by id via Expense Report v4 (/expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId})."},{"name":"Create Expense Report","description":"Create an expense report (POST /expensereports/v4/users/{userId}/context/{contextType}/reports — supported contexts: TRAVELER, PROXY). Required body fields: name, policyId."},{"name":"Update Expense Report","description":"Update an unsubmitted expense report (PATCH /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId} — supported contexts: TRAVELER, PROXY). The body must always include `reportSource` (EA, MOB, OTHER, SE, TR, or UI)."},{"name":"Delete Expense Report","description":"Delete an expense report (DELETE /expensereports/v4/reports/{reportId})."},{"name":"Submit Expense Report","description":"Submit an expense report into the workflow via Expense Report v4 (PATCH /expensereports/v4/users/{userId}/reports/{reportId}/submit). Takes no request body."},{"name":"Recall Expense Report","description":"Recall a submitted expense report (PATCH /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/recall — supported contexts: TRAVELER, PROXY). Takes no request body. This operation supports user-level access tokens: set grantType to \\"password\\" with username and password, since the default client_credentials grant yields a company-level token."},{"name":"Approve Expense Report","description":"Approve an expense report as a manager (PATCH /expensereports/v4/reports/{reportId}/approve). Optional body fields: comment, expenseRejectedComment (required if the report has rejected expenses), expectedStepCode, expectedStepSequence, statusId (default A_APPR)."},{"name":"Send Back Expense Report","description":"Send back an expense report to the employee (PATCH /expensereports/v4/reports/{reportId}/sendBack). Required body field: comment."},{"name":"List Reports To Approve","description":"List expense reports awaiting approval (GET /expensereports/v4/users/{userId}/context/MANAGER/reportsToApprove)."},{"name":"List Expenses","description":"List expenses on a report (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses)."},{"name":"Get Expense","description":"Get a single expense (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId})."},{"name":"Update Expense","description":"Update an expense (PATCH /expensereports/v4/reports/{reportId}/expenses/{expenseId}). Only Company JWT authentication is allowed on this endpoint — the password grant is rejected. A submitted report cannot be updated once it has reached a Paid workflow status. Although the primary intent of this operation is for submitted report updates, it also works on unsubmitted reports, but with the same limited set of fields."},{"name":"Delete Expense","description":"Delete an expense (DELETE /expensereports/v4/reports/{reportId}/expenses/{expenseId})."},{"name":"Get Itemizations","description":"Get expense itemizations (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId}/itemizations)."},{"name":"List Allocations","description":"List allocations on an expense (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId}/allocations)."},{"name":"Get Allocation","description":"Get a single allocation (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/allocations/{allocationId})."},{"name":"Update Allocation","description":"Update an allocation (PATCH /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/allocations/{allocationId})."},{"name":"List Attendee Associations","description":"List attendees associated with an expense (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId}/attendees)."},{"name":"Associate Attendees","description":"Associate attendees with an expense (POST /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId}/attendees)."},{"name":"Remove All Attendees","description":"Remove all attendees from an expense (DELETE /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/expenses/{expenseId}/attendees)."},{"name":"List Report Comments","description":"List comments on a report (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/comments)."},{"name":"Create Report Comment","description":"Create a comment on a report (POST /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/comments)."},{"name":"List Exceptions","description":"List exceptions on a report (GET /expensereports/v4/users/{userId}/context/{contextType}/reports/{reportId}/exceptions)."},{"name":"Create Quick Expense","description":"Create a quick expense (POST /quickexpense/v4/users/{userId}/context/{contextType}/quickexpenses). TRAVELER is the only supported context type."},{"name":"Create Quick Expense (With Image)","description":"Create a quick expense with an attached image (POST /quickexpense/v4/users/{userId}/context/{contextType}/quickexpenses/image)."},{"name":"List Receipts","description":"List receipts for a user (GET /receipts/v4/users/{userId}). Concur documents no query parameters for this endpoint, so page size and offset cannot be controlled; follow the \\"next\\" URL in the response to page forward."},{"name":"Get Receipt","description":"Get a single receipt by ID (GET /receipts/v4/{receiptId})."},{"name":"Get Receipt Status","description":"Get receipt processing status (GET /receipts/v4/status/{receiptId})."},{"name":"Upload Receipt Image","description":"Upload an image-only receipt (POST /receipts/v4/users/{userId}/image-only-receipts)."},{"name":"List Travel Requests","description":"List travel requests (GET /travelrequest/v4/requests)."},{"name":"Get Travel Request","description":"Get a single travel request (GET /travelrequest/v4/requests/{requestUuid})."},{"name":"Create Travel Request","description":"Create a travel request (POST /travelrequest/v4/requests)."},{"name":"Update Travel Request","description":"Update a travel request (PUT /travelrequest/v4/requests/{requestUuid})."},{"name":"Delete Travel Request","description":"Delete a travel request (DELETE /travelrequest/v4/requests/{requestUuid})."},{"name":"Move Travel Request (Workflow Action)","description":"Move a travel request through workflow (POST /travelrequest/v4/requests/{requestUuid}/{action}). Valid actions: submit, recall, cancel, approve, sendback, close, reopen."},{"name":"List Travel Request Comments","description":"List comments on a travel request (GET /travelrequest/v4/requests/{requestUuid}/comments)."},{"name":"Get Request Cash Advance","description":"Get a single cash advance assigned to a travel request (GET /travelrequest/v4/cashadvances/{cashAdvanceUuid}). This endpoint exists for feature parity only and will be deprecated in the future — SAP recommends relying on the list of cash advances link available in the Request payload response instead."},{"name":"Create Expected Expense","description":"Create an expected expense on a travel request (POST /travelrequest/v4/requests/{requestUuid}/expenses)."},{"name":"List Expected Expenses","description":"List expected expenses on a travel request (GET /travelrequest/v4/requests/{requestUuid}/expenses)."},{"name":"Get Expected Expense","description":"Get an expected expense (GET /travelrequest/v4/expenses/{expenseUuid})."},{"name":"Update Expected Expense","description":"Update an expected expense (PUT /travelrequest/v4/expenses/{expenseUuid})."},{"name":"Delete Expected Expense","description":"Delete an expected expense (DELETE /travelrequest/v4/expenses/{expenseUuid})."},{"name":"Create Cash Advance","description":"Create a cash advance (POST /cashadvance/v4.1/cashadvances)."},{"name":"Get Cash Advance","description":"Get a cash advance (GET /cashadvance/v4.1/cashadvances/{cashAdvanceId})."},{"name":"Issue Cash Advance","description":"Issue a cash advance (POST /cashadvance/v4.1/cashadvances/{cashAdvanceId}/issue)."},{"name":"List Itineraries (Trips)","description":"List travel trips/itineraries (GET /api/travel/trip/v1.1)."},{"name":"Get Itinerary (Trip)","description":"Get a single trip/itinerary (GET /api/travel/trip/v1.1/{tripID})."},{"name":"List Users","description":"List Concur user identities (GET /profile/identity/v4.1/Users)."},{"name":"Get User","description":"Get a single user by UUID (GET /profile/identity/v4.1/Users/{id})."},{"name":"Create User","description":"Create a new user identity (POST /profile/identity/v4.1/Users)."},{"name":"Update User (PATCH)","description":"Patch a user identity (PATCH /profile/identity/v4.1/Users/{id})."},{"name":"Delete User","description":"Hard delete a user identity (DELETE /profile/identity/v4.1/Users/{id}). Not recommended: SAP restricts hard delete to users with no transaction history and governs it by the Concur Data Retention policy. To deactivate a user instead, use SAP Concur Update User with a PATCH replacing active with false."},{"name":"Search Users","description":"Search users via SCIM .search endpoint (POST /profile/identity/v4.1/Users/.search)."},{"name":"List Lists","description":"List custom lists (GET /list/v4/lists)."},{"name":"Get List","description":"Get a single custom list (GET /list/v4/lists/{listId})."},{"name":"List List Items","description":"List the top-level items (children) for a custom list (GET /list/v4/lists/{listId}/children)."},{"name":"Get List Item","description":"Get a single list item (GET /list/v4/items/{itemId})."},{"name":"Create List Item","description":"Create a list item (POST /list/v4/items)."},{"name":"Update List Item","description":"Update a list item (PUT /list/v4/items/{itemId})."},{"name":"Delete List Item","description":"Delete a list item from all lists that contain it (DELETE /list/v4/items/{itemId}). This is not scoped to a single list, and all children of that list item are also deleted."},{"name":"List Budgets","description":"List budget item headers (GET /budget/v4/budgetItemHeader)."},{"name":"Get Budget","description":"Get a budget item header by ID (GET /budget/v4/budgetItemHeader/{id})."},{"name":"List Budget Categories","description":"List budget categories (GET /budget/v4/budgetCategory)."},{"name":"Upload Exchange Rates","description":"Bulk upload up to 100 custom exchange rates (POST /exchangerate/v4/rates). Body contains a currency_sets array, each with from_crn_code, to_crn_code, start_date (YYYY-MM-DD), and rate."},{"name":"Create Purchase Request","description":"Create a purchase request (POST /purchaserequest/v4/purchaserequests)."},{"name":"Get Purchase Request","description":"Get a purchase request by ID (GET /purchaserequest/v4/purchaserequests/{id})."},{"name":"Get Travel Profile","description":"Get a travel profile (GET /api/travelprofile/v2.0/profile). Returns the calling user by default; pass userid_type and userid_value to impersonate."},{"name":"List Travel Profiles Summary","description":"List travel profile summaries (GET /api/travelprofile/v2.0/summary). LastModifiedDate is required by Concur."},{"name":"Search Locations","description":"Search Concur location reference data (GET /localities/v5/locations)."}],"triggers":[],"skills":[{"name":"review-expense-reports","description":"List submitted SAP Concur expense reports, inspect line items, and flag policy exceptions.","content":"# Review Expense Reports\\n\\nSurface expense reports that need attention and check them against policy.\\n\\n## Steps\\n1. Run List Expense Reports to pull recently submitted reports, or List Reports To Approve for items awaiting the current approver.\\n2. For each report of interest, run Get Expense Report and List Expenses to read the individual line items, then List Exceptions to see Concur policy flags.\\n3. Summarize totals, flagged line items, and any missing receipts.\\n\\n## Output\\nReturn a per-report summary with the report ID, owner, total amount, and a list of policy exceptions or anomalies that warrant follow-up."},{"name":"route-report-approval","description":"Approve or send back a submitted SAP Concur expense report after review.","content":"# Route Report Approval\\n\\nAct on an expense report once a review decision is made.\\n\\n## Steps\\n1. Confirm the report ID and the decision.\\n2. To approve, run Approve Expense Report. To return it for correction, run Send Back Expense Report with a clear comment explaining what must change.\\n3. Optionally run Create Report Comment first to leave context for the submitter.\\n\\n## Output\\nConfirm the report ID, the action taken (approved or sent back), and the comment provided so the decision is auditable."},{"name":"capture-quick-expense","description":"Create a quick expense in SAP Concur from a receipt, attaching the receipt image.","content":"# Capture Quick Expense\\n\\nLog an out-of-pocket expense quickly, with the receipt attached.\\n\\n## Steps\\n1. If you have a receipt image, use Create Quick Expense (With Image) to upload it and create the expense in one step. To upload on its own, run Upload Receipt Image — it returns no receipt ID, only a `location` URL and a raw `link` header of the form `; rel=\\"processing-status\\"`. Parse the id out of that URL.\\n2. Run Create Quick Expense with the vendor, amount, currency, and transaction date.\\n3. To check the upload, run Get Receipt Status with the id from step 1 — that is the only working post-upload read. Do not use List Receipts or Get Receipt: they read the e-receipt family, while Upload Receipt Image writes to the disjoint image-only family, so a freshly uploaded image never appears in List Receipts and Get Receipt on its id returns 404. Reading back the image-only receipt itself requires endpoints this integration does not yet wrap.\\n4. A quick expense is not attached to a report yet, so Get Expense cannot read it. Once it has been moved onto a report, List Expenses on that report ID shows the entry.\\n\\n## Output\\nReport the created quick expense ID, the captured vendor and amount, and the receipt processing status if an image was uploaded."},{"name":"manage-travel-requests","description":"List and act on SAP Concur travel requests, moving them through the approval workflow.","content":"# Manage Travel Requests\\n\\nHandle pre-trip travel requests through their approval lifecycle.\\n\\n## Steps\\n1. Run List Travel Requests to find pending requests, then Get Travel Request for full detail on a specific one.\\n2. Review the expected expenses and any linked cash advance via Get Request Cash Advance.\\n3. Run Move Travel Request (Workflow Action) to advance, approve, or send back the request based on the decision.\\n\\n## Output\\nReturn the travel request ID, destination, estimated cost, and the workflow action applied so the trip approval state is clear."},{"name":"provision-concur-user-identity","description":"Create, update, search, and deactivate SAP Concur user identities through the SCIM Identity API.","content":"# Provision Concur User Identity\\n\\nRun the joiner, mover, and leaver steps against the SAP Concur Identity (SCIM) API.\\n\\n## Steps\\n1. Run Search Users with a SCIM search body (filter on userName or emails.value) to check whether the person already exists, or List Users with Attributes set to a narrow field list when scanning the directory.\\n2. To onboard, run Create User with the SCIM body — schemas, userName, name.givenName, name.familyName, emails, and active.\\n3. To change a role, department, or manager, run Update User (PATCH) against the user UUID, then confirm with Get User.\\n4. To offboard, prefer Update User (PATCH) setting active to false; use Delete User only when the identity must be removed outright.\\n\\n## Output\\nReport the user UUID, userName, the change applied, and the resulting active state so the identity lifecycle is auditable."},{"name":"maintain-concur-custom-lists","description":"Browse and edit SAP Concur custom lists and their items — the value sets behind list-type expense fields.","content":"# Maintain Concur Custom Lists\\n\\nKeep the value sets behind list-type expense and request fields current.\\n\\n## Steps\\n1. Run List Lists to find the list you need, filtering by Value or Category Type; note that on List Lists the Value and Level Count filters accept operator prefixes (sw:, ew:, not:, cp: on Value; eq:, gt:, gte:, lt:, lte: on Level Count), while Is Deleted accepts only eq:.\\n2. Run Get List for the definition, then List List Items with the list ID to page through its current entries — there Value, Short Code, and Short Code Or Value take the same string operator prefixes.\\n3. Run Create List Item to add a value, Update List Item to correct one, and Delete List Item to retire one. Read a single entry back with Get List Item.\\n\\n## Output\\nReturn the list ID and name, the items added, changed, or retired with their short codes and values, and the level each item sits at."},{"name":"track-budget-consumption","description":"Read SAP Concur budget item headers and categories to see how much of each budget is already consumed.","content":"# Track Budget Consumption\\n\\nCheck spend against the budgets configured in SAP Concur.\\n\\n## Steps\\n1. Run List Budget Categories to learn how budgets are grouped for the company.\\n2. Run List Budgets to page through budget item headers; enable Admin View to see every budget the credentials can administer, and set Response Schema to COMPACT for a lighter payload.\\n3. Run Get Budget on any header of interest for the full detail, including the spent and remaining amounts.\\n\\n## Output\\nReturn each budget header ID, its name and category, the budgeted amount, the amount consumed, and the remaining balance, calling out any budget already over its limit."},{"name":"issue-cash-advance","description":"Create, inspect, and issue SAP Concur cash advances, including advances attached to a travel request.","content":"# Issue Cash Advance\\n\\nMove a cash advance from request through to issued funds.\\n\\n## Steps\\n1. Run Create Cash Advance with the amount, currency code, and comment describing the need.\\n2. Run Get Cash Advance on the returned ID to confirm the amount and current status, or Get Request Cash Advance when the advance hangs off a travel request UUID.\\n3. Once approved, run Issue Cash Advance to record the disbursement, supplying the issued amount and exchange rate in the body when they differ from the request.\\n\\n## Output\\nReturn the cash advance ID, requested and issued amounts with currency, the current status, and the linked travel request UUID when there is one."}],"templates":[{"title":"SAP Concur expense classifier","prompt":"Build a scheduled workflow that polls SAP Concur for newly submitted expense reports, classifies each line item, validates against policy, and routes exceptions to the approver in Slack.","integrations":[{"id":"sap_concur","name":"SAP Concur"},{"id":"slack","name":"Slack"}]},{"title":"SAP Concur policy auditor","prompt":"Create a scheduled monthly workflow that audits SAP Concur expense reports against policy, flags pattern violations by employee, and writes a compliance report.","integrations":[{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SAP Concur travel pre-approval","prompt":"Build a scheduled workflow that polls SAP Concur for pending travel requests, routes each to the right approver based on amount and destination, captures the decision over Microsoft Teams, and moves the request to the approved or sent-back state.","integrations":[{"id":"sap_concur","name":"SAP Concur"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SAP Concur receipt OCR","prompt":"Create a workflow that processes SAP Concur receipt images with AWS Textract, validates the extracted vendor and amount against the report line, and flags mismatches.","integrations":[{"id":"sap_concur","name":"SAP Concur"},{"id":"textract","name":"AWS Textract"}]},{"title":"SAP Concur reimbursement chaser","prompt":"Build a scheduled workflow that finds SAP Concur reports stuck pending more than 7 days, sends the approver a reminder, and writes the chase log to a table.","integrations":[{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SAP Concur travel reconciler","prompt":"Create a workflow that reconciles SAP Concur travel bookings with corporate card transactions, flags missing receipts, and writes a reconciliation table for finance.","integrations":[{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SAP Concur budget watcher","prompt":"Build a scheduled monthly workflow that aggregates SAP Concur spend per department, compares against budget, and pings managers in Teams when overspend is projected.","integrations":[{"id":"sap_concur","name":"SAP Concur"},{"id":"microsoft_teams","name":"Microsoft Teams"}]}]},{"id":"sap_s4hana","type":"sap_s4hana","slug":"sap-s4hana","name":"SAP S4HANA","description":"Read and write SAP S4HANA Cloud business data via OData","category":"HR","docsUrl":"https://docs.sim.ai/integrations/sap_s4hana","authType":"api-key","connections":[],"operations":[{"name":"List Business Partners","description":"List business partners from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_BusinessPartner) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Business Partner","description":"Retrieve a single business partner by BusinessPartner key from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_BusinessPartner)."},{"name":"Create Business Partner","description":"Create a business partner in SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_BusinessPartner). For Person category 1 provide FirstName and LastName. For Organization category 2 provide OrganizationBPName1."},{"name":"Update Business Partner","description":"Update fields on an A_BusinessPartner entity in SAP S/4HANA Cloud (API_BUSINESS_PARTNER). Uses HTTP MERGE (OData v2 partial update) — only the fields you provide are written; existing values are preserved. If-Match defaults to a wildcard (unconditional) — for safe concurrent updates pass the ETag from a prior GET to avoid lost updates. Deep updates on nested associations (e.g. to_BusinessPartnerAddress) are not supported by SAP (KBA 2833338) — use the dedicated child endpoints."},{"name":"List Customers","description":"List customers from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_Customer) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Customer","description":"Retrieve a single customer by Customer key from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_Customer)."},{"name":"Update Customer","description":""},{"name":"List Suppliers","description":"List suppliers from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_Supplier) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Supplier","description":"Retrieve a single supplier by Supplier key from SAP S/4HANA Cloud (API_BUSINESS_PARTNER, A_Supplier)."},{"name":"Update Supplier","description":""},{"name":"List Sales Orders","description":"List sales orders from SAP S/4HANA Cloud (API_SALES_ORDER_SRV, A_SalesOrder) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Sales Order","description":"Retrieve a single sales order by SalesOrder key from SAP S/4HANA Cloud (API_SALES_ORDER_SRV, A_SalesOrder)."},{"name":"Create Sales Order","description":"Create a sales order in SAP S/4HANA Cloud (API_SALES_ORDER_SRV, A_SalesOrder) with deep insert of sales order items via to_Item."},{"name":"Update Sales Order","description":""},{"name":"Delete Sales Order","description":"Delete an A_SalesOrder entity in SAP S/4HANA Cloud (API_SALES_ORDER_SRV). Only orders without subsequent documents (deliveries, invoices) can be deleted; otherwise reject items via update instead."},{"name":"List Outbound Deliveries","description":"List outbound deliveries from SAP S/4HANA Cloud (API_OUTBOUND_DELIVERY_SRV;v=0002, A_OutbDeliveryHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Outbound Delivery","description":"Retrieve a single outbound delivery by DeliveryDocument key from SAP S/4HANA Cloud (API_OUTBOUND_DELIVERY_SRV;v=0002, A_OutbDeliveryHeader)."},{"name":"List Inbound Deliveries","description":"List inbound deliveries from SAP S/4HANA Cloud (API_INBOUND_DELIVERY_SRV;v=0002, A_InbDeliveryHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Inbound Delivery","description":"Retrieve a single inbound delivery by DeliveryDocument key from SAP S/4HANA Cloud (API_INBOUND_DELIVERY_SRV;v=0002, A_InbDeliveryHeader)."},{"name":"List Billing Documents","description":"List billing documents (customer invoices) from SAP S/4HANA Cloud (API_BILLING_DOCUMENT_SRV, A_BillingDocument) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Billing Document","description":"Retrieve a single billing document (customer invoice) by BillingDocument key from SAP S/4HANA Cloud (API_BILLING_DOCUMENT_SRV, A_BillingDocument)."},{"name":"List Products","description":"List products (materials) from SAP S/4HANA Cloud (API_PRODUCT_SRV, A_Product) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Product","description":"Retrieve a single product (material) by Product key from SAP S/4HANA Cloud (API_PRODUCT_SRV, A_Product)."},{"name":"Update Product","description":""},{"name":"List Material Stock","description":"List material stock quantities from SAP S/4HANA Cloud (API_MATERIAL_STOCK_SRV, A_MatlStkInAcctMod). The entity uses an 11-field composite key (Material, Plant, StorageLocation, Batch, Supplier, Customer, WBSElementInternalID, SDDocument, SDDocumentItem, InventorySpecialStockType, InventoryStockType) — query with $filter on these fields instead of a direct key lookup."},{"name":"List Material Documents","description":"List material document headers (goods movements) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Material Document","description":"Retrieve a single material document header by composite key (MaterialDocument + MaterialDocumentYear) from SAP S/4HANA Cloud (API_MATERIAL_DOCUMENT_SRV, A_MaterialDocumentHeader)."},{"name":"List Purchase Requisitions","description":"List purchase requisitions from SAP S/4HANA Cloud (API_PURCHASEREQ_PROCESS_SRV, A_PurchaseRequisitionHeader) with optional OData $filter, $top, $skip, $orderby, $select, $expand. Note: API_PURCHASEREQ_PROCESS_SRV is deprecated since S/4HANA Cloud Public Edition 2402; the successor is API_PURCHASEREQUISITION_2 (OData v4). This tool still works against tenants where the legacy service is enabled."},{"name":"Get Purchase Requisition","description":"Retrieve a single purchase requisition by PurchaseRequisition key from SAP S/4HANA Cloud (API_PURCHASEREQ_PROCESS_SRV, A_PurchaseRequisitionHeader). Note: API_PURCHASEREQ_PROCESS_SRV is deprecated since S/4HANA Cloud Public Edition 2402; the successor is API_PURCHASEREQUISITION_2 (OData v4). This tool still works against tenants where the legacy service is enabled."},{"name":"Create Purchase Requisition","description":"Create a purchase requisition in SAP S/4HANA Cloud (API_PURCHASEREQ_PROCESS_SRV, A_PurchaseRequisitionHeader). PurchaseRequisition is auto-assigned by SAP from the document number range; provide line items via the to_PurchaseReqnItem deep-insert array. Note: API_PURCHASEREQ_PROCESS_SRV is deprecated since S/4HANA Cloud Public Edition 2402; the successor is API_PURCHASEREQUISITION_2 (OData v4). This tool still works against tenants where the legacy service is enabled."},{"name":"Update Purchase Requisition","description":""},{"name":"List Purchase Orders","description":"List purchase orders from SAP S/4HANA Cloud (API_PURCHASEORDER_PROCESS_SRV, A_PurchaseOrder) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Purchase Order","description":"Retrieve a single purchase order by PurchaseOrder key from SAP S/4HANA Cloud (API_PURCHASEORDER_PROCESS_SRV, A_PurchaseOrder)."},{"name":"Create Purchase Order","description":"Create a purchase order in SAP S/4HANA Cloud (API_PURCHASEORDER_PROCESS_SRV, A_PurchaseOrder). PurchaseOrder is auto-assigned by SAP from the document number range; provide line items via the body parameter."},{"name":"Update Purchase Order","description":"Update fields on an A_PurchaseOrder header in SAP S/4HANA Cloud (API_PURCHASEORDER_PROCESS_SRV). Uses HTTP MERGE (OData v2 partial update) — only the fields you provide are written; existing values are preserved. Header-only — line-item changes are not supported via deep update on the header (SAP KBA 2833338); use the A_PurchaseOrderItem entity directly to modify items. If-Match defaults to a wildcard - for safe concurrent updates pass the ETag from a prior GET to avoid lost updates."},{"name":"List Supplier Invoices","description":"List supplier invoices from SAP S/4HANA Cloud (API_SUPPLIERINVOICE_PROCESS_SRV, A_SupplierInvoice) with optional OData $filter, $top, $skip, $orderby, $select, $expand."},{"name":"Get Supplier Invoice","description":"Retrieve a single supplier invoice by composite key (SupplierInvoice + FiscalYear) from SAP S/4HANA Cloud (API_SUPPLIERINVOICE_PROCESS_SRV, A_SupplierInvoice)."},{"name":"OData Query (advanced)","description":"Make an arbitrary OData v2 call against any SAP S/4HANA Cloud whitelisted Communication Scenario. Use when no dedicated tool exists for the entity. The integration handles auth, CSRF, and OData unwrapping. For write operations (POST/PUT/PATCH/MERGE/DELETE), pass an If-Match ETag obtained from a prior GET to avoid lost updates; misuse will mutate production data."}],"triggers":[],"skills":[{"name":"look-up-business-partner","description":"Find a customer, supplier, or business partner in SAP S4HANA and return their master data.","content":"# Look Up Business Partner\\n\\nRetrieve master data for a customer, supplier, or general business partner.\\n\\n## Steps\\n1. Run List Business Partners (or List Customers / List Suppliers for the typed view) with a filter on name, ID, or other criteria.\\n2. Once the right record is identified, run Get Business Partner, Get Customer, or Get Supplier to pull full detail.\\n3. Note key fields such as the partner ID, addresses, roles, and payment terms.\\n\\n## Output\\nReturn the matched partner ID and the relevant master-data fields, and call out if no match or multiple matches were found."},{"name":"check-sales-order-status","description":"Look up a SAP S4HANA sales order and trace its related deliveries and billing documents.","content":"# Check Sales Order Status\\n\\nTrace a sales order from creation through delivery and billing.\\n\\n## Steps\\n1. Run List Sales Orders to find the order, or Get Sales Order if you already have the order number.\\n2. Run List Outbound Deliveries and List Billing Documents to find the delivery and invoice tied to that order.\\n3. Get any specific delivery or billing document for line-level detail.\\n\\n## Output\\nReturn the sales order number, its status, the linked delivery numbers, and billing document numbers so the order-to-cash state is clear."},{"name":"create-purchase-requisition","description":"Create a purchase requisition in SAP S4HANA via OData from supplied line-item details.","content":"# Create Purchase Requisition\\n\\nRaise a purchase requisition for procurement.\\n\\n## Steps\\n1. Gather the requisition header and line items: material or product, quantity, plant, and delivery date.\\n2. Optionally run List Products and Get Product to confirm material numbers before submitting.\\n3. Run Create Purchase Requisition with the assembled payload.\\n4. Confirm by running Get Purchase Requisition on the returned number.\\n\\n## Output\\nReport the created purchase requisition number and a summary of its line items, and surface any OData validation error verbatim."},{"name":"check-material-stock","description":"Read current material stock and recent material documents for an item in SAP S4HANA.","content":"# Check Material Stock\\n\\nReport on-hand stock and recent inventory movements for a material.\\n\\n## Steps\\n1. Run List Material Stock filtered by the material and plant to read current quantities.\\n2. Run List Material Documents to see recent goods movements for that material, and Get Material Document for line detail on a specific posting.\\n3. Compare on-hand stock against expected levels.\\n\\n## Output\\nReturn the material number, plant, current stock quantity, and a short list of recent material movements with their document numbers."}],"templates":[{"title":"SAP business partner sync","prompt":"Build a workflow that takes new customer rows from a CRM-backed table and creates or updates SAP S/4HANA business partners via the API_BUSINESS_PARTNER service, mapping person and organization categories correctly so finance and sales stay aligned.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"SAP sales order monitor","prompt":"Create a scheduled workflow that lists open SAP S/4HANA sales orders, flags orders past their expected delivery date, summarizes top blockers, logs them to a tracking table, and emails the operations leads a daily prioritized list.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"SAP supplier invoice intake","prompt":"Build a workflow that ingests inbound supplier invoice PDFs from Gmail, extracts header and line-item data with an agent, validates the vendor against SAP S/4HANA suppliers, creates the supplier invoice via OData, and writes the outcome to a finance audit table.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"},{"id":"gmail","name":"Gmail"}]},{"title":"SAP billing reconciliation","prompt":"Create a scheduled workflow that pulls SAP S/4HANA billing documents, joins them against your CRM revenue table, flags mismatches in amounts or customers, and emails finance a reconciliation report file with the specific rows to investigate.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"SAP delivery exception alerts","prompt":"Build a workflow that runs every hour, lists SAP S/4HANA outbound and inbound deliveries with delays or missing reference documents, classifies the exception, posts a Slack alert to the operations channel, and updates a remediation tracking table.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"},{"id":"slack","name":"Slack"}]},{"title":"SAP stock-level digest","prompt":"Create a scheduled daily workflow that queries SAP S/4HANA for product stock and material document movements, identifies SKUs trending toward stock-out, writes a prioritized digest file, and Slacks the supply chain team for action.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"},{"id":"slack","name":"Slack"}]},{"title":"SAP purchase requisition router","prompt":"Build a workflow exposed to internal users as a form that captures purchase requisition details, classifies the request, creates the requisition in SAP S/4HANA via OData, posts the requisition number back to the requester, and logs the request in a tracking table.","integrations":[{"id":"sap_s4hana","name":"SAP S4HANA"}]}]},{"id":"semrush","type":"semrush","slug":"semrush","name":"Semrush","description":"Research SEO and paid search data with Semrush","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/semrush","authType":"api-key","connections":[],"operations":[{"name":"Domain Overview","description":"Get the Semrush rank plus organic and paid search totals for a domain in one regional database."},{"name":"Domain Overview (All Databases)","description":"Get organic and paid search totals for a domain across every regional Semrush database."},{"name":"Domain Overview History","description":"Get the historical trend of a domain rank plus its organic and paid search totals."},{"name":"Domain Organic Keywords","description":"List the keywords a domain ranks for in Google organic search, with position, volume, and traffic share."},{"name":"Domain Paid Keywords","description":"List the keywords a domain buys in Google Ads, with ad position, copy, and traffic share."},{"name":"Domain Ad Copies","description":"List the unique Google Ads creatives a domain runs, with title, description, and keyword count."},{"name":"Domain Ad History","description":"List a domain’s past Google Ads placements month by month, with the copy used each time."},{"name":"Organic Competitors","description":"List the domains competing with a target domain in Google organic search results."},{"name":"Paid Competitors","description":"List the domains competing with a target domain in Google paid search results."},{"name":"Domain PLA Keywords","description":"List the keywords that trigger a domain’s product listing ads, with the promoted product and price."},{"name":"Domain PLA Copies","description":"List the unique product listing ads a domain runs, with product title, price, and shop name."},{"name":"Domain vs. Domain","description":"Compare up to five domains on the keywords they rank for, returning each domain’s position side by side."},{"name":"Subdomain Overview","description":"Get the organic and paid search totals for a subdomain in one regional database."},{"name":"Subdomain Overview (All Databases)","description":"Get organic and paid search totals for a subdomain across every regional Semrush database."},{"name":"Subdomain Overview History","description":"Get the historical trend of a subdomain’s organic and paid search totals."},{"name":"Subdomain Organic Keywords","description":"List the keywords a subdomain ranks for in Google organic search."},{"name":"Subdomain Paid Keywords","description":"List the keywords a subdomain buys in Google Ads."},{"name":"Subdomain Ad Copies","description":"List the unique Google Ads creatives a subdomain runs."},{"name":"URL Overview","description":"Get the organic and paid search totals for a single URL in one regional database."},{"name":"URL Overview (All Databases)","description":"Get organic and paid search totals for a single URL across every regional Semrush database."},{"name":"URL Overview History","description":"Get the historical trend of a URL’s organic and paid search totals."},{"name":"URL Organic Keywords","description":"List the keywords a single URL ranks for in Google organic search."},{"name":"URL Paid Keywords","description":"List the keywords a single URL is advertised on in Google Ads, with the ad copy used."},{"name":"Keyword Overview","description":"Get search volume, CPC, competition, difficulty, and intent for a single keyword."},{"name":"Keyword Overview (All Databases)","description":"Get search volume, CPC, and competition for a keyword across every regional Semrush database."},{"name":"Batch Keyword Overview","description":"Get search volume, CPC, competition, difficulty, and intent for up to 100 keywords at once."},{"name":"Keyword Difficulty","description":"Get the Keyword Difficulty Index for up to 100 keywords at once."},{"name":"Related Keywords","description":"Find keywords semantically related to a seed keyword, with volume, difficulty, and relevance."},{"name":"Broad Match Keywords","description":"Find broad-match and phrase-match variations of a seed keyword, with volume and difficulty."},{"name":"Keyword Questions","description":"Find question-form keywords containing a seed keyword, with volume and difficulty."},{"name":"Organic Results","description":"List the domains and URLs ranking in Google organic search results for a keyword."},{"name":"Paid Results","description":"List the domains and URLs advertising on a keyword in Google paid search results."},{"name":"Keyword Ad History","description":"List which domains advertised on a keyword month by month, with the copy each one used."},{"name":"Winners and Losers","description":"List the domains that gained or lost the most organic and paid search visibility in a database."},{"name":"Top Domains","description":"List the highest-ranked domains in a regional database by Semrush rank."},{"name":"Backlinks Overview","description":"Get the Authority Score and backlink profile totals for a domain, subdomain, or URL."},{"name":"Backlinks","description":"List the backlinks pointing at a domain, subdomain, or URL, with source page, anchor, and authority."},{"name":"Referring Domains","description":"List the domains linking to a target, with Authority Score, backlink count, and country."},{"name":"Referring IPs","description":"List the IP addresses linking to a target, with the domain and backlink counts behind each one."},{"name":"Backlink TLD Distribution","description":"Break a target’s backlink profile down by the top-level domain of its referring domains."},{"name":"Backlink Country Distribution","description":"Break a target’s backlink profile down by the country of its referring domains."},{"name":"Backlink Anchors","description":"List the anchor texts used in backlinks to a target, with domain and backlink counts."},{"name":"Indexed Pages","description":"List the pages of a target that attract backlinks, with response code and link counts."},{"name":"Backlink Competitors","description":"List domains with a backlink profile similar to the target, ranked by shared referring domains."}],"triggers":[],"skills":[{"name":"keyword-gap-analysis","description":"Compare your domain against competitors in Semrush to find the keywords they rank for and you do not.","content":"# Keyword Gap Analysis\\n\\nUse the Semrush Domain vs. Domain report to compare keyword profiles side by side.\\n\\n## Steps\\n1. Run Domain vs. Domain with your domain and up to four competitors, choosing organic or paid keywords.\\n2. Keep the rows where a competitor ranks well and your position is 0 or far lower.\\n3. Run Keyword Overview on the strongest gaps to confirm volume, CPC, and difficulty.\\n\\n## Output\\nA prioritized gap table: keyword, each domain position, search volume, and difficulty, split into quick wins and long-term targets."},{"name":"competitor-keyword-research","description":"Identify who competes with a domain in Semrush organic search and pull the keywords driving their traffic.","content":"# Competitor Keyword Research\\n\\nFind the real organic competitors for a domain and study what they rank for.\\n\\n## Steps\\n1. Run Organic Competitors for the domain to rank rivals by keyword overlap and traffic.\\n2. For the top competitors, run Domain Organic Keywords sorted by traffic share.\\n3. Group the results by topic and note which pages of theirs capture the traffic.\\n\\n## Output\\nA ranked competitor list plus each competitor\'s top traffic-driving keywords and landing pages."},{"name":"backlink-audit","description":"Audit a backlink profile in Semrush and report authority, referring domains, and anchor text distribution.","content":"# Backlink Audit\\n\\nReview the health and shape of a backlink profile using Semrush Backlink Analytics.\\n\\n## Steps\\n1. Run Backlinks Overview for the target to capture Authority Score and follow/nofollow totals.\\n2. Pull Referring Domains sorted by Authority Score, and Backlink Anchors for the anchor mix.\\n3. Flag anchor over-optimization and low-authority referring domains worth disavowing.\\n\\n## Output\\nA profile summary with totals, the strongest referring domains, the anchor text distribution, and any risks to address."},{"name":"keyword-research-report","description":"Expand a seed keyword in Semrush into a prioritized list with volume, difficulty, and intent.","content":"# Keyword Research Report\\n\\nTurn one seed keyword into a working keyword list.\\n\\n## Steps\\n1. Run Related Keywords and Broad Match Keywords on the seed to gather candidates.\\n2. Run Keyword Difficulty on the shortlist to score how hard each one is to rank for.\\n3. Sort by volume against difficulty and label each keyword with its search intent.\\n\\n## Output\\nA keyword table with volume, CPC, difficulty, and intent, grouped into quick wins and long-term targets."},{"name":"competitor-ad-copy-research","description":"Study a competitor paid search strategy in Semrush, including the keywords they bid on and the ad copy they run.","content":"# Competitor Ad Copy Research\\n\\nUnderstand what a competitor is buying and how they write their ads.\\n\\n## Steps\\n1. Run Domain Paid Keywords for the competitor to see the terms they bid on and the traffic each drives.\\n2. Run Domain Ad Copies to collect the unique creatives and the keyword count behind each.\\n3. Run Domain Ad History to see which messages they have sustained month over month.\\n\\n## Output\\nA summary of their bidded keywords, recurring headlines and calls to action, and which creatives they keep running."},{"name":"question-keyword-content-brief","description":"Build a content brief from the questions people search around a topic, using Semrush question keywords.","content":"# Question Keyword Content Brief\\n\\nTurn real searcher questions into an article outline.\\n\\n## Steps\\n1. Run Keyword Questions on the seed topic to collect question-form searches.\\n2. Run Keyword Overview on the seed to anchor the brief to volume and difficulty.\\n3. Group the questions into sections and order them the way a reader would ask them.\\n\\n## Output\\nAn outline where each H2 is a real question, annotated with search volume and difficulty."},{"name":"backlink-gap-analysis","description":"Find domains linking to your Semrush backlink competitors but not to you, and rank them as outreach targets.","content":"# Backlink Gap Analysis\\n\\nSurface link opportunities your competitors already have.\\n\\n## Steps\\n1. Run Backlink Competitors for your target to find domains with a similar backlink profile.\\n2. Run Referring Domains for each competitor and for your own domain.\\n3. Subtract your referring domains from theirs and rank what is left by Authority Score.\\n\\n## Output\\nA prioritized outreach list: referring domain, Authority Score, which competitors it links to, and why it is a fit."},{"name":"shopping-ads-competitor-research","description":"Research a competitor product listing ads in Semrush, including the keywords they trigger on and the products promoted.","content":"# Shopping Ads Competitor Research\\n\\nStudy how a retailer competitor runs Google Shopping.\\n\\n## Steps\\n1. Run Domain PLA Keywords for the competitor to see which searches trigger their product ads.\\n2. Run Domain PLA Copies to collect the promoted products, titles, and prices.\\n3. Compare their prices and product mix against your own catalogue on the same keywords.\\n\\n## Output\\nA report of the shopping keywords they compete on, the products they push, and where your pricing is off."}],"templates":[{"title":"Semrush rank tracker","prompt":"Create a scheduled weekly workflow that pulls Semrush domain organic keywords for my site, writes position changes into a table, and posts a Slack summary of the biggest gainers and losers.","integrations":[{"id":"semrush","name":"Semrush"},{"id":"slack","name":"Slack"}]},{"title":"Semrush content gap finder","prompt":"Build a workflow that runs a Semrush Domain vs. Domain comparison between my site and two competitors, has an agent pick the keywords they rank for and I do not, and writes a prioritized content brief table.","integrations":[{"id":"semrush","name":"Semrush"}]},{"title":"Semrush keyword research assistant","prompt":"Create a workflow where I submit a seed keyword, Semrush returns related keywords, broad match variations, and questions, and an agent clusters them into topic groups with search volume and difficulty.","integrations":[{"id":"semrush","name":"Semrush"}]},{"title":"Semrush backlink monitor","prompt":"Build a scheduled workflow that pulls new Semrush referring domains for my site weekly, flags any with a high Authority Score, and posts a Slack digest with the linking page and anchor text.","integrations":[{"id":"semrush","name":"Semrush"},{"id":"slack","name":"Slack"}]},{"title":"Semrush competitor ad watch","prompt":"Create a scheduled workflow that pulls Semrush domain paid keywords and paid competitors for my top three rivals, diffs them against last week, and emails the growth team a summary of new ad copy and bids.","integrations":[{"id":"semrush","name":"Semrush"},{"id":"gmail","name":"Gmail"}]},{"title":"Semrush landing page audit","prompt":"Build a workflow that reads a list of landing page URLs from a table, pulls the Semrush URL overview and organic keywords for each, and writes traffic and keyword counts back to the table for review.","integrations":[{"id":"semrush","name":"Semrush"}]},{"title":"Semrush new competitor alert","prompt":"Create a monthly workflow that pulls Semrush organic competitors for my domain, compares them against my tracked competitor list, and posts newly surfaced competitors to Slack for review.","integrations":[{"id":"semrush","name":"Semrush"},{"id":"slack","name":"Slack"}]},{"title":"Semrush + Ahrefs visibility scoreboard","prompt":"Build a scheduled monthly workflow that joins Semrush domain overview data with Ahrefs backlink metrics, writes a combined visibility scoreboard table, and emails leadership.","integrations":[{"id":"semrush","name":"Semrush"},{"id":"ahrefs","name":"Ahrefs"},{"id":"gmail","name":"Gmail"}]}]},{"id":"sendblue","type":"sendblue","slug":"sendblue","name":"Sendblue","description":"Send and receive iMessage and SMS","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/sendblue","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send an iMessage or SMS to a single recipient via Sendblue."},{"name":"Send Group Message","description":"Send an iMessage or SMS to a group of recipients via Sendblue."},{"name":"Evaluate Service","description":"Check whether a phone number can receive iMessage or only SMS."},{"name":"Send Typing Indicator","description":"Display a typing indicator to a recipient (not supported in group chats)."},{"name":"Get Message","description":"Retrieve a single message and its current status by message handle/ID."}],"triggers":[{"id":"sendblue_message_received","name":"Sendblue Message Received","description":"Trigger when an inbound iMessage or SMS is received in Sendblue"},{"id":"sendblue_message_status_updated","name":"Sendblue Message Status Updated","description":"Trigger when an outbound message status changes (SENT, DELIVERED, ERROR) in Sendblue"}],"skills":[{"name":"send-imessage-notification","description":"Send an iMessage or SMS notification to a single recipient via Sendblue.","content":"# Send an iMessage or SMS Notification\\n\\nDeliver a message to one recipient through your Sendblue number.\\n\\n## Steps\\n1. Choose the Send Message operation.\\n2. Enter the Recipient Number and your From Number in E.164 format (for example +19998887777).\\n3. Write the Message text. To send media instead of or alongside text, add a Media URL.\\n4. Provide your Sendblue API Key ID and API Secret Key.\\n\\n## Output\\nReturn the message status (QUEUED, SENT, DELIVERED, ERROR) and the message handle so the send can be tracked."},{"name":"route-imessage-or-sms","description":"Check whether a number supports iMessage before sending with Sendblue.","content":"# Route iMessage vs SMS\\n\\nDecide how to reach a recipient based on their service.\\n\\n## Steps\\n1. Use the Evaluate Service operation with the Recipient Number to learn whether the number supports iMessage or only SMS.\\n2. Branch on the returned service value.\\n3. Send a rich iMessage when supported, or a plain SMS fallback otherwise, using the Send Message operation.\\n\\n## Output\\nReturn the evaluated number and its supported service so downstream steps can branch correctly."},{"name":"reply-to-inbound-message","description":"Trigger on an inbound Sendblue message and reply automatically.","content":"# Reply to an Inbound Message\\n\\nRespond to customers as soon as they text in.\\n\\n## Steps\\n1. Add the Sendblue Message Received trigger and point your Sendblue Receive Webhook at the generated URL.\\n2. Read the inbound content, from_number, and service from the trigger output.\\n3. Draft a reply with an agent and send it back with the Send Message operation, using the from_number as the recipient.\\n\\n## Output\\nReturn the reply message handle and status so the conversation can be tracked."}],"templates":[{"title":"Sendblue lead speed-to-text","prompt":"Build a workflow that fires when a new lead submits a form, drafts a friendly intro, and sends it as an iMessage via Sendblue within seconds so reps reach hot leads while they are still interested.","integrations":[{"id":"sendblue","name":"Sendblue"},{"id":"typeform","name":"Typeform"}]},{"title":"Sendblue appointment reminders","prompt":"Create a scheduled workflow that reads tomorrow\'s appointments from a table and sends each customer a personalized Sendblue iMessage reminder with the time and a reschedule link.","integrations":[{"id":"sendblue","name":"Sendblue"}]},{"title":"Sendblue inbound reply autoresponder","prompt":"Build a workflow triggered when a Sendblue message is received that classifies the inbound text, drafts a context-aware reply with an agent, and sends it back to the same number as an iMessage.","integrations":[{"id":"sendblue","name":"Sendblue"}]},{"title":"Sendblue iMessage vs SMS routing","prompt":"Create a workflow that evaluates whether a recipient number supports iMessage with Sendblue, then sends a rich iMessage when supported or a plain SMS fallback otherwise.","integrations":[{"id":"sendblue","name":"Sendblue"}]},{"title":"Sendblue order-status notifier","prompt":"Create a workflow triggered when an order ships that looks up the customer phone number and sends a Sendblue iMessage with the tracking number and estimated delivery date.","integrations":[{"id":"sendblue","name":"Sendblue"},{"id":"shopify","name":"Shopify"}]},{"title":"Sendblue delivery-failure alerts","prompt":"Build a workflow triggered by a Sendblue message status update that, when the status is ERROR, posts the failing number and error message to a Slack channel so the team can follow up.","integrations":[{"id":"sendblue","name":"Sendblue"},{"id":"slack","name":"Slack"}]},{"title":"Sendblue group broadcast","prompt":"Create a workflow that reads a list of VIP customers from a table and sends them a single Sendblue group iMessage announcing a new product launch with an image attachment.","integrations":[{"id":"sendblue","name":"Sendblue"}]},{"title":"Sendblue conversational support agent","prompt":"Build a workflow triggered on inbound Sendblue messages that shows a typing indicator, looks up the customer in a table, answers their question with an agent, and replies over iMessage.","integrations":[{"id":"sendblue","name":"Sendblue"}]}]},{"id":"sendgrid","type":"sendgrid","slug":"sendgrid","name":"SendGrid","description":"Send emails and manage contacts, lists, and templates with SendGrid","category":"Email","docsUrl":"https://docs.sim.ai/integrations/sendgrid","authType":"api-key","connections":[],"operations":[{"name":"Send Mail","description":"Send an email using SendGrid API"},{"name":"Add Contact","description":"Add a new contact to SendGrid"},{"name":"Get Contact","description":"Get a specific contact by ID from SendGrid"},{"name":"Search Contacts","description":"Search for contacts in SendGrid using a query"},{"name":"Delete Contacts","description":"Delete one or more contacts from SendGrid"},{"name":"Create List","description":"Create a new contact list in SendGrid"},{"name":"Get List","description":"Get a specific list by ID from SendGrid"},{"name":"List All Lists","description":"Get all contact lists from SendGrid"},{"name":"Delete List","description":"Delete a contact list from SendGrid"},{"name":"Add Contacts to List","description":"Add or update contacts and assign them to a list in SendGrid (uses PUT /v3/marketing/contacts)"},{"name":"Remove Contacts from List","description":"Remove contacts from a specific list in SendGrid"},{"name":"Create Template","description":"Create a new email template in SendGrid"},{"name":"Get Template","description":"Get a specific template by ID from SendGrid"},{"name":"List Templates","description":"Get all email templates from SendGrid"},{"name":"Delete Template","description":"Delete an email template from SendGrid"},{"name":"Create Template Version","description":"Create a new version of an email template in SendGrid"}],"triggers":[],"skills":[{"name":"send-transactional-email","description":"Send a transactional email through SendGrid, optionally using a dynamic template and variables.","content":"# Send Transactional Email\\n\\nSend a single transactional email (receipt, confirmation, password reset) through SendGrid.\\n\\n## Steps\\n1. Set the verified From address and the recipient To address.\\n2. For a one-off message, set the Subject and Content (choose HTML or plain text). For a templated message, set the Template ID and provide Dynamic Template Data as a JSON object whose keys match the template variables.\\n3. Add CC, BCC, or Reply-To addresses if needed, and attach files via Attachments.\\n4. Run the Send Mail operation and capture the returned message ID.\\n\\n## Output\\nReport whether the send succeeded and include the SendGrid message ID for later delivery tracking and audit."},{"name":"sync-contacts-to-list","description":"Add or update marketing contacts and place them on a specific SendGrid list for a campaign segment.","content":"# Sync Contacts to List\\n\\nUpsert marketing contacts and assign them to a SendGrid list so a segment is ready to receive a campaign.\\n\\n## Steps\\n1. If the target list does not exist, run Create List with a descriptive name and keep the returned list ID.\\n2. Build a JSON array of contacts, each with at least an email plus optional first name, last name, and custom fields.\\n3. Run Add Contacts to List with the list ID and the contacts array.\\n4. Optionally run Remove Contacts from List to drop addresses that no longer qualify for the segment.\\n\\n## Output\\nReport the list ID, the count of contacts added, and the job ID returned for the async upsert."},{"name":"clean-contact-list","description":"Search SendGrid marketing contacts for invalid or unwanted addresses and remove them.","content":"# Clean Contact List\\n\\nFind and remove low-quality marketing contacts using SendGrid Query Language.\\n\\n## Steps\\n1. Run Search Contacts with an SGQL query that targets the unwanted records (for example addresses matching a bad domain or stale by created date).\\n2. Collect the contact IDs from the results.\\n3. Run Delete Contacts with the comma-separated contact IDs, or Remove Contacts from List to drop them only from a specific segment.\\n4. Record what was removed for a cleanup report.\\n\\n## Output\\nReport the search criteria used, the number of contacts found, and how many were deleted or removed from the list."},{"name":"create-dynamic-template","description":"Create a SendGrid dynamic template and an active version with HTML and a subject line.","content":"# Create Dynamic Template\\n\\nStand up a reusable SendGrid dynamic template for a recurring transactional message.\\n\\n## Steps\\n1. Run Create Template with a descriptive name and the dynamic generation.\\n2. Keep the returned template ID.\\n3. Run Create Template Version against that template ID, supplying a version name, the Template Subject (Handlebars variables allowed), and the HTML content. Set the version active so it is used on send.\\n4. Optionally supply plain text content as a fallback.\\n\\n## Output\\nReport the template ID and version, and confirm the active version is ready to reference from Send Mail operations."}],"templates":[{"title":"Mailchimp + SendGrid hybrid sender","prompt":"Create a workflow that uses Mailchimp for marketing audience management and segmentation but sends the actual campaign through SendGrid for deliverability, syncing send results, opens, and clicks back to the Mailchimp audience as merge fields.","integrations":[{"id":"sendgrid","name":"SendGrid"},{"id":"mailchimp","name":"Mailchimp"}]},{"title":"SendGrid transactional pipeline","prompt":"Build a workflow that listens for product events from my tables — signup, password reset, receipt — picks the matching SendGrid dynamic template, populates the variables, sends the email, and writes the message ID back to the table for audit.","integrations":[{"id":"sendgrid","name":"SendGrid"}]},{"title":"SendGrid send-failure monitor","prompt":"Create a workflow that sends emails through SendGrid, logs each send result and any error to a delivery table, and posts a Slack alert summarizing failure patterns by recipient domain and template when the failure rate crosses a threshold.","integrations":[{"id":"sendgrid","name":"SendGrid"},{"id":"slack","name":"Slack"}]},{"title":"SendGrid + Resend failover","prompt":"Build a workflow that sends transactional emails through SendGrid by default and automatically falls back to Resend when the primary send fails or rate limits, logging every send and the provider used to a delivery table.","integrations":[{"id":"sendgrid","name":"SendGrid"},{"id":"resend","name":"Resend"}]},{"title":"SendGrid contact list cleaner","prompt":"Create a scheduled workflow that searches SendGrid marketing contacts for invalid or duplicate entries, removes the bad addresses, merges duplicates, and writes a cleanup report to a tracking table.","integrations":[{"id":"sendgrid","name":"SendGrid"}]},{"title":"SendGrid + SES enterprise sender","prompt":"Build a workflow that splits transactional traffic between SendGrid and AWS SES based on message category and recipient region, balances volume to stay under per-provider limits, and writes provider, status, and latency to a delivery table.","integrations":[{"id":"sendgrid","name":"SendGrid"},{"id":"ses","name":"AWS SES"}]},{"title":"SendGrid + Mailgun send scorecard","prompt":"Create a scheduled weekly workflow that sends categorized test messages through both SendGrid and Mailgun, records each provider response, latency, and error to a delivery table, and generates a scorecard file recommending which provider to use per send category.","integrations":[{"id":"sendgrid","name":"SendGrid"},{"id":"mailgun","name":"Mailgun"}]},{"title":"SendGrid segmented list builder","prompt":"Build a workflow that reads a freshly scored audience from a table, creates a new SendGrid marketing list, adds each matching contact to the list, and removes anyone who no longer qualifies so the segment is ready for the next campaign send.","integrations":[{"id":"sendgrid","name":"SendGrid"}]}]},{"id":"sentry","type":"sentry","slug":"sentry","name":"Sentry","description":"Manage Sentry issues, projects, events, and releases","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/sentry","authType":"api-key","connections":[],"operations":[{"name":"List Issues","description":"List issues from Sentry for a specific organization and optionally a specific project. Returns issue details including status, error counts, and last seen timestamps."},{"name":"Get Issue","description":"Retrieve detailed information about a specific Sentry issue by its ID. Returns complete issue details including metadata, tags, and statistics."},{"name":"Update Issue","description":"Update a Sentry issue by changing its status, assignment, bookmark state, or other properties. Returns the updated issue details."},{"name":"List Projects","description":"List all projects in a Sentry organization. Returns project details including name, platform, teams, and configuration."},{"name":"Get Project","description":"Retrieve detailed information about a specific Sentry project by its slug. Returns complete project details including teams, features, and configuration."},{"name":"Create Project","description":"Create a new Sentry project in an organization. Requires a team to associate the project with. Returns the created project details."},{"name":"Update Project","description":"Update a Sentry project by changing its name, slug, platform, or other settings. Returns the updated project details."},{"name":"List Teams","description":"List all teams in a Sentry organization. Useful for discovering the team slug required when creating a project. Returns team details including slug, name, member count, and associated projects."},{"name":"List Events","description":"List events from a Sentry project. Can be filtered by issue ID, query, or time period. Returns event details including context, tags, and user information."},{"name":"Get Event","description":"Retrieve detailed information about a specific Sentry event by its ID. Returns complete event details including stack traces, breadcrumbs, context, and user information."},{"name":"List Releases","description":"List releases for a Sentry organization or project. Returns release details including version, commits, deploy information, and associated projects."},{"name":"Create Release","description":"Create a new release in Sentry. A release is a version of your code deployed to an environment. Can include commit information and associated projects. Returns the created release details."},{"name":"Create Deploy","description":"Create a deploy record for a Sentry release in a specific environment. Deploys track when and where releases are deployed. Returns the created deploy details."}],"triggers":[{"id":"sentry_issue_created","name":"Sentry Issue Created","description":"Trigger workflow when a new issue is created in Sentry"},{"id":"sentry_issue_resolved","name":"Sentry Issue Resolved","description":"Trigger workflow when an issue is resolved in Sentry"},{"id":"sentry_error_created","name":"Sentry Error Created","description":"Trigger workflow when a new error event is created in Sentry"},{"id":"sentry_issue_alert","name":"Sentry Issue Alert","description":"Trigger workflow when a Sentry issue alert rule fires"},{"id":"sentry_metric_alert","name":"Sentry Metric Alert","description":"Trigger workflow when a Sentry metric alert changes state (critical, warning, resolved)"}],"skills":[{"name":"triage-unresolved-errors","description":"List unresolved Sentry issues, rank them by impact, and summarize the most urgent errors to fix.","content":"# Triage Unresolved Errors\\n\\nProduce a prioritized view of the Sentry errors that most need attention.\\n\\n## Steps\\n1. Run List Issues with the query is:unresolved, sorting by frequency or user count and setting a stats period such as 24h or 7d.\\n2. For the top issues, run Get Issue to pull the title, culprit, event count, and number of affected users.\\n3. Rank by a blend of event volume, affected users, and recency.\\n\\n## Output\\nReturn a ranked list of issues with their ID, title, event count, affected users, and a one-line recommendation for each. Link each issue so an engineer can open it directly."},{"name":"resolve-or-assign-issue","description":"Update a Sentry issue to change status, assign an owner, or bookmark it for follow-up.","content":"# Resolve or Assign Issue\\n\\nAct on a specific Sentry issue once a decision has been made.\\n\\n## Steps\\n1. Identify the issue ID (from a triage step or a notification).\\n2. Run Update Issue, setting the new status (resolved, ignored, or resolved in next release) as appropriate.\\n3. To route ownership, set Assign To with a user ID or email. Bookmark or subscribe if the team wants to track it.\\n\\n## Output\\nConfirm the issue ID, its new status, and the assignee, so the change is auditable."},{"name":"investigate-issue-events","description":"Pull the events behind a Sentry issue to inspect impacted users, environments, and context.","content":"# Investigate Issue Events\\n\\nDrill into the raw events for an issue to understand who and what is affected.\\n\\n## Steps\\n1. Run List Events for the project, optionally filtering by an issue ID and an events search query (for example user.email or environment filters).\\n2. Run Get Event on a representative event ID to retrieve the full payload: tags, breadcrumbs, request context, and stack trace.\\n3. Group findings by environment, release, browser, or OS.\\n\\n## Output\\nSummarize the affected environments and users, the common context across events, and the likely trigger, citing the specific event IDs examined."},{"name":"track-release-and-deploy","description":"Create a Sentry release for a version and mark a deploy to an environment for regression tracking.","content":"# Track Release and Deploy\\n\\nRegister a new version in Sentry so errors can be attributed to the release that introduced them.\\n\\n## Steps\\n1. Run Create Release with the version string and the comma-separated project slugs. Add the git ref, release URL, and commits JSON if available so Sentry can associate suspect commits.\\n2. Run Create Deploy with the same version and the target environment (for example production), including start and finish times.\\n3. Optionally run List Releases afterward to confirm the version is registered.\\n\\n## Output\\nReport the created release version, the deploy environment, and confirm both were recorded for regression monitoring."}],"templates":[{"title":"incident.io postmortem starter","prompt":"Create a scheduled workflow that polls incident.io for recently resolved incidents, pulls the Slack thread, related Sentry errors, and deploy timeline, then drafts a postmortem doc in Google Docs.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"incidentio","name":"incident.io"},{"id":"google_docs","name":"Google Docs"}]},{"title":"LaunchDarkly flag-flip safety gate","prompt":"Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"datadog","name":"Datadog"},{"id":"slack","name":"Slack"}]},{"title":"LogRocket + Sentry incident context","prompt":"Build a workflow that triggers on a new Sentry issue, requests LogRocket session highlights for the impacted user, and posts a combined stack trace plus session narrative into the incident Slack channel.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"logrocket","name":"LogRocket"},{"id":"slack","name":"Slack"}]},{"title":"Sentry on-call triage agent","prompt":"Build an agent that monitors Sentry for new errors, automatically triages them by severity and affected users, creates Linear tickets for critical issues with full stack traces, and sends a Slack notification to the on-call channel.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Sentry error triage","prompt":"Build a scheduled workflow that polls Sentry for new unresolved issues, classifies severity, groups similar issues, creates a Linear ticket on first occurrence above the threshold, and pings the owning team in Slack.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"Sentry release health gate","prompt":"Create a workflow that runs after a Vercel deploy, checks Sentry release health, and rolls back the deploy if the error rate exceeds the threshold, posting an alert to Slack.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]},{"title":"Sentry weekly regression brief","prompt":"Build a scheduled weekly workflow that compares Sentry error rates week-over-week, identifies top regressors, and writes a brief to engineering leadership in Slack.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Sentry source-map verifier","prompt":"Create a scheduled workflow that scans Sentry for issues with missing or stale source maps, writes a tracking table, and opens Linear tickets for the worst offenders.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"linear","name":"Linear"}]},{"title":"Sentry customer-impact mapper","prompt":"Build a workflow that takes a Sentry issue and matches affected users to CRM accounts, scoring customer impact, and creates a customer-facing incident note in HubSpot for the worst-affected accounts.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Sentry release tracker on deploy","prompt":"Create a workflow that watches GitHub for merges to main, creates a new Sentry release with the commit range, marks the deploy in Sentry for the production environment, and posts the release notes and linked issues to Slack so the team knows what shipped.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"github","name":"GitHub"},{"id":"slack","name":"Slack"}]},{"title":"Slack incident postmortem writer","prompt":"Create a workflow that when triggered after an incident, pulls the Slack thread from the incident channel, gathers relevant Sentry errors and deployment logs, and drafts a structured postmortem with timeline, root cause, and action items.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Telegram alert relay","prompt":"Build a workflow that listens for critical alerts from Sentry or PagerDuty and forwards a concise summary with severity, link, and the on-call person to a Telegram group.","integrations":[{"id":"sentry","name":"Sentry"},{"id":"telegram","name":"Telegram"},{"id":"pagerduty","name":"PagerDuty"}]}]},{"id":"serper","type":"serper","slug":"serper","name":"Serper","description":"Search the web using Serper","category":"Search","docsUrl":"https://docs.sim.ai/integrations/serper","authType":"api-key","connections":[],"operations":[{"name":"Web Search","description":"Search Google through the Serper.dev API for web, news, places, images, videos, shopping, scholar, or patent results. Available response sections include organic results, a knowledge graph, an answer box, related questions, related searches, and top stories."}],"triggers":[],"skills":[{"name":"research-web-topic","description":"Run a Serper web search on a topic and synthesize the top organic results into a sourced summary.","content":"# Research Web Topic\\n\\nGather current web results on a topic and turn them into a concise, sourced briefing.\\n\\n## Steps\\n1. Run the search operation with a focused query. Set the country and language for the target audience and choose a result count (10 to 100) appropriate to the depth needed.\\n2. Read the organic results, titles, snippets, and any answer box or knowledge graph data.\\n3. Synthesize the findings, noting agreement and disagreement across sources.\\n\\n## Output\\nReturn a short summary of what the web says about the topic, each key claim linked to the result URL it came from."},{"name":"monitor-news-mentions","description":"Search recent news for a brand, person, or topic via Serper and summarize the coverage.","content":"# Monitor News Mentions\\n\\nTrack what the news is saying about a brand, competitor, person, or topic.\\n\\n## Steps\\n1. Run the news operation with the entity or topic as the query, setting country and language to scope the coverage.\\n2. Collect the headlines, sources, publish dates, and snippets.\\n3. Group the coverage by sentiment or theme and highlight the most recent and most prominent items.\\n\\n## Output\\nReturn a dated list of news items with source and headline, plus a short overall read on tone and notable developments."},{"name":"compare-regional-rankings","description":"Run the same Serper query across multiple regions to compare search rankings by geography.","content":"# Compare Regional Rankings\\n\\nSee how search results differ for the same query across countries.\\n\\n## Steps\\n1. Pick the target keyword and the set of countries to compare.\\n2. Run the search operation once per country, varying only the country (and language where relevant), keeping the result count consistent.\\n3. Line up the top organic results per region and note which domains rank where.\\n\\n## Output\\nReturn a per-region ranking comparison for the keyword, calling out domains that rank strongly in some regions but not others."},{"name":"find-local-businesses","description":"Use the Serper places operation to find local businesses for a query and area, and rank them.","content":"# Find Local Businesses\\n\\nPull Google Maps style local results for a query in a target area.\\n\\n## Steps\\n1. Run the places operation with a query that includes the business type and location (for example coffee shops in Seattle), setting the country and language to scope results.\\n2. Read each place result: name, address, rating, review count, category, and phone or website where present.\\n3. Rank or filter the results by rating, review volume, or proximity to the target area.\\n\\n## Output\\nReturn a ranked list of local businesses with name, address, rating, and review count, noting the top candidates for the query."}],"templates":[{"title":"Serper SERP digest","prompt":"Build a scheduled daily workflow that runs Serper searches for tracked keywords, writes the SERP positions of my domain into a tables-based SEO log, and pings on changes.","integrations":[{"id":"serper","name":"Serper"},{"id":"slack","name":"Slack"}]},{"title":"Serper competitor SERP watcher","prompt":"Create a workflow that runs Serper searches for competitor keywords weekly, captures top SERP entries, and writes a competitive SEO digest to Slack.","integrations":[{"id":"serper","name":"Serper"},{"id":"slack","name":"Slack"}]},{"title":"Serper news monitor","prompt":"Build a scheduled workflow that uses Serper news search for brand keywords, classifies each result, and posts notable mentions to a Slack PR channel.","integrations":[{"id":"serper","name":"Serper"},{"id":"slack","name":"Slack"}]},{"title":"Serper local-pack tracker","prompt":"Create a workflow that uses Serper to track Google local-pack rankings for tracked queries by city, writes the results to a tables-based SEO log, and surfaces wins.","integrations":[{"id":"serper","name":"Serper"}]},{"title":"Serper research agent","prompt":"Build an agent that uses Serper as a primary web-search tool, returns answers with citations, and saves long-form research to a knowledge base.","integrations":[{"id":"serper","name":"Serper"}]},{"title":"Serper image-search collector","prompt":"Create a workflow that uses Serper image search for brand or product mentions, captures unique image URLs into a table, and flags potential trademark misuse.","integrations":[{"id":"serper","name":"Serper"}]},{"title":"Serper geo-SERP comparator","prompt":"Build a scheduled workflow that runs Serper across multiple regions for the same keywords, identifies geo-relevant ranking differences, and writes the analysis to a file.","integrations":[{"id":"serper","name":"Serper"}]}]},{"id":"servicenow","type":"servicenow_v2","slug":"servicenow","name":"ServiceNow","description":"Create, read, update, and delete ServiceNow records","category":"Support","docsUrl":"https://docs.sim.ai/integrations/servicenow","authType":"api-key","connections":[],"operations":[{"name":"Create Incident","description":"Create an incident in ServiceNow. Reference fields (caller, assignment group, assigned to, configuration item) take sys_ids unless input display value is enabled."},{"name":"Get Incident","description":"Retrieve a single ServiceNow incident by number (e.g., INC0010001) or sys_id. Reference fields are returned with both their sys_id and their label by default."},{"name":"List Incidents","description":"Search ServiceNow incidents by state, priority, assignment, caller, or text. All filters are ANDed together."},{"name":"Update Incident","description":"Update fields on an existing ServiceNow incident. Only the fields you supply are changed. Reference fields take sys_ids unless input display value is enabled."},{"name":"Resolve Incident","description":"Move a ServiceNow incident to Resolved (state 6) with a resolution code and resolution notes."},{"name":"Close Incident","description":"Move a ServiceNow incident to Closed (state 7) with a resolution code and resolution notes. Which roles may close an incident is instance-configurable, so the credential may need elevated rights."},{"name":"Add Incident Comment","description":"Append an internal work note or a customer-visible additional comment to a ServiceNow incident. Both are journal fields, so the text is appended rather than replacing earlier entries."},{"name":"Create Change Request","description":"Create a change request in ServiceNow. Reference fields (assignment group, assigned to, requested by, configuration item) take sys_ids unless input display value is enabled."},{"name":"Get Change Request","description":"Retrieve a single ServiceNow change request by number (e.g., CHG0030001) or sys_id. Reference fields are returned with both their sys_id and their label by default."},{"name":"List Change Requests","description":"Search ServiceNow change requests by state, type, risk, assignment, or text. All filters are ANDed together."},{"name":"Update Change Request","description":"Update fields on an existing ServiceNow change request. Only the fields you supply are changed. Use Move ServiceNow Change State for state transitions."},{"name":"Move Change State","description":"Move a ServiceNow change request to another state. Base-system change model states are -5=New, -4=Assess, -3=Authorize, -2=Scheduled, -1=Implement, 0=Review, 3=Closed, 4=Canceled. The state machine rejects transitions whose conditions are not met."},{"name":"List Change Tasks","description":"List the change tasks belonging to a ServiceNow change request, via the Change Management API. Every field is returned as {value, display_value}, so a reference field carries both its sys_id and its label. This endpoint is not the Table API: the shape is fixed with no display-value option, and the results come back under `tasks` rather than the `records` the other list operations use."},{"name":"Get Change Next States","description":"Read the states a ServiceNow change request can actually move to next, with the instance\'s own state-to-label map and the conditions each transition still has to meet. Use this instead of assuming the base-system state codes, which a customized change model can change."},{"name":"List Catalog Items","description":"Browse or search the ServiceNow service catalog. Returns each item with its sys_id, name, description, type, category, and catalogs, which is what Order ServiceNow Catalog Item needs."},{"name":"Order Catalog Item","description":"Submit a service catalog request for a catalog item using the Service Catalog API order_now endpoint. Returns the generated request number and sys_id."},{"name":"List Requested Items","description":"List requested items (RITMs) from the ServiceNow Requested Item [sc_req_item] table, optionally scoped to a parent request or a catalog item. To scope by requester, pass an encoded query against the parent request, for example \\"request.requested_for=\\"."},{"name":"Get Requested Item","description":"Retrieve a single ServiceNow requested item (RITM) by number (e.g., RITM0010001) or sys_id from the Requested Item [sc_req_item] table."},{"name":"List Approvals","description":"List approval records from the ServiceNow Approval [sysapproval_approver] table. Defaults to the \\"requested\\" state, which is what a user\'s pending approvals look like."},{"name":"Approve or Reject","description":"Approve or reject a ServiceNow approval record by setting its state on the Approval [sysapproval_approver] table."},{"name":"Search Configuration Items","description":"Search the ServiceNow CMDB for configuration items. Defaults to the base cmdb_ci table, which returns CIs of every class; pass a CI class to scope the search to a subclass such as cmdb_ci_linux_server."},{"name":"Get Configuration Item","description":"Retrieve a configuration item and its CMDB relationships through the CMDB Instance API. Returns the CI attributes plus its inbound and outbound relations, each carrying the related CI and the relationship type."},{"name":"List CI Relationships","description":"List rows from the CI Relationship [cmdb_rel_ci] table for a configuration item. Each row carries the parent CI, the child CI, and the relationship type."},{"name":"Search Knowledge","description":"Search ServiceNow knowledge base articles through the Knowledge Management API. Returns ranked results with a snippet and the article number, which Get ServiceNow Knowledge Article accepts to fetch the full body."},{"name":"Get Knowledge Article","description":"Retrieve the full content of a ServiceNow knowledge article by sys_id or KB number through the Knowledge Management API."},{"name":"Find User","description":"Look up ServiceNow users by email, user name, or display name. Use this to resolve the sys_id needed by reference fields such as caller_id, assigned_to, and approver."},{"name":"List Group Members","description":"List the members of a ServiceNow group from the Group Member [sys_user_grmember] table. Each row links a user to a group, so use it to find who can be assigned work for an assignment group."},{"name":"Create Record","description":"Create a new record in a ServiceNow table"},{"name":"Read Records","description":"Read records from a ServiceNow table"},{"name":"Update Record","description":"Update an existing record in a ServiceNow table"},{"name":"Delete Record","description":"Delete a record from a ServiceNow table"},{"name":"Aggregate Records","description":"Compute aggregate statistics (count, sum, average, min, max, group by) over a ServiceNow table"},{"name":"List Attachments","description":"List the attachments on a ServiceNow record"},{"name":"Download Attachment","description":"Download an attachment file from ServiceNow by its sys_id"},{"name":"Upload Attachment","description":"Attach a file to a ServiceNow record"}],"triggers":[{"id":"servicenow_incident_created","name":"ServiceNow Incident Created","description":"Trigger workflow when a new incident is created in ServiceNow"},{"id":"servicenow_incident_updated","name":"ServiceNow Incident Updated","description":"Trigger workflow when an incident is updated in ServiceNow"},{"id":"servicenow_change_request_created","name":"ServiceNow Change Request Created","description":"Trigger workflow when a new change request is created in ServiceNow"},{"id":"servicenow_change_request_updated","name":"ServiceNow Change Request Updated","description":"Trigger workflow when a change request is updated in ServiceNow"},{"id":"servicenow_webhook","name":"ServiceNow Webhook (All Events)","description":"Trigger workflow on any ServiceNow webhook event"}],"skills":[{"name":"create-incident","description":"File a ServiceNow incident with the right category, priority, and description.","content":"# Create Incident\\n\\nFile a new ServiceNow incident from a reported issue.\\n\\n## Steps\\n1. Use the Create Incident operation. It targets the incident table for you — do not reach for the generic Create Record operation, which makes you name the table and hand-build the field payload.\\n2. Set a clear short description, the longer description, and the category.\\n3. Set priority through impact and urgency rather than writing priority directly; ServiceNow derives priority from those two and overwrites a directly written value.\\n4. Set the caller and assignment group when they are known.\\n\\n## Output\\nReturn the created sys_id and incident number so the reporter can track it, and echo the category and the derived priority."},{"name":"triage-incidents","description":"Find the ServiceNow incidents matching a state, priority, or assignment and summarize them.","content":"# Triage Incidents\\n\\nPull the incidents that need attention and summarize them.\\n\\n## Steps\\n1. Use the List Incidents operation with the filters it exposes — state, priority, assignment group, or an encoded query for anything else. Reserve the generic Read Records operation for tables that have no semantic operation of their own.\\n2. Always set the limit. Nothing sends one for you, and the ServiceNow Table API falls back to its own default of 10,000 records, so an unset limit pulls far more than you will read.\\n3. Keep the display-value setting at \\"all\\" so reference fields come back with both their sys_id and a human-readable label.\\n4. Read a single incident in full with Get Incident once you have picked one out.\\n\\n## Output\\nSummarize the matched incidents by number, short description, state, and priority, and say how many matched."},{"name":"progress-incident","description":"Move a ServiceNow incident forward — comment on it, update fields, resolve it, or close it.","content":"# Progress an Incident\\n\\nAdvance an incident once work has happened on it.\\n\\n## Steps\\n1. Identify the incident by number or sys_id, from List Incidents or from the trigger payload.\\n2. Pick the operation that matches the action: Add Incident Comment for a note, Update Incident for field changes, Resolve Incident when a fix is in place, Close Incident to finish it.\\n3. Resolve Incident requires a close code and close notes — ServiceNow rejects a resolution without them.\\n4. When commenting, choose the journal field deliberately: work notes are internal, additional comments are visible to the caller.\\n\\n## Output\\nConfirm the incident number, which operation ran, and the resulting state so the update is auditable."},{"name":"manage-change-request","description":"Raise a ServiceNow change request and drive it through its approval state machine.","content":"# Manage a Change Request\\n\\nRaise a change and move it through its lifecycle.\\n\\n## Steps\\n1. Use Create Change Request, choosing the type — normal, standard, or emergency — that matches the risk. Standard changes are pre-approved; emergency changes skip the usual review.\\n2. Use Update Change Request for field edits such as the plans, schedule, or assignment group.\\n3. Do not write the state field directly. Call Get Change Next States first to learn which transitions the state machine currently permits, then Move Change State to take one — the machine rejects a transition whose conditions have not been met, and the error will not say which condition failed.\\n4. Use List Change Tasks to see the work items under the change.\\n\\n## Output\\nReport the change number, its current state, and the transitions that are still available from here."},{"name":"order-catalog-item","description":"Order a ServiceNow catalog item and track the requested item it produces.","content":"# Order a Catalog Item\\n\\nSubmit a service catalog request on behalf of a requester.\\n\\n## Steps\\n1. Use List Catalog Items to find the item and its sys_id; ordering needs the sys_id, not the display name.\\n2. Use Order Catalog Item with that sys_id, the quantity, and the item variables. Variables are item-specific — read them off the catalog item rather than assuming a shape.\\n3. Track the result with List Requested Items or Get Requested Item, which is where the fulfillment state lives.\\n\\n## Output\\nReturn the request number, the requested-item number, and the current fulfillment state."},{"name":"handle-approvals","description":"Find pending ServiceNow approvals and record an approve or reject decision.","content":"# Handle Approvals\\n\\nWork the approval queue.\\n\\n## Steps\\n1. Use List Approvals filtered by state. The pending state is `requested`; the state values are not uniformly punctuated — `not requested` has a space while `not_required` has an underscore — so pick from the offered list instead of typing one.\\n2. Read what is being approved before deciding. The approval record points at a source record; fetch it with Get Change Request or Get Requested Item.\\n3. Use Approve or Reject to record the decision. Only those two are writable here — every other approval state is set by the approval engine, not by an approver.\\n4. Include a comment explaining the decision when the process expects a justification.\\n\\n## Output\\nConfirm which approval record was acted on, the decision recorded, and what it unblocks."},{"name":"investigate-cmdb","description":"Look up a ServiceNow configuration item and map what it depends on and what depends on it.","content":"# Investigate the CMDB\\n\\nEstablish blast radius before a change or during an incident.\\n\\n## Steps\\n1. Use Search Configuration Items to locate the CI by name or class, then Get Configuration Item for its full record.\\n2. Use List CI Relationships to walk the dependency graph. Choose the direction deliberately: parents are what this CI depends on, children are what depends on it, and impact analysis usually wants the children.\\n3. Follow the graph outward one hop at a time rather than pulling everything at once — CMDB relationship sets grow quickly.\\n\\n## Output\\nName the CI, its class and operational status, and list the dependent CIs a change to it would affect."},{"name":"search-knowledge","description":"Search the ServiceNow knowledge base for an existing fix before escalating.","content":"# Search Knowledge\\n\\nCheck whether a documented fix already exists.\\n\\n## Steps\\n1. Use Search Knowledge with the wording the reporter used; the search runs over article text, so their own phrasing usually matches better than a normalized restatement.\\n2. Use Get Knowledge Article to pull the full body of a promising hit — the search result carries only a snippet.\\n3. Prefer this before Create Incident when the issue looks routine; a linked article often resolves it outright.\\n\\n## Output\\nCite the article number and title, summarize the fix, and say plainly if nothing relevant was found so the caller escalates instead of guessing."}],"templates":[{"title":"JSM-to-ServiceNow bridge","prompt":"Create a workflow that mirrors Jira Service Management incident requests into ServiceNow incident records and vice versa, keeping status, assignment, and comments in sync so teams on either side see the same truth.","integrations":[{"id":"servicenow","name":"ServiceNow"},{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"ServiceNow incident commander","prompt":"Build a workflow triggered when a ServiceNow incident is created at P1 or P2 that opens a Slack war-room channel, posts the incident description and impacted CI, invites the assignment group, and keeps the channel topic in sync with the incident state.","integrations":[{"id":"servicenow","name":"ServiceNow"},{"id":"slack","name":"Slack"}]},{"title":"ServiceNow change request analyzer","prompt":"Create a workflow that reads new ServiceNow change requests, scores risk based on affected services, blackout windows, and change history, and updates the change record with a recommended approver chain and a risk justification note.","integrations":[{"id":"servicenow","name":"ServiceNow"}]},{"title":"ServiceNow knowledge sync","prompt":"Build a scheduled workflow that pulls Confluence pages tagged for IT operations and creates or updates matching ServiceNow knowledge articles, mapping categories and authors so the knowledge base stays in sync without manual copy-paste.","integrations":[{"id":"servicenow","name":"ServiceNow"},{"id":"confluence","name":"Confluence"}]},{"title":"ServiceNow asset audit","prompt":"Create a scheduled workflow that queries the ServiceNow CMDB for assets missing owner, lifecycle, or last-discovered fields, flags stale or orphaned records in a tracking table, and opens remediation tasks against the responsible group.","integrations":[{"id":"servicenow","name":"ServiceNow"}]},{"title":"ServiceNow ticket auto-classifier","prompt":"Build a workflow triggered by new ServiceNow incidents that classifies category and subcategory, sets impact and urgency, infers the affected service from the description, and routes the ticket to the right assignment group.","integrations":[{"id":"servicenow","name":"ServiceNow"}]},{"title":"ServiceNow weekly ops digest","prompt":"Create a scheduled weekly workflow that pulls ServiceNow incident, change, and request data, calculates MTTR, change success rate, and top failing services, and posts a digest to Slack with the standout records linked.","integrations":[{"id":"servicenow","name":"ServiceNow"},{"id":"slack","name":"Slack"}]},{"title":"ServiceNow ticket deflection bot","prompt":"Build a Slack bot that lets employees report IT issues in natural language, reads similar resolved ServiceNow records to suggest a fix first, and only creates a new ServiceNow incident record with the right category when self-service does not resolve it.","integrations":[{"id":"servicenow","name":"ServiceNow"},{"id":"slack","name":"Slack"}]}]},{"id":"sftp","type":"sftp_v2","slug":"sftp","name":"SFTP","description":"Transfer files via SFTP (SSH File Transfer Protocol)","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/sftp","authType":"api-key","connections":[],"operations":[{"name":"Upload Files","description":"Upload files to a remote SFTP server"},{"name":"Create File","description":""},{"name":"Download File","description":"Download a file from a remote SFTP server"},{"name":"List Directory","description":"List files and directories on a remote SFTP server"},{"name":"Delete File/Directory","description":"Delete a file or directory on a remote SFTP server"},{"name":"Create Directory","description":"Create a directory on a remote SFTP server"}],"triggers":[],"skills":[{"name":"pull-remote-drop-folder","description":"Poll a remote SFTP drop folder on a schedule and ingest any new files.","content":"# Pull Remote Drop Folder\\n\\nPeriodically fetch newly arrived files from a remote SFTP directory into a workflow.\\n\\n## Steps\\n1. Use the List Directory operation to read the remote drop folder and inspect `entries`.\\n2. Filter for files newer than the last processed timestamp.\\n3. For each new file, use the Download File operation and read `file`.\\n4. Pass the file to downstream blocks for parsing.\\n\\n## Output\\nNew remote files are downloaded and available for processing each run."},{"name":"push-report-to-partner","description":"Upload a generated report to a partner SFTP server under a dated path.","content":"# Push Report To Partner\\n\\nDeliver a generated file to an external partner over SFTP.\\n\\n## Steps\\n1. Produce the report file in an earlier block.\\n2. Use the Upload Files operation with the partner `remotePath` (e.g. `/outbound/2026-07-01/`).\\n3. Enable overwrite only if same-day re-delivery is expected.\\n4. Confirm delivery from `uploadedFiles`.\\n\\n## Output\\nThe report lands on the partner SFTP server at the intended remote path."},{"name":"archive-and-cleanup","description":"Download aging remote files to archive them, then delete the originals.","content":"# Archive And Cleanup\\n\\nKeep a remote SFTP directory tidy by archiving and removing old files.\\n\\n## Steps\\n1. List the target directory and identify files past the retention window.\\n2. Download each stale file to archive it elsewhere.\\n3. Use the Delete File/Directory operation to remove the original and check `deletedPath`.\\n4. Schedule the workflow to run nightly.\\n\\n## Output\\nAging files are preserved in an archive and cleared from the live remote directory."},{"name":"remote-directory-inventory","description":"Capture a detailed listing of a remote SFTP directory for auditing.","content":"# Remote Directory Inventory\\n\\nRecord what currently exists in a remote SFTP path.\\n\\n## Steps\\n1. Use the List Directory operation with detailed info enabled.\\n2. Read `entries` for names, sizes, and timestamps.\\n3. Store the inventory in a table or log for auditing.\\n\\n## Output\\nA point-in-time inventory of the remote directory is captured."}],"templates":[{"title":"Pull new files from an SFTP folder","prompt":"Build a workflow that runs on a schedule, lists a remote SFTP drop folder, downloads any new files, and passes their contents into the workflow for processing.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Push a generated report to a partner SFTP","prompt":"Build a workflow that generates a report file and uploads it to a partner SFTP server under a dated remote path.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Mirror a local export to SFTP","prompt":"Build a workflow that lists a remote SFTP directory, compares it to the files produced by an earlier block, and uploads any missing files to keep the remote directory in sync.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Archive and delete old SFTP files","prompt":"Build a workflow that runs nightly, lists an SFTP directory, downloads files older than a threshold to archive them, and then deletes the originals from the remote server.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Notify Slack when new files land on SFTP","prompt":"Build a workflow that checks an SFTP inbox folder on a schedule and sends a Slack message listing any new files that have arrived since the last run.","integrations":[{"id":"sftp","name":"SFTP"},{"id":"slack","name":"Slack"}]},{"title":"Inventory an SFTP directory","prompt":"Build a workflow that lists a remote SFTP directory with detailed metadata and records the file names, sizes, and timestamps for auditing.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Write a manifest file to SFTP","prompt":"Build a workflow that assembles a manifest of processed records and creates a manifest.txt file on a remote SFTP path so downstream systems know the batch is ready.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Download an SFTP file and summarize it","prompt":"Build a workflow that downloads a file from an SFTP server and passes its contents to an agent that summarizes the key points.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Pull new files from an SFTP folder","prompt":"Build a workflow that runs on a schedule, lists a remote SFTP drop folder, downloads any new files, and passes their contents into the workflow for processing.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Push a generated report to a partner SFTP","prompt":"Build a workflow that generates a report file and uploads it to a partner SFTP server under a dated remote path.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Mirror a local export to SFTP","prompt":"Build a workflow that lists a remote SFTP directory, compares it to the files produced by an earlier block, and uploads any missing files to keep the remote directory in sync.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Archive and delete old SFTP files","prompt":"Build a workflow that runs nightly, lists an SFTP directory, downloads files older than a threshold to archive them, and then deletes the originals from the remote server.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Notify Slack when new files land on SFTP","prompt":"Build a workflow that checks an SFTP inbox folder on a schedule and sends a Slack message listing any new files that have arrived since the last run.","integrations":[{"id":"sftp","name":"SFTP"},{"id":"slack","name":"Slack"}]},{"title":"Inventory an SFTP directory","prompt":"Build a workflow that lists a remote SFTP directory with detailed metadata and records the file names, sizes, and timestamps for auditing.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Write a manifest file to SFTP","prompt":"Build a workflow that assembles a manifest of processed records and creates a manifest.txt file on a remote SFTP path so downstream systems know the batch is ready.","integrations":[{"id":"sftp","name":"SFTP"}]},{"title":"Download an SFTP file and summarize it","prompt":"Build a workflow that downloads a file from an SFTP server and passes its contents to an agent that summarizes the key points.","integrations":[{"id":"sftp","name":"SFTP"}]}]},{"id":"sharepoint","type":"sharepoint_v2","slug":"sharepoint","name":"SharePoint","description":"Work with pages and lists","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/sharepoint","authType":"oauth","connections":[{"id":"sharepoint","kind":"oauth","label":"Connect with OAuth","providerId":"sharepoint","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/sharepoint","requiredScopes":[{"id":"openid","label":"Standard authentication"},{"id":"profile","label":"Access profile information"},{"id":"email","label":"Access email address"},{"id":"Sites.Read.All","label":"Read documents and list items in all SharePoint sites"},{"id":"Sites.ReadWrite.All","label":"Create, edit, and delete documents and list items in all SharePoint sites"},{"id":"Sites.Manage.All","label":"Create and delete lists and document libraries in all SharePoint sites"},{"id":"offline_access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Create Page","description":"Create a new page in a SharePoint site"},{"name":"Read Page","description":"Read a specific page from a SharePoint site"},{"name":"Update Page","description":"Update the title and/or content of a SharePoint page"},{"name":"Publish Page","description":"Publish the latest version of a SharePoint page, making it available to all users"},{"name":"Delete Page","description":"Delete a page from a SharePoint site"},{"name":"List Sites","description":"List details of all SharePoint sites"},{"name":"Create List","description":"Create a new list in a SharePoint site"},{"name":"Read List","description":"Get metadata (and optionally columns/items) for a SharePoint list"},{"name":"Update List Item","description":"Update the properties (fields) on a SharePoint list item"},{"name":"Add List Item","description":"Add a new item to a SharePoint list"},{"name":"Get List Item","description":"Get a single item (with field values) from a SharePoint list"},{"name":"Delete List Item","description":"Delete an item from a SharePoint list"},{"name":"Upload File","description":"Upload files to a SharePoint document library"},{"name":"Download File","description":"Download a file from a SharePoint document library"},{"name":"Get Drive Item","description":"Get metadata for a file or folder in a SharePoint document library"},{"name":"Delete File","description":"Delete a file (or folder) from a SharePoint document library"}],"triggers":[],"skills":[{"name":"publish-site-page","description":"Create a new SharePoint page on a site with a title and content body.","content":"# Publish Site Page\\n\\nCreate a new page on a SharePoint site, for example an announcement or knowledge article.\\n\\n## Steps\\n1. Run List Sites to find the target site and note its identifier.\\n2. Run Create Page on that site with a clear title and the page content body.\\n3. Optionally run Read Page afterward to confirm the page was created as intended.\\n\\n## Output\\nReturn the created page title and its URL or identifier so the page can be shared."},{"name":"append-list-items","description":"Add rows to a SharePoint list, creating the list first if it does not yet exist.","content":"# Append List Items\\n\\nWrite structured rows into a SharePoint list.\\n\\n## Steps\\n1. Run List Sites to locate the site, then Read List to confirm the target list and its column schema.\\n2. If the list does not exist, run Create List with the needed columns.\\n3. Run Add List Items with the field values mapped to the list columns.\\n\\n## Output\\nReturn the list name and the number of items added, and confirm the field values matched the list schema."},{"name":"read-list-data","description":"Read items from a SharePoint list and summarize the rows for downstream use.","content":"# Read List Data\\n\\nPull the contents of a SharePoint list into the workflow.\\n\\n## Steps\\n1. Run List Sites to find the site, then Read List against the target list.\\n2. Inspect the returned items and their column values.\\n3. Filter or summarize the rows as needed for the task.\\n\\n## Output\\nReturn the list items with their relevant column values and a count of rows read."},{"name":"upload-file-to-site","description":"Upload a file to a SharePoint site document library from a previous block.","content":"# Upload File to Site\\n\\nStore a file in a SharePoint document library.\\n\\n## Steps\\n1. Run List Sites to identify the destination site.\\n2. Provide the file from a previous block and run Upload File to the target site library.\\n3. Confirm the upload completed.\\n\\n## Output\\nReturn the uploaded file name and its location on the SharePoint site."}],"templates":[{"title":"Excel invoice generator","prompt":"Create a workflow that reads a sales orders table, populates an existing Microsoft Excel invoice worksheet per order, and posts the workbook link for finance review.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Excel + SharePoint forecast hub","prompt":"Create a workflow that aggregates regional forecasts submitted in Microsoft Excel files on SharePoint, normalizes formats, and writes a consolidated forecast table for leadership.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_excel","name":"Microsoft Excel"}]},{"title":"Microsoft Planner retrospective","prompt":"Build a scheduled workflow that runs at the end of a sprint, pulls completed Microsoft Planner tasks, summarizes wins and patterns, and writes the retro doc to a SharePoint page.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_planner","name":"Microsoft Planner"}]},{"title":"Word document knowledge sync","prompt":"Build a scheduled workflow that lists Word documents in a SharePoint library, reads each one, and syncs the extracted text into a knowledge base for retrieval.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_word","name":"Microsoft Word"}]},{"title":"OneDrive backup verifier","prompt":"Build a scheduled workflow that verifies OneDrive backups by sampling files and comparing checksums against the originating SharePoint copy, writing the report to an SRE table.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"onedrive","name":"OneDrive"}]},{"title":"SharePoint policy publisher","prompt":"Build a workflow that turns a Google Docs policy update into a published SharePoint page, posts the change diff to the policies team in Microsoft Teams, and writes the version history.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"google_docs","name":"Google Docs"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SharePoint stale-page sweeper","prompt":"Create a scheduled workflow that lists SharePoint pages not updated in 180 days, opens an owner-review thread in Teams, and archives pages once the owner approves.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SharePoint knowledge agent","prompt":"Build an agent that indexes SharePoint sites into a knowledge base, answers internal questions with cited links, and deploys as a Teams chat endpoint.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SharePoint external-share audit","prompt":"Create a scheduled workflow that audits SharePoint external sharing, flags items above the sensitivity threshold, and posts a security report to Teams compliance channel.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SharePoint onboarding hub","prompt":"Build a workflow triggered by a new hire in Workday that creates a personalized SharePoint onboarding hub with role-relevant docs and shares it with the hire and their manager.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"workday","name":"Workday"}]},{"title":"SharePoint search-relevance auditor","prompt":"Create a scheduled workflow that runs benchmark queries against SharePoint search weekly, scores the top result relevance, and writes a quality report to Teams.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"SharePoint to Confluence migrator","prompt":"Build a workflow that imports SharePoint pages into Confluence under matching spaces, preserves attachments, and writes a mapping table so links can be redirected.","integrations":[{"id":"sharepoint","name":"SharePoint"},{"id":"confluence","name":"Confluence"}]}]},{"id":"shopify","type":"shopify","slug":"shopify","name":"Shopify","description":"Manage products, orders, customers, and inventory in your Shopify store","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/shopify","authType":"oauth","connections":[{"id":"shopify","kind":"oauth","label":"Connect with OAuth","providerId":"shopify","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/shopify","requiredScopes":[{"id":"write_products","label":"Read and manage Shopify products"},{"id":"write_orders","label":"Read and manage Shopify orders"},{"id":"write_customers","label":"Read and manage Shopify customers"},{"id":"write_inventory","label":"Read and manage Shopify inventory levels"},{"id":"read_locations","label":"View store locations"},{"id":"write_merchant_managed_fulfillment_orders","label":"Read and fulfill orders assigned to merchant-managed locations"}],"fields":[]},{"id":"shopify-service-account","kind":"service_account","providerId":"shopify-service-account","label":"Add admin API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/shopify-service-account","fields":[{"id":"apiToken","label":"Admin API access token","placeholder":"shpat_...","secret":true,"hint":"Shopify Admin API access tokens usually start with shpat_."},{"id":"domain","label":"Store domain","placeholder":"your-store.myshopify.com","secret":false,"hint":"Shopify store domains look like your-store.myshopify.com."}]}],"operations":[{"name":"Create Product","description":"Create a new product in your Shopify store"},{"name":"Get Product","description":"Get a single product by ID from your Shopify store"},{"name":"List Products","description":"List products from your Shopify store with optional filtering"},{"name":"Update Product","description":"Update an existing product in your Shopify store"},{"name":"Delete Product","description":"Delete a product from your Shopify store"},{"name":"Get Order","description":"Get a single order by ID from your Shopify store"},{"name":"List Orders","description":"List orders from your Shopify store with optional filtering"},{"name":"Update Order","description":"Update an existing order in your Shopify store (note, tags, email)"},{"name":"Cancel Order","description":"Cancel an order in your Shopify store"},{"name":"Create Customer","description":"Create a new customer in your Shopify store"},{"name":"Get Customer","description":"Get a single customer by ID from your Shopify store"},{"name":"List Customers","description":"List customers from your Shopify store with optional filtering"},{"name":"Update Customer","description":"Update an existing customer in your Shopify store"},{"name":"Delete Customer","description":"Delete a customer from your Shopify store"},{"name":"List Inventory Items","description":"List inventory items from your Shopify store. Use this to find inventory item IDs by SKU."},{"name":"Get Inventory Level","description":"Get inventory level for a product variant at a specific location"},{"name":"Adjust Inventory","description":"Adjust inventory quantity for a product variant at a specific location"},{"name":"List Locations","description":"List inventory locations from your Shopify store. Use this to find location IDs needed for inventory operations."},{"name":"Create Fulfillment","description":"Create a fulfillment to mark order items as shipped. Requires a fulfillment order ID (use List Fulfillment Orders to find it)."},{"name":"List Collections","description":"List product collections from your Shopify store. Filter by title, type (custom/smart), or handle."},{"name":"List Fulfillment Orders","description":"Find fulfillment order IDs and remaining items for an order at merchant-managed locations"},{"name":"Get Fulfillment Order","description":"Read a fulfillment order and one page of line items for partial fulfillment"},{"name":"Get Job","description":"Read Shopify job progress or the outcome and errors of an order cancellation"},{"name":"Create Product Variants","description":"Create product variants with pricing, options, inventory attributes, and metafields"},{"name":"Update Product Variants","description":"Update product variants with pricing, options, inventory attributes, and metafields"},{"name":"Get Fulfillment","description":"Read shipment tracking and one page of fulfilled line items"},{"name":"Update Fulfillment Tracking","description":"Update tracking numbers, URLs, or carrier for an existing fulfillment"},{"name":"Get Collection","description":"Get a specific collection by ID, including its products. Use this to retrieve products within a collection."}],"triggers":[],"skills":[{"name":"create-product-listing","description":"Create a Shopify product and add variants with pricing.","content":"# Create Product Listing\\n\\nAdd a new product to the Shopify store.\\n\\n## Steps\\n1. Run Create Product with the title, body description, vendor, and product type.\\n2. Set status to draft while preparing the listing and run Create Product Variants to add options and prices. Active status alone does not publish a product to sales channels.\\n3. Verify with Get Product on the returned product ID.\\n\\n## Output\\nReturn the new product ID, title, and status, and confirm the listing was created as draft or active as intended."},{"name":"process-recent-orders","description":"List recent Shopify orders and summarize them by status, value, or fulfillment need.","content":"# Process Recent Orders\\n\\nReview the latest orders to triage fulfillment and flag anything unusual.\\n\\n## Steps\\n1. Run List Orders filtered by status (open, closed, cancelled, or any) and a recent time window.\\n2. For orders needing detail, run Get Order to read line items, customer, and shipping address.\\n3. Group orders by fulfillment status and total value.\\n\\n## Output\\nReturn a summary of recent orders with their order numbers, totals, and status, highlighting any that need immediate fulfillment or review."},{"name":"fulfill-order","description":"Create a fulfillment for a Shopify order and update its status.","content":"# Fulfill Order\\n\\nMark an order as fulfilled once it has shipped.\\n\\n## Steps\\n1. Run Get Order to confirm the order, then List Fulfillment Orders to find the fulfillment order ID and assigned location.\\n2. Use Get Fulfillment Order to page through remaining items. Run Create Fulfillment with its fulfillment order ID, optional item IDs and quantities, and tracking details.\\n3. Optionally run Update Order to record any notes.\\n\\n## Output\\nConfirm the order number, the fulfillment created, and any tracking number supplied."},{"name":"adjust-inventory","description":"Check and adjust Shopify inventory levels for an item at a location.","content":"# Adjust Inventory\\n\\nReconcile stock levels for an inventory item.\\n\\n## Steps\\n1. Run List Inventory Items and List Locations to identify the item and the location.\\n2. Run Get Inventory Level to read the current available quantity.\\n3. Run Adjust Inventory with the delta and expected current quantity. Reuse the idempotency key when retrying the same adjustment.\\n\\n## Output\\nReport the inventory item, the location, the previous and new quantities, and the adjustment applied."},{"name":"manage-customer-record","description":"Create, look up, or update a Shopify customer record.","content":"# Manage Customer Record\\n\\nMaintain a customer profile in Shopify.\\n\\n## Steps\\n1. To find an existing customer, run List Customers with a filter or Get Customer by ID.\\n2. To add a new one, run Create Customer with name, email, and any tags.\\n3. To change details, run Update Customer with only the fields to modify.\\n\\n## Output\\nReturn the customer ID, name, and email, and note whether the record was created, found, or updated."},{"name":"update-variant-prices","description":"Update prices for selected variants without changing other product details.","content":"# Update Variant Prices\\n\\nMaintain product pricing in Shopify.\\n\\n## Steps\\n1. Run Get Product and follow variant cursors to find the target variant IDs.\\n2. Run Update Product Variants with each ID, price, and optional compareAtPrice.\\n3. Check userErrors and read the affected variants again.\\n\\n## Output\\nReturn updated variant IDs, prices, and any rejected changes."},{"name":"correct-shipment-tracking","description":"Correct carrier or tracking information on an existing fulfillment.","content":"# Correct Shipment Tracking\\n\\nKeep shipment references current.\\n\\n## Steps\\n1. Run Get Order to find the fulfillment ID, then Get Fulfillment to read its tracking information.\\n2. Run Update Fulfillment Tracking with the corrected carrier, number, or URL.\\n3. Enable customer notification only when requested.\\n\\n## Output\\nReturn the fulfillment ID and the confirmed tracking information."}],"templates":[{"title":"Google Sheets inventory sync","prompt":"Build a workflow that pulls Shopify inventory into Google Sheets hourly, calculates days-of-cover, and highlights items needing reorder for the ops team.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Sendblue order-status notifier","prompt":"Create a workflow triggered when an order ships that looks up the customer phone number and sends a Sendblue iMessage with the tracking number and estimated delivery date.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"sendblue","name":"Sendblue"}]},{"title":"Shopify order monitor","prompt":"Build a workflow that monitors Shopify orders, flags high-value or unusual orders for review, tracks fulfillment status in a table, and sends daily inventory and sales summaries to Slack with restock alerts when items run low.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"slack","name":"Slack"}]},{"title":"Shopify unpaid order recovery","prompt":"Build a scheduled workflow that lists Shopify orders left open and unpaid in the past day, drafts a personalized recovery email referencing the items, and sends it via Gmail while logging recovery attempts to a table.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"gmail","name":"Gmail"}]},{"title":"Shopify restock alerter","prompt":"Create a scheduled hourly workflow that lists Shopify inventory items, computes days-of-cover from recent sales velocity, flags SKUs below a configurable threshold, and posts a Slack alert to the operations channel with the variant, location, and recommended reorder quantity.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"slack","name":"Slack"}]},{"title":"Shopify VIP segmenter","prompt":"Build a scheduled weekly workflow that pulls Shopify customers, uses amount spent and lifetime order count to group them into VIP and regular cohorts in a tracking table, and emails the marketing team via Gmail with a list of new VIPs to nurture.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"gmail","name":"Gmail"}]},{"title":"Shopify fulfillment tracker","prompt":"Create a scheduled workflow that lists Shopify orders and their fulfillment status, updates a status table with fulfillment status and tracking links, and proactively emails customers when their order misses an SLA so support gets ahead of the inquiry.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"gmail","name":"Gmail"}]},{"title":"Shopify product launcher","prompt":"Build a workflow that takes a new product brief, creates a draft product in Shopify, creates its variants with pricing, adds it to a collection using Collections To Join, drafts a launch announcement, and sends a Slack and Gmail draft announcement for marketing review. Publish to sales channels in Shopify after approval.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Shopify order anomaly detector","prompt":"Create a scheduled workflow that runs every fifteen minutes, lists recent Shopify orders, scores each for anomalies — high value, unusual destination, mismatched billing — flags suspects in a review queue table, and Slacks the operations team for hands-on inspection.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"slack","name":"Slack"}]},{"title":"Twilio order-status notifier","prompt":"Create a workflow triggered when an order ships that looks up the customer’s phone number and sends a Twilio SMS with the tracking number and estimated delivery date.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Webflow product catalog sync","prompt":"Create a scheduled workflow that mirrors Shopify products and pricing into a Webflow CMS product collection, keeps both in sync, and posts conflict alerts to Slack.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"webflow","name":"Webflow"},{"id":"slack","name":"Slack"}]},{"title":"WhatsApp order tracking","prompt":"Create a workflow that watches Shopify shipment events and sends customers a WhatsApp message with the tracking number, ETA, and a follow-up review request after delivery.","integrations":[{"id":"shopify","name":"Shopify"},{"id":"whatsapp","name":"WhatsApp"}]}]},{"id":"similarweb","type":"similarweb","slug":"similarweb","name":"Similarweb","description":"Website traffic and analytics data","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/similarweb","authType":"api-key","connections":[],"operations":[{"name":"Website Overview","description":"Get website traffic, rankings, engagement, and traffic sources."},{"name":"Traffic Visits","description":"Get total website visits over time (desktop and mobile combined)"},{"name":"Bounce Rate","description":"Get website bounce rate over time (desktop and mobile combined)"},{"name":"Pages Per Visit","description":"Get average pages per visit over time (desktop and mobile combined)"},{"name":"Visit Duration (Desktop)","description":"Get average desktop visit duration over time (in seconds)"},{"name":"Page Views","description":"Get total page views over time (desktop and mobile combined)"}],"triggers":[],"skills":[{"name":"profile-website-traffic","description":"Pull a Similarweb website overview and traffic metrics for a domain and summarize its scale.","content":"# Profile Website Traffic\\n\\nBuild a quick traffic profile for a single domain.\\n\\n## Steps\\n1. Run Website Overview for the domain to get a high-level snapshot.\\n2. Run Traffic Visits, Bounce Rate, Pages Per Visit, and Visit Duration for deeper engagement metrics, setting the country (or worldwide) to scope the data.\\n3. Interpret the numbers together: high visits with a low bounce rate and long duration indicates strong engagement.\\n\\n## Output\\nReturn a concise profile of the domain: estimated monthly visits, bounce rate, pages per visit, and average visit duration, with a one-line read on overall traffic health."},{"name":"compare-competitor-domains","description":"Pull Similarweb traffic metrics for several domains and rank them for a competitive view.","content":"# Compare Competitor Domains\\n\\nBenchmark a set of competing domains on traffic and engagement.\\n\\n## Steps\\n1. For each domain, run Website Overview and Traffic Visits using the same country scope so the numbers are comparable.\\n2. Optionally add Bounce Rate and Pages Per Visit for an engagement dimension.\\n3. Rank the domains by visits and engagement.\\n\\n## Output\\nReturn a ranked table of the domains with their visits, bounce rate, and engagement metrics, and a short read on which competitor leads."},{"name":"score-prospect-domains","description":"Score a list of prospect domains by Similarweb traffic size to prioritize outreach.","content":"# Score Prospect Domains\\n\\nPrioritize sales prospects by the size of their web traffic.\\n\\n## Steps\\n1. For each prospect domain, run Website Overview and Traffic Visits in the relevant region.\\n2. Assign a score based on monthly visits and any visible growth trend.\\n3. Sort the prospects from highest to lowest score.\\n\\n## Output\\nReturn the prospect domains ranked by score, each with its estimated monthly visits, so the sales team can prioritize the biggest-traffic targets."}],"templates":[{"title":"Ahrefs + Similarweb growth scoreboard","prompt":"Build a scheduled monthly workflow that joins Ahrefs SEO data with Similarweb traffic intelligence, writes a growth scoreboard table, and emails leadership.","integrations":[{"id":"similarweb","name":"Similarweb"},{"id":"ahrefs","name":"Ahrefs"},{"id":"gmail","name":"Gmail"}]},{"title":"Polymarket + Similarweb event volume tracker","prompt":"Create a workflow that overlays Polymarket market activity with Similarweb traffic for the involved entities, identifies volume-driving news, and writes the analysis.","integrations":[{"id":"similarweb","name":"Similarweb"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Similarweb traffic intelligence","prompt":"Build a scheduled workflow that pulls Similarweb traffic data for tracked competitor domains monthly, writes traffic, sources, and engagement to a tables-based scoreboard, and flags step changes in Slack.","integrations":[{"id":"similarweb","name":"Similarweb"},{"id":"slack","name":"Slack"}]},{"title":"Similarweb account intel sync","prompt":"Create a workflow that watches my CRM for new accounts, pulls Similarweb data on each account domain, writes traffic estimates, rankings, and engagement signals back to the account record for sales context.","integrations":[{"id":"similarweb","name":"Similarweb"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Similarweb category benchmarking","prompt":"Create a scheduled workflow that pulls Similarweb category rank, visit duration, and bounce rate for my domain and a set of tracked competitors, then writes a ranked benchmarking table for the marketing review.","integrations":[{"id":"similarweb","name":"Similarweb"}]},{"title":"Similarweb funnel-source analyzer","prompt":"Build a scheduled workflow that pulls Similarweb traffic-source data for my domain and competitors, surfaces shifting acquisition channels, and writes the analysis to a marketing table.","integrations":[{"id":"similarweb","name":"Similarweb"}]},{"title":"Similarweb traffic-source overlap finder","prompt":"Create a scheduled workflow that pulls Similarweb traffic-source breakdowns for my domain and tracked competitors, identifies channels where competitors over-index, and writes an acquisition opportunity table.","integrations":[{"id":"similarweb","name":"Similarweb"}]},{"title":"Similarweb engagement scorecard","prompt":"Build a scheduled workflow that pulls Similarweb bounce rate, pages per visit, and average visit duration for my domain and key competitors, writes the engagement metrics to a table, and posts a Slack scorecard highlighting where my site under- or over-performs the set.","integrations":[{"id":"similarweb","name":"Similarweb"},{"id":"slack","name":"Slack"}]},{"title":"Similarweb prospect prioritizer","prompt":"Create a workflow that reads a list of target company domains from a table, pulls each domain\'s Similarweb website overview and monthly visits, scores them by traffic size and growth, and writes a prioritized outbound list for the sales team.","integrations":[{"id":"similarweb","name":"Similarweb"}]}]},{"id":"sixtyfour","type":"sixtyfour","slug":"sixtyfour-ai","name":"Sixtyfour AI","description":"Enrich leads and companies with AI-powered research","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/sixtyfour","authType":"api-key","connections":[],"operations":[{"name":"Find Phone","description":"Find phone numbers for a lead using Sixtyfour AI."},{"name":"Find Email","description":"Find email addresses for a lead using Sixtyfour AI."},{"name":"Enrich Lead","description":"Enrich lead information with contact details, social profiles, and company data using Sixtyfour AI."},{"name":"Enrich Company","description":"Enrich company data with additional information and find associated people using Sixtyfour AI."}],"triggers":[],"skills":[{"name":"enrich-lead","description":"Enrich a single lead with Sixtyfour AI research to fill in role, company, and contact context.","content":"# Enrich Lead\\n\\nTurn a thin lead record into a researched profile.\\n\\n## Steps\\n1. Run Enrich Lead with whatever you know about the person: name, company, email, or LinkedIn.\\n2. Request only the fields you need to keep credit usage down.\\n3. Review the returned profile: title, seniority, company, and any social or contact data.\\n\\n## Output\\nReturn the enriched lead profile with the discovered role, company, and context, and note any fields the research could not resolve."},{"name":"find-contact-details","description":"Find a verified email or phone number for a prospect using Sixtyfour AI.","content":"# Find Contact Details\\n\\nLocate a reachable email or phone number for a prospect.\\n\\n## Steps\\n1. Provide the person identity you have: name plus company or domain.\\n2. Run Find Email to discover a work email, or Find Phone for a phone number. Choose the professional or personal type as appropriate.\\n3. Validate that the result matches the intended person before using it.\\n\\n## Output\\nReturn the discovered email or phone number with its type, and clearly state if no verified contact could be found."},{"name":"enrich-company","description":"Research a company with Sixtyfour AI to build a firmographic and account-context profile.","content":"# Enrich Company\\n\\nBuild an account profile for a target company.\\n\\n## Steps\\n1. Run Enrich Company with the company name or domain.\\n2. Request the firmographic fields you need: industry, size, location, funding, and technologies in use.\\n3. Use the result to qualify the account against your ideal customer profile.\\n\\n## Output\\nReturn the company profile with industry, size, location, and notable signals, plus a short note on how well it fits the target profile."}],"templates":[{"title":"Sixtyfour contact researcher","prompt":"Build a workflow that runs Sixtyfour AI on inbound leads, enriches with deep research-grade signals, and writes a research brief into the CRM contact record.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Sixtyfour account intelligence","prompt":"Create a workflow that for tracked accounts runs Sixtyfour deep research weekly, surfaces new signals, and writes the digest into a research table.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Sixtyfour outbound briefer","prompt":"Build a workflow that runs Sixtyfour on a prospect, generates a tailored outreach brief with hooks, and queues it for the rep to send via Email Bison.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Sixtyfour event-attendee researcher","prompt":"Create a workflow that takes a Luma event attendee list, runs Sixtyfour deep research per attendee, and writes per-person briefs for the sales team.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"luma","name":"Luma"}]},{"title":"Sixtyfour competitor-intel digest","prompt":"Build a scheduled weekly workflow that runs Sixtyfour deep research on competitors and writes a competitive-intel digest to a Slack channel.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"slack","name":"Slack"}]},{"title":"Sixtyfour CRM enricher","prompt":"Create a scheduled workflow that finds CRM accounts missing deep-research signals, runs Sixtyfour, and writes the structured findings back to the account record.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Sixtyfour deal-prep packet","prompt":"Build a workflow that runs Sixtyfour the morning of every meeting, generates a meeting-prep packet with company and attendee research, and emails the rep.","integrations":[{"id":"sixtyfour","name":"Sixtyfour AI"},{"id":"gmail","name":"Gmail"}]}]},{"id":"slack","type":"slack_v2","slug":"slack","name":"Slack","description":"Manage Slack messages, channels, users, files, Lists, canvases, and Agent Sessions","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/slack","authType":"oauth","connections":[{"id":"slack","kind":"oauth","label":"Connect with OAuth","providerId":"slack","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/slack","requiredScopes":[{"id":"channels:read","label":"View public channels"},{"id":"channels:history","label":"Read public channel messages"},{"id":"channels:manage","label":"Create, archive, and rename public channels"},{"id":"groups:read","label":"View private channels"},{"id":"groups:history","label":"Read private channel messages"},{"id":"groups:write","label":"Create, archive, and manage private channels"},{"id":"chat:write","label":"Send messages"},{"id":"chat:write.public","label":"Post to public channels without joining them"},{"id":"im:write","label":"Start direct messages"},{"id":"im:read","label":"View direct message channels"},{"id":"users:read","label":"View workspace users"},{"id":"files:write","label":"Upload, edit, and delete files"},{"id":"files:read","label":"Download and read files"},{"id":"canvases:read","label":"Read canvas sections"},{"id":"canvases:write","label":"Create, edit, and delete canvas documents"},{"id":"reactions:write","label":"Add emoji reactions to messages"},{"id":"reactions:read","label":"View emoji reactions on messages"}],"fields":[]},{"id":"slack-custom-bot","kind":"service_account","providerId":"slack-custom-bot","label":"Set up a custom bot","setup":"slack-bot","docsUrl":"https://docs.sim.ai/integrations/slack","fields":[{"id":"botToken","label":"Bot token","placeholder":"xoxb-...","secret":true},{"id":"signingSecret","label":"Signing secret","placeholder":"Paste the signing secret","secret":true}]}],"operations":[{"name":"Send Message","description":"Send messages to Slack channels or direct messages. Supports Slack mrkdwn formatting."},{"name":"Send Ephemeral Message","description":"Send an ephemeral message visible only to a specific user in a channel. Optionally reply in a thread. The message does not persist across sessions."},{"name":"Create Canvas","description":"Create and share Slack canvases in channels. Canvases are collaborative documents within Slack."},{"name":"Read Messages","description":"Read the latest messages from Slack channels. Retrieve conversation history with filtering options."},{"name":"Get Message","description":"Retrieve a specific message by its timestamp. Useful for getting a thread parent message."},{"name":"Get Thread","description":"Retrieve an entire thread including the parent message and all replies. Useful for getting full conversation context."},{"name":"Get Thread Replies","description":"Fetch every message in a Slack thread, automatically following pagination across all pages. Returns the parent message and the full set of replies."},{"name":"Get Channel History","description":"Fetch message history from a Slack channel, automatically following pagination. Optionally filter by a time range to scrape messages since a given timestamp."},{"name":"Get Message Permalink","description":"Get a stable permalink URL to a specific Slack message."},{"name":"Set Assistant Status","description":"Set or clear the assistant thread status indicator (the loading shimmer) on a Slack AI app thread. Pass an empty status to clear it."},{"name":"Set Assistant Title","description":"Set the title of a Slack assistant thread (shown in the AI app thread header)."},{"name":"Set Assistant Suggested Prompts","description":"Set the clickable suggested prompts shown in a Slack assistant thread (the prompt chips in an AI app)."},{"name":"Set Agent Suggested Prompts","description":"Set suggested prompts in Slack Agent View, optionally scoped to a specific thread."},{"name":"Set Agent Session Status","description":"Create or update the state of a Slack agent session associated with a thread."},{"name":"Rename Agent Session","description":"Rename the Slack agent session associated with a thread."},{"name":"List Channels","description":"List one page of accessible public and private Slack channels. Pass the returned nextCursor as cursor to fetch the next page."},{"name":"List Channel Members","description":"List all members (user IDs) in a Slack channel. Use with Get User Info to resolve IDs to names."},{"name":"List Users","description":"List all users in a Slack workspace. Returns user profiles with names and avatars."},{"name":"Get User Info","description":"Get detailed information about a specific Slack user by their user ID."},{"name":"Download File","description":"Download a file from Slack"},{"name":"Update Message","description":"Update a message previously sent by the bot in Slack"},{"name":"Delete Message","description":"Delete a message previously sent by the bot in Slack"},{"name":"Add Reaction","description":"Add an emoji reaction to a Slack message"},{"name":"Remove Reaction","description":"Remove an emoji reaction from a Slack message"},{"name":"Get Channel Info","description":"Get detailed information about a Slack channel by its ID"},{"name":"Get User Presence","description":"Check whether a Slack user is currently active or away"},{"name":"Edit Canvas","description":"Edit an existing Slack canvas by inserting, replacing, or deleting content"},{"name":"Create Channel Canvas","description":"Create a canvas pinned to a Slack channel as its resource hub"},{"name":"Get Canvas Info","description":"Get Slack canvas file metadata by canvas ID"},{"name":"List Canvases","description":"List Slack canvases available to the authenticated user or bot"},{"name":"Lookup Canvas Sections","description":"Find Slack canvas section IDs matching criteria for later edits"},{"name":"Delete Canvas","description":"Delete a Slack canvas by its canvas ID"},{"name":"Create List","description":"Create a Slack List with an optional column schema. Requires a paid Slack plan."},{"name":"Update List","description":"Update a Slack List name, description, or task tracking fields."},{"name":"Share List","description":"Grant users or channels access to a Slack List. Provide exactly one of userIds or channelIds. Read allows viewing, write allows editing, and owner grants ownership to users only; only a current owner can grant ownership."},{"name":"Read List Items","description":"Read a page of Slack List rows and optionally its column schema. Pass nextCursor as cursor to continue; an empty nextCursor ends pagination."},{"name":"Get List Item","description":"Read a Slack List row and its parent List column schema."},{"name":"Create List Item","description":"Create a Slack List row using real column IDs and typed cell values. Text columns require rich_text, not text."},{"name":"Update List Items","description":"Update cells across Slack List rows. Each cell requires row_id, column_id, and one typed value. Use empty arrays to clear array-valued cells, or false to clear a checkbox."},{"name":"Delete List Item","description":"Delete a row from an existing Slack List."},{"name":"Create Conversation","description":"Create a new public or private channel in a Slack workspace."},{"name":"Invite to Conversation","description":"Invite one or more users to a Slack channel. Supports up to 100 users at a time."},{"name":"Open View","description":"Open a modal view in Slack using a trigger_id from an interaction payload. Used to display forms, confirmations, and other interactive modals."},{"name":"Update View","description":"Update an existing modal view in Slack. Identify the view by view_id or external_id, and provide the updated view payload."},{"name":"Push View","description":"Push a new view onto an existing modal stack in Slack. Limited to 2 additional views after the initial modal is opened."},{"name":"Publish View","description":"Publish a static view to a user\'s Home tab in Slack. Used to create or update the app\'s Home tab experience."},{"name":"Schedule Message","description":"Schedule a message to be sent to a Slack channel or DM at a future time."},{"name":"List Scheduled Messages","description":"List pending scheduled messages in a Slack workspace, optionally filtered by channel."},{"name":"Delete Scheduled Message","description":"Delete a pending scheduled message before it posts to Slack."},{"name":"Archive Conversation","description":"Archive a Slack channel so it is closed to new activity."},{"name":"Rename Conversation","description":"Rename an existing Slack channel."},{"name":"Set Conversation Topic","description":"Set the topic for a Slack channel (max 250 characters)."},{"name":"Set Conversation Purpose","description":"Set the purpose (description) for a Slack channel (max 250 characters)."},{"name":"Revoke List Access","description":"Remove access to a Slack List for either users or channels."},{"name":"Start List Export","description":"Start an asynchronous CSV or JSON List export. Use the returned job_id with Get List Export and the same format options."},{"name":"Get List Export","description":"Read a List export job status and its download URL when ready. Format, Include Threads, and Include Attachments must match Start List Export."},{"name":"Delete List Items","description":"Delete multiple rows from a Slack List in one call."},{"name":"Share Canvas","description":"Change access for users or regular channels on a standalone canvas. For sharing, first send the canvas link in Slack to the target. Channel resource canvases cannot be changed this way."},{"name":"Revoke Canvas Access","description":"Remove user or regular-channel access to a standalone canvas. Channel-granted access must be revoked at the channel level."},{"name":"Join Conversation","description":"Join a public Slack channel as the authenticated bot."},{"name":"Leave Conversation","description":"Leave a Slack channel as the authenticated identity."},{"name":"Remove User from Conversation","description":"Remove a user from a Slack conversation, subject to workspace permissions."},{"name":"Unarchive Conversation","description":"Restore an archived Slack channel."},{"name":"Close Conversation","description":"Close a direct message or group direct message for the authenticated identity."},{"name":"Mark Conversation Read","description":"Move the authenticated identity’s read cursor to a message timestamp."},{"name":"Open Conversation","description":"Open a DM or group DM with 1–8 user IDs, or resume a conversation by ID. Supply exactly one target; omit the calling user from User IDs."},{"name":"Find User by Email","description":"Find a Slack user by their email address."},{"name":"List User Conversations","description":"List one page of conversations accessible to the selected user. Continue with response_metadata.next_cursor."},{"name":"Get User Profile","description":"Read a Slack user’s profile, status, and custom fields. Omit User ID for the authenticated identity."},{"name":"Set Bot Presence","description":"Set the selected custom bot’s presence to away or automatic. This does not change a workspace member’s presence."},{"name":"Get File Info","description":"Read Slack file metadata and one page of legacy file comments. Continue with response_metadata.next_cursor."},{"name":"List Files","description":"List one page of Slack files matching user, channel, type, or timestamp filters. Continue using paging.page and paging.pages."},{"name":"Delete File","description":"Permanently delete a Slack file the authenticated identity is allowed to delete."},{"name":"Get Reactions","description":"Get reactions for exactly one message, file, or file comment. Messages require both Channel ID and Message Timestamp."},{"name":"List Reactions","description":"List one page of items reacted to by a user. Continue with response_metadata.next_cursor."},{"name":"Pin Message","description":"Pin a message to its Slack conversation."},{"name":"Unpin Message","description":"Remove a message from its conversation’s pinned items."},{"name":"List Pins","description":"Read the pinned messages and files in a Slack conversation."},{"name":"Add Bookmark","description":"Add a link bookmark to a Slack channel."},{"name":"Edit Bookmark","description":"Change a channel link bookmark’s title, URL, or emoji."},{"name":"List Bookmarks","description":"Read the bookmarks in a Slack channel."},{"name":"Remove Bookmark","description":"Remove a bookmark from a Slack channel."},{"name":"Create User Group","description":"Create a Slack user group with a mention handle and default channels. Requires a paid plan and permission to manage user groups."},{"name":"Update User Group","description":"Change a Slack user group’s name, handle, description, or default channels. Requires permission to manage user groups."},{"name":"Enable User Group","description":"Reactivate a disabled Slack user group. Requires permission to manage user groups."},{"name":"Disable User Group","description":"Disable a Slack user group and remove its members. Requires permission to manage user groups."},{"name":"List User Groups","description":"Read Slack user groups, optionally including disabled groups, members, and member counts."},{"name":"List User Group Members","description":"Read the user IDs in a Slack user group."},{"name":"Update User Group Members","description":"Replace all members of a Slack user group with the supplied user IDs. An empty list is not supported; disable the group instead."},{"name":"Get Do Not Disturb Info","description":"Read a user’s Do Not Disturb schedule and available snooze information."},{"name":"Get Team Do Not Disturb Info","description":"Read Do Not Disturb settings for the supplied user IDs."},{"name":"List Custom Emoji","description":"List workspace custom emoji as names mapped to image URLs or alias references."},{"name":"Get Workspace Info","description":"Read a Slack workspace’s name, domain, icon, and available organization details."},{"name":"Get Workspace Profile Fields","description":"Read the workspace’s custom profile field definitions, optionally filtered by visibility."},{"name":"Unfurl Links","description":"Attach custom previews to links already shared in a message. Configure the relevant unfurl domains in your Slack app."}],"triggers":[{"id":"slack_oauth","name":"Slack","description":"Trigger from Slack events, interactions, and slash commands"}],"skills":[{"name":"daily-standup-summary","description":"Read a standup channel and post a structured recap of progress, plans, and blockers.","content":"# Daily Standup Summary\\n\\nRead the messages posted in the standup channel since the last working day and produce a concise team recap.\\n\\n## Steps\\n1. Collect every standup update in the channel from the relevant window (skip bot and off-topic messages).\\n2. Group the content into three sections:\\n - **Done** — what was completed.\\n - **Today** — what each person plans to work on.\\n - **Blockers** — anything waiting on someone else, with the owner @-mentioned.\\n3. Call out anyone who did not post an update.\\n\\n## Output\\nPost a single threaded message with the three sections as bullet lists. Keep each bullet to one line. Lead with blockers if any exist so they are not missed."},{"name":"channel-catch-up","description":"Summarize what happened in a busy Slack channel so you can catch up fast.","content":"# Channel Catch-Up\\n\\nSummarize recent activity in a Slack channel for someone who has been away.\\n\\n## Steps\\n1. Pull messages from the requested time range (default: since the user was last active, or the last 24 hours).\\n2. Cluster the conversation into topics or threads rather than listing messages chronologically.\\n3. For each topic, capture: the gist, any decision reached, and open questions still unanswered.\\n\\n## Output\\n- A 1-sentence TL;DR.\\n- A bulleted list of topics, each with **Decision:** and **Open:** lines where relevant.\\n- A final \\"Needs your input\\" list of items where the user was @-mentioned or a question is unresolved.\\nLink to the source thread for each topic."},{"name":"slack-question-responder","description":"Watch a channel for questions and draft sourced, in-thread answers from your knowledge base.","content":"# Slack Question Responder\\n\\nMonitor a support or help channel and answer incoming questions.\\n\\n## Steps\\n1. Detect when a message is a genuine question (ends in a question mark, asks \\"how/where/can someone\\", or is a help request).\\n2. Search the connected knowledge base for the answer.\\n3. If a confident answer exists, draft a concise reply in the thread with the answer and a citation/link to the source.\\n4. If no confident answer exists, do not guess — post a short note that a human should help, and @-mention the channel owner.\\n\\n## Guidance\\n- Always reply in-thread, never in the main channel.\\n- Keep answers to 2–4 sentences plus the source link.\\n- Never fabricate links or policy."},{"name":"escalate-urgent-messages","description":"Scan a channel for urgent or at-risk messages and surface them to the right owner.","content":"# Escalate Urgent Messages\\n\\nTriage a channel for messages that need fast attention.\\n\\n## Steps\\n1. Review recent messages and classify each as **Urgent**, **Today**, or **FYI** based on signals like \\"blocked\\", \\"down\\", \\"ASAP\\", customer impact, or an unanswered direct ask.\\n2. For Urgent items, identify the most likely owner from the channel topic or message context.\\n3. Skip resolved threads (those with a ✅ reaction or a clear answer).\\n\\n## Output\\nPost a short escalation summary listing only Urgent and Today items: each as a one-line description, an @-mention of the owner, and a link to the message. If nothing is urgent, say so in one line."}],"templates":[{"title":"Affinity pipeline digest","prompt":"Build a workflow that runs every Monday, pages my Affinity deal list for every row with its stage, owner, and last interaction date, and posts a Slack summary of what moved, what is stalled, and what is closing this month.","integrations":[{"id":"slack","name":"Slack"},{"id":"affinity","name":"Affinity"}]},{"title":"AgentMail thread escalation router","prompt":"Create a scheduled workflow that polls AgentMail inboxes for new messages, detects urgent or negative threads with an agent, forwards the full thread to the on-call address, and posts a Slack alert so nothing high-priority sits unanswered.","integrations":[{"id":"slack","name":"Slack"},{"id":"agentmail","name":"AgentMail"}]},{"title":"Ahrefs keyword tracker","prompt":"Create a scheduled weekly workflow that queries Ahrefs for ranking positions of my tracked keywords, logs the results into a tables-based SEO scorecard, and posts a Slack summary of gainers and losers.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs competitor backlink monitor","prompt":"Build a scheduled workflow that pulls new Ahrefs referring domains for my competitors weekly, flags high-authority links, and posts a Slack digest with the linking page and anchor text.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs organic competitor finder","prompt":"Build a monthly workflow that pulls Ahrefs organic competitors for my domain, cross-references them against my tracked competitor list, and posts newly surfaced competitors to Slack for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs + Profound combined visibility","prompt":"Create a scheduled weekly workflow that combines Ahrefs SEO rankings with Profound AI-visibility scores, writes a combined visibility report, and surfaces gaps to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"},{"id":"profound","name":"Profound"}]},{"title":"Ahrefs domain-health watchdog","prompt":"Build a scheduled workflow that checks Ahrefs domain rating and backlink stats for my site daily, logs the values to a trend table, and posts a Slack alert when domain rating drops or a spike of lost referring domains is detected.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs Rank Tracker daily digest","prompt":"Build a scheduled daily workflow that pulls the Ahrefs Rank Tracker overview for my project, has an agent summarize position and traffic movers, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Ahrefs Site Audit issue tracker","prompt":"Build a scheduled weekly workflow that pulls crawled pages from an Ahrefs Site Audit project, writes non-compliant or broken pages to a remediation table, and posts a Slack summary for the SEO lead.","integrations":[{"id":"slack","name":"Slack"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"Airtable data sync","prompt":"Create a scheduled workflow that syncs records from my Airtable base into a Sim table every hour, keeping both in sync. Use an agent to detect changes, resolve conflicts, and flag any discrepancies for review in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"airtable","name":"Airtable"}]},{"title":"Airtable two-way sync","prompt":"Build a scheduled workflow that mirrors records between an Airtable base and a Sim table, detects conflicts, and pings Slack on records that need manual resolution.","integrations":[{"id":"slack","name":"Slack"},{"id":"airtable","name":"Airtable"}]},{"title":"Airtable approval workflow","prompt":"Create a workflow that watches Airtable for new approval rows, posts a Slack message with quick-action buttons, captures the decision, and updates the row state.","integrations":[{"id":"slack","name":"Slack"},{"id":"airtable","name":"Airtable"}]},{"title":"Algolia index inventory","prompt":"Create a scheduled workflow that lists all Algolia indices and their record counts, writes a daily inventory snapshot to a table, and pings on-call in Slack when an index record count drops unexpectedly.","integrations":[{"id":"slack","name":"Slack"},{"id":"algolia","name":"Algolia"}]},{"title":"Amplitude product analytics digest","prompt":"Create a scheduled weekly workflow that pulls key product metrics from Amplitude — active users, event segmentation for top events, and revenue — generates an executive summary with week-over-week trends, and posts it to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"amplitude","name":"Amplitude"}]},{"title":"Amplitude event regression watcher","prompt":"Build a scheduled workflow that runs event segmentation on key Amplitude events every morning, compares the counts against the trailing 14-day baseline, and posts a Slack alert when any event drops more than a configurable threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"amplitude","name":"Amplitude"}]},{"title":"Amplitude revenue digest","prompt":"Build a scheduled weekly workflow that pulls Amplitude revenue data, breaks it down by week-over-week change, and posts a digest to the product Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"amplitude","name":"Amplitude"}]},{"title":"Amplitude + PostHog cross-tool dashboard","prompt":"Build a scheduled workflow that aggregates equivalent active-user and event metrics from both Amplitude and PostHog, writes a side-by-side comparison to a table, and surfaces discrepancies to the product team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"amplitude","name":"Amplitude"},{"id":"posthog","name":"PostHog"}]},{"title":"Amplitude + Hex deep-dive notebook","prompt":"Create a workflow that triggers a Hex deep-dive notebook when an Amplitude metric crosses an anomaly threshold, runs analysis, and posts the notebook output to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"amplitude","name":"Amplitude"},{"id":"hex","name":"Hex"}]},{"title":"Apify monitor digest","prompt":"Build a scheduled workflow that watches an Apify actor’s runs for failures, captures error patterns, and posts a digest to engineering Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"apify","name":"Apify"}]},{"title":"Apify ecommerce price tracker","prompt":"Create a workflow that uses Apify scrapers to capture competitor pricing daily, writes the price history to a table, and posts price-drop alerts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"apify","name":"Apify"}]},{"title":"AppConfig deployment monitor","prompt":"Build a scheduled workflow that lists in-progress AWS AppConfig deployments for an environment, gets each deployment status, and posts a Slack alert when a deployment is rolling back or has stalled.","integrations":[{"id":"slack","name":"Slack"},{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig drift checker","prompt":"Create a scheduled workflow that retrieves the live AWS AppConfig configuration and compares it against an expected baseline stored in a table, alerting Slack when the deployed configuration drifts from the approved version.","integrations":[{"id":"slack","name":"Slack"},{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"AppConfig gated rollout","prompt":"Create a workflow that gates an AWS AppConfig deployment behind a Slack approval: it creates the configuration version, waits for sign-off, starts the deployment with a linear strategy, and monitors completion before reporting back.","integrations":[{"id":"slack","name":"Slack"},{"id":"appconfig","name":"AWS AppConfig"}]},{"title":"Apollo pipeline tracker","prompt":"Create a scheduled workflow that searches Apollo opportunities by stage, summarizes new and at-risk deals with an agent, logs the snapshot to a pipeline table, and posts a daily deal-movement digest to the sales Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"apollo","name":"Apollo"}]},{"title":"ArXiv top-author tracker","prompt":"Create a scheduled workflow that monitors ArXiv for new papers by tracked authors and posts a Slack alert when a watched author publishes new work.","integrations":[{"id":"slack","name":"Slack"},{"id":"arxiv","name":"ArXiv"}]},{"title":"Asana sprint planner","prompt":"Build a workflow that on Monday morning compiles uncompleted Asana tasks, rebalances against capacity, and posts the sprint plan to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"asana","name":"Asana"}]},{"title":"Asana stuck-task surfacer","prompt":"Create a scheduled workflow that finds Asana tasks with no progress for 5+ days, pings the assignee in Slack with a quick-action prompt, and updates the task status based on their answer.","integrations":[{"id":"slack","name":"Slack"},{"id":"asana","name":"Asana"}]},{"title":"Asana cross-team blocker watcher","prompt":"Build a scheduled workflow that searches Asana for tasks tagged blocked, identifies the blocking team based on dependency metadata, and posts a request to the right channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"asana","name":"Asana"}]},{"title":"Asana retro generator","prompt":"Create a workflow that pulls Asana tasks completed in a sprint, summarizes wins, blockers, and patterns, and writes a retro doc shared with the team via Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"asana","name":"Asana"}]},{"title":"Ashby pipeline digest","prompt":"Build a scheduled daily workflow that lists open Ashby jobs, summarizes candidate counts per stage, flags applications stalled for more than five days, logs metrics to a tracking table, and Slacks hiring managers a personalized pipeline digest.","integrations":[{"id":"slack","name":"Slack"},{"id":"ashby","name":"Ashby"}]},{"title":"Ashby interview note logger","prompt":"Build a workflow that runs after every interview is logged in your meeting tool, summarizes the transcript, scores the candidate against the job requirements, creates a structured note on the matching Ashby candidate, and notifies the hiring manager in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ashby","name":"Ashby"}]},{"title":"Ashby offer-ready brief","prompt":"Build a workflow that runs when an Ashby application reaches the offer stage, gathers compensation benchmarks, interview feedback, and candidate priorities, drafts an offer brief file for the hiring manager, and Slacks the people team to start the offer process.","integrations":[{"id":"slack","name":"Slack"},{"id":"ashby","name":"Ashby"}]},{"title":"Athena scheduled report runner","prompt":"Create a scheduled workflow that runs a saved AWS Athena query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.","integrations":[{"id":"slack","name":"Slack"},{"id":"athena","name":"Athena"}]},{"title":"Athena cost-explorer query","prompt":"Build a scheduled workflow that runs Athena queries against AWS cost-and-usage reports daily, writes top cost movers per service to a table, and posts an anomaly digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"athena","name":"Athena"}]},{"title":"Athena ad-hoc query agent","prompt":"Build a Slack agent that translates natural-language analytics questions into safe AWS Athena queries, executes them, and returns the table answer with the query for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"athena","name":"Athena"}]},{"title":"Attio deal pipeline tracker","prompt":"Create a scheduled workflow that mirrors Attio deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.","integrations":[{"id":"slack","name":"Slack"},{"id":"attio","name":"Attio"}]},{"title":"Attio Slack channel-per-deal","prompt":"Build a workflow that for Attio deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.","integrations":[{"id":"slack","name":"Slack"},{"id":"attio","name":"Attio"}]},{"title":"Daily telemetry digest","prompt":"Create a scheduled workflow that queries Azure Data Explorer every morning for yesterday error rates, latency percentiles, and traffic by service, summarizes what moved against the prior week, and posts the digest to our engineering Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"azure_data_explorer","name":"Azure Data Explorer"}]},{"title":"Azure DevOps build failure alerter","prompt":"Build a workflow triggered when an Azure DevOps build fails that fetches the build timeline and failing-stage logs, summarizes the root cause with an agent, and posts an actionable Slack alert with a deep link to the run.","integrations":[{"id":"slack","name":"Slack"},{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Azure DevOps work-item triager","prompt":"Create a workflow triggered when an Azure DevOps work item is created that classifies it by type and priority, enriches the description, assigns the right area path, and posts a summary to the team channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Azure DevOps pipeline health report","prompt":"Create a scheduled daily workflow that lists Azure DevOps pipeline runs, computes pass rate and average duration per pipeline, logs them to a table for trend tracking, and Slacks a morning summary highlighting any regressions.","integrations":[{"id":"slack","name":"Slack"},{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Azure DevOps sprint burndown digest","prompt":"Build a scheduled daily workflow that queries Azure DevOps work items in the active sprint, computes remaining effort and at-risk items, logs the burndown to a table, and posts a morning summary to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"azure_devops","name":"Azure DevOps"}]},{"title":"Bitbucket pipeline failure diagnosis","prompt":"Create a workflow that inspects a failed Bitbucket pipeline, lists its steps, reads the bounded tail of each failed step log, identifies the likely root cause, and sends an actionable diagnosis to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Bitbucket stale pull request review","prompt":"Build a scheduled workflow that lists open Bitbucket pull requests, identifies stale work from its update timestamps and review state, summarizes the next action for each, and posts a weekly reminder in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"bitbucket","name":"Bitbucket"}]},{"title":"Box approval-flow router","prompt":"Create a workflow that watches a Box approval folder, posts a Slack request with quick-action buttons for each new doc, captures the decision, and labels the file accordingly.","integrations":[{"id":"slack","name":"Slack"},{"id":"box","name":"Box"}]},{"title":"Brex daily expense digest","prompt":"Build a scheduled workflow that runs every weekday morning, lists Brex expenses settled in the last 24 hours, summarizes total spend by merchant category, and posts the digest to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"brex","name":"Brex"}]},{"title":"Brex cash balance monitor","prompt":"Build a scheduled workflow that checks Brex cash account balances every morning and sends a Slack alert when the available balance of any account drops below a set threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"brex","name":"Brex"}]},{"title":"Bright Data competitor pricing","prompt":"Create a workflow that uses Bright Data to track competitor pricing across regions, captures geo-priced data, and posts notable price changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"brightdata","name":"Bright Data"}]},{"title":"Bright Data localization checker","prompt":"Build a scheduled workflow that uses Bright Data geo-targeted browsing to verify the brand’s site renders correctly in tracked regions, and writes findings to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"brightdata","name":"Bright Data"}]},{"title":"Bright Data brand mention search","prompt":"Create a workflow that uses Bright Data to scrape mentions of the brand across global forums and review sites, writes mentions into a tracking table, and pings on spikes.","integrations":[{"id":"slack","name":"Slack"},{"id":"brightdata","name":"Bright Data"}]},{"title":"Browser Use competitor pricing scraper","prompt":"Create a scheduled workflow that runs Browser Use weekly to navigate competitor pricing pages, captures the current plans and prices, diffs against last week, and posts changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"browser_use","name":"Browser Use"}]},{"title":"Browser Use legacy ERP scraper","prompt":"Create a workflow that uses Browser Use to log into a legacy ERP without an API, exports daily reports, parses them into a table, and posts a summary to Slack so old systems still feed modern ops.","integrations":[{"id":"slack","name":"Slack"},{"id":"browser_use","name":"Browser Use"}]},{"title":"Buffer failed-post alert to Slack","prompt":"Create a scheduled workflow that lists Buffer posts with status error, and for each failed post sends a Slack alert with the channel, the post text, and the publishing error message so the team can fix and reschedule it.","integrations":[{"id":"slack","name":"Slack"},{"id":"buffer","name":"Buffer"}]},{"title":"Buffer ideas from Slack","prompt":"Create a workflow triggered by a Slack message in the content-ideas channel that cleans up the message text and saves it as a Buffer idea with a short title so the marketing team can draft it later.","integrations":[{"id":"slack","name":"Slack"},{"id":"buffer","name":"Buffer"}]},{"title":"Cal.com reschedule chaser","prompt":"Build a scheduled workflow that finds Cal.com bookings that have been rescheduled more than twice, posts a Slack alert to the host, and proposes a fixed time.","integrations":[{"id":"slack","name":"Slack"},{"id":"calcom","name":"Cal.com"}]},{"title":"Calendly no-show tracker","prompt":"Build a scheduled workflow that lists yesterday\'s Calendly scheduled events, checks invitee status to find no-shows, logs them to a table for follow-up, and posts a recap of attended versus missed meetings to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"calendly","name":"Calendly"}]},{"title":"CB Insights exit probability watchlist","prompt":"Create a scheduled workflow that reads the outlook for every company on my watchlist, flags any whose two-year IPO or M&A exit probability moved meaningfully against its peer mean, and posts the changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"cbinsights","name":"CB Insights"}]},{"title":"CB Insights competitor strategy map","prompt":"Create a workflow that takes a competitor, pulls its CB Insights strategy map, and summarizes which categories it is investing in, partnering across, and acquiring into — then posts the summary to my strategy channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"cbinsights","name":"CB Insights"}]},{"title":"Background check on offer","prompt":"Build a workflow that runs when a candidate reaches the offer stage in Greenhouse, creates the candidate in Checkr with their email, sends a Checkr invitation for the role’s package, and posts the invitation link and status to the hiring channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"checkr","name":"Checkr"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Checkr report completed alert","prompt":"Create a workflow triggered by a completed Checkr report that reads the report, summarizes the result and any screenings that need review, and notifies the recruiter in Slack with a clear or consider recommendation.","integrations":[{"id":"slack","name":"Slack"},{"id":"checkr","name":"Checkr"}]},{"title":"Background check status digest","prompt":"Build a scheduled daily workflow that lists pending Checkr invitations, reads each invited candidate’s reports and their estimated completion dates, and sends the hiring team a digest of who is waiting, what is delayed, and which candidates need to act.","integrations":[{"id":"slack","name":"Slack"},{"id":"checkr","name":"Checkr"}]},{"title":"Circleback recap to Slack","prompt":"Build a workflow that triggers when a meeting is processed in Circleback, takes the notes and action items from the payload, and posts a clean recap to the relevant Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"circleback","name":"Circleback"}]},{"title":"Circleback meeting prep brief","prompt":"Build a scheduled workflow that lists upcoming calendar events from Circleback each morning, pulls past meetings and notes for the same attendees, and posts a prep brief for each external meeting to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"circleback","name":"Circleback"}]},{"title":"Circleback action-item chaser","prompt":"Create a scheduled workflow that lists pending Circleback action items across the workspace each week, groups them by assignee, and sends each owner a summary of what is still open.","integrations":[{"id":"slack","name":"Slack"},{"id":"circleback","name":"Circleback"}]},{"title":"Circleback weekly meeting digest","prompt":"Build a scheduled weekly workflow that lists the past week of Circleback meetings, aggregates decisions, action items, and recurring themes, and posts a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"circleback","name":"Circleback"}]},{"title":"Clerk session anomaly watcher","prompt":"Build a scheduled workflow that lists recent Clerk sessions, flags unusual patterns — impossible travel, repeated login failures — and pings the security Slack channel on real threats.","integrations":[{"id":"slack","name":"Slack"},{"id":"clerk","name":"Clerk"}]},{"title":"Daily ClickHouse metrics digest","prompt":"Create a scheduled workflow that runs a set of ClickHouse aggregation queries each morning, summarizes the key trends and anomalies with an agent, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickhouse","name":"ClickHouse"}]},{"title":"Alert on slow ClickHouse queries","prompt":"Create a scheduled workflow that lists ClickHouse running queries and posts a Slack alert for any whose elapsed time exceeds an explicit threshold I set, including the query_id, user, and elapsed time so a human can investigate and decide whether to intervene.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickhouse","name":"ClickHouse"}]},{"title":"ClickHouse storage growth report","prompt":"Create a scheduled workflow that collects ClickHouse table stats (rows and size on disk) each week, has an agent summarize the largest tables and fastest growth, and posts the report to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickhouse","name":"ClickHouse"}]},{"title":"ClickUp task intake","prompt":"Build a workflow that turns incoming Slack requests into ClickUp tasks in the right list with a clear name, description, priority, and due date, then replies in the thread with the task link.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickup","name":"ClickUp"}]},{"title":"ClickUp standup digest","prompt":"Create a scheduled weekday workflow that pulls open ClickUp tasks for each list, groups them by assignee and status, and posts a morning standup summary to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickup","name":"ClickUp"}]},{"title":"ClickUp sprint retro writer","prompt":"Build a workflow that pulls the ClickUp tasks completed during a sprint, summarizes wins, blockers, and recurring themes with an agent, and shares a retro document with the team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"clickup","name":"ClickUp"}]},{"title":"Cloudflare DNS change tracker","prompt":"Create a scheduled workflow that pulls every Cloudflare DNS record for my zones each hour, diffs the snapshot against the previous run, logs added, removed, and modified records to a table, and posts a Slack alert when sensitive records like MX or NS change.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudflare","name":"Cloudflare"}]},{"title":"Cloudflare cache purge on deploy","prompt":"Build a workflow that fires when a Vercel deployment succeeds on production, purges the Cloudflare cache for the affected hostnames, verifies the new content is being served, and posts a confirmation message to Slack with the purged paths.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudflare","name":"Cloudflare"},{"id":"vercel","name":"Vercel"}]},{"title":"Cloudflare zone provisioning","prompt":"Create a workflow that accepts a domain name from a form, creates a new Cloudflare zone, sets opinionated default DNS records and zone settings, generates the nameserver instructions, and posts the setup summary to Slack so the team can finalize delegation.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudflare","name":"Cloudflare"}]},{"title":"Cloudflare WAF and rate limit rollout","prompt":"Build a workflow that reads a table of WAF rules — expression, action, and rate limit — validates each row against the zone it targets, deploys it into the matching Cloudflare ruleset phase, and posts a Slack summary of every rule created, changed, or skipped.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudflare","name":"Cloudflare"}]},{"title":"CloudFormation drift detector","prompt":"Create a scheduled daily workflow that runs drift detection on every CloudFormation stack in my AWS account, waits for detection to complete, summarizes drifted resources, logs them to a table, and posts a Slack alert when any production stack drifts.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation failure investigator","prompt":"Build a scheduled workflow that polls CloudFormation stack events every few minutes, detects rollbacks and create-failed events, pulls the failure reason and recent events from the stack, summarizes the root cause, opens a Linear ticket with the diagnosis, and posts to the on-call Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudformation","name":"CloudFormation"},{"id":"linear","name":"Linear"}]},{"title":"CloudFormation pre-deploy drift gate","prompt":"Create a workflow that runs before a deploy, initiates drift detection on the target CloudFormation stack, polls until drift detection completes, and either approves the deploy or blocks it with a Slack alert explaining the drifted resources.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation change set approval","prompt":"Build a workflow that creates a CloudFormation change set for a stack update, describes the proposed resource changes, posts a summary to Slack for approval, and executes the change set only after an approver replies, otherwise deletes the change set.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudFormation environment provisioner","prompt":"Create a workflow that takes an environment name and template parameters as input, creates a new CloudFormation stack for that environment, polls stack events until it reaches CREATE_COMPLETE or fails, and posts the stack outputs to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudformation","name":"CloudFormation"}]},{"title":"CloudTrail root login alerter","prompt":"Create a scheduled workflow that looks up AWS CloudTrail ConsoleLogin events every 15 minutes, flags any sign-in by the root user or a login without MFA, and posts the actor, source IP, and time to a Slack security channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudTrail access key forensics","prompt":"Build a workflow that takes an AWS access key ID, looks up every CloudTrail event made with it in the last 90 days, groups the calls by service and source IP, and returns a timeline of what that credential did.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudTrail Lake audit agent","prompt":"Build a Slack agent that turns natural-language audit questions into CloudTrail Lake SQL, starts the query, polls until it finishes, and returns the result rows with the SQL it ran for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudTrail Insights anomaly digest","prompt":"Create a daily workflow that looks up AWS CloudTrail Insights events, correlates each API call-rate or error-rate anomaly with the principals active at that time, and posts a digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudtrail","name":"CloudTrail"}]},{"title":"CloudWatch alarm digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of CloudWatch alarms by service and severity, identifies repeat offenders, and posts a digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"CloudWatch cost-control alerts","prompt":"Create a scheduled workflow that pulls CloudWatch billing alarms daily, projects month-end spend by service, and posts an alert when projection exceeds budget thresholds.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"CloudWatch log error triager","prompt":"Create a workflow that runs a CloudWatch Logs Insights query against application log groups every few minutes, groups recurring error signatures with an agent, opens a Linear issue for any new error pattern, and posts a Slack alert.","integrations":[{"id":"slack","name":"Slack"},{"id":"cloudwatch","name":"CloudWatch"},{"id":"linear","name":"Linear"}]},{"title":"Coda bug tracker triage","prompt":"Create a workflow that lists new rows in a Coda bug tracker table, has an agent classify severity and suggest an owner for each bug, updates the rows with the triage fields, and posts the high-severity bugs to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"coda","name":"Coda"}]},{"title":"Coda doc engagement report","prompt":"Build a scheduled workflow that pulls last week of Coda doc analytics, ranks docs by sessions and views, and posts the most and least used team docs to Slack so owners can archive stale docs.","integrations":[{"id":"slack","name":"Slack"},{"id":"coda","name":"Coda"}]},{"title":"CodePipeline deploy approver","prompt":"Build a workflow that checks a CodePipeline pipeline for pending manual approvals, posts the change summary and source revisions to Slack, and approves or rejects the deployment based on the team lead reply.","integrations":[{"id":"slack","name":"Slack"},{"id":"codepipeline","name":"CodePipeline"}]},{"title":"CodePipeline failure triage","prompt":"Create a scheduled workflow that polls CodePipeline executions every few minutes, and when one fails, pulls the pipeline state to find the failing stage and action error, opens a Linear issue, and alerts the on-call channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"codepipeline","name":"CodePipeline"},{"id":"linear","name":"Linear"}]},{"title":"CodePipeline release train","prompt":"Build a scheduled workflow that starts the release CodePipeline pipeline every weekday at 9am with the release version as a pipeline variable, then posts the execution ID and a link to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"codepipeline","name":"CodePipeline"}]},{"title":"CodePipeline deploy digest","prompt":"Create a scheduled daily workflow that lists executions across the team CodePipeline pipelines, summarizes successes, failures, and rollbacks with their source revisions, and posts a digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"codepipeline","name":"CodePipeline"}]},{"title":"CodePipeline rollback brake","prompt":"Create a workflow that watches CloudWatch alarms after a deployment, and when an error-rate alarm fires while a CodePipeline execution is in progress, stops the execution with a reason and notifies the release channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"codepipeline","name":"CodePipeline"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"PagerDuty incident coordinator","prompt":"Create a knowledge base connected to my Confluence or Notion with runbooks and incident procedures. Then build a workflow triggered by PagerDuty incidents that searches the runbooks, gathers related Datadog alerts, identifies the on-call rotation, and posts a comprehensive incident brief to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"confluence","name":"Confluence"},{"id":"notion","name":"Notion"},{"id":"pagerduty","name":"PagerDuty"},{"id":"datadog","name":"Datadog"}]},{"title":"Confluence knowledge base sync","prompt":"Create a knowledge base connected to my Confluence workspace so all wiki pages are automatically synced and searchable. Then build a scheduled workflow that identifies stale pages not updated in 90 days and sends a Slack reminder to page owners to review them.","integrations":[{"id":"slack","name":"Slack"},{"id":"confluence","name":"Confluence"}]},{"title":"Confluence weekly contributor digest","prompt":"Build a scheduled workflow that aggregates the week’s new and updated Confluence pages, identifies top contributors, and posts a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"confluence","name":"Confluence"}]},{"title":"Confluence question router","prompt":"Build a workflow that watches a Confluence space for new questions, finds the right SME via labels, pings them on Slack, and updates the question page with a sourced answer once available.","integrations":[{"id":"slack","name":"Slack"},{"id":"confluence","name":"Confluence"}]},{"title":"Confluence knowledge assistant","prompt":"Create a knowledge base synced from a Confluence space, then build a Slack agent that searches Confluence pages to answer team questions, cites the source page, and offers to create a new page when an answer is missing.","integrations":[{"id":"slack","name":"Slack"},{"id":"confluence","name":"Confluence"}]},{"title":"Context.dev competitor monitor","prompt":"Build a scheduled workflow that scrapes competitor pricing and changelog pages to markdown with Context.dev weekly, diffs against the prior snapshot, logs changes to a table, and posts notable updates to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"context_dev","name":"Context.dev"}]},{"title":"Convex support ticket triage","prompt":"Build a workflow that runs a Convex query to fetch open support tickets, classifies each by urgency with an agent, writes the triage label back via a Convex mutation, and posts critical tickets to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"convex","name":"Convex"}]},{"title":"Convex change-data alerting","prompt":"Build a scheduled workflow that polls Convex Document Deltas for changed rows since the last run, filters for high-value records like fraud flags or large orders, and posts an alert with context to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"convex","name":"Convex"}]},{"title":"Convex daily metrics digest","prompt":"Create a scheduled daily workflow that runs Convex queries for new signups, active users, and key feature usage, summarizes the numbers with an agent, and posts a digest to Slack with day-over-day trend.","integrations":[{"id":"slack","name":"Slack"},{"id":"convex","name":"Convex"}]},{"title":"Convex schema drift monitor","prompt":"Create a scheduled workflow that runs Convex List Tables, diffs the returned table schemas against the last snapshot stored in a table, and notifies the engineering channel when fields are added, removed, or change type.","integrations":[{"id":"slack","name":"Slack"},{"id":"convex","name":"Convex"}]},{"title":"CrowdStrike alert triage","prompt":"Create a workflow that queries new high-severity CrowdStrike alerts, pulls their details, summarizes the tactic, technique, and affected host for each, posts the triage summary to Slack, and marks the reviewed alerts in progress.","integrations":[{"id":"slack","name":"Slack"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike host containment","prompt":"Create a workflow that takes a host ID, contains the host in CrowdStrike, opens a Real Time Response session to capture running processes and network connections, and posts the collected evidence to Slack for the on-call responder.","integrations":[{"id":"slack","name":"Slack"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike case digest","prompt":"Create a scheduled workflow that queries open CrowdStrike Case Management cases, pulls each case status, severity, and assignee, and posts a daily standup digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"CrowdStrike sensor coverage gaps","prompt":"Create a scheduled workflow that queries CrowdStrike Identity Protection sensors, identifies devices reporting an unprotected or degraded status, opens a PagerDuty incident for critical gaps, and posts the list to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"crowdstrike","name":"CrowdStrike"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Crunchbase funding round watcher","prompt":"Build a workflow that runs every morning, searches Crunchbase for funding rounds announced in the last day in my target categories, and posts each round — company, stage, amount raised, and lead investors — to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Crunchbase competitor tracker","prompt":"Build a workflow that takes my competitor list, looks each company up in Crunchbase, compares headcount, operating status, and latest funding against what I stored last month, and alerts me in Slack when anything changed.","integrations":[{"id":"slack","name":"Slack"},{"id":"crunchbase","name":"Crunchbase"}]},{"title":"Cursor cloud agent launcher","prompt":"Build a workflow that takes a feature description and a GitHub repository, launches a Cursor cloud agent with structured instructions, polls until the agent finishes, captures the generated pull request link, and posts a summary to Slack so the team can review.","integrations":[{"id":"slack","name":"Slack"},{"id":"cursor","name":"Cursor"}]},{"title":"Cursor agent fleet monitor","prompt":"Build a scheduled workflow that runs every fifteen minutes, lists all active Cursor cloud agents, logs status, runtime, and repository to a tracking table, and posts a daily Slack summary of completed, failing, and long-running agents.","integrations":[{"id":"slack","name":"Slack"},{"id":"cursor","name":"Cursor"}]},{"title":"Cursor stuck-agent cleaner","prompt":"Create a scheduled workflow that runs hourly, lists Cursor cloud agents, detects agents stuck in the same state longer than a configurable threshold, stops or deletes them based on rules, and posts a Slack report of the cleanup actions taken.","integrations":[{"id":"slack","name":"Slack"},{"id":"cursor","name":"Cursor"}]},{"title":"Dagster pipeline status digest","prompt":"Create a scheduled daily workflow that pulls Dagster run statuses for the previous day, identifies failed and skipped runs, and posts a digest with links to the worst offenders in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dagster","name":"Dagster"}]},{"title":"Dagster sensor health watcher","prompt":"Build a scheduled workflow that lists Dagster sensors, checks their tick history, and alerts Slack when a sensor stops emitting ticks unexpectedly.","integrations":[{"id":"slack","name":"Slack"},{"id":"dagster","name":"Dagster"}]},{"title":"Databricks cluster cost guard","prompt":"Create a scheduled workflow that lists Databricks clusters hourly, flags clusters that are running while idle, and posts a Slack alert with the candidates to shut down so the platform team can reclaim spend.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks notebook scheduler","prompt":"Build a workflow that runs a parameterized Databricks notebook, captures the outputs as files, and posts the result to a chosen Slack channel for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks model evaluator","prompt":"Build a workflow that runs a Databricks ML model evaluation job on the latest data, captures the metrics, writes results to a model-registry table, and pings Slack on regression.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks job failure watcher","prompt":"Build a workflow that lists recent Databricks job runs every 15 minutes, detects failed runs, pulls the run output and error for an agent to summarize the likely cause, and posts an actionable Slack alert with a link to the run.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks Genie Slack analyst","prompt":"Build an agent that answers data questions asked in a Slack channel with Databricks Genie. It keeps one Genie conversation per Slack thread in a table so follow-up questions keep their context, then replies in the thread with the answer, a short table of the result rows, and the SQL Genie ran.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks Genie space router","prompt":"Create an agent that lists the Databricks Genie spaces I can access, picks the space whose title and description best fit each incoming question, asks that Genie space, and posts the answer to Slack with which space answered it.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Databricks Genie KPI digest","prompt":"Build a scheduled workflow that asks a Databricks Genie agent every Monday for a research report on last week\'s key business metrics and what drove them, then posts the report and the SQL behind it to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"databricks","name":"Databricks"}]},{"title":"Datadog infra health report","prompt":"Create a scheduled daily workflow that queries Datadog for key infrastructure metrics — error rates, latency percentiles, CPU and memory usage — logs them to a table for trend tracking, and sends a morning Slack report highlighting any anomalies or degradations.","integrations":[{"id":"slack","name":"Slack"},{"id":"datadog","name":"Datadog"}]},{"title":"Datadog alert-to-Linear bridge","prompt":"Build a scheduled workflow that polls Datadog monitors for any in an alerting state, classifies severity, creates a Linear ticket for non-paging issues with full context, and posts a Slack notification linking both.","integrations":[{"id":"slack","name":"Slack"},{"id":"datadog","name":"Datadog"},{"id":"linear","name":"Linear"}]},{"title":"Datadog cost optimizer","prompt":"Build a scheduled workflow that queries Datadog estimated-usage timeseries for the top custom metrics by volume, writes optimization recommendations to a finance review file, and pings the platform team.","integrations":[{"id":"slack","name":"Slack"},{"id":"datadog","name":"Datadog"}]},{"title":"Daytona CSV analysis","prompt":"Build a workflow that takes an uploaded CSV file, uploads it into a Daytona sandbox, runs a Python analysis script over it, downloads the generated report file, and shares the findings in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"daytona","name":"Daytona"}]},{"title":"Daytona sandbox janitor","prompt":"Build a scheduled weekly workflow that lists all Daytona sandboxes, stops any that have been running longer than expected, deletes sandboxes labeled as temporary, and posts a cleanup summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"daytona","name":"Daytona"}]},{"title":"Daytona repo health check","prompt":"Build a scheduled workflow that creates a Daytona sandbox, clones the main branch of a repository, runs install and build commands, records any failures in a table, and alerts the engineering channel when the build breaks.","integrations":[{"id":"slack","name":"Slack"},{"id":"daytona","name":"Daytona"}]},{"title":"Devin session launcher","prompt":"Build a workflow that accepts a coding task description, creates a new Devin session with rich context, polls the session until it produces a pull request or hits a blocker, and posts the session link and status to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"devin","name":"Devin"}]},{"title":"Devin session monitor","prompt":"Build a scheduled workflow that runs every ten minutes, lists Devin sessions for your organization, tracks status changes, logs sessions, pull requests, and tags to a table, and sends a Slack alert when any session has been stuck for more than two hours.","integrations":[{"id":"slack","name":"Slack"},{"id":"devin","name":"Devin"}]},{"title":"Devin progress nudger","prompt":"Build a workflow that runs every hour against active Devin sessions, detects sessions that are suspended or awaiting input, sends a targeted follow-up message via the Devin API to unblock progress, and notifies the requester if a session needs human intervention.","integrations":[{"id":"slack","name":"Slack"},{"id":"devin","name":"Devin"}]},{"title":"Discord community manager","prompt":"Create a knowledge base connected to my Google Docs or Notion with product documentation. Then build a workflow that monitors my Discord server for unanswered questions, answers them using the knowledge base, tracks common questions in a table, and sends a weekly community summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"discord","name":"Discord"},{"id":"google_docs","name":"Google Docs"},{"id":"notion","name":"Notion"}]},{"title":"Discord weekly community digest","prompt":"Create a scheduled weekly workflow that summarizes Discord activity — top threads, helpful members, new questions — and posts the digest to the announcements channel and Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"discord","name":"Discord"}]},{"title":"DocuSign chase reminder","prompt":"Create a scheduled workflow that lists DocuSign envelopes pending signature for over 48 hours, notifies the owning rep in Slack to nudge each signer, and escalates with a flagged message after 7 days.","integrations":[{"id":"slack","name":"Slack"},{"id":"docusign","name":"DocuSign"}]},{"title":"DocuSign stalled envelope resolver","prompt":"Create a scheduled workflow that lists in-flight DocuSign envelopes, checks each envelope’s recipients for signers who have left the company, voids the affected envelopes, and posts the list to Slack so a rep can resend from the right template.","integrations":[{"id":"slack","name":"Slack"},{"id":"docusign","name":"DocuSign"}]},{"title":"DocuSign signature analytics digest","prompt":"Build a scheduled weekly workflow that pulls DocuSign envelope analytics — time-to-sign, completion rate, drop-off — and posts a digest to the sales ops Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"docusign","name":"DocuSign"}]},{"title":"Downdetector outage alerter","prompt":"Build a scheduled workflow that checks the Downdetector status of my critical vendors every 15 minutes and posts a Slack alert whenever any of them flips to a \\"danger\\" (outage) status.","integrations":[{"id":"slack","name":"Slack"},{"id":"downdetector","name":"Downdetector"}]},{"title":"Downdetector vendor status digest","prompt":"Build a scheduled daily workflow that searches Downdetector for each of my vendors, reads their current status and 24h report stats, writes a status digest table, and posts a Slack summary.","integrations":[{"id":"slack","name":"Slack"},{"id":"downdetector","name":"Downdetector"}]},{"title":"Dropbox vendor-invoice intake","prompt":"Build a scheduled workflow that lists a Dropbox vendor folder for invoice PDFs added since the last run, extracts vendor and amount with an agent, writes the row to a payables table, and pings finance on Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dropbox","name":"Dropbox"}]},{"title":"DSPy + LangSmith trace harness","prompt":"Create a workflow that runs a DSPy program over an eval set, logs each prediction as a LangSmith trace for evaluation, captures the quality delta against the previous run, and writes the comparison to engineering Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dspy","name":"DSPy"},{"id":"langsmith","name":"LangSmith"}]},{"title":"Dub campaign link batcher","prompt":"Create a workflow that reads a table of campaign destinations, upserts a Dub short link for each row with consistent UTM tags, writes the resulting short URL back into the table, and posts a Slack confirmation summarizing how many links were created or refreshed.","integrations":[{"id":"slack","name":"Slack"},{"id":"dub","name":"Dub"}]},{"title":"Dub analytics digest","prompt":"Build a scheduled weekly workflow that pulls Dub link analytics — clicks, leads, sales, and top referrers — for active campaigns, writes a narrative summary highlighting winners and decliners, and delivers the digest to Slack with deep links into the Dub dashboard.","integrations":[{"id":"slack","name":"Slack"},{"id":"dub","name":"Dub"}]},{"title":"Dub release announcement linker","prompt":"Create a workflow triggered by a GitHub release that creates a Dub short link for the release notes URL, posts the short link to the marketing Slack channel, and stores the mapping of release tag to short link in a tracking table.","integrations":[{"id":"slack","name":"Slack"},{"id":"dub","name":"Dub"},{"id":"github","name":"GitHub"}]},{"title":"DuckDuckGo daily digest","prompt":"Create a scheduled daily workflow that queries DuckDuckGo for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"duckduckgo","name":"DuckDuckGo"}]},{"title":"DynamoDB hot-partition watcher","prompt":"Build a scheduled workflow that pulls DynamoDB CloudWatch metrics, identifies hot partitions and throttled requests, and writes the report to a Slack channel with mitigation suggestions.","integrations":[{"id":"slack","name":"Slack"},{"id":"dynamodb","name":"Amazon DynamoDB"},{"id":"cloudwatch","name":"CloudWatch"}]},{"title":"DynamoDB GSI health audit","prompt":"Create a scheduled workflow that scans DynamoDB GSIs for skew, low projection efficiency, and unused indexes, and writes a remediation plan to engineering Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dynamodb","name":"Amazon DynamoDB"}]},{"title":"Dynatrace problem triage","prompt":"Build a scheduled workflow that polls Dynatrace every five minutes for open problems, pulls the root cause entity and recent logs for each one, summarizes the likely cause with an agent, and posts the enriched problem to Slack and PagerDuty.","integrations":[{"id":"slack","name":"Slack"},{"id":"dynatrace","name":"Dynatrace"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Dynatrace vulnerability digest","prompt":"Create a scheduled daily workflow that lists open critical and high Dynatrace security problems, groups them by affected service and CVE, writes them to a Sim table, and posts a remediation digest to the security channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dynatrace","name":"Dynatrace"}]},{"title":"Dynatrace log error triage","prompt":"Create a scheduled workflow that searches Dynatrace logs for new error patterns in the last fifteen minutes, clusters them by message shape with an agent, and posts only the previously unseen clusters to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"dynatrace","name":"Dynatrace"}]},{"title":"EC2 off-hours scheduler","prompt":"Create a scheduled workflow that every weekday evening finds Amazon EC2 instances tagged Schedule=office-hours that are running, stops them, starts them again each morning, and posts a summary of the instances changed to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 unused Elastic IP finder","prompt":"Build a scheduled weekly workflow that lists Amazon EC2 Elastic IP addresses, flags any with no association, records them in a cost table with their allocation IDs and tags, and asks for approval in Slack before releasing them.","integrations":[{"id":"slack","name":"Slack"},{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 open security group audit","prompt":"Create a scheduled daily workflow that describes Amazon EC2 security groups, flags inbound rules open to 0.0.0.0/0 or ::/0 on ports other than 80 and 443, files a finding for each with the group, VPC, and offending rule, and revokes the rule once the owner approves in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 unattached volume cleanup","prompt":"Create a scheduled weekly workflow that finds Amazon EC2 EBS volumes in the available state, estimates their monthly cost from size and type, snapshots each one, sends the list to Slack for approval, and deletes the approved volumes.","integrations":[{"id":"slack","name":"Slack"},{"id":"ec2","name":"Amazon EC2"}]},{"title":"EC2 tag compliance enforcer","prompt":"Create a scheduled workflow that lists Amazon EC2 instances, volumes, and Elastic IPs, finds resources missing the Owner or CostCenter tag, applies a default tag where the owner can be inferred, and reports the rest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ec2","name":"Amazon EC2"}]},{"title":"Elasticsearch index lifecycle audit","prompt":"Build a scheduled weekly workflow that audits Elasticsearch indices against retention policies, identifies over-retained data, and writes the cleanup plan to a Slack approval thread.","integrations":[{"id":"slack","name":"Slack"},{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"Elasticsearch slow-query digest","prompt":"Create a scheduled daily workflow that aggregates Elasticsearch slow-log entries, clusters the top offenders, and posts a digest to the platform Slack channel with recommended fixes.","integrations":[{"id":"slack","name":"Slack"},{"id":"elasticsearch","name":"Elasticsearch"}]},{"title":"ElevenLabs blog-to-podcast","prompt":"Build a workflow that takes a blog post, narrates it with an ElevenLabs voice, saves the audio file, and posts a player-ready link to the marketing Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"ElevenLabs daily voice digest","prompt":"Build a scheduled daily workflow that generates an ElevenLabs voice digest of the day’s key metrics, saves the audio, and Slacks the player link to leadership.","integrations":[{"id":"slack","name":"Slack"},{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"Email Bison reply triage","prompt":"Create a workflow that pulls new Email Bison replies on a schedule, classifies each as interested, not interested, objection, or out-of-office, applies the matching tag to the lead, and pings the rep in Slack for hot replies.","integrations":[{"id":"slack","name":"Slack"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Email Bison weekly outbound digest","prompt":"Build a scheduled weekly workflow that pulls Email Bison campaign performance — sends, opens, replies, positive reply rate — generates a digest with the top campaigns and bottom performers, and posts it to a Slack sales channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Inbound lead qualifier","prompt":"Create a workflow that on a new inbound signup runs the Company Info enrichment on the email domain to pull industry and headcount, scores fit against my ICP with an agent, and routes qualified leads to the sales Slack channel.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Exa competitor news monitor","prompt":"Build a scheduled daily workflow that runs Exa search for fresh news about my competitors, gets the page contents and finds similar coverage, summarizes the notable moves with citations, and posts a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"exa","name":"Exa"}]},{"title":"Extend structured-data extractor","prompt":"Build a workflow that runs uploaded forms through Extend to pull labelled fields, writes the structured rows to a table, and notifies Slack on missing required fields.","integrations":[{"id":"slack","name":"Slack"},{"id":"extend","name":"Extend"}]},{"title":"Extend insurance claim ingester","prompt":"Create a workflow that uses Extend to ingest claim forms, extracts policy number, claim amount, and incident details to structured rows, and routes high-value claims to a Slack adjuster channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"extend","name":"Extend"}]},{"title":"Extend purchase-order extractor","prompt":"Create a workflow that processes inbound PO PDFs with Extend, writes vendor, SKU, quantity, and total to an orders table, and pings Slack when a PO exceeds the approval threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"extend","name":"Extend"}]},{"title":"Fathom meeting recap to Slack","prompt":"Build a workflow that triggers when a Fathom meeting completes, pulls the summary and action items, and posts a recap to the relevant Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"fathom","name":"Fathom"}]},{"title":"Firecrawl competitor change tracker","prompt":"Build a scheduled workflow that scrapes competitor websites, pricing pages, and changelog pages weekly using Firecrawl, compares against previous snapshots, summarizes any changes, logs them to a tracking table, and sends a Slack alert for major updates.","integrations":[{"id":"slack","name":"Slack"},{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Firecrawl competitor site monitor","prompt":"Build a scheduled workflow that uses Firecrawl to scrape competitor pricing, product, and changelog pages weekly, diffs against the prior snapshot, and posts changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Firecrawl product-launch detector","prompt":"Build a scheduled workflow that crawls competitor blogs and product pages with Firecrawl daily, classifies posts as product launches, and posts notable launches to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"firecrawl","name":"Firecrawl"}]},{"title":"Fireflies meeting recap to Slack","prompt":"Build a workflow that runs when a Fireflies recording finishes, pulls the transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"fireflies","name":"Fireflies"}]},{"title":"Fireflies talk-ratio coach","prompt":"Build a scheduled weekly workflow that pulls Fireflies sales-call analytics per rep — talk ratio, longest monologue, question rate — and posts a coaching digest to managers.","integrations":[{"id":"slack","name":"Slack"},{"id":"fireflies","name":"Fireflies"}]},{"title":"Fireflies competitor-mention tracker","prompt":"Build a workflow that scans Fireflies sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts notable patterns to Slack weekly.","integrations":[{"id":"slack","name":"Slack"},{"id":"fireflies","name":"Fireflies"}]},{"title":"Failed sync triage","prompt":"Build a workflow triggered when a Fivetran sync ends with a failure that reads the connection, its active warnings, and the last day of sync history, has an agent explain the likely cause and fix, and posts the summary to the data team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"fivetran","name":"Fivetran"}]},{"title":"Self-serve source onboarding","prompt":"Build a workflow that takes a requested source type and team, creates a paused Fivetran connection in the right group, generates a Connect Card link, and sends it to the requester in Slack so they can authorize the source themselves.","integrations":[{"id":"slack","name":"Slack"},{"id":"fivetran","name":"Fivetran"}]},{"title":"Flint site update from Slack","prompt":"Build a workflow triggered by a Slack message in the #website channel that turns the request into a Flint agent task prompt, starts the task, and replies in the thread with the task ID.","integrations":[{"id":"slack","name":"Slack"},{"id":"flint","name":"Flint"}]},{"title":"Flint failed-task alerts","prompt":"Create a workflow that checks a Flint task status and, when the task has failed, posts the task ID and error message to a Slack channel so the team can rerun it.","integrations":[{"id":"slack","name":"Slack"},{"id":"flint","name":"Flint"}]},{"title":"Gamma customer-story builder","prompt":"Create a workflow that takes a customer-story brief, generates a Gamma deck with the challenge, solution, results, and pull quote, and shares the link with the marketing team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"gamma","name":"Gamma"}]},{"title":"Gamma weekly all-hands deck","prompt":"Build a scheduled weekly workflow that pulls KPIs from tables, generates a Gamma all-hands deck with the latest numbers, and posts the link to the leadership Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"gamma","name":"Gamma"}]},{"title":"GitHub weekly team digest","prompt":"Build a scheduled workflow that runs every Friday, pulls the week\'s GitHub commits, closed Linear issues, and key Slack conversations, then emails a formatted weekly summary to the team.","integrations":[{"id":"slack","name":"Slack"},{"id":"github","name":"GitHub"},{"id":"linear","name":"Linear"}]},{"title":"Get GitHub activity alerts in Slack","prompt":"Create an agent that watches GitHub for new pull requests, commits, issues, or deployments and posts formatted Slack notifications so your engineering team never misses a critical event.","integrations":[{"id":"slack","name":"Slack"},{"id":"github","name":"GitHub"}]},{"title":"GitLab pipeline failure responder","prompt":"Build a scheduled workflow that lists recent GitLab pipelines on the main branch, finds newly failed runs, summarizes the root cause from the job logs, identifies the most likely owner from recent commits, opens a GitLab issue with the diagnosis, and posts an alert to Slack with a link to the failing pipeline.","integrations":[{"id":"slack","name":"Slack"},{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab issue triager","prompt":"Create a scheduled workflow that runs every hour, pulls new GitLab issues, classifies each by component, severity, and effort, applies labels and assigns the right owner, and posts a daily Slack digest of unassigned and stale issues so nothing slips through.","integrations":[{"id":"slack","name":"Slack"},{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab project health digest","prompt":"Create a scheduled weekly workflow that pulls open issues, stale merge requests, recent pipeline failures, and contributor activity for every GitLab project, logs metrics to a tracking table, and sends a Slack health digest to engineering leadership.","integrations":[{"id":"slack","name":"Slack"},{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab merge request unblocker","prompt":"Build a scheduled daily workflow that lists open GitLab merge requests, identifies those blocked on review for more than two days, sends targeted Slack DMs to the assigned reviewers with the MR link, and updates a table tracking unblock actions.","integrations":[{"id":"slack","name":"Slack"},{"id":"gitlab","name":"GitLab"}]},{"title":"GitLab access governance agent","prompt":"Build a scheduled workflow that lists pending GitLab access requests and invitations across our key groups, checks each requester against a table of approved teams, approves or denies the access requests at the right access level, revokes stale invitations older than 14 days, and posts a summary of every access decision to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"gitlab","name":"GitLab"}]},{"title":"Gmail triage assistant","prompt":"Build a workflow that scans my Gmail inbox every hour, categorizes emails by urgency and type (action needed, FYI, follow-up), drafts replies for routine messages, and sends me a prioritized summary in Slack so I only open what matters. Schedule it to run hourly.","integrations":[{"id":"slack","name":"Slack"},{"id":"gmail","name":"Gmail"}]},{"title":"Gmail invoice processor","prompt":"Build a workflow that processes invoice PDFs from Gmail, extracts vendor name, amount, due date, and line items, then logs everything to a tracking table and sends a Slack alert for invoices due within 7 days.","integrations":[{"id":"slack","name":"Slack"},{"id":"gmail","name":"Gmail"}]},{"title":"Gong sales call analyzer","prompt":"Build a workflow that pulls call transcripts from Gong after each sales call, identifies key objections raised, action items promised, and competitor mentions, updates the deal record in my CRM, and posts a call summary with next steps to the Slack deal channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"gong","name":"Gong"}]},{"title":"Gong objection tracker","prompt":"Build a scheduled weekly workflow that scans Gong sales calls for recurring objections, scores frequency and stage, and writes a competitive-intel digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"gong","name":"Gong"}]},{"title":"Gong deal-risk surfacer","prompt":"Create a workflow that monitors Gong conversation intelligence signals, identifies deals at risk based on talk patterns, and posts a Slack alert to the AE and manager.","integrations":[{"id":"slack","name":"Slack"},{"id":"gong","name":"Gong"}]},{"title":"Google Ads spend pacing","prompt":"Build a scheduled daily workflow that pulls Google Ads campaign spend, compares against monthly budget, and posts a Slack alert when any campaign is pacing more than 15% over.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_ads","name":"Google Ads"}]},{"title":"Google Ads + Stripe ROAS tracker","prompt":"Create a scheduled workflow that joins Google Ads spend with Stripe revenue only where an explicit campaign ID or UTM mapping was captured, reports unmatched revenue separately, calculates attributed ROAS with that limitation, and posts the per-channel breakdown to Slack each morning.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_ads","name":"Google Ads"},{"id":"stripe","name":"Stripe"}]},{"title":"Google Ads + PageSpeed landing audit","prompt":"Create a scheduled workflow that for active Google Ads campaigns runs Google PageSpeed on the landing pages weekly, flags slow LPs, and pings the marketing team.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_ads","name":"Google Ads"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"Google Ads + Profound brand comparison","prompt":"Build a scheduled workflow that joins Google Ads spend per campaign with Profound AI brand-visibility scores, writes a comparison table without claiming causal attribution, and posts findings to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_ads","name":"Google Ads"},{"id":"profound","name":"Profound"}]},{"title":"AppSheet order intake","prompt":"Build a workflow triggered by a form submission that adds a new row to an AppSheet Orders table, then posts a confirmation message to Slack with the order details.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_appsheet","name":"Google AppSheet"}]},{"title":"BigQuery scheduled report runner","prompt":"Build a scheduled workflow that runs a saved BigQuery query daily, writes the result rows to a Sim table, and posts a Slack summary of the top movers.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"BigQuery cost-tracking alerts","prompt":"Build a scheduled daily workflow that pulls BigQuery slot and storage usage, projects month-end spend, and posts a Slack alert when projection exceeds budget.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"BigQuery NL analytics agent","prompt":"Build a Slack agent that lists BigQuery datasets and tables to understand the schema, translates a teammate\'s natural-language question into a safe BigQuery SQL query, runs it, and replies with the result table plus the query used.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"Calendar daily agenda digest","prompt":"Create a scheduled weekday workflow that lists my Google Calendar events for the day, summarizes them with attendee context and prep notes, and posts a clean morning agenda to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Google Docs review request","prompt":"Build a workflow that reads a Google Doc when its title is marked ready for review, summarizes the key points with an agent, and posts a review request with the doc link to the named reviewers in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Google Docs change digester","prompt":"Create a scheduled weekly workflow that reads each tracked Google Doc, compares its content against the snapshot stored in a table, summarizes what changed with an agent, and posts a digest to the team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Meeting notes to Google Docs","prompt":"Create a workflow that after a meeting pulls the transcript, summarizes decisions, action items, and owners with an agent, and creates a formatted Google Docs document in the shared team folder with a link posted to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Google Drive contract intake","prompt":"Create a workflow that watches a Google Drive intake folder for new contract PDFs, extracts clauses with Reducto, writes structured terms to a table, and pings legal in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_drive","name":"Google Drive"},{"id":"reducto","name":"Reducto"}]},{"title":"Google Drive retention enforcer","prompt":"Create a scheduled monthly workflow that finds Google Drive files past the retention horizon, requires owner approval over Slack, and archives or deletes per the policy.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_drive","name":"Google Drive"}]},{"title":"Google Forms support intake","prompt":"Create a workflow that turns Google Forms support submissions into Zendesk tickets, prioritizes them with an agent, and posts the new ticket to the support Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_forms","name":"Google Forms"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Google Forms survey analyzer","prompt":"Create a workflow that processes Google Forms survey responses, classifies sentiment and themes with an agent, and writes a weekly insight digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Forms approvals router","prompt":"Build a workflow that turns Google Forms approval requests into Slack messages with quick-action buttons, captures the decision, and emails the requester the outcome.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Forms PTO collector","prompt":"Create a workflow that processes PTO requests from Google Forms, captures manager approval over Slack, and updates the HR table with approved time off.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_forms","name":"Google Forms"}]},{"title":"Google Groups quarterly access review","prompt":"Build a scheduled workflow that runs each quarter, lists every Google Group with members and owners, writes the report to a table for compliance review, and pings owners to confirm membership in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_groups","name":"Google Groups"}]},{"title":"Google Groups self-serve requester","prompt":"Build a workflow that accepts a Google Group access request via a form, gets manager approval over Slack, adds the user to the group, and notifies the requester when access is granted.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_groups","name":"Google Groups"}]},{"title":"Google Groups distribution-list audit","prompt":"Create a scheduled workflow that scans Google Groups marked as distribution lists, flags external members against an allowlist, and posts a Slack report to the security team.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_groups","name":"Google Groups"}]},{"title":"Google Groups empty-group cleanup","prompt":"Build a scheduled workflow that lists Google Groups with no members, opens a confirmation thread with the owner in Slack, and deletes the group once approved.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_groups","name":"Google Groups"}]},{"title":"Google Groups settings hardening","prompt":"Create a scheduled workflow that reads the settings for every Google Group, flags groups that allow external posting or open membership against policy, and posts the findings to the security team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_groups","name":"Google Groups"}]},{"title":"Google Maps store-locator updater","prompt":"Build a scheduled workflow that audits store locations on the website against Google Maps Places data, flags out-of-date hours or addresses, and pings the team to correct.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_maps","name":"Google Maps"}]},{"title":"Google Maps review tracker","prompt":"Create a scheduled workflow that watches Google Maps reviews of brand locations daily, classifies sentiment, and pings the right manager in Slack on new negative reviews.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_maps","name":"Google Maps"}]},{"title":"Google Meet daily standup link","prompt":"Build a scheduled workflow that posts the day’s Google Meet standup link to the team Slack channel five minutes before standup, with the rolling agenda from the standup table.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_meet","name":"Google Meet"}]},{"title":"PageSpeed monitor for top pages","prompt":"Create a scheduled workflow that runs Google PageSpeed Insights weekly against my top landing pages, writes mobile and desktop scores to a tables-based history, and flags regressions in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"PageSpeed CWV release gate","prompt":"Create a workflow triggered after a marketing-site deploy that runs Google PageSpeed Insights on the key landing pages for both mobile and desktop, compares Core Web Vitals against the prior baseline, and posts a pass/fail summary to Slack with the specific metrics that regressed.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_pagespeed","name":"Google PageSpeed"}]},{"title":"SERP rank tracker","prompt":"Create a scheduled weekly workflow that runs Google searches for my target keywords, records where my domain appears in the results, logs positions to a tables-based scorecard, and posts a Slack summary of gainers and losers.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_search","name":"Google Search"}]},{"title":"Brand mention monitor","prompt":"Build a scheduled workflow that searches Google for new mentions of my brand and key executives, filters out noise with an agent, and posts notable mentions with links to a Slack channel for the comms team.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_search","name":"Google Search"}]},{"title":"Google Sheets approval gate","prompt":"Build a workflow that watches a Google Sheets row for a status change to \\"review\\", posts the row context to Slack with approval buttons, and writes the decision back.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Send Slack messages from Google Sheets","prompt":"Build a workflow that watches a Google Sheets spreadsheet for new rows or changes, then posts formatted Slack updates to keep stakeholders informed in real time.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Google Slides weekly board update","prompt":"Create a scheduled weekly workflow that updates a Google Slides board deck with the latest KPIs from tables, swaps the cover image, and shares the link to the leadership thread.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_slides","name":"Google Slides"}]},{"title":"Google Tasks Slack sync","prompt":"Create a workflow that watches Slack for messages tagged with the saved-task emoji, captures the message and creates a Google Tasks entry with a link to the Slack thread.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_tasks","name":"Google Tasks"}]},{"title":"Google Translate Slack translator","prompt":"Create a workflow that watches an international Slack channel, detects non-English messages with Google Translate, translates them to the team\'s language, and posts the translation in a thread so everyone stays in the loop.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Grafana alert auto-context","prompt":"Build a scheduled workflow that reads Grafana alert-state annotations to find rules that just started firing, queries the underlying data source for the current metric value, summarizes the two together with an agent, and posts the enriched alert to PagerDuty and Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"grafana","name":"Grafana"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Grafana on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of Grafana alerts by service and severity, and posts an on-call digest to Slack each morning.","integrations":[{"id":"slack","name":"Slack"},{"id":"grafana","name":"Grafana"}]},{"title":"Grafana + Linear feature-impact","prompt":"Build a scheduled workflow that queries a Grafana data source for latency and error rates, compares each series against the prior period to spot regressions, correlates them with recent Linear releases, and posts a regression review to the team Slack with the suspected change.","integrations":[{"id":"slack","name":"Slack"},{"id":"grafana","name":"Grafana"},{"id":"linear","name":"Linear"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"},{"id":"linear","name":"Linear"}]},{"title":"Grain weekly call digest","prompt":"Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"}]},{"title":"Grain competitor mentions tracker","prompt":"Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"}]},{"title":"Grain action-item ticket creator","prompt":"Build a workflow that extracts action items from Grain meeting transcripts, creates Linear tasks for each with owners and due dates, and pings the team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"},{"id":"linear","name":"Linear"}]},{"title":"Grain weekly call digest","prompt":"Create a scheduled weekly workflow that summarizes Grain meeting insights — common objections, decisions made, blockers — and posts a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"}]},{"title":"Grain competitor mentions tracker","prompt":"Build a scheduled workflow that scans Grain sales transcripts for competitor mentions, logs the context and outcome to a competitive-intel table, and posts a weekly pattern summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"grain","name":"Grain"}]},{"title":"Granola meeting brief","prompt":"Build a scheduled workflow that reads upcoming meetings from Granola notes, researches attendees and topic with Apollo, and posts a prep brief to Slack before each meeting.","integrations":[{"id":"slack","name":"Slack"},{"id":"granola","name":"Granola"},{"id":"apollo","name":"Apollo"}]},{"title":"Granola weekly digest","prompt":"Create a scheduled weekly workflow that aggregates Granola meeting notes, identifies recurring themes and decisions, and writes a digest to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"granola","name":"Granola"}]},{"title":"Greenhouse pipeline monitor","prompt":"Build a scheduled workflow that syncs open jobs and candidates from Greenhouse to a tracking table daily, flags candidates who have been in the same stage for more than 5 days, and sends a Slack summary to hiring managers with pipeline stats and bottlenecks.","integrations":[{"id":"slack","name":"Slack"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse to onboarding kickoff","prompt":"Build a workflow that fires when a Greenhouse application is marked hired, gathers the new hire profile, kicks off an onboarding plan in a table, schedules week-one meetings via Google Calendar, and posts a welcome announcement to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"greenhouse","name":"Greenhouse"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Greenhouse interview prep packet","prompt":"Create a workflow that runs the morning of every Greenhouse interview, pulls the candidate profile, prior interview notes, and job rubric, assembles a one-page prep file for the interviewer, and emails it with a Slack DM reminder thirty minutes before the slot.","integrations":[{"id":"slack","name":"Slack"},{"id":"greenhouse","name":"Greenhouse"},{"id":"gmail","name":"Gmail"}]},{"title":"Greenhouse pipeline report","prompt":"Build a scheduled workflow that lists open Greenhouse jobs and active applications, follows every cursor page, joins current interview stages and time-in-stage records, and writes per-role counts and stalled stages to a recruiting table. Send the report to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greenhouse scorecard follow-up","prompt":"Build a workflow that lists completed Greenhouse interviews and related scorecards, identifies pending feedback, and prepares a Slack reminder for the recruiting coordinator to review.","integrations":[{"id":"slack","name":"Slack"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Greptile Slack Q&A bot","prompt":"Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files.","integrations":[{"id":"slack","name":"Slack"},{"id":"greptile","name":"Greptile"}]},{"title":"Harmonic saved search sync","prompt":"Create a scheduled workflow that resolves a team-visible Harmonic people saved search, pages every result, compares person URNs with the prior table snapshot, and posts newly seen contacts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"harmonic","name":"Harmonic"}]},{"title":"Harmonic talent scout","prompt":"Build an agent that uses Harmonic Scout to find candidates with a requested title, industry background, and geography, ranks the normalized contacts, and sends the shortlist to a Slack hiring channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"harmonic","name":"Harmonic"}]},{"title":"Daily Support Queue Digest","prompt":"Every weekday morning, list active and pending Help Scout conversations, group them by inbox and assignee, flag the ones customers have waited on longest, and post the digest to the support team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"helpscout","name":"Help Scout"}]},{"title":"Hex project notebook runner","prompt":"Create a scheduled workflow that runs a Hex notebook with parameters every morning, waits for the run to finish, and posts a summary with the published notebook link to a Slack data channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"hex","name":"Hex"}]},{"title":"Hex anomaly digest","prompt":"Build a workflow that runs a Hex notebook for anomaly detection on key metrics nightly, captures detected anomalies into a table, and pages the on-call data team on Slack for severe deltas.","integrations":[{"id":"slack","name":"Slack"},{"id":"hex","name":"Hex"}]},{"title":"Hex + Stripe revenue notebook","prompt":"Build a scheduled workflow that runs a Hex notebook over Stripe payment data daily, captures MRR, churn, and expansion metrics, and posts a summary with the notebook link to a Slack data channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"hex","name":"Hex"},{"id":"stripe","name":"Stripe"}]},{"title":"Hex run failure monitor","prompt":"Build a workflow that lists recent Hex project runs every hour, checks each run status, and when a scheduled notebook fails pulls the error, summarizes the likely cause with an agent, and posts a Slack alert with a link to the run.","integrations":[{"id":"slack","name":"Slack"},{"id":"hex","name":"Hex"}]},{"title":"Get HubSpot deal alerts in Slack","prompt":"Build a workflow that watches HubSpot for deal stage changes, new contacts, and revenue milestones, then posts instant Slack notifications to your sales team.","integrations":[{"id":"slack","name":"Slack"},{"id":"hubspot","name":"HubSpot"}]},{"title":"HubSpot ticket triage","prompt":"Build a workflow that on a new HubSpot support ticket classifies priority and topic, adds a triage note, associates it with the right company, and posts an alert to the support Slack channel for high-priority cases.","integrations":[{"id":"slack","name":"Slack"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Hugging Face sentiment scorer","prompt":"Create a workflow that scores customer feedback with a Hugging Face chat model, writes sentiment and score columns back to the table, and pings Slack on a sudden negative spike.","integrations":[{"id":"slack","name":"Slack"},{"id":"huggingface","name":"Hugging Face"}]},{"title":"Hugging Face feedback classifier","prompt":"Build a workflow that reads new customer feedback rows, uses a Hugging Face chat model to classify sentiment and theme, writes the labels back to the table, and posts a Slack alert when negative feedback spikes.","integrations":[{"id":"slack","name":"Slack"},{"id":"huggingface","name":"Hugging Face"}]},{"title":"IAM permission drift detector","prompt":"Build a scheduled workflow that diffs AWS IAM policies against the Terraform source of truth, alerts on drift, and writes the drift report to a security Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"iam","name":"AWS IAM"}]},{"title":"IAM access-review automator","prompt":"Build a scheduled quarterly workflow that posts AWS IAM access-review requests to role owners in Slack, captures attestations, and writes the audit log to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"iam","name":"AWS IAM"}]},{"title":"IAM stale-key sweeper","prompt":"Create a scheduled workflow that reviews IAM users for aged access keys, notifies the owner via Slack, and rotates the key with a fresh one or removes it after a grace period.","integrations":[{"id":"slack","name":"Slack"},{"id":"iam","name":"AWS IAM"}]},{"title":"IAM unused-role cleaner","prompt":"Build a scheduled monthly workflow that finds IAM roles with no recent activity, requires owner approval in Slack, and removes the role to reduce attack surface.","integrations":[{"id":"slack","name":"Slack"},{"id":"iam","name":"AWS IAM"}]},{"title":"IAM policy guardrail watcher","prompt":"Build a scheduled workflow that snapshots AWS IAM managed policies and role attachments, classifies risk on each change, and pings the security team in Slack when a change broadens permissions.","integrations":[{"id":"slack","name":"Slack"},{"id":"iam","name":"AWS IAM"}]},{"title":"Identity Center access-review","prompt":"Build a scheduled quarterly workflow that surfaces AWS Identity Center permission sets and group memberships, requests owner attestation in Slack, and writes the audit log to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Identity Center assignment monitor","prompt":"Create a scheduled workflow that snapshots AWS Identity Center account assignments and permission sets, flags new or broadened access, and pings the security Slack channel on changes.","integrations":[{"id":"slack","name":"Slack"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Identity Center permission-set drift","prompt":"Build a scheduled workflow that diffs AWS Identity Center permission sets against the Terraform source of truth, alerts on drift, and writes the report.","integrations":[{"id":"slack","name":"Slack"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Inbound email to Slack","prompt":"Build a workflow that triggers when a new email arrives via IMAP, summarizes the subject and body with an agent, and posts the summary with the sender to a Slack channel.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"incident.io commander","prompt":"Build a scheduled workflow that polls incident.io for newly declared incidents, opens a Slack war-room for each, invites responders from the on-call schedule, pulls related PagerDuty alerts, and pins the runbook.","integrations":[{"id":"slack","name":"Slack"},{"id":"incidentio","name":"incident.io"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"incident.io weekly digest","prompt":"Create a scheduled weekly workflow that summarizes incident.io activity — declared incidents, MTTR, top affected services, action-item completion rate — and posts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"incidentio","name":"incident.io"}]},{"title":"Infisical environment drift detector","prompt":"Create a scheduled workflow that diffs Infisical environments against expected schemas, alerts on missing or extra secrets, and writes a remediation queue.","integrations":[{"id":"slack","name":"Slack"},{"id":"infisical","name":"Infisical"}]},{"title":"Infisical secret-inventory reviewer","prompt":"Create a scheduled quarterly workflow that lists Infisical secrets per project and environment, flags ones with weak or aged values for owner attestation in Slack, and writes the review to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"infisical","name":"Infisical"}]},{"title":"Instantly reply triager","prompt":"Create a workflow triggered when an Instantly reply is received that classifies intent, updates the lead interest status, and posts a Slack alert for positive replies so reps follow up fast.","integrations":[{"id":"slack","name":"Slack"},{"id":"instantly","name":"Instantly"}]},{"title":"Instantly performance report","prompt":"Create a scheduled weekly workflow that lists Instantly campaigns and emails, computes reply and interest rates per campaign, logs them to a table for trend tracking, and Slacks a summary to the sales team.","integrations":[{"id":"slack","name":"Slack"},{"id":"instantly","name":"Instantly"}]},{"title":"Instantly reply router","prompt":"Build a scheduled workflow that lists new Instantly campaign email replies, classifies each as interested, objection, or out-of-office with an agent, updates the lead\'s interest status, and posts hot replies to the sales Slack channel for a fast follow-up.","integrations":[{"id":"slack","name":"Slack"},{"id":"instantly","name":"Instantly"}]},{"title":"Intercom feedback analyzer","prompt":"Build a scheduled workflow that pulls support tickets and conversations from Intercom daily, categorizes them by theme and sentiment, tracks trends in a table, and sends a weekly Slack report highlighting the top feature requests and pain points.","integrations":[{"id":"slack","name":"Slack"},{"id":"intercom","name":"Intercom"}]},{"title":"Intercom VIP escalation","prompt":"Create a workflow that monitors new Intercom conversations, looks up the contact in the CRM, and when the contact belongs to a top-tier account, snoozes the conversation, posts a Slack alert in #vip-support with full context, and tags the conversation as VIP.","integrations":[{"id":"slack","name":"Slack"},{"id":"intercom","name":"Intercom"}]},{"title":"Jina competitor watch","prompt":"Create a scheduled workflow that reads competitor pricing and changelog pages with Jina Reader, diffs against the last snapshot, and posts notable changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"jina","name":"Jina"}]},{"title":"Jina Slack research bot","prompt":"Create a Slack bot that runs Jina web search on the asked question, reads the most relevant results with Jina Reader, and replies with a summarized answer and source links.","integrations":[{"id":"slack","name":"Slack"},{"id":"jina","name":"Jina"}]},{"title":"Jira backlog grooming digest","prompt":"Build a scheduled weekly workflow that scans Jira backlog for tickets missing estimates, owners, or priorities, generates a grooming queue, and posts the top items to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"jira","name":"Jira"}]},{"title":"Jira stale-ticket sweeper","prompt":"Create a scheduled workflow that lists Jira tickets with no activity in 14 days, pings the assignee in Slack with a status prompt, and updates the ticket based on the response.","integrations":[{"id":"slack","name":"Slack"},{"id":"jira","name":"Jira"}]},{"title":"JSM major incident broadcaster","prompt":"Build a workflow triggered when a major-incident request is created in Jira Service Management that pulls the affected service from PagerDuty, identifies the current on-call, posts a structured incident brief to a Slack war-room channel, and adds the responders as JSM request participants.","integrations":[{"id":"slack","name":"Slack"},{"id":"jira_service_management","name":"Jira Service Management"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"JSM approval router","prompt":"Build a workflow that watches Jira Service Management requests for new approval steps, posts a Slack DM to each approver with request context and quick-action buttons, and answers the approval in JSM based on their response while keeping the request in sync.","integrations":[{"id":"slack","name":"Slack"},{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"JSM self-service deflection bot","prompt":"Create a knowledge base from internal IT docs, then build a Slack agent that answers employee help requests with cited steps and, when it can\'t resolve the issue, creates a Jira Service Management request with the right request type so nothing falls through.","integrations":[{"id":"slack","name":"Slack"},{"id":"jira_service_management","name":"Jira Service Management"}]},{"title":"Jotform lead routing to Slack","prompt":"Create a workflow that reads unread Jotform submissions for a contact form, has an agent classify each one as a sales lead, support request, or spam, and posts the qualified leads to the sales channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"jotform","name":"Jotform"}]},{"title":"Jotform report generation on demand","prompt":"Create a workflow that takes a form ID and a date range, creates a CSV Jotform report scoped to the selected question fields, and posts the shareable report link to the requesting Slack thread.","integrations":[{"id":"slack","name":"Slack"},{"id":"jotform","name":"Jotform"}]},{"title":"Jupyter kernel health check","prompt":"Build a scheduled workflow that lists running Jupyter kernels, restarts any kernel stuck in a busy state, and posts a summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"jupyter","name":"Jupyter"}]},{"title":"Jupyter kernel health check","prompt":"Build a scheduled workflow that lists running Jupyter kernels, restarts any kernel stuck in a busy state, and posts a summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"jupyter","name":"Jupyter"}]},{"title":"Kalshi event-contract tracker","prompt":"Create a scheduled workflow that polls Kalshi for prices on tracked event contracts, writes the price history to a tables-based portfolio, and posts large-move alerts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"kalshi","name":"Kalshi"}]},{"title":"Kalshi + Polymarket arbitrage scanner","prompt":"Create a scheduled workflow that fetches comparable contracts on Kalshi and Polymarket, computes implied-probability spreads, writes the top arbitrage candidates to a table, and pings Slack on significant gaps.","integrations":[{"id":"slack","name":"Slack"},{"id":"kalshi","name":"Kalshi"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Kalshi position rebalancer","prompt":"Build a workflow that monitors Kalshi position weights against a target allocation, captures drift, and pings Slack with proposed rebalancing trades.","integrations":[{"id":"slack","name":"Slack"},{"id":"kalshi","name":"Kalshi"}]},{"title":"Lambda function runner","prompt":"Create a workflow that takes a JSON request as input, invokes an AWS Lambda function with it, parses the returned payload, and posts the result to Slack. If the invocation returns a function error, include the decoded execution log tail in the alert.","integrations":[{"id":"slack","name":"Slack"},{"id":"lambda","name":"Lambda"}]},{"title":"Lambda blue-green release","prompt":"Build a workflow that updates a Lambda function from a new S3 deployment package, publishes a version, shifts 10 percent of alias traffic to it with weighted routing, waits for approval in Slack, then promotes the alias to 100 percent or rolls it back.","integrations":[{"id":"slack","name":"Slack"},{"id":"lambda","name":"Lambda"}]},{"title":"Lambda concurrency guard","prompt":"Create a scheduled workflow that reads Lambda account settings and each function reserved concurrency, detects when unreserved concurrency drops below a safe floor, and alerts the on-call channel with the functions consuming the most reserved capacity.","integrations":[{"id":"slack","name":"Slack"},{"id":"lambda","name":"Lambda"}]},{"title":"Lambda event source auditor","prompt":"Build a scheduled workflow that lists every Lambda event source mapping, flags any whose state is not Enabled or whose last processing result reports errors, summarizes the likely cause, and posts a daily digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"lambda","name":"Lambda"}]},{"title":"Lambda async failure triage","prompt":"Create a workflow that reads the asynchronous invocation configuration of a Lambda function, pulls failed invocation records from its on-failure destination queue, invokes the function again in dry run mode to check permissions, and summarizes the failure cause in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"lambda","name":"Lambda"}]},{"title":"LangSmith error logger","prompt":"Create a workflow that on a failed agent step forwards a LangSmith run tagged as an error with the inputs and error message, and posts the run link to Slack for the ML team.","integrations":[{"id":"slack","name":"Slack"},{"id":"langsmith","name":"LangSmith"}]},{"title":"LaTeX weekly metrics report","prompt":"Build a scheduled weekly workflow that pulls metrics from a table, typesets a LaTeX report with charts and tables, compiles it to PDF, and posts it to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"latex","name":"LaTeX"}]},{"title":"LaunchDarkly rollout digest","prompt":"Build a scheduled weekly workflow that lists LaunchDarkly flags with their current status and rollout percentage per environment, summarizes what changed since last week, and posts a digest to the product Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"launchdarkly","name":"LaunchDarkly"}]},{"title":"LaunchDarkly flag-flip safety gate","prompt":"Create a scheduled workflow that reads the LaunchDarkly audit log for recent production flag flips, checks Sentry error rate and Datadog SLO burn against each, toggles the flag back off on regression, and posts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"sentry","name":"Sentry"},{"id":"datadog","name":"Datadog"}]},{"title":"LaunchDarkly + Linear release planner","prompt":"Create a workflow that watches Linear releases marked behind a LaunchDarkly flag, validates the flag exists, posts the rollout plan to Slack, and tracks rollout progress on the release ticket.","integrations":[{"id":"slack","name":"Slack"},{"id":"launchdarkly","name":"LaunchDarkly"},{"id":"linear","name":"Linear"}]},{"title":"Lemlist reply router","prompt":"Create a workflow triggered by Lemlist reply webhooks that classifies each reply by intent and posts a Slack notification to the lead owner with a one-line summary, the intent, and the reply text.","integrations":[{"id":"slack","name":"Slack"},{"id":"lemlist","name":"Lemlist"}]},{"title":"Lemlist bounced lead sweeper","prompt":"Build a workflow triggered by Lemlist email-bounced events that looks up the lead, writes the bounce to a suppression table, and posts a Slack alert so the team can clean the list and keep quality high.","integrations":[{"id":"slack","name":"Slack"},{"id":"lemlist","name":"Lemlist"}]},{"title":"Meeting notes to Linear tasks","prompt":"Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"linear","name":"Linear"},{"id":"asana","name":"Asana"}]},{"title":"Linear issue updates in Slack","prompt":"Build a workflow that monitors Linear for new issues, assignments, and completions, and posts a formatted Slack message for each event so your team is always in the loop.","integrations":[{"id":"slack","name":"Slack"},{"id":"linear","name":"Linear"}]},{"title":"Bug report to Linear issue","prompt":"Build a workflow that watches a Slack channel for bug reports, extracts the steps to reproduce and severity with an agent, creates a labeled Linear issue in the right team, and replies in-thread with the issue link.","integrations":[{"id":"slack","name":"Slack"},{"id":"linear","name":"Linear"}]},{"title":"Linear sprint review digest","prompt":"Build a scheduled weekly workflow that searches Linear for issues completed and still open in the active cycle, summarizes progress and blockers with an agent, logs velocity to a table, and posts a sprint review digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"linear","name":"Linear"}]},{"title":"Linkup + Slack research bot","prompt":"Build a Slack bot that answers research questions with Linkup-grounded citations, hands off to a human on low-confidence answers, and logs each conversation.","integrations":[{"id":"slack","name":"Slack"},{"id":"linkup","name":"Linkup"}]},{"title":"Logfire error digest","prompt":"Create a scheduled workflow that runs every morning, searches Logfire for records at error level or above from the last 24 hours, groups them by service and exception type, and posts a ranked digest to Slack with the worst offenders first.","integrations":[{"id":"slack","name":"Slack"},{"id":"logfire","name":"Logfire"}]},{"title":"LogRocket audit log compliance export","prompt":"Create a scheduled workflow that pages through the LogRocket audit log every night, writes each entry to a compliance table, and alerts Slack when a session was viewed by someone outside the approved reviewer list.","integrations":[{"id":"slack","name":"Slack"},{"id":"logrocket","name":"LogRocket"}]},{"title":"LogRocket + Sentry incident context","prompt":"Build a workflow that triggers on a new Sentry issue, requests LogRocket session highlights for the impacted user, and posts a combined stack trace plus session narrative into the incident Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"logrocket","name":"LogRocket"},{"id":"sentry","name":"Sentry"}]},{"title":"LogRocket release tagging on deploy","prompt":"Build a workflow that runs after a GitHub deployment succeeds, registers the deployed version as a LogRocket release so stack traces decode against it, and posts the tagged version to the release channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"logrocket","name":"LogRocket"},{"id":"github","name":"GitHub"}]},{"title":"Mailchimp campaign performance digest","prompt":"Build a scheduled workflow that pulls the previous week of Mailchimp campaign reports, compares open and click rates against my benchmarks, and posts a Slack digest with the winners, losers, and one-line takeaways.","integrations":[{"id":"slack","name":"Slack"},{"id":"mailchimp","name":"Mailchimp"}]},{"title":"Mailgun event analytics digest","prompt":"Build a scheduled workflow that pulls Mailgun message events, aggregates deliveries, opens, clicks, and complaints by tag and domain, and posts a Slack digest with anomalies and the top-performing tags of the day.","integrations":[{"id":"slack","name":"Slack"},{"id":"mailgun","name":"Mailgun"}]},{"title":"Mailgun domain verification monitor","prompt":"Create a scheduled workflow that checks the status of each Mailgun sending domain, flags any domain whose SPF, DKIM, or tracking records fall out of verification, and pages the on-call engineer in Slack with the exact records that need fixing.","integrations":[{"id":"slack","name":"Slack"},{"id":"mailgun","name":"Mailgun"}]},{"title":"Claude Managed Agents overnight refactor","prompt":"Build a workflow that runs nightly, opens a Claude Managed Agents session against a mounted repository, asks it to work through the migration backlog, and posts the branches it pushed to Slack in the morning.","integrations":[{"id":"slack","name":"Slack"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Claude Managed Agents approval gate","prompt":"Build a workflow that creates a Claude Managed Agents session, polls it for tool calls waiting on permission, posts each one to Slack for a human decision, and sends the allow or deny answer back to the session so it keeps working.","integrations":[{"id":"slack","name":"Slack"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Claude Managed Agents conversational assistant","prompt":"Build a workflow that creates a Claude Managed Agents session on the first Slack message in a thread, stores the session id, and sends every later reply in that thread to the same session so the agent keeps its context across runs.","integrations":[{"id":"slack","name":"Slack"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"Claude Managed Agents runaway stopper","prompt":"Build a scheduled workflow that checks long-running Claude Managed Agents sessions, interrupts any that have been working past a threshold, archives the ones that already finished, and posts what it stopped to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"managed_agent","name":"Claude Managed Agents"}]},{"title":"File a ServiceDesk Plus ticket from Slack","prompt":"When someone posts in the #it-help Slack channel, create a ServiceDesk Plus request with their message as the description and the first line as the subject, then reply in the thread with the request number.","integrations":[{"id":"slack","name":"Slack"},{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Post the ServiceDesk Plus change calendar to Slack","prompt":"Every Monday morning, list ServiceDesk Plus changes scheduled for the coming week and post a summary to the #change-management Slack channel, grouped by change type and showing the owner of each.","integrations":[{"id":"slack","name":"Slack"},{"id":"manageengine_sdp","name":"ManageEngine ServiceDesk Plus"}]},{"title":"Mem0 + Slack assistant memory","prompt":"Build a Slack bot that uses Mem0 to remember user preferences and prior conversations, so each follow-up question lands in context instead of starting fresh.","integrations":[{"id":"slack","name":"Slack"},{"id":"mem0","name":"Mem0"}]},{"title":"Dataverse record sync","prompt":"Build a scheduled workflow that mirrors records between Microsoft Dataverse and a Sim table, normalizes schemas, and posts conflict reports to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"microsoft_dataverse","name":"Microsoft Dataverse"}]},{"title":"Dynamics pipeline review","prompt":"Create a scheduled workflow that lists open Dynamics 365 opportunities with an OData filter, summarizes the current page by owner and expected close date, and posts the review to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"microsoft_dynamics_365","name":"Microsoft Dynamics 365 CRM"}]},{"title":"Word incident postmortem","prompt":"Build a workflow triggered by a resolved Linear incident that drafts a postmortem in Word from the issue timeline, exports it as PDF, and shares the PDF in the incident Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"microsoft_word","name":"Microsoft Word"},{"id":"linear","name":"Linear"}]},{"title":"Mintlify docs-gap reporter","prompt":"Create a scheduled workflow that exports Mintlify assistant conversations weekly, filters the ones marked unanswered, groups them into themes, and posts the top documentation gaps to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"mintlify","name":"Mintlify"}]},{"title":"Mintlify support answer bot","prompt":"Build a workflow that takes an inbound support question, asks the Mintlify docs assistant for an answer, and replies in Slack with the answer and its cited documentation links.","integrations":[{"id":"slack","name":"Slack"},{"id":"mintlify","name":"Mintlify"}]},{"title":"Mistral Parser invoice intake","prompt":"Build a workflow that runs each incoming invoice PDF through Mistral Parser, extracts vendor, line items, totals, and due date into an accounts-payable table, and flags any invoice missing a PO number for the finance team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Mistral Parser resume screener","prompt":"Build a workflow that parses uploaded resume PDFs with Mistral Parser, extracts candidate skills, experience, and contact details into a hiring table, and posts a shortlist summary to the recruiting channel in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"mistral_parse","name":"Mistral Parser"}]},{"title":"Modal self-hosted chat","prompt":"Create a workflow that answers incoming Slack messages by generating a chat completion on a Modal Endpoint running an open-weight model, then posts the reply back to the thread.","integrations":[{"id":"slack","name":"Slack"},{"id":"modal","name":"Modal"}]},{"title":"Modal endpoint health check","prompt":"Build a scheduled workflow that lists the models a Modal token can reach, sends a short test completion to each one, records the latency in a table, and alerts the engineering channel when an endpoint stops responding.","integrations":[{"id":"slack","name":"Slack"},{"id":"modal","name":"Modal"}]},{"title":"Modal image generation","prompt":"Create a workflow that takes a prompt from a form, calls a deployed Modal function that generates an image, and shares the result in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"modal","name":"Modal"}]},{"title":"Monday status digest","prompt":"Create a scheduled weekly workflow that pulls Monday board progress, computes completion rate, and posts a status update to leadership Slack with the at-risk items highlighted.","integrations":[{"id":"slack","name":"Slack"},{"id":"monday","name":"Monday"}]},{"title":"Monday board automator","prompt":"Build a workflow that watches Monday boards for status changes, applies branching automations — assign owners, set due dates, post Slack updates — based on a rules table.","integrations":[{"id":"slack","name":"Slack"},{"id":"monday","name":"Monday"}]},{"title":"MongoDB orphaned-doc cleaner","prompt":"Build a scheduled workflow that runs weekly, finds orphaned references in MongoDB, dry-runs the cleanup plan, posts to Slack for approval, and executes once approved.","integrations":[{"id":"slack","name":"Slack"},{"id":"mongodb","name":"MongoDB"}]},{"title":"MongoDB query digest","prompt":"Create a scheduled daily workflow that aggregates MongoDB query telemetry from the profiler, identifies the top-cost queries, and posts a Slack engineering digest.","integrations":[{"id":"slack","name":"Slack"},{"id":"mongodb","name":"MongoDB"}]},{"title":"SQL Server metrics digest to Slack","prompt":"Create a scheduled workflow that queries key business metrics from Microsoft SQL Server each morning, has an agent summarize the numbers and notable changes, and posts the digest to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"SQL Server threshold breach alert","prompt":"Build a scheduled workflow that queries a Microsoft SQL Server count or aggregate, compares it to a threshold, and posts a Slack alert only when the value crosses the limit so the team hears about problems early.","integrations":[{"id":"slack","name":"Slack"},{"id":"mssql","name":"Microsoft SQL Server"}]},{"title":"Daily MySQL metrics report to Slack","prompt":"Create a scheduled workflow that runs a MySQL query for yesterday’s key metrics, has an agent summarize the rows into a short update, and posts the digest to a Slack channel every morning.","integrations":[{"id":"slack","name":"Slack"},{"id":"mysql","name":"MySQL"}]},{"title":"Nightly MySQL data-quality audit","prompt":"Build a scheduled workflow that runs MySQL queries checking for nulls, duplicates, and orphaned foreign keys, has an agent describe any issues found, and alerts the team in Slack when the counts are non-zero.","integrations":[{"id":"slack","name":"Slack"},{"id":"mysql","name":"MySQL"}]},{"title":"Neo4j fraud-ring detector","prompt":"Create a scheduled workflow that queries Neo4j for suspicious connection patterns — shared devices, overlapping addresses — writes risk-scored clusters to a fraud table, and pings Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"neo4j","name":"Neo4j"}]},{"title":"New Relic health report","prompt":"Create a scheduled daily workflow that runs NRQL queries against New Relic for error rate, latency percentiles, and throughput, logs the results to a table for trend tracking, and Slacks a morning summary highlighting any degradations.","integrations":[{"id":"slack","name":"Slack"},{"id":"new_relic","name":"New Relic"}]},{"title":"New Relic deployment tracker","prompt":"Build a workflow that fires after each production release, records a New Relic deployment change event for the affected entity, and posts a Slack note linking the deployment to the dashboard for the on-call engineer.","integrations":[{"id":"slack","name":"Slack"},{"id":"new_relic","name":"New Relic"}]},{"title":"New Relic entity inventory","prompt":"Build a scheduled weekly workflow that searches New Relic for all monitored entities, fetches details for each, logs them into an inventory table, and Slacks a diff of newly added or removed services.","integrations":[{"id":"slack","name":"Slack"},{"id":"new_relic","name":"New Relic"}]},{"title":"New Relic incident war-room kickoff","prompt":"Create a workflow triggered by a PagerDuty incident that runs NRQL queries for the impacted service, pulls the latest deployment change event from New Relic, and posts a war-room summary with golden-signal charts to the incident Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"new_relic","name":"New Relic"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Notify your team from Notion","prompt":"Build a workflow that watches Notion for new or updated pages and automatically posts a Slack message so your team stays aligned without manual check-ins.","integrations":[{"id":"slack","name":"Slack"},{"id":"notion","name":"Notion"}]},{"title":"Notion weekly digest builder","prompt":"Create a scheduled weekly workflow that queries a Notion project database for items completed this week, appends a summary section to a Notion review page, and posts the highlights to Slack for the team.","integrations":[{"id":"slack","name":"Slack"},{"id":"notion","name":"Notion"}]},{"title":"Okta quarterly access review","prompt":"Build a scheduled quarterly workflow that pulls Okta group memberships per app, posts an attestation thread to each owner in Slack, captures confirmations, and writes the audit log to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"okta","name":"Okta"}]},{"title":"Okta compromised-account responder","prompt":"Create a workflow triggered by a CrowdStrike detection on a user that suspends the matching Okta account, resets their password, and pings the security Slack channel with the action taken.","integrations":[{"id":"slack","name":"Slack"},{"id":"okta","name":"Okta"},{"id":"crowdstrike","name":"CrowdStrike"}]},{"title":"1Password access-review automator","prompt":"Build a scheduled quarterly workflow that inventories 1Password items per vault, requires owner re-attestation in Slack, and writes the audit log to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"onepassword","name":"1Password"}]},{"title":"1Password Slack secret-share guard","prompt":"Create a workflow that monitors Slack for accidental secret sharing, redacts the message, and posts a polite reminder to use 1Password Secret Sharing instead.","integrations":[{"id":"slack","name":"Slack"},{"id":"onepassword","name":"1Password"}]},{"title":"Oracle KPI digest","prompt":"Create a scheduled workflow that queries key business metrics from Oracle Database each morning, has an agent summarize changes and anomalies, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"oracledb","name":"Oracle Database"}]},{"title":"Alert on Oracle thresholds","prompt":"Build a scheduled workflow that runs an Oracle aggregate query, compares the result with a threshold, and sends a Slack alert only when the limit is crossed.","integrations":[{"id":"slack","name":"Slack"},{"id":"oracledb","name":"Oracle Database"}]},{"title":"Otter meeting recap to Slack","prompt":"Build a workflow that runs when an Otter conversation finishes processing, turns its summary, action items, and insights into a short recap, and posts it to the team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"otter","name":"Otter.ai"}]},{"title":"Outlook executive triage","prompt":"Build a scheduled workflow that scans Outlook every hour, ranks new emails by urgency, summarizes the top items, and posts a prioritized digest to a Slack channel so executives can act without opening the inbox.","integrations":[{"id":"slack","name":"Slack"},{"id":"outlook","name":"Outlook"}]},{"title":"Outlook daily agenda digest","prompt":"Create a scheduled workflow that lists my Outlook calendar events for the day each morning, summarizes each meeting with its attendees and join link, and posts the agenda to a Slack DM before my first meeting.","integrations":[{"id":"slack","name":"Slack"},{"id":"outlook","name":"Outlook"}]},{"title":"PagerDuty incident war room","prompt":"Build a scheduled workflow that polls PagerDuty for new severity-1 incidents, opens a Slack war-room channel, invites responders, posts the incident summary, and updates the channel topic with status.","integrations":[{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PagerDuty on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of PagerDuty incidents, MTTR, and on-call load by responder, and posts a Slack digest to the SRE channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"PagerDuty customer-impact notifier","prompt":"Create a scheduled workflow that polls PagerDuty for incidents on customer-facing services, looks up affected accounts in Salesforce, and drafts a status-page update plus a Slack alert to the customer success team for high-impact outages.","integrations":[{"id":"slack","name":"Slack"},{"id":"pagerduty","name":"PagerDuty"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Parallel AI competitor monitor","prompt":"Create a scheduled workflow that uses Parallel AI search to find new announcements from a list of competitors, extracts the key details from each source URL, and posts a cited digest to Slack for the product team.","integrations":[{"id":"slack","name":"Slack"},{"id":"parallel_ai","name":"Parallel AI"}]},{"title":"PDL hiring-signal alerter","prompt":"Create a scheduled workflow that runs People Data Labs person-search for new hires in relevant roles at tracked accounts and posts a Slack alert when a match appears.","integrations":[{"id":"slack","name":"Slack"},{"id":"peopledatalabs","name":"People Data Labs"}]},{"title":"Daily news brief via Perplexity","prompt":"Create a scheduled daily workflow that queries Perplexity for the latest news on topics I follow, summarizes each thread with citations, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"perplexity","name":"Perplexity"}]},{"title":"Perplexity competitor-watch monitor","prompt":"Build a scheduled workflow that asks Perplexity for any new launches, pricing changes, or announcements from a list of competitors, summarizes what changed since last run, and posts a cited digest to a Slack channel for the product team.","integrations":[{"id":"slack","name":"Slack"},{"id":"perplexity","name":"Perplexity"}]},{"title":"Persona decision router","prompt":"Build a workflow that takes an inquiry ID, fetches the inquiry from Persona, and routes on its status: approved customers get a welcome email, needs-review inquiries post to a compliance Slack channel with a summary, and declined inquiries update our CRM.","integrations":[{"id":"slack","name":"Slack"},{"id":"persona","name":"Persona"},{"id":"gmail","name":"Gmail"}]},{"title":"Persona pending-review digest","prompt":"Build a scheduled workflow that runs every morning, lists Persona inquiries with needs_review status from the last 24 hours, summarizes each one, and posts a digest to the compliance team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"persona","name":"Persona"}]},{"title":"Persona case triage agent","prompt":"Build an agent that lists open Persona cases, fetches the linked inquiry and verification details for each, drafts a recommended approve/decline decision with reasoning, and posts the triage summary to Slack for a human reviewer.","integrations":[{"id":"slack","name":"Slack"},{"id":"persona","name":"Persona"}]},{"title":"Pinecone retrieval-quality monitor","prompt":"Build a scheduled weekly workflow that runs a fixed set of benchmark queries against a Pinecone index, records top-k similarity scores per namespace to a table, and pings Slack when retrieval quality regresses.","integrations":[{"id":"slack","name":"Slack"},{"id":"pinecone","name":"Pinecone"}]},{"title":"Pipedrive deal pipeline tracker","prompt":"Create a scheduled workflow that mirrors Pipedrive deals into a Sim table, calculates pipeline velocity per stage, and posts a daily Slack summary of deals at risk.","integrations":[{"id":"slack","name":"Slack"},{"id":"pipedrive","name":"Pipedrive"}]},{"title":"Pipedrive Slack channel-per-deal","prompt":"Create a workflow that for Pipedrive deals above a threshold creates a Slack channel, invites the account team, and pins the deal record link.","integrations":[{"id":"slack","name":"Slack"},{"id":"pipedrive","name":"Pipedrive"}]},{"title":"PitchBook deal flow monitor","prompt":"Build a scheduled workflow that runs a PitchBook company search for early-stage VC deals in my target verticals closed in the last week, pulls each deal size and lead investor, writes them to a deal-flow table, and posts a digest to the investment team Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"pitchbook","name":"PitchBook"}]},{"title":"Plane daily project digest","prompt":"Build a scheduled workflow that pages through Plane work items and sends a daily summary of overdue, blocked, and completed work to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"plane","name":"Plane"}]},{"title":"Deployment status report","prompt":"Build a workflow. On a schedule, list Vitess deploy requests and report their deployment states to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"planetscale","name":"PlanetScale"}]},{"title":"Polymarket position monitor","prompt":"Create a scheduled workflow that fetches Polymarket prices for tracked markets, computes price changes vs entry, writes the portfolio to a table, and pings Slack when any position swings beyond a threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Polymarket large-order tracker","prompt":"Build a scheduled workflow that pulls Polymarket order book activity, identifies unusually large orders on tracked markets, and pings Slack on whale activity.","integrations":[{"id":"slack","name":"Slack"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Polymarket arbitrage scanner","prompt":"Build a scheduled workflow that fetches prices for related Polymarket markets, detects when complementary outcomes sum away from fair value, writes the mispriced pairs to a table, and pings Slack with the implied edge for each opportunity.","integrations":[{"id":"slack","name":"Slack"},{"id":"polymarket","name":"Polymarket"}]},{"title":"Postgres metrics digest to Slack","prompt":"Create a scheduled workflow that queries key business metrics from PostgreSQL each morning, has an agent summarize the numbers and notable changes, and posts the digest to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"postgresql","name":"PostgreSQL"}]},{"title":"Postgres threshold breach alert","prompt":"Build a scheduled workflow that queries a PostgreSQL count or aggregate, compares it to a threshold, and posts a Slack alert only when the value crosses the limit so the team hears about problems early.","integrations":[{"id":"slack","name":"Slack"},{"id":"postgresql","name":"PostgreSQL"}]},{"title":"PostHog insight digest","prompt":"Create a scheduled daily workflow that pulls key PostHog insights — DAU, top events, funnels — and posts a digest to Slack with week-over-week deltas and emoji indicators.","integrations":[{"id":"slack","name":"Slack"},{"id":"posthog","name":"PostHog"}]},{"title":"PostHog feature flag flip notifier","prompt":"Build a scheduled workflow that polls PostHog feature flags, detects status changes since the last run, and posts a Slack notification with the old and new state for each changed flag.","integrations":[{"id":"slack","name":"Slack"},{"id":"posthog","name":"PostHog"}]},{"title":"PostHog survey response analyzer","prompt":"Create a scheduled workflow that lists active PostHog surveys, pulls their responses with a query, runs sentiment and theme analysis across the open-text answers, and posts a summary of top themes and NPS movement to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"posthog","name":"PostHog"}]},{"title":"Power BI sales target alert","prompt":"Create a scheduled workflow that queries approved sales and target measures from a Power BI semantic model, compares complete results with a configured threshold, and alerts the sales team in Slack when the target is missed.","integrations":[{"id":"slack","name":"Slack"},{"id":"powerbi","name":"Power BI"}]},{"title":"Power BI refresh failure monitor","prompt":"Create a scheduled workflow that retrieves refresh history for critical Power BI semantic models, identifies failed requests and their error details, and notifies an operations Slack channel once per request ID using a Sim table to track previously reported failures.","integrations":[{"id":"slack","name":"Slack"},{"id":"powerbi","name":"Power BI"}]},{"title":"Profound AI-visibility tracker","prompt":"Create a scheduled weekly workflow that pulls Profound brand-visibility scores across AI search engines, tracks how my brand surfaces in answers for tracked prompts, and reports week-over-week shifts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"profound","name":"Profound"}]},{"title":"Profound visibility-drop alerter","prompt":"Create a workflow that checks Profound brand-visibility scores daily, compares each tracked prompt against its baseline, and immediately pages the marketing on-call in Slack when visibility drops sharply on a high-priority prompt.","integrations":[{"id":"slack","name":"Slack"},{"id":"profound","name":"Profound"}]},{"title":"Pulse document summarizer","prompt":"Build a workflow that extracts the text of an uploaded PDF or Office file with Pulse OCR, has an agent write a concise summary, and posts it to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"pulse","name":"Pulse"}]},{"title":"Quartr earnings call digest","prompt":"Create a scheduled workflow that lists yesterday’s Quartr events for my watchlist tickers, fetches the AI-generated summary for each event, and posts a digest with source links to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"quartr","name":"Quartr"}]},{"title":"Quartr live earnings monitor","prompt":"Create a scheduled workflow that polls Quartr live events for my watchlist, and when a company goes live, posts the live audio and transcript stream links to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"quartr","name":"Quartr"}]},{"title":"RabbitMQ dead-letter triage","prompt":"Build a scheduled workflow that reads messages off the RabbitMQ dead-letter queue every 15 minutes, groups them by failure reason, writes the groups to a table, and posts a summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ to Slack incident relay","prompt":"Create a scheduled workflow that drains a RabbitMQ alerts queue, summarizes each message with an agent, and posts the summary to the on-call Slack channel with a severity label.","integrations":[{"id":"slack","name":"Slack"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ stalled consumer detector","prompt":"Build a scheduled workflow that cross-references RabbitMQ queue depth with consumers and channels, flags queues whose consumers are inactive or whose unacknowledged counts are stuck at the prefetch limit, and posts the findings to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"RabbitMQ dead-letter policy rollout","prompt":"Create a workflow that audits RabbitMQ policies across virtual hosts, finds queue families with no dead-letter exchange configured, and applies a standard dead-lettering policy after posting the plan for approval.","integrations":[{"id":"slack","name":"Slack"},{"id":"rabbitmq","name":"RabbitMQ"}]},{"title":"Railway deployment monitor","prompt":"Build a scheduled workflow that lists the latest Railway deployments across my services every few minutes, detects failed or crashed deployments, summarizes the failure with an agent, and posts an actionable Slack alert with a link to the service.","integrations":[{"id":"slack","name":"Slack"},{"id":"railway","name":"Railway"}]},{"title":"Railway deploy on merge","prompt":"Create a workflow that watches GitHub for merges to the main branch, triggers a Railway service deployment for the matching environment, and posts the deployment status back as a Slack notification.","integrations":[{"id":"slack","name":"Slack"},{"id":"railway","name":"Railway"},{"id":"github","name":"GitHub"}]},{"title":"Railway project inventory","prompt":"Create a scheduled workflow that lists every Railway project, its services, and environments weekly, logs them into a tracking table, and Slacks a diff of any added or removed resources so infrastructure changes never go unnoticed.","integrations":[{"id":"slack","name":"Slack"},{"id":"railway","name":"Railway"}]},{"title":"Railway config sync","prompt":"Build a workflow that reads service configuration from a table and upserts the matching Railway environment variables for each service, then posts a Slack summary of every variable that was created or changed.","integrations":[{"id":"slack","name":"Slack"},{"id":"railway","name":"Railway"}]},{"title":"Railway project onboarding kit","prompt":"Build a workflow that takes a new service name, creates a Railway project, sets up staging and production environments, seeds baseline environment variables from a table, and posts the project members and access summary to Slack for the team.","integrations":[{"id":"slack","name":"Slack"},{"id":"railway","name":"Railway"}]},{"title":"RB2B visitor Slack alerts","prompt":"Create a workflow that reads a list of website visitor IPs, uses RB2B to resolve each person and their company, and posts an alert with the identified LinkedIn profile and company to the sales Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"rb2b","name":"RB2B"}]},{"title":"RDS daily metrics digest","prompt":"Build a scheduled workflow that runs an aggregate SQL query against my Amazon RDS database each morning, summarizes the key numbers with an agent, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rds","name":"Amazon RDS"}]},{"title":"RDS record updater from Slack","prompt":"Build a workflow that reads update requests posted in a Slack channel, parses the target record and fields with an agent, and runs the matching UPDATE against Amazon RDS with the conditions applied.","integrations":[{"id":"slack","name":"Slack"},{"id":"rds","name":"Amazon RDS"}]},{"title":"RDS row-change alerter","prompt":"Create a scheduled workflow that queries Amazon RDS for rows matching a watch condition, compares them to the previous run stored in a table, and posts a Slack alert when a tracked record changes.","integrations":[{"id":"slack","name":"Slack"},{"id":"rds","name":"Amazon RDS"}]},{"title":"Reddit mention tracker","prompt":"Create a scheduled workflow that monitors Reddit and X for mentions of my brand and competitors, scores each mention by sentiment and reach, logs them to a table, and sends a daily Slack digest of notable mentions.","integrations":[{"id":"slack","name":"Slack"},{"id":"reddit","name":"Reddit"},{"id":"x","name":"X"}]},{"title":"Reddit subreddit monitor","prompt":"Build a scheduled workflow that uses Reddit to watch target subreddits for posts matching brand or product keywords, scores each for relevance and sentiment, and posts notable hits to Slack with the original link.","integrations":[{"id":"slack","name":"Slack"},{"id":"reddit","name":"Reddit"}]},{"title":"Reddit crisis-signal alerter","prompt":"Build a scheduled workflow that polls Reddit for sudden bursts of negative posts about the brand, classifies severity, and pages the PR team via Slack and PagerDuty when a real crisis emerges.","integrations":[{"id":"slack","name":"Slack"},{"id":"reddit","name":"Reddit"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Redis daily counter digest","prompt":"Create a scheduled workflow that reads the day’s Redis counters by key pattern, builds a summary of the totals with an agent, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"redis","name":"Redis"}]},{"title":"Reducto form-intake router","prompt":"Build a workflow that runs each uploaded intake form through Reducto, extracts the applicant fields into a table, and routes the parsed submission to the right reviewer in Slack based on the form type.","integrations":[{"id":"slack","name":"Slack"},{"id":"reducto","name":"Reducto"}]},{"title":"Resend domain monitor","prompt":"Create a scheduled workflow that lists Resend domains, checks DNS verification status for each, and posts a Slack alert the moment any domain shows a verification or DKIM problem so we never silently lose deliverability.","integrations":[{"id":"slack","name":"Slack"},{"id":"resend","name":"Resend"}]},{"title":"RevenueCat MRR dashboard","prompt":"Build a scheduled daily workflow that pulls RevenueCat subscriber and offering data, calculates MRR, ARPU, and trial-to-paid conversion, logs the metrics to a tracking table with historical trends, and posts a daily Slack summary for the growth team.","integrations":[{"id":"slack","name":"Slack"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"RevenueCat entitlement granter","prompt":"Create a workflow that listens for a customer-success approval — for example a Slack reaction or a row in a table — looks up the RevenueCat subscriber, grants a promotional entitlement with the right expiry, and logs the grant in an audit table for compliance.","integrations":[{"id":"slack","name":"Slack"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"RevenueCat offering report","prompt":"Build a scheduled weekly workflow that pulls RevenueCat offerings and recent purchases, computes conversion rate per offering and per package, writes a narrative analysis file with recommendations, and Slacks growth leadership the top findings.","integrations":[{"id":"slack","name":"Slack"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"Rippling new-hire provisioning","prompt":"Build a scheduled workflow that polls Rippling for new workers, creates accounts in the matching downstream tools, drops each new hire into the right Slack channels, books day-one onboarding via Google Calendar, and writes provisioning status to a tracking table.","integrations":[{"id":"slack","name":"Slack"},{"id":"rippling","name":"Rippling"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Rippling departure offboarder","prompt":"Create a scheduled workflow that polls Rippling for workers transitioning out, gathers their owned resources, deactivates downstream accounts, schedules data handoff meetings, posts a structured offboarding checklist to a table, and notifies the people team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rippling","name":"Rippling"}]},{"title":"Rippling org chart export","prompt":"Build a scheduled weekly workflow that pulls Rippling workers, departments, teams, and titles, writes an updated org chart file, diffs against last week to find structural changes, and Slacks people operations any unexpected moves for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"rippling","name":"Rippling"}]},{"title":"Rocketlane onboarding kickoff","prompt":"Build a workflow that creates a Rocketlane project from an onboarding template for a new customer, assigns the implementation manager placeholder, adds the account team as members, and posts a kickoff summary with the project details to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rocketlane task escalation","prompt":"Build a scheduled daily workflow that lists Rocketlane tasks with a due date before today that are not complete, marks them at risk, and posts an escalation to Slack tagging each task name, project, and assignees.","integrations":[{"id":"slack","name":"Slack"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rocketlane time rollup","prompt":"Create a scheduled weekly workflow that searches Rocketlane time entries for the past week, totals billable and non-billable minutes per project, and posts a formatted utilization rollup to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rocketlane timesheet reminder","prompt":"Build a scheduled Friday workflow that lists active Rocketlane team members, searches this week’s time entries per user, and sends a Slack reminder to anyone who has logged less than their expected hours.","integrations":[{"id":"slack","name":"Slack"},{"id":"rocketlane","name":"Rocketlane"}]},{"title":"Rootly incident war-room","prompt":"Build a scheduled workflow that polls Rootly for newly opened incidents, creates a Slack war-room channel for each, invites responders, posts the incident summary, and keeps the channel topic in sync with severity.","integrations":[{"id":"slack","name":"Slack"},{"id":"rootly","name":"Rootly"}]},{"title":"Rootly retro generator","prompt":"Create a scheduled workflow that polls Rootly for recently closed incidents, drafts the retrospective doc, pulls the Slack thread and timeline, and assigns owners for follow-up actions in Linear.","integrations":[{"id":"slack","name":"Slack"},{"id":"rootly","name":"Rootly"},{"id":"linear","name":"Linear"}]},{"title":"Rootly weekly digest","prompt":"Build a scheduled weekly workflow that summarizes Rootly incident counts, MTTR, top affected services, and outstanding action items, and posts a digest to leadership Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"rootly","name":"Rootly"}]},{"title":"Rootly on-call digest","prompt":"Create a scheduled daily workflow that summarizes the past 24 hours of Rootly pages, the on-call responder load by person, and writes a digest to the SRE Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"rootly","name":"Rootly"}]},{"title":"RSS post to Slack","prompt":"Build a workflow that triggers when a new item is published in an RSS feed, writes a one-line summary of the item with an agent, and posts the title, summary, and link to a Slack channel.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"S3 report archiver","prompt":"Build a scheduled workflow that generates a daily report file, uploads it to an S3 bucket under a dated prefix, and posts the object link to Slack so the team always has the latest archived copy.","integrations":[{"id":"slack","name":"Slack"},{"id":"s3","name":"S3"}]},{"title":"SailPoint joiner access review","prompt":"Create a scheduled workflow that lists recent SailPoint account activities for joiners, summarizes their granted access and time-to-access, and posts a digest to Slack for the identity team.","integrations":[{"id":"slack","name":"Slack"},{"id":"sailpoint","name":"SailPoint"}]},{"title":"SailPoint access request bot","prompt":"Build a Slack bot where a user describes the access they need, the agent searches SailPoint entitlements and access profiles, and submits a SailPoint access request on their behalf with a correlation note in client metadata.","integrations":[{"id":"slack","name":"Slack"},{"id":"sailpoint","name":"SailPoint"}]},{"title":"SailPoint privileged access watch","prompt":"Create a scheduled workflow that searches SailPoint identities holding privileged roles, cross-references recent account activities, and flags any new privileged grants to a security review channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"sailpoint","name":"SailPoint"}]},{"title":"Salesforce pipeline tracker","prompt":"Create a table with columns for deal name, stage, amount, close date, and next steps. Build a workflow that syncs open deals from Salesforce into this table daily, and sends me a Slack summary each morning of deals that need attention or are at risk of slipping.","integrations":[{"id":"slack","name":"Slack"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Push Salesforce pipeline updates to Slack","prompt":"Build a workflow that monitors Salesforce opportunities and posts a Slack notification to your sales team whenever a deal advances, closes, or needs immediate attention.","integrations":[{"id":"slack","name":"Slack"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Salesforce lead router","prompt":"Build a workflow that triggers on new inbound form submissions, creates a Salesforce lead with the captured fields, runs a SOQL query to check for an existing account match, assigns the lead to the right owner, and posts the new lead with its score to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Salesforce case escalation","prompt":"Create a scheduled workflow that queries open Salesforce cases past their SLA, escalates each by updating its priority and owner, creates a follow-up task on the account, and Slacks the support lead a summary of everything that breached.","integrations":[{"id":"slack","name":"Slack"},{"id":"salesforce","name":"Salesforce"}]},{"title":"SAP Concur expense classifier","prompt":"Build a scheduled workflow that polls SAP Concur for newly submitted expense reports, classifies each line item, validates against policy, and routes exceptions to the approver in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sap_concur","name":"SAP Concur"}]},{"title":"SAP delivery exception alerts","prompt":"Build a workflow that runs every hour, lists SAP S/4HANA outbound and inbound deliveries with delays or missing reference documents, classifies the exception, posts a Slack alert to the operations channel, and updates a remediation tracking table.","integrations":[{"id":"slack","name":"Slack"},{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"SAP stock-level digest","prompt":"Create a scheduled daily workflow that queries SAP S/4HANA for product stock and material document movements, identifies SKUs trending toward stock-out, writes a prioritized digest file, and Slacks the supply chain team for action.","integrations":[{"id":"slack","name":"Slack"},{"id":"sap_s4hana","name":"SAP S4HANA"}]},{"title":"Secrets Manager inventory auditor","prompt":"Create a scheduled workflow that lists all AWS Secrets Manager secrets, flags ones missing descriptions or older than a chosen age, writes a security review, and posts the findings to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]},{"title":"Secrets Manager stale-secret cleaner","prompt":"Build a scheduled workflow that lists AWS Secrets Manager secrets, identifies ones created before a chosen cutoff, requests owner approval in Slack, deletes the approved secrets, and writes the cleanup audit.","integrations":[{"id":"slack","name":"Slack"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]},{"title":"Secrets Manager break-glass retrieval","prompt":"Build a workflow that gates retrieval of a sensitive AWS Secrets Manager secret behind a Slack approval, captures the requester and justification, fetches the secret only after sign-off, and writes the audit record.","integrations":[{"id":"slack","name":"Slack"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]},{"title":"Secrets Manager change watcher","prompt":"Build a scheduled workflow that polls AWS Secrets Manager secret version IDs, compares them against a baseline stored in a table, and pings the security Slack channel when a secret changes unexpectedly.","integrations":[{"id":"slack","name":"Slack"},{"id":"secrets_manager","name":"AWS Secrets Manager"}]},{"title":"Semrush rank tracker","prompt":"Create a scheduled weekly workflow that pulls Semrush domain organic keywords for my site, writes position changes into a table, and posts a Slack summary of the biggest gainers and losers.","integrations":[{"id":"slack","name":"Slack"},{"id":"semrush","name":"Semrush"}]},{"title":"Semrush backlink monitor","prompt":"Build a scheduled workflow that pulls new Semrush referring domains for my site weekly, flags any with a high Authority Score, and posts a Slack digest with the linking page and anchor text.","integrations":[{"id":"slack","name":"Slack"},{"id":"semrush","name":"Semrush"}]},{"title":"Semrush new competitor alert","prompt":"Create a monthly workflow that pulls Semrush organic competitors for my domain, compares them against my tracked competitor list, and posts newly surfaced competitors to Slack for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"semrush","name":"Semrush"}]},{"title":"Sendblue delivery-failure alerts","prompt":"Build a workflow triggered by a Sendblue message status update that, when the status is ERROR, posts the failing number and error message to a Slack channel so the team can follow up.","integrations":[{"id":"slack","name":"Slack"},{"id":"sendblue","name":"Sendblue"}]},{"title":"SendGrid send-failure monitor","prompt":"Create a workflow that sends emails through SendGrid, logs each send result and any error to a delivery table, and posts a Slack alert summarizing failure patterns by recipient domain and template when the failure rate crosses a threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"sendgrid","name":"SendGrid"}]},{"title":"Sentry on-call triage agent","prompt":"Build an agent that monitors Sentry for new errors, automatically triages them by severity and affected users, creates Linear tickets for critical issues with full stack traces, and sends a Slack notification to the on-call channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"},{"id":"linear","name":"Linear"}]},{"title":"Sentry error triage","prompt":"Build a scheduled workflow that polls Sentry for new unresolved issues, classifies severity, groups similar issues, creates a Linear ticket on first occurrence above the threshold, and pings the owning team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"},{"id":"linear","name":"Linear"}]},{"title":"Sentry release health gate","prompt":"Create a workflow that runs after a Vercel deploy, checks Sentry release health, and rolls back the deploy if the error rate exceeds the threshold, posting an alert to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"},{"id":"vercel","name":"Vercel"}]},{"title":"Sentry weekly regression brief","prompt":"Build a scheduled weekly workflow that compares Sentry error rates week-over-week, identifies top regressors, and writes a brief to engineering leadership in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"}]},{"title":"Sentry release tracker on deploy","prompt":"Create a workflow that watches GitHub for merges to main, creates a new Sentry release with the commit range, marks the deploy in Sentry for the production environment, and posts the release notes and linked issues to Slack so the team knows what shipped.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"},{"id":"github","name":"GitHub"}]},{"title":"Serper SERP digest","prompt":"Build a scheduled daily workflow that runs Serper searches for tracked keywords, writes the SERP positions of my domain into a tables-based SEO log, and pings on changes.","integrations":[{"id":"slack","name":"Slack"},{"id":"serper","name":"Serper"}]},{"title":"Serper competitor SERP watcher","prompt":"Create a workflow that runs Serper searches for competitor keywords weekly, captures top SERP entries, and writes a competitive SEO digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"serper","name":"Serper"}]},{"title":"Serper news monitor","prompt":"Build a scheduled workflow that uses Serper news search for brand keywords, classifies each result, and posts notable mentions to a Slack PR channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"serper","name":"Serper"}]},{"title":"ServiceNow incident commander","prompt":"Build a workflow triggered when a ServiceNow incident is created at P1 or P2 that opens a Slack war-room channel, posts the incident description and impacted CI, invites the assignment group, and keeps the channel topic in sync with the incident state.","integrations":[{"id":"slack","name":"Slack"},{"id":"servicenow","name":"ServiceNow"}]},{"title":"ServiceNow weekly ops digest","prompt":"Create a scheduled weekly workflow that pulls ServiceNow incident, change, and request data, calculates MTTR, change success rate, and top failing services, and posts a digest to Slack with the standout records linked.","integrations":[{"id":"slack","name":"Slack"},{"id":"servicenow","name":"ServiceNow"}]},{"title":"ServiceNow ticket deflection bot","prompt":"Build a Slack bot that lets employees report IT issues in natural language, reads similar resolved ServiceNow records to suggest a fix first, and only creates a new ServiceNow incident record with the right category when self-service does not resolve it.","integrations":[{"id":"slack","name":"Slack"},{"id":"servicenow","name":"ServiceNow"}]},{"title":"SES verified-identity audit","prompt":"Build a scheduled workflow that lists AWS SES verified identities, checks the account sending quota and reputation, and posts a Slack report when any identity is unverified or the account approaches the daily quota.","integrations":[{"id":"slack","name":"Slack"},{"id":"ses","name":"AWS SES"}]},{"title":"SES new-domain onboarding","prompt":"Create a workflow that takes a new sending domain from a table, creates the SES email identity, polls get email identity until DKIM verification succeeds, creates a dedicated configuration set with open and click tracking enabled, and posts the DNS tokens to Slack for the infrastructure team to add.","integrations":[{"id":"slack","name":"Slack"},{"id":"ses","name":"AWS SES"}]},{"title":"Notify Slack when new files land on SFTP","prompt":"Build a workflow that checks an SFTP inbox folder on a schedule and sends a Slack message listing any new files that have arrived since the last run.","integrations":[{"id":"slack","name":"Slack"},{"id":"sftp","name":"SFTP"}]},{"title":"Notify Slack when new files land on SFTP","prompt":"Build a workflow that checks an SFTP inbox folder on a schedule and sends a Slack message listing any new files that have arrived since the last run.","integrations":[{"id":"slack","name":"Slack"},{"id":"sftp","name":"SFTP"}]},{"title":"Shopify order monitor","prompt":"Build a workflow that monitors Shopify orders, flags high-value or unusual orders for review, tracks fulfillment status in a table, and sends daily inventory and sales summaries to Slack with restock alerts when items run low.","integrations":[{"id":"slack","name":"Slack"},{"id":"shopify","name":"Shopify"}]},{"title":"Shopify restock alerter","prompt":"Create a scheduled hourly workflow that lists Shopify inventory items, computes days-of-cover from recent sales velocity, flags SKUs below a configurable threshold, and posts a Slack alert to the operations channel with the variant, location, and recommended reorder quantity.","integrations":[{"id":"slack","name":"Slack"},{"id":"shopify","name":"Shopify"}]},{"title":"Shopify product launcher","prompt":"Build a workflow that takes a new product brief, creates a draft product in Shopify, creates its variants with pricing, adds it to a collection using Collections To Join, drafts a launch announcement, and sends a Slack and Gmail draft announcement for marketing review. Publish to sales channels in Shopify after approval.","integrations":[{"id":"slack","name":"Slack"},{"id":"shopify","name":"Shopify"},{"id":"gmail","name":"Gmail"}]},{"title":"Shopify order anomaly detector","prompt":"Create a scheduled workflow that runs every fifteen minutes, lists recent Shopify orders, scores each for anomalies — high value, unusual destination, mismatched billing — flags suspects in a review queue table, and Slacks the operations team for hands-on inspection.","integrations":[{"id":"slack","name":"Slack"},{"id":"shopify","name":"Shopify"}]},{"title":"Similarweb traffic intelligence","prompt":"Build a scheduled workflow that pulls Similarweb traffic data for tracked competitor domains monthly, writes traffic, sources, and engagement to a tables-based scoreboard, and flags step changes in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"similarweb","name":"Similarweb"}]},{"title":"Similarweb engagement scorecard","prompt":"Build a scheduled workflow that pulls Similarweb bounce rate, pages per visit, and average visit duration for my domain and key competitors, writes the engagement metrics to a table, and posts a Slack scorecard highlighting where my site under- or over-performs the set.","integrations":[{"id":"slack","name":"Slack"},{"id":"similarweb","name":"Similarweb"}]},{"title":"Sixtyfour competitor-intel digest","prompt":"Build a scheduled weekly workflow that runs Sixtyfour deep research on competitors and writes a competitive-intel digest to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"sixtyfour","name":"Sixtyfour AI"}]},{"title":"Slack Q&A bot","prompt":"Create a knowledge base connected to my Notion workspace so it stays synced with my company wiki. Then build a workflow that monitors Slack channels for questions and answers them using the knowledge base with source citations.","integrations":[{"id":"slack","name":"Slack"},{"id":"notion","name":"Notion"}]},{"title":"Slack churn risk alerts","prompt":"Create a workflow that monitors customer activity — support ticket frequency, response sentiment, usage patterns — scores each account for churn risk in a table, and triggers a Slack alert to the account team when a customer crosses the risk threshold.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Slack incident postmortem writer","prompt":"Create a workflow that when triggered after an incident, pulls the Slack thread from the incident channel, gathers relevant Sentry errors and deployment logs, and drafts a structured postmortem with timeline, root cause, and action items.","integrations":[{"id":"slack","name":"Slack"},{"id":"sentry","name":"Sentry"}]},{"title":"Slack code Q&A bot","prompt":"Build a workflow that monitors a Slack channel for code questions, routes them to Greptile against the relevant repository, and replies in-thread with the answer and the cited files so the team gets quick, sourced engineering answers.","integrations":[{"id":"slack","name":"Slack"},{"id":"greptile","name":"Greptile"}]},{"title":"Slack knowledge search","prompt":"Create a knowledge base connected to my Slack workspace so all channel conversations and threads are automatically synced and searchable. Then build an agent I can ask things like \\"what did the team decide about the launch date?\\" or \\"what was the outcome of the design review?\\" and get answers with links to the original messages.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Slack narrative report","prompt":"Build a scheduled workflow that pulls key data from my tables every week, analyzes trends and anomalies, and writes a narrative report — not just charts and numbers, but written insights explaining what changed, why it matters, and what to do next. Save it as a document and send a summary to Slack.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Slack reading digest","prompt":"Create a scheduled daily workflow that searches the web for the latest articles, papers, and news on topics I care about, picks the top 5 most relevant pieces, writes a one-paragraph summary for each, and delivers a curated reading digest to my inbox or Slack.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Slack standup summary","prompt":"Create a scheduled workflow that reads the #standup Slack channel each morning, summarizes what everyone is working on, identifies blockers, and posts a structured recap to a Google Docs document.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Slack onboarding automation","prompt":"Build a workflow that when triggered with a new hire\'s info, creates their accounts, sends a personalized welcome message in Slack, schedules 1:1s with their team on Google Calendar, shares relevant onboarding docs from the knowledge base, and tracks completion in a table.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Slack customer 360 alerts","prompt":"Create a comprehensive customer table that aggregates data from my CRM, support tickets, billing history, and product usage into a single unified view per customer. Schedule it to sync daily and send a Slack alert when any customer shows signs of trouble across multiple signals.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Slack thread translator","prompt":"Build a workflow that watches international Slack channels, detects non-English messages, translates them with Google Translate, and posts the English version in a thread so the wider team stays in the loop.","integrations":[{"id":"slack","name":"Slack"},{"id":"google_translate","name":"Google Translate"}]},{"title":"Archive Slack conversations to Notion","prompt":"Build a workflow that captures important Slack messages and threads and saves them as Notion pages or database entries, so meeting notes and decisions are always documented.","integrations":[{"id":"slack","name":"Slack"},{"id":"notion","name":"Notion"}]},{"title":"Smartlead reply triage","prompt":"Create a scheduled workflow that pulls Smartlead campaign statistics filtered to replied, reads each lead message history, classifies the reply as interested, not interested, objection, or out-of-office, sets the matching Smartlead lead category, and posts hot replies to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"smartlead","name":"Smartlead"}]},{"title":"Snowflake asynchronous reporting","prompt":"Build a scheduled workflow that starts a long-running Snowflake report asynchronously, polls its statement handle until complete, summarizes the result, and posts the report to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake task failure monitor","prompt":"Create a workflow that checks recent Snowflake task failures, retrieves the failed run details, summarizes the likely cause, and posts an actionable Slack alert.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake warehouse cost control","prompt":"Build a scheduled workflow that reviews Snowflake warehouse state and suspends an approved idle warehouse after notifying the data platform channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake result export","prompt":"Build a scheduled workflow that unloads a Snowflake query result to a stage as a single CSV file with headers, then posts the file count and row total to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake task pause and resume","prompt":"Create a workflow that suspends a Snowflake task when its recent runs keep failing, notifies the data platform channel, and resumes it once someone confirms the fix.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake Cortex Analyst Slack analyst","prompt":"Build an agent that answers data questions asked in a Slack channel with Snowflake Cortex Analyst over our semantic view. It keeps each Slack thread\'s Cortex Analyst conversation in a table so follow-up questions keep their context, starting fresh after a handful of turns, runs the generated SQL, and replies in the thread with the interpretation, a short table of rows, and the SQL.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake Cortex Analyst router","prompt":"Create an agent that sends each incoming business question to Snowflake Cortex Analyst with our sales, finance, and support semantic views, lets Cortex Analyst pick the right one, runs the generated SQL, and posts the results and which view answered to Slack, or posts the suggested rephrasings when the question is ambiguous.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake Cortex Analyst KPI digest","prompt":"Build a scheduled workflow that asks Snowflake Cortex Analyst a fixed list of weekly KPI questions against our semantic view, runs each generated SQL, and posts a digest of the results and the SQL behind them to a Slack channel every Monday.","integrations":[{"id":"slack","name":"Slack"},{"id":"snowflake","name":"Snowflake"}]},{"title":"Splunk error spike triage","prompt":"Build a scheduled workflow that runs a Splunk SPL search for error spikes every 15 minutes, summarizes the top offending hosts and sourcetypes with an agent, and posts the triage summary to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"splunk","name":"Splunk"}]},{"title":"Splunk index capacity watch","prompt":"Build a scheduled weekly workflow that lists Splunk indexes, flags any index close to its maximum data size or retention limit, and posts a capacity warning to the platform team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"splunk","name":"Splunk"}]},{"title":"Sportmonks daily fixtures digest","prompt":"Build a scheduled daily workflow that fetches today\'s football fixtures from Sportmonks for the leagues I follow, summarizes the key matchups and kickoff times, and posts the digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Sportmonks live score alerter","prompt":"Create a scheduled workflow that polls Sportmonks inplay football scores, detects goals and status changes since the last run, and pings Slack with the updated scoreline for tracked matches.","integrations":[{"id":"slack","name":"Slack"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Sportmonks race weekend digest","prompt":"Build a scheduled workflow that fetches this weekend\'s motorsport sessions from Sportmonks, summarizes the practice, qualifying, and race times, and posts the schedule to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Sportmonks live odds alerter","prompt":"Create a scheduled workflow that polls Sportmonks in-play odds for a fixture, detects sharp price moves since the last run, and pings Slack with the updated lines.","integrations":[{"id":"slack","name":"Slack"},{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Spotify request bot","prompt":"Create a workflow triggered by a Slack message that takes a song request, searches Spotify for the best match, and adds the track to a shared office playlist, replying in the thread with what was added.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Spotify playlist growth tracker","prompt":"Build a scheduled workflow that checks the follower count on each of an artist’s Spotify playlists, logs the daily totals to a table, and pings Slack when a playlist crosses a follower milestone.","integrations":[{"id":"slack","name":"Slack"}]},{"title":"Square daily sales summary","prompt":"Build a scheduled daily workflow that lists Square payments from the previous day across all locations, totals gross sales, refunds, and net revenue, writes the figures to a table for historical tracking, and posts a Slack summary with day-over-day trends.","integrations":[{"id":"slack","name":"Slack"},{"id":"square","name":"Square"}]},{"title":"Square new customer welcome","prompt":"Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"square","name":"Square"},{"id":"gmail","name":"Gmail"}]},{"title":"Square low-stock reorder alerts","prompt":"Create a scheduled workflow that lists the Square catalog, identifies items flagged as low or out of stock, drafts a reorder summary grouped by supplier, and posts it to a Slack purchasing channel with the items and quantities to reorder.","integrations":[{"id":"slack","name":"Slack"},{"id":"square","name":"Square"}]},{"title":"SSH health check to Slack","prompt":"Every morning, SSH into the production server and run a health check command (uptime, load average, and free memory). Summarize stdout with an agent and post the result to the #ops Slack channel so the team starts the day knowing the box is healthy.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"Disk-usage alert with SSH","prompt":"On a schedule, SSH into the server and execute \'df -h /\' to read disk usage. Parse the stdout, and if the used percentage crosses 85%, send an alert to Slack with the current usage; otherwise stay silent.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"Summarize a remote log over SSH","prompt":"SSH into the server and read the last 200 lines of /var/log/app.log, then hand the content to an agent that summarizes recent errors and warnings into a short digest. Post the digest so on-call engineers can scan incidents at a glance.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"SSH health check to Slack","prompt":"Every morning, SSH into the production server and run a health check command (uptime, load average, and free memory). Summarize stdout with an agent and post the result to the #ops Slack channel so the team starts the day knowing the box is healthy.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"Disk-usage alert with SSH","prompt":"On a schedule, SSH into the server and execute \'df -h /\' to read disk usage. Parse the stdout, and if the used percentage crosses 85%, send an alert to Slack with the current usage; otherwise stay silent.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"Summarize a remote log over SSH","prompt":"SSH into the server and read the last 200 lines of /var/log/app.log, then hand the content to an agent that summarizes recent errors and warnings into a short digest. Post the digest so on-call engineers can scan incidents at a glance.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssh","name":"SSH"}]},{"title":"Systems Manager patch reporter","prompt":"Build a scheduled workflow that reads AWS Systems Manager patch compliance for every managed node, flags nodes with missing critical or security patches, and posts a ranked remediation list to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Systems Manager runbook responder","prompt":"Build a workflow that receives an incident alert, starts the matching AWS Systems Manager Automation runbook, polls the execution until it finishes, and reports the step results back to the incident channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Systems Manager config promoter","prompt":"Create a workflow that reads application configuration from one AWS Systems Manager Parameter Store path, requests approval in Slack, writes the approved values to the production path, and records the change in a table.","integrations":[{"id":"slack","name":"Slack"},{"id":"ssm","name":"AWS Systems Manager"}]},{"title":"Stagehand price-monitor sweep","prompt":"Build a scheduled workflow that uses Stagehand to navigate a catalog of supplier sites, capture current prices and stock for items in a tracking table, and alert Slack on threshold breaches.","integrations":[{"id":"slack","name":"Slack"},{"id":"stagehand","name":"Stagehand"}]},{"title":"Stripe weekly metrics report","prompt":"Build a scheduled workflow that pulls data from Stripe and my database every Monday, calculates key metrics like MRR, churn, new subscriptions, and failed payments, writes results to Google Sheets, and sends the team a Slack summary with week-over-week trends.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Stripe revenue dashboard","prompt":"Create a scheduled daily workflow that pulls payment data from Stripe, calculates MRR, net revenue, failed payments, and new subscriptions, logs everything to a table with historical tracking, and sends a daily Slack summary with trends and anomalies.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"}]},{"title":"Stripe failed payment recovery","prompt":"Build a workflow that listens for Stripe failed-payment events, looks up the customer, classifies the failure reason, drafts a tailored recovery email and a Slack alert to the success team, and logs the attempt in a tracking table so recovery rate can be measured.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"}]},{"title":"Stripe churn flagger","prompt":"Create a scheduled daily workflow that lists Stripe subscriptions canceled or scheduled for cancellation, enriches each customer with usage and support history, scores the churn risk, and logs the cohort to a table with recommended save plays for the success team.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"}]},{"title":"Stripe invoice chaser","prompt":"Build a scheduled workflow that lists Stripe invoices overdue by more than seven days, sends a polite chase email tailored to the customer history, escalates to a Slack alert at thirty days, and writes every action into a collections tracking table.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"}]},{"title":"Stripe customer welcome flow","prompt":"Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"},{"id":"calendly","name":"Calendly"}]},{"title":"Stripe refund pattern analyzer","prompt":"Build a scheduled weekly workflow that lists Stripe charge and dispute events, classifies each refund or dispute by reason and product, identifies recurring patterns or fraud signals, writes a narrative report file, and Slacks finance with the top concerns and recommended actions.","integrations":[{"id":"slack","name":"Slack"},{"id":"stripe","name":"Stripe"}]},{"title":"AWS STS access key identifier","prompt":"Build a workflow that takes an AWS access key ID, uses AWS STS to look up the owning account and entity, flags keys that belong to unexpected accounts, and pings the security Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"sts","name":"AWS STS"}]},{"title":"STS just-in-time access grant","prompt":"Build a workflow that handles JIT-access requests, captures Slack-based approval, mints short-lived AWS STS credentials, and writes the access record.","integrations":[{"id":"slack","name":"Slack"},{"id":"sts","name":"AWS STS"}]},{"title":"STS cross-account access grant","prompt":"Create a workflow that handles cross-account access requests, assumes the target AWS STS role with the supplied external ID, requires owner attestation in Slack, and writes the grant record to a compliance table.","integrations":[{"id":"slack","name":"Slack"},{"id":"sts","name":"AWS STS"}]},{"title":"STS Identity-Center role broker","prompt":"Build a workflow that takes an Identity Center user request, assumes the matching AWS STS role to mint scoped short-lived credentials, writes the issuance to a session log, and alerts Slack when a request targets a privileged role.","integrations":[{"id":"slack","name":"Slack"},{"id":"sts","name":"AWS STS"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Supabase row-level audit log","prompt":"Build a scheduled workflow that polls Supabase sensitive tables for recently changed rows, captures the diff against the last snapshot into an audit log table, and pings Slack on unusual write patterns.","integrations":[{"id":"slack","name":"Slack"},{"id":"supabase","name":"Supabase"}]},{"title":"Supabase high-priority row alerter","prompt":"Create a scheduled workflow that polls Supabase frequently for high-priority rows — new orders, fraud flags — and posts a Slack alert with context for each new row it finds.","integrations":[{"id":"slack","name":"Slack"},{"id":"supabase","name":"Supabase"}]},{"title":"Supabase analytics digest","prompt":"Create a scheduled daily workflow that queries Supabase for new signups, active users, and key feature usage, and posts a digest to Slack with week-over-week trend.","integrations":[{"id":"slack","name":"Slack"},{"id":"supabase","name":"Supabase"}]},{"title":"Tailscale ACL drift detector","prompt":"Create a scheduled workflow that diffs Tailscale ACLs against the source of truth, validates the proposed policy with Validate ACL, alerts on drift to Slack, and, on approval, pushes the corrected policy back with Set ACL.","integrations":[{"id":"slack","name":"Slack"},{"id":"tailscale","name":"Tailscale"}]},{"title":"Tailscale unauthorized-tag watcher","prompt":"Build a scheduled workflow that polls Tailscale device tags and the ACL for unauthorized changes, posts a Slack alert to the security channel, and writes the audit.","integrations":[{"id":"slack","name":"Slack"},{"id":"tailscale","name":"Tailscale"}]},{"title":"Tailscale key-expiry sweeper","prompt":"Create a scheduled workflow that lists Tailscale auth keys expiring in 14 days, notifies owners, and rotates keys past their grace period.","integrations":[{"id":"slack","name":"Slack"},{"id":"tailscale","name":"Tailscale"}]},{"title":"Tavily competitive monitor","prompt":"Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, logs the top hits to a tables-based competitive log, and posts highlights to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"tavily","name":"Tavily"}]},{"title":"Tavily news watcher","prompt":"Create a scheduled daily workflow that runs Tavily searches for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"tavily","name":"Tavily"}]},{"title":"Temporal order approval gate","prompt":"Create a workflow that receives an approval decision from a form, signals the matching Temporal order workflow with the decision, and posts a confirmation to Slack with the workflow ID and current status.","integrations":[{"id":"slack","name":"Slack"},{"id":"temporal","name":"Temporal"}]},{"title":"Temporal failed workflow digest","prompt":"Build a scheduled daily workflow that lists Temporal executions that failed or timed out in the last 24 hours, pulls the close event from each history to extract the failure, and posts a digest to Slack grouped by workflow type.","integrations":[{"id":"slack","name":"Slack"},{"id":"temporal","name":"Temporal"}]},{"title":"Textract handwritten-note digitizer","prompt":"Build a workflow that runs scanned handwritten intake notes through AWS Textract, converts the recognized text into clean Markdown, indexes it into a knowledge base, and posts a confidence summary to Slack so low-confidence pages get a human review.","integrations":[{"id":"slack","name":"Slack"},{"id":"textract","name":"AWS Textract"}]},{"title":"Thrive compliance digest","prompt":"Create a scheduled weekly workflow that lists Thrive enrolments for a compliance assignment, filters those still open or overdue, and posts a Slack summary to the people-ops channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"thrive","name":"Thrive"}]},{"title":"Thrive trending content to Slack","prompt":"Create a scheduled workflow that queries recently updated Thrive content and activity records, summarises the most engaged-with learning, and posts a weekly highlight to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"thrive","name":"Thrive"}]},{"title":"TikTok performance reporter","prompt":"Build a workflow that lists recent TikTok videos, summarizes view and engagement trends with an agent, and posts the digest to Slack every week.","integrations":[{"id":"slack","name":"Slack"},{"id":"tiktok","name":"TikTok"}]},{"title":"TikTok draft review pipeline","prompt":"Create a workflow that uploads a new video to a TikTok inbox draft for review, then notifies the marketing team on Slack to approve and post it from the TikTok app.","integrations":[{"id":"slack","name":"Slack"},{"id":"tiktok","name":"TikTok"}]},{"title":"Tinybird usage-meter dashboard","prompt":"Build a workflow that exposes a Tinybird endpoint reporting per-customer usage for billing, refreshes a Sim table hourly, and surfaces top consumers to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"tinybird","name":"Tinybird"}]},{"title":"Tinybird funnel analytics digest","prompt":"Create a scheduled workflow that queries a Tinybird pipe for daily signup, activation, and conversion counts, calculates step-over-step drop-off, and posts a funnel digest with week-over-week deltas to the growth Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"tinybird","name":"Tinybird"}]},{"title":"TinyFish competitor pricing watch","prompt":"Create a scheduled workflow that runs a TinyFish agent weekly against three competitor pricing pages, extracts every plan name and monthly price into a fixed output schema, diffs it against the table from last week, and posts the changes to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"tinyfish","name":"TinyFish"}]},{"title":"Trello SLA monitor","prompt":"Build a workflow that watches Trello cards for due-date breaches, sends reminders, and escalates to managers via Slack when items slip more than 2 days.","integrations":[{"id":"slack","name":"Slack"},{"id":"trello","name":"Trello"}]},{"title":"Trello stale-card sweeper","prompt":"Create a scheduled workflow that scans a Trello board for cards with no activity in 30 days, comments a nudge on each, and posts a stale-card list to Slack for the project owner.","integrations":[{"id":"slack","name":"Slack"},{"id":"trello","name":"Trello"}]},{"title":"Trigger.dev failed-run monitor","prompt":"Build a scheduled workflow that lists Trigger.dev runs with status FAILED or CRASHED from the last hour, summarizes the failures per task, and posts a digest to the engineering Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev stuck-run janitor","prompt":"Build a scheduled workflow that lists Trigger.dev runs still executing past their expected duration, cancels the stuck runs, and posts the canceled run IDs to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev human approval gate","prompt":"Build a workflow where a Trigger.dev task waits on a waitpoint token, an approver reviews the request in Slack, and the workflow completes the waitpoint token with the approval decision so the task resumes.","integrations":[{"id":"slack","name":"Slack"},{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev deploy watchdog","prompt":"Create a workflow that checks the latest Trigger.dev deployment after each release, and if the deployment failed or new runs start crashing, promotes the previous deployment version and alerts the on-call channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Twilio Voice call QA reviewer","prompt":"Create a scheduled workflow that lists yesterday\'s Twilio Voice calls, pulls each recording, transcribes and scores it for tone, compliance phrases, and resolution, and writes a QA scorecard to a table while flagging low-scoring calls to the team lead in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Typeform survey summarizer","prompt":"Create a workflow that pulls new Typeform responses daily, categorizes feedback by theme and sentiment, logs structured results to a table, and sends a Slack digest when a new batch of responses comes in with the key takeaways.","integrations":[{"id":"slack","name":"Slack"},{"id":"typeform","name":"Typeform"}]},{"title":"Typeform NPS pipeline","prompt":"Build a workflow that collects Typeform NPS responses, classifies each as promoter/passive/detractor, writes the rolled-up score to a tracking table, and pings Slack on detractor spikes.","integrations":[{"id":"slack","name":"Slack"},{"id":"typeform","name":"Typeform"}]},{"title":"Upstash counter digest","prompt":"Create a scheduled daily workflow that reads Upstash Redis counter keys for the day, summarizes the totals, and posts a usage digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"upstash","name":"Upstash"}]},{"title":"UptimeRobot downtime alert to Slack","prompt":"Build a scheduled workflow that lists UptimeRobot incidents from the last hour, filters to ones that are still active, and posts a formatted Slack alert with the affected monitor name, cause, and how long it has been down.","integrations":[{"id":"slack","name":"Slack"},{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"UptimeRobot incident to Linear","prompt":"Build a scheduled workflow that polls UptimeRobot for active incidents, and for any new incident creates a Linear ticket with the monitor name, cause, and root-cause URL, then posts the ticket link to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"uptimerobot","name":"UptimeRobot"},{"id":"linear","name":"Linear"}]},{"title":"Vanta failing test alerts","prompt":"Create a scheduled workflow that lists Vanta tests with status NEEDS_ATTENTION each morning, fetches the failing entities for each test, and posts a remediation digest to a Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"vanta","name":"Vanta"}]},{"title":"Vanta onboarding task chaser","prompt":"Create a scheduled workflow that lists current Vanta people with overdue security tasks and sends each person a direct Slack reminder with their task summary status and due date, asking them to review outstanding tasks in Vanta.","integrations":[{"id":"slack","name":"Slack"},{"id":"vanta","name":"Vanta"}]},{"title":"Vercel deployment monitor","prompt":"Build a scheduled workflow that polls Vercel for the latest deployments across my projects every five minutes, detects failed or stuck builds, fetches the build logs, summarizes the failure cause, and posts an actionable alert to Slack with a deep link to the deployment.","integrations":[{"id":"slack","name":"Slack"},{"id":"vercel","name":"Vercel"}]},{"title":"Vercel domain and DNS inventory","prompt":"Build a scheduled workflow that lists every domain and DNS record across my Vercel account weekly, logs them into a tracking table, and sends a Slack diff of any added, removed, or modified records so DNS changes never go unnoticed.","integrations":[{"id":"slack","name":"Slack"},{"id":"vercel","name":"Vercel"}]},{"title":"Vercel project pause guard","prompt":"Build a scheduled workflow that scans Vercel projects daily for low-traffic or stale candidates flagged in a table, pauses projects that meet the criteria, and Slacks a digest of paused and unpaused projects to the platform team for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"vercel","name":"Vercel"}]},{"title":"Vercel failed deploy recovery","prompt":"Build a workflow that watches Vercel for failed production deployments, identifies the last known good production deployment, promotes it back to production for an instant rollback, and posts a Slack incident summary with the failure cause and rollback confirmation.","integrations":[{"id":"slack","name":"Slack"},{"id":"vercel","name":"Vercel"}]},{"title":"Wealthbox book-of-business digest","prompt":"Create a scheduled weekly workflow that reads the contacts and open tasks for each advisor from a tracking table, summarizes the book-of-business activity, and posts the digest to leadership in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Wealthbox referral tracker","prompt":"Build a scheduled workflow that polls Wealthbox notes for new referrals, captures the source and prospect, writes the referral chain into a CRM table, and pings the advisor in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Webflow lead capture pipeline","prompt":"Create a workflow that monitors new Webflow form submissions, enriches each lead with company and contact data using Apollo and web search, adds them to a tracking table with a lead score, and sends a Slack notification to the sales team for high-potential leads.","integrations":[{"id":"slack","name":"Slack"},{"id":"webflow","name":"Webflow"},{"id":"apollo","name":"Apollo"}]},{"title":"Webflow product catalog sync","prompt":"Create a scheduled workflow that mirrors Shopify products and pricing into a Webflow CMS product collection, keeps both in sync, and posts conflict alerts to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"webflow","name":"Webflow"},{"id":"shopify","name":"Shopify"}]},{"title":"Wikipedia summary alerter","prompt":"Build a scheduled workflow that monitors Wikipedia pages for tracked entities, detects significant edits, and posts a summary diff to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wiza credit monitor","prompt":"Create a scheduled workflow that checks the remaining Wiza credit balance each morning, logs the daily usage to a table, and posts a Slack alert when credits fall below the threshold so reveals never silently stall mid-campaign.","integrations":[{"id":"slack","name":"Slack"},{"id":"wiza","name":"Wiza"}]},{"title":"Workday new-hire kickoff","prompt":"Build a scheduled workflow that polls Workday for newly hired employees, gathers each one’s position and start date, kicks off provisioning in downstream tools, assigns an onboarding plan, schedules introductions on Google Calendar, and notifies the team in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"workday","name":"Workday"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Workday job change orchestrator","prompt":"Build a workflow that watches a Sim table of approved promotions, transfers, and demotions, performs the Workday change-job action for each row, updates downstream tools and Slack channel membership, and writes the outcome back to the table for audit.","integrations":[{"id":"slack","name":"Slack"},{"id":"workday","name":"Workday"}]},{"title":"X (Twitter) brand mention triage","prompt":"Build a scheduled workflow that polls X mentions of the brand, classifies each as praise, support request, or complaint, and routes complaints to the support team with one-tap context.","integrations":[{"id":"slack","name":"Slack"},{"id":"x","name":"X"}]},{"title":"X competitor watcher","prompt":"Build a scheduled workflow that tracks tweets from competitor handles and key industry voices, captures notable posts in a table, and surfaces high-engagement items to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"x","name":"X"}]},{"title":"You.com news monitor","prompt":"Build a scheduled daily workflow that runs You.com Search with day freshness for my competitors, extracts highlights from each news result, and posts a short digest to Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"youcom","name":"You.com"}]},{"title":"You.com credit alert","prompt":"Build a scheduled workflow that checks the You.com account balance every morning and sends a Slack alert when remaining credits fall below a set threshold.","integrations":[{"id":"slack","name":"Slack"},{"id":"youcom","name":"You.com"}]},{"title":"YouTube comment triage","prompt":"Build a scheduled workflow that pulls recent YouTube comments on a video, classifies each as helpful, question, or spam, drafts suggested answers to questions using a knowledge base, and routes them to the community team in Slack for review.","integrations":[{"id":"slack","name":"Slack"},{"id":"youtube","name":"YouTube"}]},{"title":"Zendesk SLA breach alert","prompt":"Create a scheduled workflow that searches Zendesk every 15 minutes for tickets at risk of breaching first-response or resolution SLA, summarizes each one, and posts a Slack alert to the responsible group with deep links to the tickets.","integrations":[{"id":"slack","name":"Slack"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Zendesk weekly CX pulse","prompt":"Create a scheduled weekly workflow that pulls Zendesk ticket volume, CSAT, top tags, and recurring issues, generates a narrative CX pulse with week-over-week deltas, and posts it to Slack with links to the standout tickets.","integrations":[{"id":"slack","name":"Slack"},{"id":"zendesk","name":"Zendesk"}]},{"title":"Zep + Slack team-context bot","prompt":"Build a Slack bot that stores each conversation in Zep keyed by channel and user, retrieves the relevant prior context when someone asks a follow-up, and answers in thread with continuity across the whole team’s history.","integrations":[{"id":"slack","name":"Slack"},{"id":"zep","name":"Zep"}]},{"title":"Zoho Desk new-ticket Slack alert","prompt":"When a new ticket is created in Zoho Desk, send a formatted Slack message to my support channel with the subject, priority, requester, and a link to the ticket.","integrations":[{"id":"slack","name":"Slack"},{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk escalation watcher","prompt":"Create a scheduled workflow that lists open high-priority Zoho Desk tickets with no agent response, and pings the on-call engineer in Slack with the ticket details.","integrations":[{"id":"slack","name":"Slack"},{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoom recording recap","prompt":"Build a workflow that runs after a Zoom meeting ends, pulls the cloud recording transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.","integrations":[{"id":"slack","name":"Slack"},{"id":"zoom","name":"Zoom"}]},{"title":"Zoom recurring 1:1 logger","prompt":"Create a workflow that captures Zoom 1:1 meeting recaps, appends them to a per-employee log file, and surfaces talking points for the next 1:1 to the manager in Slack.","integrations":[{"id":"slack","name":"Slack"},{"id":"zoom","name":"Zoom"}]},{"title":"ZoomInfo intent monitor","prompt":"Build a scheduled workflow that pulls ZoomInfo intent signals for tracked accounts, ranks accounts surging on relevant topics, and posts a daily Slack alert for the sales team.","integrations":[{"id":"slack","name":"Slack"},{"id":"zoominfo","name":"ZoomInfo"}]}]},{"id":"smartlead","type":"smartlead","slug":"smartlead","name":"Smartlead","description":"Manage Smartlead cold email campaigns, sequences, and leads","category":"Email","docsUrl":"https://docs.sim.ai/integrations/smartlead","authType":"api-key","connections":[],"operations":[{"name":"List Campaigns","description":"Retrieves all Smartlead campaigns for the authenticated account."},{"name":"Get Campaign","description":"Retrieves a single Smartlead campaign by ID."},{"name":"Create Campaign","description":"Creates a Smartlead campaign. The campaign starts in DRAFTED status; add sequences, email accounts, and a schedule before starting it."},{"name":"Update Campaign Status","description":"Starts, pauses, or stops a Smartlead campaign. START requires the campaign to already have a schedule, sequences, and at least one email account."},{"name":"Update Campaign Schedule","description":"Sets the sending window, timezone, and throughput limits for a Smartlead campaign. A campaign cannot be started until a schedule exists."},{"name":"Update Campaign Settings","description":"Updates tracking, stop-on-activity, and sending settings for a Smartlead campaign."},{"name":"Get Campaign Analytics","description":"Retrieves lifetime performance totals for a Smartlead campaign — sends, opens, clicks, replies, bounces, and lead counts by state."},{"name":"Get Campaign Analytics by Date","description":"Retrieves Smartlead campaign performance totals for a date range. Smartlead rejects ranges longer than roughly one month."},{"name":"Get Campaign Sequences","description":"Retrieves the email sequence steps for a Smartlead campaign, including subjects, bodies, and per-step delays."},{"name":"Save Campaign Sequences","description":"Replaces the email sequence for a Smartlead campaign. Send every step in one call — steps omitted from the request are removed. An empty subject makes a step reply in the previous thread."},{"name":"Get Campaign Statistics","description":"Retrieves per-email statistics rows for a Smartlead campaign, filterable by sequence step, engagement status, and sent-time range."},{"name":"Add Leads to Campaign","description":"Adds leads to a Smartlead campaign, up to 400 per call. Returns per-reason counts for leads that were skipped as duplicates, blocked, bounced, or invalid."},{"name":"List Campaign Leads","description":"Retrieves the leads in a Smartlead campaign with their per-campaign status."},{"name":"Get Lead by Email","description":"Looks up a Smartlead lead by email address and returns the lead record plus every campaign it belongs to."},{"name":"Update Lead","description":"Updates a lead in a Smartlead campaign. Smartlead requires the email field even when it is unchanged, and lead edits apply across every campaign the lead belongs to."},{"name":"Update Lead Category","description":"Sets the category of a lead in a Smartlead campaign, such as Interested or Not Interested. Use List Lead Categories to resolve a category ID."},{"name":"Pause Lead","description":"Pauses a lead in a Smartlead campaign so it stops receiving sequence emails."},{"name":"Resume Lead","description":"Resumes a paused lead in a Smartlead campaign, optionally after a delay."},{"name":"List Lead Categories","description":"Retrieves the lead categories configured on the Smartlead account, with the category IDs needed to categorize a lead."},{"name":"Get Lead Message History","description":"Retrieves the sent-and-received message history for a lead in a Smartlead campaign."},{"name":"List Campaign Webhooks","description":"Retrieves the webhooks registered on a Smartlead campaign."},{"name":"Create or Update Webhook","description":"Creates a webhook on a Smartlead campaign, or updates an existing one when a webhook ID is supplied. Smartlead requires at least one lead category."},{"name":"Delete Campaign Webhook","description":"Deletes a webhook from a Smartlead campaign."},{"name":"Get Webhook Summary","description":"Retrieves webhook delivery counts for a Smartlead campaign over a time window, for checking whether events are reaching their destination."},{"name":"Duplicate Campaign","description":"Copies a Smartlead campaign, including its sequences and settings. The copy is named \\" - copy\\" and starts in DRAFTED status."},{"name":"Delete Campaign","description":"Permanently deletes a Smartlead campaign along with its sequences, leads, and webhooks. This cannot be undone."},{"name":"Export Campaign Leads (CSV)","description":"Exports every lead in a Smartlead campaign as CSV, including engagement counts and the sequence step last sent to each lead."},{"name":"List Campaign Email Accounts","description":"Retrieves the sending email accounts attached to a Smartlead campaign."},{"name":"Add Email Accounts to Campaign","description":"Attaches sending email accounts to a Smartlead campaign. A campaign needs at least one attached account before it can start."},{"name":"Remove Email Accounts from Campaign","description":"Detaches sending email accounts from a Smartlead campaign."},{"name":"List Email Accounts","description":"Retrieves the sending email accounts on the Smartlead account, including their IDs for attaching to a campaign."},{"name":"Get Campaign Lead Statistics","description":"Retrieves per-lead engagement statistics for a Smartlead campaign."},{"name":"Get Campaign Mailbox Statistics","description":"Retrieves per-mailbox sending statistics for a Smartlead campaign, for spotting which sending accounts are underperforming."},{"name":"Get Top-Level Analytics by Date","description":"Retrieves top-level Smartlead campaign counts for a date range, including positive replies, skipped, failed, and stopped counts not present in the standard analytics."},{"name":"List Lead Activities","description":"Retrieves recent lead activity across all Smartlead campaigns — opens, clicks, replies, and status changes. Smartlead exposes no campaign filter on this endpoint."},{"name":"Get Lead by ID","description":"Looks up a Smartlead lead by its ID."},{"name":"Unsubscribe Lead from Campaign","description":"Unsubscribes a lead from a single Smartlead campaign, leaving it active in other campaigns."},{"name":"Unsubscribe Lead Globally","description":"Unsubscribes a lead across every Smartlead campaign and adds it to the account-wide unsubscribe list."},{"name":"Mark Lead Complete","description":"Marks a lead as completed in a Smartlead campaign so it stops receiving further sequence steps."},{"name":"Delete Lead from Campaign","description":"Removes a lead from a Smartlead campaign. The lead record itself remains on the account."},{"name":"List Inbox Replies","description":"Retrieves replies from the Smartlead master inbox across all campaigns, optionally limited to unread replies. Smartlead exposes no campaign filter on this endpoint."},{"name":"List Lead Lists","description":"Retrieves the lead lists on the Smartlead account with their lead counts."},{"name":"Get Lead List","description":"Retrieves a single Smartlead lead list by ID."},{"name":"Create Lead List","description":"Creates a lead list on the Smartlead account."},{"name":"Update Lead List","description":"Renames a Smartlead lead list."},{"name":"Delete Lead List","description":"Deletes a Smartlead lead list."},{"name":"List Clients","description":"Retrieves the clients on a Smartlead agency account, including the client IDs used to scope campaigns and email accounts."}],"triggers":[],"skills":[{"name":"launch-smartlead-campaign","description":"Create a Smartlead campaign end to end — sequence, schedule, and settings — ready for a human to start.","content":"# Launch a Smartlead Campaign\\n\\nStand up a new cold email campaign in Smartlead.\\n\\n## Steps\\n1. Call Create Campaign with the campaign name. It returns the campaign ID and starts in DRAFTED status.\\n2. Call Save Campaign Sequences with every step in one array — each step takes seq_number, delay_in_days, subject, and email_body. Leave subject empty on follow-ups so they reply in the same thread. Personalize with {{first_name}} and {{company_name}}.\\n3. Call Update Campaign Schedule with the timezone, sending days (1 is Monday), start and end hour, and daily lead cap. A campaign cannot start without a schedule.\\n4. Optionally call Update Campaign Settings to disable open or click tracking and choose what stops a lead.\\n5. Add leads with Add Leads to Campaign (max 400 per call).\\n\\n## Output\\nReport the campaign ID, number of sequence steps saved, the schedule, and how many leads were added versus skipped. Do NOT start the campaign — Update Campaign Status with START also requires at least one connected email account, so leave that to a human."},{"name":"triage-smartlead-replies","description":"Find Smartlead leads who replied, classify intent, and set the matching lead category.","content":"# Triage Smartlead Replies\\n\\nRoute inbound replies to an outbound campaign.\\n\\n## Steps\\n1. Call Get Campaign Statistics with emailStatus set to replied to find engaged leads.\\n2. For each lead, call Get Lead Message History to read the thread.\\n3. Classify the reply as interested, not interested, objection, out-of-office, or auto-reply.\\n4. Call List Lead Categories to resolve the category ID, then Update Lead Category. Set pauseLead when the lead should stop receiving follow-ups.\\n\\n## Output\\nReturn each lead with its email, classification, and the category applied. Surface interested replies first so a rep can follow up."},{"name":"report-smartlead-performance","description":"Summarize Smartlead campaign performance with open, click, and reply rates over a date range.","content":"# Report Smartlead Performance\\n\\nProduce an outbound performance snapshot.\\n\\n## Steps\\n1. Call List Campaigns to get every campaign and its status.\\n2. For lifetime totals call Get Campaign Analytics; for a window call Get Campaign Analytics by Date. Keep ranges to about a month — Smartlead rejects longer spans.\\n3. Compute rates from the returned counts: opens divided by sends, clicks divided by sends, replies divided by sends. Prefer the unique_* counts for rates so repeat opens do not inflate them.\\n4. Rank campaigns by reply rate.\\n\\n## Output\\nReturn a digest with per-campaign sends, unique opens, clicks, replies, and bounces plus the derived rates, calling out the best and worst performers and one takeaway each."},{"name":"import-smartlead-leads","description":"Load prospects into a Smartlead campaign and report exactly what was skipped.","content":"# Import Leads to a Smartlead Campaign\\n\\nBulk-load prospects into an existing campaign.\\n\\n## Steps\\n1. Confirm the campaign ID — resolve it with List Campaigns if only a name is known.\\n2. Normalize each prospect to email (required) plus first_name, last_name, company_name, website, location, linkedin_profile, and a custom_fields object for personalization tokens.\\n3. Call Add Leads to Campaign in batches of at most 400. Only override the block, unsubscribe, duplicate, or bounce lists when the user explicitly asks.\\n4. Verify with List Campaign Leads.\\n\\n## Output\\nReport upload_count against total_leads and break down every skip reason — already_added_to_campaign, duplicate_count, invalid_email_count, block_count, bounce_count — and flag is_lead_limit_exhausted if the plan cap was hit."}],"templates":[{"title":"Smartlead campaign builder","prompt":"Build a workflow that takes a target persona and offer, drafts a three-step Smartlead email sequence with {{first_name}} and {{company_name}} personalization, creates the campaign, saves the sequence, sets a weekday 9-to-5 sending schedule, and reports the campaign ID for review before it is started.","integrations":[{"id":"smartlead","name":"Smartlead"}]},{"title":"Smartlead reply triage","prompt":"Create a scheduled workflow that pulls Smartlead campaign statistics filtered to replied, reads each lead message history, classifies the reply as interested, not interested, objection, or out-of-office, sets the matching Smartlead lead category, and posts hot replies to a Slack channel.","integrations":[{"id":"smartlead","name":"Smartlead"},{"id":"slack","name":"Slack"}]},{"title":"Smartlead lead loader","prompt":"Build a workflow that reads prospects from a table, normalizes each name, company, and email, adds them to a Smartlead campaign in batches of 400 with the block list respected, and writes back how many were uploaded versus skipped as duplicates, bounces, or invalid emails.","integrations":[{"id":"smartlead","name":"Smartlead"}]},{"title":"Smartlead weekly outbound digest","prompt":"Create a scheduled weekly workflow that lists Smartlead campaigns, pulls analytics by date for the last seven days for each active campaign, computes open, click, and reply rates, ranks best and worst performers, and emails the digest to the sales lead.","integrations":[{"id":"smartlead","name":"Smartlead"},{"id":"gmail","name":"Gmail"}]},{"title":"Smartlead + HubSpot sync","prompt":"Build a workflow that reads Smartlead campaign leads and their categories, finds or creates the matching HubSpot contact, mirrors the outreach status onto the contact, and creates a HubSpot task for a rep whenever a lead is categorized as interested.","integrations":[{"id":"smartlead","name":"Smartlead"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Smartlead bounce cleanup","prompt":"Create a scheduled workflow that pulls Smartlead campaign statistics filtered to bounced, pauses each bounced lead, records the suppression in a table with the campaign and bounce date, and reports how many leads were paused so deliverability stays healthy.","integrations":[{"id":"smartlead","name":"Smartlead"}]},{"title":"Smartlead sequence A/B rewriter","prompt":"Build a workflow that reads a Smartlead campaign sequence and its per-step statistics, identifies the step with the weakest reply rate, drafts two stronger subject and body variants for it, and saves the updated sequence back to the campaign after a human approves.","integrations":[{"id":"smartlead","name":"Smartlead"}]},{"title":"Smartlead engagement webhook wiring","prompt":"Create a workflow that lists Smartlead campaigns, checks which ones are missing a reply webhook, and registers a webhook on each for EMAIL_REPLY and LEAD_UNSUBSCRIBED scoped to the Interested category so downstream automations receive engagement events.","integrations":[{"id":"smartlead","name":"Smartlead"}]}]},{"id":"smtp","type":"smtp","slug":"smtp","name":"SMTP","description":"Send emails via any SMTP mail server","category":"Email","docsUrl":"https://docs.sim.ai/integrations/smtp","authType":"api-key","connections":[],"operations":[{"name":"SMTP Send Mail","description":"Send emails via SMTP server"}],"triggers":[],"skills":[{"name":"send-html-email","description":"Send a formatted HTML email over SMTP with subject, recipients, and a reply-to.","content":"# Send HTML Email\\n\\nSend a well-formatted email through any SMTP server.\\n\\n## Steps\\n1. Set the from, to, and subject fields, adding cc or bcc recipients when needed.\\n2. Compose the body as HTML and set the content type to html.\\n3. Set a reply-to address so responses route to the right inbox.\\n4. Send the email and capture the returned message id.\\n\\n## Output\\nReport whether the email was sent, the recipient, the subject, and the message id."},{"name":"email-with-attachment","description":"Attach a generated file to an email and send it over SMTP.","content":"# Email With Attachment\\n\\nSend a report or document as an email attachment.\\n\\n## Steps\\n1. Generate or reference the file from a previous block.\\n2. Pass the file into the attachments field of the SMTP send.\\n3. Write a short body summarizing what the attachment contains.\\n4. Send to the recipients and record the message id.\\n\\n## Output\\nConfirm the email was sent with the attachment, and return the recipient and message id."},{"name":"personalized-batch-email","description":"Send an individual, personalized email to each recipient in a table.","content":"# Personalized Batch Email\\n\\nSend one tailored email per recipient from a table of contacts.\\n\\n## Steps\\n1. Read the recipient rows, each with an email address and personalization fields.\\n2. For each row, draft a personalized subject and body.\\n3. Send an individual email over SMTP so recipients do not see one another.\\n4. Track successes and failures per recipient.\\n\\n## Output\\nReturn the count of emails sent, and list any recipients that failed with the error."},{"name":"scheduled-digest-email","description":"Compile updates on a schedule and send them as a recurring digest email.","content":"# Scheduled Digest Email\\n\\nSend a recurring summary email on a fixed cadence.\\n\\n## Steps\\n1. On the schedule, gather the relevant updates for the period.\\n2. Have an agent build a concise HTML summary.\\n3. Set the subject with the date or period and send over SMTP to the distribution list.\\n4. Use bcc for large lists to protect recipient privacy.\\n\\n## Output\\nConfirm the digest was sent, the number of recipients, and the message id."}],"templates":[{"title":"SMTP daily digest email","prompt":"Build a scheduled workflow that gathers the day’s key updates, has an agent write a clean HTML summary, and sends it as a daily digest email to the team over SMTP.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP alert email on threshold","prompt":"Create a workflow that checks a metric or status, and when it crosses a threshold, sends an alert email over SMTP with the details and a clear subject so the on-call person notices immediately.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP report as attachment","prompt":"Build a workflow that generates a report file, then sends it as an email attachment over SMTP to the requested recipients with a short summary in the body.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP outreach from a table","prompt":"Create a workflow that reads a table of recipients, has an agent draft a personalized message for each row, and sends an individual email to every contact over SMTP with their name and details filled in.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP form-submission auto-reply","prompt":"Build a workflow that triggers on a new form submission and sends an automatic confirmation email over SMTP to the submitter, using their address as the recipient and a friendly reply-to.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP incident notification","prompt":"Create a workflow that, when an incident is detected, sends a notification email over SMTP to a distribution list with the severity, impact, and next steps, cc’ing the stakeholders who need to be looped in.","integrations":[{"id":"smtp","name":"SMTP"}]},{"title":"SMTP weekly summary email","prompt":"Build a scheduled workflow that compiles the week’s results into an HTML summary with an agent and emails it over SMTP to the team every Friday, with a link-friendly reply-to for follow-ups.","integrations":[{"id":"smtp","name":"SMTP"}]}]},{"id":"snowflake","type":"snowflake","slug":"snowflake","name":"Snowflake","description":"Query data, ask Cortex Analyst, and manage warehouses and tasks in Snowflake","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/snowflake","authType":"api-key","connections":[{"id":"snowflake-service-account","kind":"service_account","providerId":"snowflake-service-account","label":"Add programmatic access token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/snowflake-service-account","fields":[{"id":"domain","label":"Account host","placeholder":"myorg-myaccount.snowflakecomputing.com","secret":false,"hint":"Snowflake account hosts end in .snowflakecomputing.com."},{"id":"apiToken","label":"Programmatic access token","placeholder":"Paste a programmatic access token","secret":true}]}],"operations":[{"name":"Execute SQL","description":"Execute one parameterized SQL statement through the Snowflake SQL API."},{"name":"Get Statement","description":"Check a running or completed statement and retrieve exactly one result partition. Canceled or failed statements are returned as errors."},{"name":"Cancel Statement","description":"Cancel a running Snowflake SQL API statement."},{"name":"Insert Rows","description":"Insert structured JSON rows using bound values."},{"name":"Update Rows","description":"Update matching rows with a bound MERGE statement without inserting new rows."},{"name":"Upsert Rows","description":"Update matching rows and insert unmatched rows with a bound MERGE statement."},{"name":"Delete Rows","description":"Delete rows matching a required set of bound column filters."},{"name":"Load Data","description":"Load files from an existing Snowflake stage with COPY INTO."},{"name":"Unload Data","description":"Export a Snowflake table to files in a stage with COPY INTO."},{"name":"List Databases","description":"List the databases the credential can access."},{"name":"List Schemas","description":"List the schemas in a Snowflake database."},{"name":"List Tables","description":"List the tables in a Snowflake schema."},{"name":"List Warehouses","description":"List warehouses visible to the active Snowflake role."},{"name":"Get Warehouse","description":"Get the full details for a Snowflake virtual warehouse."},{"name":"Resume Warehouse","description":"Resume a Snowflake virtual warehouse if it is suspended."},{"name":"Suspend Warehouse","description":"Suspend a Snowflake virtual warehouse."},{"name":"Alter Warehouse","description":"Resize a Snowflake warehouse or change its auto-suspend and auto-resume settings."},{"name":"List Tasks","description":"List tasks in a Snowflake schema."},{"name":"Get Task","description":"Describe a Snowflake task."},{"name":"Run Task","description":"Run a Snowflake task immediately, optionally retrying its last failed graph."},{"name":"Resume Task","description":"Resume a suspended Snowflake task so its schedule runs again."},{"name":"Suspend Task","description":"Suspend a Snowflake task so its schedule stops triggering runs."},{"name":"List Task Runs","description":"Query up to seven days of Snowflake task history, capped at 10000 rows."},{"name":"Get Task Run","description":"Find one task history record by query ID within Snowflake’s seven-day window and 10000 most recent records after optional filters."},{"name":"Cancel Task Query","description":"Cancel one running task query by query ID with SYSTEM$CANCEL_QUERY. Task runs already in flight are unaffected and must be cancelled individually; a cancelled child marks the task graph run failed, so downstream tasks are skipped."},{"name":"Get Task Run Output","description":"Read a task query result with RESULT_SCAN during Snowflake’s 24-hour retention window using the task owner role."},{"name":"List Query History","description":"List queries that completed in the last seven days, optionally filtered."},{"name":"List Copy History","description":"List staged-file load results for a table over the last fourteen days."},{"name":"Introspect Schema","description":"Inspect table and column metadata through Snowflake INFORMATION_SCHEMA views."},{"name":"Call Procedure","description":"Call a stored procedure with explicitly typed Snowflake bindings."},{"name":"Ask Cortex Analyst","description":"Ask Snowflake Cortex Analyst a question in natural language against a semantic view or semantic model. Returns its interpretation and the generated SQL, or suggested questions when the question is ambiguous, and can run the SQL to return rows. Pass the returned conversation as history to ask a follow-up."},{"name":"Send Cortex Analyst Feedback","description":"Rate a Cortex Analyst answer thumbs up or down, with an optional comment. Feedback appears in the Snowsight Cortex Analyst monitoring tab."}],"triggers":[],"skills":[{"name":"query-snowflake-data","description":"Run a bounded parameterized Snowflake query and summarize its result.","content":"# Query Snowflake Data\\n\\n## Steps\\n1. Confirm the warehouse and SQL statement.\\n2. Use typed bindings for values.\\n3. Execute the statement with a bounded row limit.\\n4. If it is asynchronous, poll the handle and request only the needed partition.\\n\\n## Output\\nReturn the rows, column meanings, and a concise summary."},{"name":"sync-snowflake-rows","description":"Insert, update, or upsert structured records safely in Snowflake.","content":"# Synchronize Snowflake Rows\\n\\n## Steps\\n1. Confirm the target table and record keys.\\n2. Keep the structured request within Sim’s request-size limit, and use Load Data for bulk ingestion.\\n3. Choose insert, update, or upsert and provide match columns when needed.\\n4. Report Snowflake DML statistics.\\n\\n## Output\\nReturn inserted, updated, deleted, and total affected row counts."},{"name":"load-snowflake-stage","description":"Load files already present in a Snowflake stage into a table.","content":"# Load a Snowflake Stage\\n\\n## Steps\\n1. Confirm the target table and existing stage path.\\n2. Select the named file format and COPY options.\\n3. Run the staged load.\\n4. Review every returned file status before reporting success.\\n\\n## Output\\nSummarize loaded and rejected files and any COPY errors."},{"name":"monitor-snowflake-tasks","description":"Inspect Snowflake task history, diagnose failed runs, and pause or resume a task.","content":"# Monitor Snowflake Tasks\\n\\n## Steps\\n1. Query the relevant time window within seven days.\\n2. Filter to failures when appropriate.\\n3. Get the selected run by query ID.\\n4. Retrieve output only when it remains available and access permits it.\\n5. Suspend a task to stop its schedule, and resume it once the cause is fixed. Resume every child task before the root task of a task graph.\\n\\n## Output\\nReturn run state, timing, query ID, a failure summary, and any schedule change made."},{"name":"control-snowflake-warehouse","description":"Inspect, resume, suspend, or resize a Snowflake warehouse.","content":"# Control a Snowflake Warehouse\\n\\n## Steps\\n1. List or describe the target warehouse.\\n2. Confirm its name and current state.\\n3. Resume, suspend, or alter its size, auto-suspend, and auto-resume only when requested.\\n4. Verify the statement completed.\\n\\n## Output\\nReturn the warehouse name, prior state, requested action, and result."},{"name":"export-snowflake-results","description":"Unload a table or query result to files in a Snowflake stage.","content":"# Export Snowflake Results\\n\\n## Steps\\n1. Confirm the destination table and the stage path, and whether existing files may be overwritten.\\n2. To export a query result rather than a whole table, materialize it first — create a view or use CREATE TABLE AS SELECT via Execute SQL — then unload that object.\\n3. Pick a named file format, and decide on column headings and whether one file or several.\\n4. Run the unload and review the reported file count and row totals.\\n\\n## Output\\nReturn the stage path, files written, and rows unloaded."},{"name":"browse-snowflake-objects","description":"Discover the databases, schemas, and tables a Snowflake credential can reach.","content":"# Browse Snowflake Objects\\n\\n## Steps\\n1. List databases to find the one in scope.\\n2. List schemas in that database, then tables in the chosen schema.\\n3. Narrow long lists with a SQL LIKE pattern and a row limit.\\n4. Introspect the chosen table when column types matter.\\n\\n## Output\\nReturn the object names found and the qualified name of the one selected."},{"name":"review-snowflake-history","description":"Review recent query executions and staged-file loads to explain a failure.","content":"# Review Snowflake History\\n\\n## Steps\\n1. For query problems, list query history over the window in question, optionally filtered to one user or warehouse, or to failures only. It reaches back seven days.\\n2. For ingestion problems, list copy history for the target table. It requires a start time and reaches back fourteen days.\\n3. Read the error message and file status on the offending rows.\\n\\n## Output\\nReturn the failing statement or file, its error, and the likely cause."},{"name":"audit-snowflake-schema","description":"Inspect Snowflake tables and columns for schema review or drift detection.","content":"# Audit a Snowflake Schema\\n\\n## Steps\\n1. Choose a database and optional schema or table filter.\\n2. Decide whether views belong in scope.\\n3. Introspect the bounded metadata result.\\n4. Compare names, types, nullability, and ordering.\\n\\n## Output\\nReturn the schema inventory and notable compatibility risks."},{"name":"call-snowflake-procedure","description":"Call a Snowflake stored procedure with explicitly typed arguments.","content":"# Call a Snowflake Procedure\\n\\n## Steps\\n1. Confirm the fully qualified procedure and argument order.\\n2. Assign each argument an explicit Snowflake binding type and string value.\\n3. Execute the call and inspect its result.\\n\\n## Output\\nReturn the procedure result and statement handle."},{"name":"ask-cortex-analyst","description":"Answer a business question with Snowflake Cortex Analyst over a semantic view, then run the SQL and report the result.","content":"# Ask Snowflake Cortex Analyst\\n\\nAnswer a data question from a governed semantic view.\\n\\n## Steps\\n1. Ask Cortex Analyst the question with the semantic view (or several views to choose between), passing the previous conversation as history for a follow-up.\\n2. If it returns suggestions instead of SQL, surface them so the user can pick a clearer question.\\n3. Otherwise run the generated SQL and capture the rows; if the run is still RUNNING, fetch the rows with Get Statement.\\n4. Note whether a verified query was used.\\n5. Start a new conversation after a handful of turns, since the full history is reprocessed on every question.\\n\\n## Output\\nThe interpretation, a compact table of the key rows, the SQL, and the conversation to continue from."}],"templates":[{"title":"Snowflake asynchronous reporting","prompt":"Build a scheduled workflow that starts a long-running Snowflake report asynchronously, polls its statement handle until complete, summarizes the result, and posts the report to Slack.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake incremental upsert","prompt":"Create a workflow that receives changed customer records, validates their keys, and upserts them into a Snowflake dimension table in bounded batches.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake staged ingestion","prompt":"Build a workflow that loads newly staged CSV files into a Snowflake table with a named file format, records COPY results, and alerts on rejected files.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake task failure monitor","prompt":"Create a workflow that checks recent Snowflake task failures, retrieves the failed run details, summarizes the likely cause, and posts an actionable Slack alert.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake warehouse cost control","prompt":"Build a scheduled workflow that reviews Snowflake warehouse state and suspends an approved idle warehouse after notifying the data platform channel.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake result export","prompt":"Build a scheduled workflow that unloads a Snowflake query result to a stage as a single CSV file with headers, then posts the file count and row total to Slack.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake ingestion audit","prompt":"Create a workflow that reviews Snowflake copy history for a landing table, identifies files that failed to load, and opens a ticket with the first error on each one.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake slow-query review","prompt":"Build a weekly workflow that lists the longest-running Snowflake queries on a warehouse, summarizes the patterns behind them, and reports the top offenders with their elapsed times.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake task pause and resume","prompt":"Create a workflow that suspends a Snowflake task when its recent runs keep failing, notifies the data platform channel, and resumes it once someone confirms the fix.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake schema-drift audit","prompt":"Create a daily workflow that introspects a Snowflake schema, compares its tables and columns with the previous snapshot, and reports breaking schema changes.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake procedure orchestrator","prompt":"Build a workflow that validates typed arguments, calls a Snowflake stored procedure, captures its output, and routes failures for operator review.","integrations":[{"id":"snowflake","name":"Snowflake"}]},{"title":"Snowflake Cortex Analyst Slack analyst","prompt":"Build an agent that answers data questions asked in a Slack channel with Snowflake Cortex Analyst over our semantic view. It keeps each Slack thread\'s Cortex Analyst conversation in a table so follow-up questions keep their context, starting fresh after a handful of turns, runs the generated SQL, and replies in the thread with the interpretation, a short table of rows, and the SQL.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake Cortex Analyst router","prompt":"Create an agent that sends each incoming business question to Snowflake Cortex Analyst with our sales, finance, and support semantic views, lets Cortex Analyst pick the right one, runs the generated SQL, and posts the results and which view answered to Slack, or posts the suggested rephrasings when the question is ambiguous.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]},{"title":"Snowflake Cortex Analyst KPI digest","prompt":"Build a scheduled workflow that asks Snowflake Cortex Analyst a fixed list of weekly KPI questions against our semantic view, runs each generated SQL, and posts a digest of the results and the SQL behind them to a Slack channel every Monday.","integrations":[{"id":"snowflake","name":"Snowflake"},{"id":"slack","name":"Slack"}]}]},{"id":"splunk","type":"splunk","slug":"splunk","name":"Splunk","description":"Run SPL searches and manage saved searches and alerts in Splunk","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/splunk","authType":"api-key","connections":[],"operations":[{"name":"Run Search","description":"Run an SPL search synchronously and return its results in a single call (oneshot mode). A oneshot search buffers the whole result set in one response with no paging, so use it for short searches; for anything large use Create Search Job with Get Search Results, which defaults to 100 rows and pages with offset."},{"name":"Create Search Job","description":"Start a Splunk search job and return its search ID (sid). The search runs asynchronously — poll its status and fetch results separately."},{"name":"Get Search Job","description":"Get the status and progress of a Splunk search job by search ID, including dispatch state, completion progress, and event/result counts."},{"name":"Get Search Results","description":"Fetch the transformed results of a completed Splunk search job by search ID, with pagination."},{"name":"Cancel Search Job","description":"Cancel a running Splunk search job and delete its result cache."},{"name":"List Saved Searches","description":"List saved searches and reports configured in Splunk, including their SPL, schedule, and alert configuration."},{"name":"Get Saved Search","description":"Get the configuration of a single Splunk saved search by name, including its SPL, schedule, and alert settings."},{"name":"Dispatch Saved Search","description":"Run a Splunk saved search immediately and return the search ID (sid) of the dispatched job."},{"name":"List Fired Alerts","description":"List the saved searches with currently triggered (unexpired) Splunk alerts and how many times each has fired."},{"name":"Get Fired Alerts","description":"List the unexpired triggered instances of a Splunk alert by saved search name, including severity, trigger time, and the search ID of each firing."},{"name":"List Indexes","description":"List the indexes configured on the Splunk instance with their size, event count, and retention settings."},{"name":"List Apps","description":"List the apps installed on the Splunk instance with their label, version, author, and enabled state."}],"triggers":[],"skills":[{"name":"search-splunk-logs","description":"Answer a question about production behavior by running an SPL search.","content":"# Search Splunk Logs\\n\\nTurn a question about production into an SPL search and answer from the rows.\\n\\n## Steps\\n1. Write a single SPL search scoped to one index and a bounded time range (for example `index=main error earliest=-1h`).\\n2. Run the run search operation, which executes the search synchronously and returns the rows in one call.\\n3. Read resultCount and results to gather the evidence.\\n4. Summarize what the rows show, quoting the fields that matter.\\n\\n## Notes\\nRun search buffers its whole result set in one response and cannot page. For a larger result set, create a search job and page through get search results with offset.\\n\\n## Output\\nReturn the SPL that was run, the row count, and a short answer to the question."},{"name":"long-running-search-job","description":"Dispatch a long Splunk search, poll it to completion, then page the results.","content":"# Long-Running Search Job\\n\\nRun a search that is too slow for a synchronous call.\\n\\n## Steps\\n1. Create a search job with the SPL and time range. Keep the returned sid.\\n2. Poll get search job with that sid until dispatchState is DONE. Check isFailed and isZombie on each poll and stop if either is true.\\n3. Fetch results with get search results, paging with count and offset until the rows are exhausted.\\n4. Cancel the job when abandoning it early so the result cache is released.\\n\\n## Output\\nReport the sid, the final dispatch state, the number of rows fetched, and the summarized findings."},{"name":"triage-fired-alerts","description":"Pull currently firing Splunk alerts and turn them into a triage summary.","content":"# Triage Fired Alerts\\n\\nTurn unexpired Splunk alerts into an actionable summary.\\n\\n## Steps\\n1. List fired alerts to get every saved search with triggered alerts and its trigger count.\\n2. For the noisiest saved searches, get fired alerts by name to read the individual instances with their severity, sid, and trigger time.\\n3. Group the instances by saved search and severity, and rank by trigger count.\\n4. Have an agent write a short triage note naming what is firing, how often, and what to look at first.\\n\\n## Output\\nReturn the ranked alert list with trigger counts and the triage note."},{"name":"run-saved-search","description":"Dispatch an existing Splunk saved search and report its results.","content":"# Run Saved Search\\n\\nExecute a saved search that already encodes the right SPL.\\n\\n## Steps\\n1. List saved searches, or get one by name, to confirm the search exists and read its SPL and schedule.\\n2. Dispatch the saved search. Set trigger actions only when the alert actions should really fire.\\n3. Poll get search job with the returned sid until the job is done.\\n4. Fetch and summarize the results.\\n\\n## Output\\nReturn the saved search name, the sid of the dispatched job, and a summary of the rows it produced."},{"name":"index-capacity-report","description":"Report on Splunk index size, retention, and event volume.","content":"# Index Capacity Report\\n\\nCheck which indexes are close to their limits.\\n\\n## Steps\\n1. List indexes to read name, datatype, totalEventCount, currentDBSizeMB, maxTotalDataSizeMB, and frozenTimePeriodInSecs.\\n2. Compute how full each index is against its maximum data size.\\n3. Flag indexes above a threshold, and any whose retention window is shorter than the team expects.\\n4. Page with count and offset when the instance has more indexes than one page returns.\\n\\n## Output\\nReturn a table of indexes with size, usage percentage, and retention, plus the flagged entries."},{"name":"audit-saved-search-hygiene","description":"Inventory Splunk saved searches and flag disabled or stale scheduled ones.","content":"# Audit Saved Search Hygiene\\n\\nFind saved searches that no longer earn their schedule.\\n\\n## Steps\\n1. List saved searches, paging with count and offset until total is covered.\\n2. Read disabled, isScheduled, cronSchedule, and nextScheduledTime on each entry.\\n3. Flag scheduled searches that are disabled, searches with no next scheduled time, and duplicate SPL across entries.\\n4. Write the cleanup candidates somewhere durable, such as a table or a file.\\n\\n## Output\\nReturn the counts by category and the list of cleanup candidates with the reason each was flagged."},{"name":"app-inventory-check","description":"Inventory the apps installed on a Splunk instance and flag disabled ones.","content":"# App Inventory Check\\n\\nRecord what is installed on the Splunk instance.\\n\\n## Steps\\n1. List apps to read name, label, version, author, disabled, and configured.\\n2. Flag apps that are installed but disabled, and apps that are not configured.\\n3. Compare the versions against the versions the team expects to be running.\\n\\n## Output\\nReturn the app inventory with versions and the list of disabled or unconfigured apps."}],"templates":[{"title":"Splunk error spike triage","prompt":"Build a scheduled workflow that runs a Splunk SPL search for error spikes every 15 minutes, summarizes the top offending hosts and sourcetypes with an agent, and posts the triage summary to Slack.","integrations":[{"id":"splunk","name":"Splunk"},{"id":"slack","name":"Slack"}]},{"title":"Splunk alert to incident","prompt":"Create a scheduled workflow that polls Splunk fired alerts, deduplicates them by saved search, and opens a PagerDuty incident with the alert severity and the search ID attached.","integrations":[{"id":"splunk","name":"Splunk"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Splunk security digest","prompt":"Build a scheduled daily workflow that dispatches a Splunk saved search for failed authentication attempts, waits for the job to finish, and emails a security digest with the top source IPs.","integrations":[{"id":"splunk","name":"Splunk"},{"id":"gmail","name":"Gmail"}]},{"title":"Splunk log export to tables","prompt":"Create a scheduled workflow that runs a Splunk search for the previous hour of transaction logs and writes the results into a Sim table for downstream reporting.","integrations":[{"id":"splunk","name":"Splunk"}]},{"title":"Splunk index capacity watch","prompt":"Build a scheduled weekly workflow that lists Splunk indexes, flags any index close to its maximum data size or retention limit, and posts a capacity warning to the platform team in Slack.","integrations":[{"id":"splunk","name":"Splunk"},{"id":"slack","name":"Slack"}]},{"title":"Splunk saved search inventory","prompt":"Create a scheduled monthly workflow that lists every Splunk saved search, flags scheduled searches that have not run recently or are disabled, and writes a cleanup queue to a Sim table.","integrations":[{"id":"splunk","name":"Splunk"}]},{"title":"Splunk incident context agent","prompt":"Build an agent workflow that takes an incident description, runs targeted Splunk searches for the affected service, and returns a timeline of the relevant log events with the matching search ID.","integrations":[{"id":"splunk","name":"Splunk"}]},{"title":"Splunk + Jira defect linking","prompt":"Create a scheduled workflow that runs a Splunk search for recurring application exceptions and opens or updates a Jira bug for each distinct stack trace with the event count attached.","integrations":[{"id":"splunk","name":"Splunk"},{"id":"jira","name":"Jira"}]}]},{"id":"sportmonks","type":"sportmonks","slug":"sportmonks","name":"Sportmonks","description":"Access Sportmonks football, motorsport, odds, and reference data","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/sportmonks","authType":"api-key","connections":[],"operations":[{"name":"Football: Get Expected xG by Player","description":"Retrieve lineup-level expected goals (xG) values per player from Sportmonks"},{"name":"Football: Get Expected xG by Team","description":"Retrieve fixture-level expected goals (xG) values per team from Sportmonks"},{"name":"Football: Get All Commentaries","description":"Retrieve all textual commentaries available within your Sportmonks subscription"},{"name":"Football: Get All Fixtures","description":"Retrieve all football fixtures available within your Sportmonks subscription"},{"name":"Football: Get All Players","description":"Retrieve all football players available within your Sportmonks subscription"},{"name":"Football: Get All Rivals","description":"Retrieve all teams with their rivals information from Sportmonks"},{"name":"Football: Get All Teams","description":"Retrieve all football teams available within your Sportmonks subscription"},{"name":"Football: Get All Transfer Rumours","description":"Retrieve all transfer rumours available within your Sportmonks subscription"},{"name":"Football: Get All Transfers","description":"Retrieve all transfers available within your Sportmonks subscription"},{"name":"Football: Get Brackets by Season","description":"Retrieve the knockout-stage tournament bracket (stages and progression edges) for a season ID"},{"name":"Football: Get Coach by ID","description":"Retrieve a single football coach by their ID from Sportmonks"},{"name":"Football: Get Coaches","description":"Retrieve all football coaches available within your Sportmonks subscription"},{"name":"Football: Get Coaches by Country","description":"Retrieve all coaches for a country ID from Sportmonks"},{"name":"Football: Get Commentaries by Fixture","description":"Retrieve textual commentary for a fixture by fixture ID from Sportmonks"},{"name":"Football: Get Current Leagues by Team","description":"Retrieve all current leagues for a team ID from Sportmonks"},{"name":"Football: Get Expected Lineups by Player","description":"Retrieve the premium expected lineups for a player ID from Sportmonks"},{"name":"Football: Get Expected Lineups by Team","description":"Retrieve the premium expected lineups for a team ID from Sportmonks"},{"name":"Football: Get Extended Team Squad","description":"Retrieve all squad entries for a team (based on current seasons) by team ID"},{"name":"Football: Get Fixture by ID","description":"Retrieve a single football fixture by its ID from Sportmonks"},{"name":"Football: Get Fixtures by Date","description":"Retrieve all football fixtures on a specific date (YYYY-MM-DD) from Sportmonks"},{"name":"Football: Get Fixtures by Date Range","description":"Retrieve football fixtures between two dates (YYYY-MM-DD) from Sportmonks. Max range is 100 days."},{"name":"Football: Get Fixtures by Date Range for Team","description":"Retrieve fixtures for a team within a date range (YYYY-MM-DD) from Sportmonks"},{"name":"Football: Get Fixtures by Multiple IDs","description":"Retrieve multiple football fixtures by a comma-separated list of IDs (max 50)"},{"name":"Football: Get Grouped Standings by Round","description":"Retrieve the standing table for a round ID grouped by group where applicable from Sportmonks"},{"name":"Football: Get Head to Head","description":"Retrieve the head-to-head fixtures between two teams from Sportmonks"},{"name":"Football: Get Inplay Livescores","description":"Retrieve all fixtures that are currently being played (in-play) from Sportmonks"},{"name":"Football: Get Last Updated Coaches","description":"Retrieve all coaches that have received updates in the past two hours"},{"name":"Football: Get Latest Updated Fixtures","description":"Retrieve all fixtures that have received updates within the last 10 seconds"},{"name":"Football: Get Latest Updated Livescores","description":"Retrieve all livescores that have received updates within the last 10 seconds"},{"name":"Football: Get Last Updated Players","description":"Retrieve all players that have received updates in the past two hours"},{"name":"Football: Get Latest Team of the Week","description":"Retrieve the latest Team of the Week (TOTW) for a league ID from Sportmonks"},{"name":"Football: Get Latest Transfers","description":"Retrieve the latest transfers available within your Sportmonks subscription"},{"name":"Football: Get League by ID","description":"Retrieve a single football league by its ID from Sportmonks"},{"name":"Football: Get Leagues","description":"Retrieve all football leagues available within your Sportmonks subscription"},{"name":"Football: Get Leagues by Country","description":"Retrieve all leagues for a country ID from Sportmonks"},{"name":"Football: Get Leagues by Date","description":"Retrieve all leagues with fixtures on a given date (YYYY-MM-DD) from Sportmonks"},{"name":"Football: Get Leagues by Team","description":"Retrieve all current and historical leagues for a team ID from Sportmonks"},{"name":"Football: Get Live Leagues","description":"Retrieve all leagues that have fixtures currently being played from Sportmonks"},{"name":"Football: Get Live Probabilities","description":"Retrieve all live (in-play) prediction probabilities from Sportmonks"},{"name":"Football: Get Live Probabilities by Fixture","description":"Retrieve all live (in-play) prediction probabilities for a fixture ID from Sportmonks"},{"name":"Football: Get Live Standings by League","description":"Retrieve the live standing table for a league ID from Sportmonks"},{"name":"Football: Get Livescores","description":"Retrieve fixtures starting within 15 minutes and currently in progress from Sportmonks"},{"name":"Football: Get All Match Facts","description":"Retrieve all available match facts within your Sportmonks subscription (beta)"},{"name":"Football: Get Match Facts by Date Range","description":"Retrieve match facts within a date range (YYYY-MM-DD) from Sportmonks (beta)"},{"name":"Football: Get Match Facts by Fixture","description":"Retrieve match facts for a fixture ID from Sportmonks (beta)"},{"name":"Football: Get Match Facts by League","description":"Retrieve match facts for a league ID from Sportmonks (beta)"},{"name":"Football: Get Past Fixtures by TV Station","description":"Retrieve all past fixtures that were available for a TV station ID from Sportmonks"},{"name":"Football: Get Player by ID","description":"Retrieve a single football player by their ID from Sportmonks"},{"name":"Football: Get Players by Country","description":"Retrieve all players for a country ID from Sportmonks"},{"name":"Football: Get Post-Match News","description":"Retrieve all post-match news articles available within your Sportmonks subscription"},{"name":"Football: Get Post-Match News by Season","description":"Retrieve all post-match news articles for a season ID from Sportmonks"},{"name":"Football: Get Predictability by League","description":"Retrieve the predictions model performance for a league ID from Sportmonks"},{"name":"Football: Get Pre-Match News","description":"Retrieve all pre-match news articles available within your Sportmonks subscription"},{"name":"Football: Get Pre-Match News by Season","description":"Retrieve all pre-match news articles for a season ID from Sportmonks"},{"name":"Football: Get Pre-Match News for Upcoming Fixtures","description":"Retrieve all pre-match news articles for upcoming fixtures from Sportmonks"},{"name":"Football: Get Probabilities","description":"Retrieve all prediction probabilities available within your Sportmonks subscription"},{"name":"Football: Get Predictions by Fixture","description":"Retrieve prediction probabilities for a fixture by fixture ID from Sportmonks"},{"name":"Football: Get Referee by ID","description":"Retrieve a single football referee by their ID from Sportmonks"},{"name":"Football: Get Referees","description":"Retrieve all football referees available within your Sportmonks subscription"},{"name":"Football: Get Referees by Country","description":"Retrieve all referees for a country ID from Sportmonks"},{"name":"Football: Get Referees by Season","description":"Retrieve all referees for a season ID from Sportmonks"},{"name":"Football: Get Rivals by Team","description":"Retrieve rival teams for a team by team ID from Sportmonks"},{"name":"Football: Get Round by ID","description":"Retrieve a single football round by its ID from Sportmonks"},{"name":"Football: Get Round Statistics","description":"Retrieve all available statistics for a round ID from Sportmonks"},{"name":"Football: Get Rounds","description":"Retrieve all football rounds available within your Sportmonks subscription"},{"name":"Football: Get Rounds by Season","description":"Retrieve all rounds for a season ID from Sportmonks"},{"name":"Football: Get Schedules by Season","description":"Retrieve the full schedule (stages, rounds and fixtures) for a season by season ID"},{"name":"Football: Get Schedules by Season and Team","description":"Retrieve the full season schedule for a specific team by season ID and team ID"},{"name":"Football: Get Schedules by Team","description":"Retrieve the full schedule (stages, rounds and fixtures) for a team by team ID"},{"name":"Football: Get Season by ID","description":"Retrieve a single football season by its ID from Sportmonks"},{"name":"Football: Get Seasons","description":"Retrieve all football seasons available within your Sportmonks subscription"},{"name":"Football: Get Seasons by Team","description":"Retrieve all seasons for a team ID from Sportmonks"},{"name":"Football: Get Stage by ID","description":"Retrieve a single football stage by its ID from Sportmonks"},{"name":"Football: Get Stage Statistics","description":"Retrieve all available statistics for a stage ID from Sportmonks"},{"name":"Football: Get Stages","description":"Retrieve all football stages available within your Sportmonks subscription"},{"name":"Football: Get Stages by Season","description":"Retrieve all stages for a season ID from Sportmonks"},{"name":"Football: Get Standing Corrections by Season","description":"Retrieve point corrections (awarded or deducted) for a season ID from Sportmonks"},{"name":"Football: Get All Standings","description":"Retrieve all standings available within your Sportmonks subscription"},{"name":"Football: Get Standings by Round","description":"Retrieve the full standing table for a round ID from Sportmonks"},{"name":"Football: Get Standings by Season","description":"Retrieve the full league standings table for a season by season ID from Sportmonks"},{"name":"Football: Get State by ID","description":"Retrieve a single fixture state by its ID from Sportmonks"},{"name":"Football: Get States","description":"Retrieve all fixture states (e.g. Not Started, 1st Half, Full Time) from Sportmonks"},{"name":"Football: Get Team by ID","description":"Retrieve a single football team by its ID from Sportmonks"},{"name":"Football: Get All Team Rankings","description":"Retrieve all team rankings available within your Sportmonks subscription (beta)"},{"name":"Football: Get Team Rankings by Date","description":"Retrieve team rankings for a given date (YYYY-MM-DD) from Sportmonks (beta)"},{"name":"Football: Get Team Rankings by Team","description":"Retrieve team rankings for a team ID from Sportmonks (beta)"},{"name":"Football: Get Team Squad","description":"Retrieve the current domestic squad for a team by team ID from Sportmonks"},{"name":"Football: Get Team Squad by Season","description":"Retrieve the (historical) squad for a team in a specific season from Sportmonks"},{"name":"Football: Get Teams by Country","description":"Retrieve all teams for a country ID from Sportmonks"},{"name":"Football: Get Teams by Season","description":"Retrieve all teams for a season ID from Sportmonks"},{"name":"Football: Get Topscorers by Season","description":"Retrieve the topscorers (goals, assists, cards) for a season by season ID from Sportmonks"},{"name":"Football: Get Topscorers by Stage","description":"Retrieve topscorers for a stage by stage ID from Sportmonks"},{"name":"Football: Get All Team of the Week","description":"Retrieve all available Team of the Week (TOTW) entries from Sportmonks"},{"name":"Football: Get Team of the Week by Round","description":"Retrieve the Team of the Week (TOTW) for a round ID from Sportmonks"},{"name":"Football: Get Transfer by ID","description":"Retrieve a single transfer by its ID from Sportmonks"},{"name":"Football: Get Transfer Rumour by ID","description":"Retrieve a single transfer rumour by its ID from Sportmonks"},{"name":"Football: Get Transfer Rumours Between Dates","description":"Retrieve transfer rumours within a date range (YYYY-MM-DD) from Sportmonks"},{"name":"Football: Get Transfer Rumours by Player","description":"Retrieve transfer rumours for a player ID from Sportmonks"},{"name":"Football: Get Transfer Rumours by Team","description":"Retrieve transfer rumours for a team ID from Sportmonks"},{"name":"Football: Get Transfers Between Dates","description":"Retrieve transfers within a date range (YYYY-MM-DD) from Sportmonks"},{"name":"Football: Get Transfers by Player","description":"Retrieve transfers for a player by player ID from Sportmonks"},{"name":"Football: Get Transfers by Team","description":"Retrieve transfers for a team by team ID from Sportmonks"},{"name":"Football: Get TV Station by ID","description":"Retrieve a single TV station by its ID from Sportmonks"},{"name":"Football: Get TV Stations","description":"Retrieve all TV stations available within your Sportmonks subscription"},{"name":"Football: Get TV Stations by Fixture","description":"Retrieve broadcasting TV stations for a fixture by fixture ID from Sportmonks"},{"name":"Football: Get Upcoming Fixtures by Market","description":"Retrieve all upcoming fixtures for a market ID from Sportmonks"},{"name":"Football: Get Upcoming Fixtures by TV Station","description":"Retrieve all upcoming fixtures available for a TV station ID from Sportmonks"},{"name":"Football: Get Value Bets","description":"Retrieve all value bets available within your Sportmonks subscription"},{"name":"Football: Get Value Bets by Fixture","description":"Retrieve value bet predictions for a fixture by fixture ID from Sportmonks"},{"name":"Football: Get Venue by ID","description":"Retrieve a single football venue by its ID from Sportmonks"},{"name":"Football: Get Venues","description":"Retrieve all football venues available within your Sportmonks subscription"},{"name":"Football: Get Venues by Season","description":"Retrieve all venues for a season ID from Sportmonks"},{"name":"Football: Search Coaches","description":"Search for football coaches by name from Sportmonks"},{"name":"Football: Search Fixtures","description":"Search for football fixtures by name (participants) from Sportmonks"},{"name":"Football: Search Leagues","description":"Search for football leagues by name from Sportmonks"},{"name":"Football: Search Players","description":"Search for football players by name from Sportmonks"},{"name":"Football: Search Referees","description":"Search for football referees by name from Sportmonks"},{"name":"Football: Search Rounds","description":"Search for football rounds by name from Sportmonks"},{"name":"Football: Search Seasons","description":"Search for football seasons by name from Sportmonks"},{"name":"Football: Search Stages","description":"Search for football stages by name from Sportmonks"},{"name":"Football: Search Teams","description":"Search for football teams by name from Sportmonks"},{"name":"Football: Search Venues","description":"Search for football venues by name from Sportmonks"},{"name":"Motorsport: Get All Fixtures","description":"Retrieve all motorsport fixtures (sessions) from Sportmonks"},{"name":"Motorsport: Get Current Leagues by Team","description":"Retrieve the current motorsport leagues for a team by team ID from Sportmonks"},{"name":"Motorsport: Get Driver by ID","description":"Retrieve a single motorsport driver by their ID from Sportmonks"},{"name":"Motorsport: Get All Driver Standings","description":"Retrieve all driver championship standings from Sportmonks"},{"name":"Motorsport: Get Driver Standings by Season","description":"Retrieve the drivers championship standings for a season by season ID from Sportmonks"},{"name":"Motorsport: Get Drivers","description":"Retrieve all motorsport drivers from Sportmonks"},{"name":"Motorsport: Get Drivers by Country","description":"Retrieve all motorsport drivers for a country by country ID from Sportmonks"},{"name":"Motorsport: Get Drivers by Season","description":"Retrieve all motorsport drivers for a season by season ID from Sportmonks"},{"name":"Motorsport: Get Fixture by ID","description":"Retrieve a single motorsport fixture (session) by its ID from Sportmonks"},{"name":"Motorsport: Get Fixtures by Date","description":"Retrieve motorsport fixtures (sessions) on a specific date (YYYY-MM-DD) from Sportmonks"},{"name":"Motorsport: Get Fixtures by Date Range","description":"Retrieve motorsport fixtures (sessions) between two dates (YYYY-MM-DD, max 100 days) from Sportmonks"},{"name":"Motorsport: Get Fixtures by IDs","description":"Retrieve multiple motorsport fixtures (sessions) by their IDs (max 50) from Sportmonks"},{"name":"Motorsport: Get Laps by Fixture","description":"Retrieve all laps for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Laps by Fixture and Driver","description":"Retrieve all laps for a motorsport fixture and driver from Sportmonks"},{"name":"Motorsport: Get Laps by Fixture and Lap Number","description":"Retrieve all laps for a motorsport fixture and lap number from Sportmonks"},{"name":"Motorsport: Get Latest Laps by Fixture","description":"Retrieve the latest laps for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Latest Pitstops by Fixture","description":"Retrieve the latest pitstops for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Latest Stints by Fixture","description":"Retrieve the latest tyre stints for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Latest Updated Drivers","description":"Retrieve the most recently updated motorsport drivers from Sportmonks"},{"name":"Motorsport: Get Latest Updated Fixtures","description":"Retrieve the most recently updated motorsport fixtures (sessions) from Sportmonks"},{"name":"Motorsport: Get League by ID","description":"Retrieve a single motorsport league by its ID from Sportmonks"},{"name":"Motorsport: Get All Leagues","description":"Retrieve all motorsport leagues from Sportmonks"},{"name":"Motorsport: Get Leagues by Country","description":"Retrieve all motorsport leagues for a country by country ID from Sportmonks"},{"name":"Motorsport: Get Leagues by Fixture Date","description":"Retrieve all motorsport leagues with fixtures on a specific date (YYYY-MM-DD) from Sportmonks"},{"name":"Motorsport: Get Leagues by Live","description":"Retrieve all motorsport leagues that currently have live fixtures from Sportmonks"},{"name":"Motorsport: Get Leagues by Team","description":"Retrieve all current and historical motorsport leagues for a team by team ID from Sportmonks"},{"name":"Motorsport: Get Livescores","description":"Retrieve all live motorsport fixtures (sessions) from Sportmonks"},{"name":"Motorsport: Get Pitstops by Fixture","description":"Retrieve all pitstops for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Pitstops by Fixture and Driver","description":"Retrieve all pitstops for a motorsport fixture and driver from Sportmonks"},{"name":"Motorsport: Get Pitstops by Fixture and Lap Number","description":"Retrieve all pitstops for a motorsport fixture and lap number from Sportmonks"},{"name":"Motorsport: Get Race Results by Season and Driver","description":"Retrieve race results (stages with fixtures, lineups and lineup details) for a season and driver from Sportmonks"},{"name":"Motorsport: Get Race Results by Season and Team","description":"Retrieve race results (stages with fixtures, lineups and lineup details) for a season and team from Sportmonks"},{"name":"Motorsport: Get Schedules by Season","description":"Retrieve the full schedule (stages with nested fixtures and venues) for a season by season ID from Sportmonks"},{"name":"Motorsport: Get Season by ID","description":"Retrieve a single motorsport season by its ID from Sportmonks"},{"name":"Motorsport: Get All Seasons","description":"Retrieve all motorsport seasons from Sportmonks"},{"name":"Motorsport: Get Stage by ID","description":"Retrieve a single motorsport stage (race weekend) by its ID from Sportmonks"},{"name":"Motorsport: Get All Stages","description":"Retrieve all motorsport stages (race weekends) from Sportmonks"},{"name":"Motorsport: Get Stages by Season","description":"Retrieve all motorsport stages (race weekends) for a season by season ID from Sportmonks"},{"name":"Motorsport: Get State by ID","description":"Retrieve a single motorsport fixture state by its ID from Sportmonks"},{"name":"Motorsport: Get All States","description":"Retrieve all possible motorsport fixture states from Sportmonks"},{"name":"Motorsport: Get Stints by Fixture","description":"Retrieve all tyre stints for a motorsport fixture (session) by fixture ID from Sportmonks"},{"name":"Motorsport: Get Stints by Fixture and Driver","description":"Retrieve all tyre stints for a motorsport fixture and driver from Sportmonks"},{"name":"Motorsport: Get Stints by Fixture and Stint Number","description":"Retrieve all tyre stints for a motorsport fixture and stint number from Sportmonks"},{"name":"Motorsport: Get Team by ID","description":"Retrieve a single motorsport team (constructor) by its ID from Sportmonks"},{"name":"Motorsport: Get All Team Standings","description":"Retrieve all team (constructor) championship standings from Sportmonks"},{"name":"Motorsport: Get Team Standings by Season","description":"Retrieve the constructors championship standings for a season by season ID from Sportmonks"},{"name":"Motorsport: Get Teams","description":"Retrieve all motorsport teams (constructors) from Sportmonks"},{"name":"Motorsport: Get Teams by Country","description":"Retrieve all motorsport teams (constructors) for a country by country ID from Sportmonks"},{"name":"Motorsport: Get Teams by Season","description":"Retrieve all motorsport teams (constructors) for a season by season ID from Sportmonks"},{"name":"Motorsport: Get Venue by ID","description":"Retrieve a single motorsport venue (racing track) by its ID from Sportmonks"},{"name":"Motorsport: Get Venues","description":"Retrieve all motorsport venues (racing tracks) from Sportmonks"},{"name":"Motorsport: Get Venues by Season","description":"Retrieve all motorsport venues (racing tracks) for a season by season ID from Sportmonks"},{"name":"Motorsport: Search Drivers","description":"Search for motorsport drivers by name from Sportmonks"},{"name":"Motorsport: Search Leagues","description":"Search for motorsport leagues by name from Sportmonks"},{"name":"Motorsport: Search Stages","description":"Search for motorsport stages (race weekends) by name from Sportmonks"},{"name":"Motorsport: Search Teams","description":"Search for motorsport teams (constructors) by name from Sportmonks"},{"name":"Motorsport: Search Venues","description":"Search for motorsport venues (racing tracks) by name from Sportmonks"},{"name":"Odds: Get All Historical Odds","description":"Retrieve all available historical (premium) pre-match odd values from the Sportmonks Odds API"},{"name":"Odds: Get All In-play Odds","description":"Retrieve all available live (in-play) odds from the Sportmonks Odds API"},{"name":"Odds: Get All Pre-match Odds","description":"Retrieve all available pre-match odds from the Sportmonks Odds API"},{"name":"Odds: Get All Premium Odds","description":"Retrieve all available premium (historical) pre-match odds from the Sportmonks Odds API"},{"name":"Odds: Get Bookmaker by ID","description":"Retrieve a single bookmaker by its ID from the Sportmonks Odds API"},{"name":"Odds: Get Bookmaker Event IDs by Fixture","description":"Retrieve bookmakers\' own event ids mapped to a Sportmonks fixture via the Sportmonks Odds API"},{"name":"Odds: Get Bookmakers","description":"Retrieve all bookmakers from the Sportmonks Odds API"},{"name":"Odds: Get Bookmakers by Fixture","description":"Retrieve all bookmakers available for a fixture from the Sportmonks Odds API"},{"name":"Odds: Get In-play Odds by Fixture","description":"Retrieve live (in-play) odds for a fixture by fixture ID from the Sportmonks Odds API"},{"name":"Odds: Get In-play Odds by Fixture and Bookmaker","description":"Retrieve live (in-play) odds for a fixture from a specific bookmaker via the Sportmonks Odds API"},{"name":"Odds: Get In-play Odds by Fixture and Market","description":"Retrieve live (in-play) odds for a fixture on a specific market via the Sportmonks Odds API"},{"name":"Odds: Get Last Updated In-play Odds","description":"Retrieve in-play odds updated in the last 10 seconds from the Sportmonks Odds API"},{"name":"Odds: Get Last Updated Pre-match Odds","description":"Retrieve pre-match odds updated in the last 10 seconds from the Sportmonks Odds API"},{"name":"Odds: Get Market by ID","description":"Retrieve a single betting market by its ID from the Sportmonks Odds API"},{"name":"Odds: Get Markets","description":"Retrieve all betting markets from the Sportmonks Odds API"},{"name":"Odds: Get Pre-match Odds by Fixture","description":"Retrieve pre-match odds for a fixture by fixture ID from the Sportmonks Odds API"},{"name":"Odds: Get Pre-match Odds by Fixture and Bookmaker","description":"Retrieve pre-match odds for a fixture from a specific bookmaker via the Sportmonks Odds API"},{"name":"Odds: Get Pre-match Odds by Fixture and Market","description":"Retrieve pre-match odds for a fixture on a specific market via the Sportmonks Odds API"},{"name":"Odds: Get Premium Odds by Fixture","description":"Retrieve premium (historical) pre-match odds for a fixture from the Sportmonks Odds API"},{"name":"Odds: Get Premium Odds by Fixture and Bookmaker","description":"Retrieve premium pre-match odds for a fixture from a specific bookmaker via the Sportmonks Odds API"},{"name":"Odds: Get Premium Odds by Fixture and Market","description":"Retrieve premium pre-match odds for a fixture on a specific market via the Sportmonks Odds API"},{"name":"Odds: Get Updated Historical Odds Between Time Range","description":"Retrieve historical (premium) odds updated between two UNIX timestamps (max 5 minutes) from the Sportmonks Odds API"},{"name":"Odds: Get Updated Premium Odds Between Time Range","description":"Retrieve premium odds updated between two UNIX timestamps (max 5 minutes) from the Sportmonks Odds API"},{"name":"Odds: Search Bookmakers","description":"Search for bookmakers by name from the Sportmonks Odds API"},{"name":"Odds: Search Markets","description":"Search for betting markets by name from the Sportmonks Odds API"},{"name":"Core: Get Cities","description":"Retrieve all cities from the Sportmonks Core API"},{"name":"Core: Get City by ID","description":"Retrieve a single city by its ID from the Sportmonks Core API"},{"name":"Core: Get Continent by ID","description":"Retrieve a single continent by its ID from the Sportmonks Core API"},{"name":"Core: Get Continents","description":"Retrieve all continents from the Sportmonks Core API"},{"name":"Core: Get Countries","description":"Retrieve all countries from the Sportmonks Core API"},{"name":"Core: Get Country by ID","description":"Retrieve a single country by its ID from the Sportmonks Core API"},{"name":"Core: Get All Entity Filters","description":"Retrieve all available filters grouped per entity from the Sportmonks Core API"},{"name":"Core: Get My Usage","description":"Retrieve your Sportmonks API usage aggregated per 5 minutes"},{"name":"Core: Get Region by ID","description":"Retrieve a single region by its ID from the Sportmonks Core API"},{"name":"Core: Get Regions","description":"Retrieve all regions from the Sportmonks Core API"},{"name":"Core: Get Timezones","description":"Retrieve all supported time zones (IANA names) from the Sportmonks Core API"},{"name":"Core: Get Type by ID","description":"Retrieve a single type by its ID from the Sportmonks Core API"},{"name":"Core: Get Type by Entity","description":"Retrieve the available types grouped per entity from the Sportmonks Core API"},{"name":"Core: Get Types","description":"Retrieve all types (reference data describing events, statistics, positions, etc.) from the Sportmonks Core API"},{"name":"Core: Search Cities","description":"Search for cities by name from the Sportmonks Core API"},{"name":"Core: Search Countries","description":"Search for countries by name from the Sportmonks Core API"},{"name":"Core: Search Regions","description":"Search for regions by name from the Sportmonks Core API"}],"triggers":[],"skills":[{"name":"daily-football-fixtures","description":"List a day\'s football fixtures from Sportmonks, optionally filtered by league.","content":"# Daily Football Fixtures\\n\\nGet the football matches scheduled for a given day.\\n\\n## Steps\\n1. Use Get Football Fixtures by Date with the target date in YYYY-MM-DD format.\\n2. Optionally set Includes to `participants;scores;league` to enrich each fixture.\\n3. Optionally set Filters such as `fixtureLeagues:501,271` to restrict to specific leagues.\\n\\n## Output\\nA list of fixtures with kickoff time, the participating teams, and league."},{"name":"live-football-scores","description":"Fetch in-play football matches and their current scores from Sportmonks.","content":"# Live Football Scores\\n\\nSee which matches are being played now and the live score.\\n\\n## Steps\\n1. Use Get Inplay Football Scores to fetch matches in progress.\\n2. Set Includes to `participants;scores` for team names and the scoreline.\\n3. Optionally filter with `fixtureLeagues:501`.\\n\\n## Output\\nA list of live fixtures, each with the two teams, current score, and match state."},{"name":"football-league-table","description":"Build a football league standings table for a season from Sportmonks.","content":"# Football League Table\\n\\nGet the current standings for a competition.\\n\\n## Steps\\n1. Find the season ID (use Get Football Leagues, then its current season).\\n2. Use Get Football Standings by Season with that season ID.\\n3. Set Includes to `participant` for team names and `form` for recent results.\\n\\n## Output\\nAn ordered league table with each team\'s position, points, and recent form."},{"name":"race-weekend-sessions","description":"List the motorsport sessions on a given date from Sportmonks.","content":"# Race Weekend Sessions\\n\\nGet the practice, qualifying, and race sessions for a day.\\n\\n## Steps\\n1. Use Get Motorsport Fixtures by Date with the target date in YYYY-MM-DD format.\\n2. Set Includes to `venue;participants` to attach the track and entrants.\\n\\n## Output\\nA list of sessions for the day with type (Practice/Qualifying/Race), track, and start time."},{"name":"motorsport-championship","description":"Fetch driver and constructor championship standings for a motorsport season.","content":"# Motorsport Championship\\n\\nGet the title race state for a season.\\n\\n## Steps\\n1. Use Get Motorsport Driver Standings by Season with the season ID.\\n2. Use Get Motorsport Team Standings by Season with the same season ID.\\n3. Set Includes to `participant` for driver/team names.\\n\\n## Output\\nOrdered drivers and constructors tables with each participant\'s position and points."},{"name":"pre-match-odds","description":"Fetch pre-match odds for a fixture and compute implied probabilities.","content":"# Pre-match Odds\\n\\nGet the betting odds for an upcoming fixture.\\n\\n## Steps\\n1. Use Get Pre-match Odds by Fixture with the fixture ID.\\n2. Set Includes to `market;bookmaker` and optionally Filters like `bookmakers:2,14` to narrow results.\\n\\n## Output\\nThe odds per outcome with decimal value and implied probability, grouped by market and bookmaker."},{"name":"odds-line-shopping","description":"Find the best available price per outcome across bookmakers.","content":"# Odds Line Shopping\\n\\nFind the best odds for each outcome.\\n\\n## Steps\\n1. Use Get Pre-match Odds by Fixture for the fixture (do not filter to one bookmaker).\\n2. Group the returned odds by market and outcome label.\\n3. For each outcome, pick the highest value and note its bookmaker_id.\\n\\n## Output\\nFor each outcome, the best decimal price and which bookmaker offers it."},{"name":"resolve-country","description":"Resolve a country name to its Sportmonks ID and ISO codes via Core reference data.","content":"# Resolve Country\\n\\nNormalize a country name to Sportmonks reference data.\\n\\n## Steps\\n1. Use Search Countries with the country name.\\n2. Read the matching country id, iso2, iso3, and fifa_name.\\n\\n## Output\\nThe country id plus its ISO2, ISO3, and FIFA codes for use in other lookups."}],"templates":[{"title":"Sportmonks daily fixtures digest","prompt":"Build a scheduled daily workflow that fetches today\'s football fixtures from Sportmonks for the leagues I follow, summarizes the key matchups and kickoff times, and posts the digest to Slack.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"slack","name":"Slack"}]},{"title":"Sportmonks live score alerter","prompt":"Create a scheduled workflow that polls Sportmonks inplay football scores, detects goals and status changes since the last run, and pings Slack with the updated scoreline for tracked matches.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"slack","name":"Slack"}]},{"title":"Sportmonks league standings report","prompt":"Build a scheduled weekly workflow that pulls the Sportmonks football standings and topscorers for a season, formats a league table with recent form, and emails the report to the group.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"gmail","name":"Gmail"}]},{"title":"Sportmonks race weekend digest","prompt":"Build a scheduled workflow that fetches this weekend\'s motorsport sessions from Sportmonks, summarizes the practice, qualifying, and race times, and posts the schedule to Slack.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"slack","name":"Slack"}]},{"title":"Sportmonks championship tracker","prompt":"Create a scheduled weekly workflow that pulls the Sportmonks motorsport driver and constructor standings for the current season, formats the championship tables, and emails them to the group.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"gmail","name":"Gmail"}]},{"title":"Sportmonks pre-match odds snapshot","prompt":"Build a workflow that pulls Sportmonks pre-match odds for a fixture across selected bookmakers, computes the implied probability for each outcome, and writes the snapshot to a table.","integrations":[{"id":"sportmonks","name":"Sportmonks"}]},{"title":"Sportmonks live odds alerter","prompt":"Create a scheduled workflow that polls Sportmonks in-play odds for a fixture, detects sharp price moves since the last run, and pings Slack with the updated lines.","integrations":[{"id":"sportmonks","name":"Sportmonks"},{"id":"slack","name":"Slack"}]},{"title":"Sportmonks head-to-head preview","prompt":"Create a workflow that takes two team names, resolves them to IDs via Sportmonks football team search, pulls their head-to-head history and current standings, and writes a match preview file.","integrations":[{"id":"sportmonks","name":"Sportmonks"}]}]},{"id":"square","type":"square","slug":"square","name":"Square","description":"Process payments and manage Square commerce data","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/square","authType":"api-key","connections":[],"operations":[{"name":"Create Payment","description":"Take a payment using a payment source such as a card nonce or a card on file"},{"name":"Get Payment","description":"Retrieve details for a single payment by its ID"},{"name":"List Payments","description":"List payments taken by the account, optionally filtered by location and time range"},{"name":"Cancel Payment","description":"Cancel (void) an authorized payment that has not been captured"},{"name":"Complete Payment","description":"Capture (complete) a payment that was authorized with delayed capture"},{"name":"Refund Payment","description":"Refund all or part of a completed payment"},{"name":"Get Refund","description":"Retrieve a single payment refund by its ID"},{"name":"List Refunds","description":"List payment refunds, optionally filtered by location, status, and time range"},{"name":"Create Customer","description":"Create a new customer profile in the Square customer directory"},{"name":"Get Customer","description":"Retrieve a single customer profile by its ID"},{"name":"List Customers","description":"List customer profiles in the Square customer directory"},{"name":"Search Customers","description":"Search customer profiles using filters such as email, phone, or creation date"},{"name":"Update Customer","description":"Update fields on an existing customer profile"},{"name":"Delete Customer","description":"Delete a customer profile from the Square customer directory"},{"name":"List Locations","description":"List all locations associated with the Square account"},{"name":"Get Location","description":"Retrieve a single location by its ID"},{"name":"Create Order","description":"Create an order with line items, taxes, discounts, and fulfillments"},{"name":"Get Order","description":"Retrieve a single order by its ID"},{"name":"Search Orders","description":"Search orders across one or more locations using filters and sorting"},{"name":"Pay Order","description":"Pay for an order using one or more already-approved payments"},{"name":"Create Invoice","description":"Create a draft invoice for an existing order and customer"},{"name":"Get Invoice","description":"Retrieve a single invoice by its ID"},{"name":"List Invoices","description":"List invoices for a specific location"},{"name":"Search Invoices","description":"Search invoices across one or more locations"},{"name":"Publish Invoice","description":"Publish a draft invoice so it is sent to the customer and becomes payable"},{"name":"Cancel Invoice","description":"Cancel a published invoice that is unpaid or partially paid"},{"name":"Delete Invoice","description":"Delete a draft invoice"},{"name":"Upsert Catalog Object","description":"Create or update a catalog object such as an item, variation, or category"},{"name":"Get Catalog Object","description":"Retrieve a single catalog object by its ID"},{"name":"List Catalog","description":"List catalog objects, optionally filtered by type"},{"name":"Search Catalog Objects","description":"Search catalog objects by type and query filters"},{"name":"Create Catalog Image","description":"Upload an image and attach it to the catalog, optionally to a specific item"},{"name":"Delete Catalog Object","description":"Delete a catalog object and its children (e.g. an item and its variations)"},{"name":"Batch Retrieve Inventory Counts","description":"Retrieve current inventory counts for catalog items across locations"}],"triggers":[],"skills":[{"name":"take-payment","description":"Take a Square payment from a payment source and confirm the result.","content":"# Take Payment\\n\\nCharge a customer using Square.\\n\\n## Steps\\n1. Run Create Payment with the source ID (card nonce or card on file), the amount in the smallest denomination, and the currency.\\n2. Optionally attach a customer ID, location ID, or order ID.\\n3. Confirm the result with Get Payment if you need the latest status.\\n\\n## Output\\nReturn the payment ID, status (APPROVED, COMPLETED, or FAILED), and the amount charged. If a refund is needed, run Refund Payment with the payment ID."},{"name":"issue-and-publish-invoice","description":"Create a Square invoice for an order and publish it to the customer.","content":"# Issue And Publish Invoice\\n\\nBill a customer with a Square invoice.\\n\\n## Steps\\n1. Make sure an order exists (use Create Order if needed) and you have the customer ID.\\n2. Run Create Invoice with an invoice object referencing the location, order, primary recipient (customer), and payment requests. Note the returned invoice ID and version.\\n3. Run Publish Invoice with that invoice ID and version to send it to the customer.\\n4. Track payment with Get Invoice.\\n\\n## Output\\nReturn the invoice ID, status, and the public URL where the customer can pay."},{"name":"manage-catalog-item","description":"Create or update a Square catalog item and attach an image to it.","content":"# Manage Catalog Item\\n\\nBuild out the Square catalog.\\n\\n## Steps\\n1. Run Upsert Catalog Object with an ITEM object (use a temporary id like \\"#Name\\" for new items). Capture the returned object ID.\\n2. To add a picture, run Create Catalog Image with the image file and the object ID to attach it to the item.\\n3. Verify with Get Catalog Object or Search Catalog Objects.\\n\\n## Output\\nReturn the catalog object ID, type, and version, plus the image object ID when an image was attached."},{"name":"find-customer-activity","description":"Look up a Square customer and summarize their orders and payments.","content":"# Find Customer Activity\\n\\nBuild a purchase history view for one customer.\\n\\n## Steps\\n1. Run Search Customers (by email or phone) or Get Customer to identify the customer and their ID.\\n2. Run Search Orders across the relevant locations filtered to that customer.\\n3. Run List Payments and match payments to the customer for a full financial picture.\\n\\n## Output\\nReturn the customer ID and email plus a summary of their orders and payments: total spend, number of orders, and any refunds."}],"templates":[{"title":"Square daily sales summary","prompt":"Build a scheduled daily workflow that lists Square payments from the previous day across all locations, totals gross sales, refunds, and net revenue, writes the figures to a table for historical tracking, and posts a Slack summary with day-over-day trends.","integrations":[{"id":"square","name":"Square"},{"id":"slack","name":"Slack"}]},{"title":"Square refund pattern monitor","prompt":"Create a scheduled weekly workflow that lists Square payments and their refunds, classifies each refund by reason and location, flags any location with an unusually high refund rate, and emails finance a narrative report with recommended actions.","integrations":[{"id":"square","name":"Square"},{"id":"gmail","name":"Gmail"}]},{"title":"Square new customer welcome","prompt":"Build a workflow that takes a new Square customer, creates a welcome email tailored to their purchase, adds them to an onboarding tracking table, and posts a notification to the customer success Slack channel.","integrations":[{"id":"square","name":"Square"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Square invoice chase automation","prompt":"Create a scheduled workflow that lists Square invoices for a location, finds those that are unpaid past their due date, sends a polite reminder email per customer, and logs every chase action to a collections table.","integrations":[{"id":"square","name":"Square"},{"id":"gmail","name":"Gmail"}]},{"title":"Square catalog image enrichment","prompt":"Build a workflow that lists Square catalog items missing images, generates a product image for each one, uploads it as a catalog image attached to the item, and writes a report of which items were updated.","integrations":[{"id":"square","name":"Square"}]},{"title":"Square low-stock reorder alerts","prompt":"Create a scheduled workflow that lists the Square catalog, identifies items flagged as low or out of stock, drafts a reorder summary grouped by supplier, and posts it to a Slack purchasing channel with the items and quantities to reorder.","integrations":[{"id":"square","name":"Square"},{"id":"slack","name":"Slack"}]},{"title":"Square purchase history lookup","prompt":"Build a workflow that searches Square customers by email, pulls their orders and payments, summarizes lifetime spend and most-purchased items, and returns a concise profile the support team can use during a conversation.","integrations":[{"id":"square","name":"Square"}]}]},{"id":"ssh","type":"ssh_v2","slug":"ssh","name":"SSH","description":"Connect to remote servers via SSH","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/ssh","authType":"api-key","connections":[],"operations":[{"name":"Execute Command","description":"Execute a shell command on a remote SSH server"},{"name":"Execute Script","description":"Upload and execute a multi-line script on a remote SSH server"},{"name":"Check Command Exists","description":"Check if a command/program exists on the remote SSH server"},{"name":"Upload File","description":"Upload a file to a remote SSH server"},{"name":"Download File","description":"Download a file from a remote SSH server"},{"name":"List Directory","description":"List files and directories in a remote directory"},{"name":"Check File/Directory Exists","description":"Check if a file or directory exists on the remote SSH server"},{"name":"Create Directory","description":"Create a directory on the remote SSH server"},{"name":"Delete File/Directory","description":"Delete a file or directory from the remote SSH server"},{"name":"Move/Rename","description":"Move or rename a file or directory on the remote SSH server"},{"name":"Get System Info","description":"Retrieve system information from the remote SSH server"},{"name":"Read File Content","description":"Read the contents of a remote file"},{"name":"Write File Content","description":"Write or append content to a remote file"}],"triggers":[],"skills":[{"name":"remote-health-check","description":"Run a lightweight health check over SSH and turn the output into a readable status line.","content":"# Remote Health Check\\n\\nRun a quick SSH health probe and summarize the result.\\n\\n## Steps\\n1. Use the Execute Command operation with `uptime && free -m && df -h /`.\\n2. Read `stdout` for load, memory, and disk figures.\\n3. Confirm `exitCode` is 0 and `success` is true before trusting the output.\\n4. Summarize into one status line (healthy / degraded) for posting downstream.\\n\\n## Output\\nA short human-readable status derived from `stdout`, gated on `success`."},{"name":"guarded-command-run","description":"Check a command exists over SSH before executing it, so missing dependencies fail loudly.","content":"# Guarded Command Run\\n\\nAvoid silent failures by verifying a dependency first.\\n\\n## Steps\\n1. Use Check Command Exists with the target `commandName` (e.g. `docker`).\\n2. Branch on the `exists` output.\\n3. When `exists` is true, run the real command with Execute Command.\\n4. When false, stop and report a clear \\"dependency missing\\" message.\\n\\n## Output\\nEither the command `stdout`/`exitCode`, or an explicit missing-dependency message."},{"name":"remote-log-digest","description":"Pull the tail of a remote log over SSH and summarize errors and warnings into a digest.","content":"# Remote Log Digest\\n\\nTurn a noisy remote log into a scannable summary.\\n\\n## Steps\\n1. Use Read File Content on the log path (e.g. `/var/log/app.log`) with a sensible max size.\\n2. Take the returned `content` and pass it to an agent.\\n3. Ask the agent to extract recent errors, warnings, and their counts.\\n4. Emit a short digest for Slack or a report.\\n\\n## Output\\nA concise digest of notable log lines derived from the file `content`."},{"name":"safe-config-deploy","description":"Upload a config file over SSH, then restart the service and verify the exit code.","content":"# Safe Config Deploy\\n\\nShip a config change and confirm the service came back healthy.\\n\\n## Steps\\n1. Use Upload File (or Write File Content) to place the config at its target path.\\n2. Execute the restart command for the affected service.\\n3. Inspect `exitCode` and `stderr` to detect a failed restart.\\n4. Report `success` plus any `stderr` so a bad deploy is visible immediately.\\n\\n## Output\\nA pass/fail result built from `exitCode`, `success`, and `stderr`."}],"templates":[{"title":"SSH health check to Slack","prompt":"Every morning, SSH into the production server and run a health check command (uptime, load average, and free memory). Summarize stdout with an agent and post the result to the #ops Slack channel so the team starts the day knowing the box is healthy.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Disk-usage alert with SSH","prompt":"On a schedule, SSH into the server and execute \'df -h /\' to read disk usage. Parse the stdout, and if the used percentage crosses 85%, send an alert to Slack with the current usage; otherwise stay silent.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Run a deploy script over SSH","prompt":"Trigger a deployment by SSHing into the app server and executing a maintenance script that pulls the latest code, installs dependencies, rebuilds, and restarts the service. Check the exitCode and success outputs, then report stdout and stderr back so failures are visible.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Summarize a remote log over SSH","prompt":"SSH into the server and read the last 200 lines of /var/log/app.log, then hand the content to an agent that summarizes recent errors and warnings into a short digest. Post the digest so on-call engineers can scan incidents at a glance.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Fetch a remote report over SSH","prompt":"Download a generated report file from the remote server via SSH and pass the resulting file output into the next step for processing or storage, so a nightly export on the box flows straight into the workflow.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Verify a command exists over SSH","prompt":"Before executing a maintenance step, use Check Command Exists over SSH to confirm a tool like docker or git is installed on the remote host. If the exists output is true, run the command; if not, report a clear message that the dependency is missing.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Push a config and restart over SSH","prompt":"Upload a rendered configuration file to the remote server via SSH, write it to the target path, then execute a command to restart the affected service. Confirm success from the exitCode and stderr outputs before finishing.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"SSH health check to Slack","prompt":"Every morning, SSH into the production server and run a health check command (uptime, load average, and free memory). Summarize stdout with an agent and post the result to the #ops Slack channel so the team starts the day knowing the box is healthy.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Disk-usage alert with SSH","prompt":"On a schedule, SSH into the server and execute \'df -h /\' to read disk usage. Parse the stdout, and if the used percentage crosses 85%, send an alert to Slack with the current usage; otherwise stay silent.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Run a deploy script over SSH","prompt":"Trigger a deployment by SSHing into the app server and executing a maintenance script that pulls the latest code, installs dependencies, rebuilds, and restarts the service. Check the exitCode and success outputs, then report stdout and stderr back so failures are visible.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Summarize a remote log over SSH","prompt":"SSH into the server and read the last 200 lines of /var/log/app.log, then hand the content to an agent that summarizes recent errors and warnings into a short digest. Post the digest so on-call engineers can scan incidents at a glance.","integrations":[{"id":"ssh","name":"SSH"},{"id":"slack","name":"Slack"}]},{"title":"Fetch a remote report over SSH","prompt":"Download a generated report file from the remote server via SSH and pass the resulting file output into the next step for processing or storage, so a nightly export on the box flows straight into the workflow.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Verify a command exists over SSH","prompt":"Before executing a maintenance step, use Check Command Exists over SSH to confirm a tool like docker or git is installed on the remote host. If the exists output is true, run the command; if not, report a clear message that the dependency is missing.","integrations":[{"id":"ssh","name":"SSH"}]},{"title":"Push a config and restart over SSH","prompt":"Upload a rendered configuration file to the remote server via SSH, write it to the target path, then execute a command to restart the affected service. Confirm success from the exitCode and stderr outputs before finishing.","integrations":[{"id":"ssh","name":"SSH"}]}]},{"id":"stagehand","type":"stagehand","slug":"stagehand","name":"Stagehand","description":"Web automation and data extraction","category":"AI","docsUrl":"https://docs.sim.ai/integrations/stagehand","authType":"api-key","connections":[],"operations":[{"name":"Extract Data","description":"Extract structured data from a webpage using Stagehand"},{"name":"Run Agent","description":"Run an autonomous web agent to complete tasks and extract structured data"}],"triggers":[],"skills":[{"name":"extract-structured-data","description":"Use Stagehand to extract structured fields from a web page into a typed result.","content":"# Extract Structured Data\\n\\nPull clean, structured data off a single web page.\\n\\n## Steps\\n1. Run the Extract Data operation with the target URL.\\n2. Describe exactly what to extract and the shape you want (for example product name, price, and availability), so Stagehand returns typed fields rather than raw HTML.\\n3. Choose the LLM provider for the extraction.\\n\\n## Output\\nReturn the extracted fields as a structured object, and note any field the page did not contain so downstream steps can handle gaps."},{"name":"run-browser-agent-task","description":"Hand Stagehand a natural-language goal and let its agent navigate and act on a site autonomously.","content":"# Run Browser Agent Task\\n\\nDelegate a multi-step web task to the Stagehand agent.\\n\\n## Steps\\n1. Run the Run Agent operation with a clear natural-language goal (for example find the latest pricing on a vendor site and capture it).\\n2. Provide the starting URL and pick the execution mode (DOM, hybrid, or CUA) and the LLM provider appropriate to the task.\\n3. Let the agent navigate, click, and read pages to complete the goal.\\n\\n## Output\\nReturn the agent result, the key data it captured, and any screenshots, plus a short note if the goal could not be fully completed."},{"name":"monitor-page-for-changes","description":"Periodically extract a value from a web page with Stagehand and report when it changes.","content":"# Monitor Page for Changes\\n\\nWatch a specific value on a web page over time.\\n\\n## Steps\\n1. Run the Extract Data operation against the target URL, extracting just the value to watch (price, stock status, headline).\\n2. Compare the extracted value against the last known value stored from a previous run.\\n3. Decide whether the value changed beyond a meaningful threshold.\\n\\n## Output\\nReport the current extracted value, whether it changed since the last check, and the old and new values when a change is detected."}],"templates":[{"title":"Browser Use + Stagehand cross-tool QA","prompt":"Create a workflow that uses Browser Use and Stagehand together to run scripted browser flows against staging, captures screenshots, and writes a regression report.","integrations":[{"id":"stagehand","name":"Stagehand"},{"id":"browser_use","name":"Browser Use"}]},{"title":"Browser Use + Stagehand expense-portal grabber","prompt":"Build a workflow that uses Browser Use and Stagehand to automate expense-portal data pulls from suppliers, captures the structured data, and writes to a finance table.","integrations":[{"id":"stagehand","name":"Stagehand"},{"id":"browser_use","name":"Browser Use"}]},{"title":"Stagehand QA navigator","prompt":"Build a workflow that uses Stagehand to run scripted browser flows against staging, captures screenshots and assertion outcomes per step, and writes a regression report file.","integrations":[{"id":"stagehand","name":"Stagehand"}]},{"title":"Stagehand booking automator","prompt":"Create a workflow that uses Stagehand to log into supplier portals, place recurring orders from a tables-defined catalog, and write confirmation numbers back to the orders table.","integrations":[{"id":"stagehand","name":"Stagehand"}]},{"title":"Stagehand price-monitor sweep","prompt":"Build a scheduled workflow that uses Stagehand to navigate a catalog of supplier sites, capture current prices and stock for items in a tracking table, and alert Slack on threshold breaches.","integrations":[{"id":"stagehand","name":"Stagehand"},{"id":"slack","name":"Slack"}]},{"title":"Stagehand competitor product trial","prompt":"Build a workflow that uses Stagehand to walk through competitor product trials weekly, captures screenshots of every step, and writes a UX-comparison file.","integrations":[{"id":"stagehand","name":"Stagehand"}]},{"title":"Stagehand onboarding-flow auditor","prompt":"Create a workflow that uses Stagehand to test the production onboarding flow daily, captures friction points, and writes a UX regression table.","integrations":[{"id":"stagehand","name":"Stagehand"}]},{"title":"Stagehand structured lead extractor","prompt":"Build a workflow that uses Stagehand to visit a list of company sites from a table, extracts structured fields — company name, contact email, pricing tier, and key features — into a defined schema, and writes the clean records back into a research table for the sales team.","integrations":[{"id":"stagehand","name":"Stagehand"}]},{"title":"Stagehand autonomous task runner","prompt":"Create a workflow that hands Stagehand a natural-language goal like \\"find the latest pricing on this vendor site and download the PDF\\", lets the Stagehand agent navigate and act on the page autonomously, and saves the captured result and screenshots to files.","integrations":[{"id":"stagehand","name":"Stagehand"}]}]},{"id":"stripe","type":"stripe","slug":"stripe","name":"Stripe","description":"Process payments and manage Stripe data","category":"Commerce","docsUrl":"https://docs.sim.ai/integrations/stripe","authType":"api-key","connections":[],"operations":[{"name":"Create Payment Intent","description":"Create a new Payment Intent to process a payment"},{"name":"Retrieve Payment Intent","description":"Retrieve an existing Payment Intent by ID"},{"name":"Update Payment Intent","description":"Update an existing Payment Intent"},{"name":"Confirm Payment Intent","description":"Confirm a Payment Intent and inspect its resulting status. Confirmation can require further action or asynchronous processing before payment succeeds."},{"name":"Capture Payment Intent","description":"Capture an authorized Payment Intent"},{"name":"Cancel Payment Intent","description":"Cancel a Payment Intent"},{"name":"List Payment Intents","description":"List all Payment Intents"},{"name":"Search Payment Intents","description":"Search for Payment Intents using query syntax"},{"name":"Create Customer","description":"Create a new customer object"},{"name":"Retrieve Customer","description":"Retrieve an existing customer by ID"},{"name":"Update Customer","description":"Update an existing customer"},{"name":"Delete Customer","description":"Permanently delete a customer"},{"name":"List Customers","description":"List all customers"},{"name":"Search Customers","description":"Search for customers using query syntax"},{"name":"Create Subscription","description":"Create a new subscription for a customer"},{"name":"Retrieve Subscription","description":"Retrieve an existing subscription by ID"},{"name":"Update Subscription","description":"Update an existing subscription"},{"name":"Cancel Subscription","description":"Cancel a subscription"},{"name":"Resume Subscription","description":"Resume a paused subscription"},{"name":"List Subscriptions","description":"List one page of subscriptions. Follow starting_after while metadata.has_more is true."},{"name":"Search Subscriptions","description":"Search one page of subscriptions using query syntax. Pass metadata.next_page as page to continue."},{"name":"Create Invoice","description":"Create a new invoice"},{"name":"Retrieve Invoice","description":"Retrieve an existing invoice by ID"},{"name":"Update Invoice","description":"Update an existing invoice"},{"name":"Delete Invoice","description":"Permanently delete a draft invoice"},{"name":"Finalize Invoice","description":"Finalize a draft invoice"},{"name":"Pay Invoice","description":"Pay an invoice"},{"name":"Void Invoice","description":"Void an invoice"},{"name":"Send Invoice","description":"Send an invoice to the customer"},{"name":"List Invoices","description":"List all invoices"},{"name":"Search Invoices","description":"Search for invoices using query syntax"},{"name":"Create Charge","description":"Create a new charge to process a payment"},{"name":"Retrieve Charge","description":"Retrieve an existing charge by ID"},{"name":"Update Charge","description":"Update an existing charge"},{"name":"Capture Charge","description":"Capture an uncaptured charge"},{"name":"List Charges","description":"List all charges"},{"name":"Search Charges","description":"Search for charges using query syntax"},{"name":"Create Product","description":"Create a new product object"},{"name":"Retrieve Product","description":"Retrieve an existing product by ID"},{"name":"Update Product","description":"Update an existing product"},{"name":"Delete Product","description":"Permanently delete a product"},{"name":"List Products","description":"List all products"},{"name":"Search Products","description":"Search for products using query syntax"},{"name":"Create Price","description":"Create a new price for a product"},{"name":"Retrieve Price","description":"Retrieve an existing price by ID"},{"name":"Update Price","description":"Update an existing price"},{"name":"List Prices","description":"List all prices"},{"name":"Search Prices","description":"Search for prices using query syntax"},{"name":"Retrieve Event","description":"Retrieve an existing Event by ID"},{"name":"List Events","description":"List all Events"}],"triggers":[{"id":"stripe_webhook","name":"Stripe Webhook","description":"Triggers when Stripe events occur (payments, subscriptions, invoices, etc.)"}],"skills":[{"name":"collect-payment","description":"Create and confirm a Stripe payment intent to collect a charge from a customer.","content":"# Collect Payment\\n\\nCharge a customer by creating and confirming a payment intent.\\n\\n## Steps\\n1. Run Create Payment Intent with the amount, currency, and customer.\\n2. Confirm the intent with Confirm Payment Intent and a payment method. If the confirmed intent has status requires_capture, run Capture Payment Intent to collect the authorized funds.\\n3. If a charge needs to be aborted, run Cancel Payment Intent instead.\\n\\n## Output\\nReturn the payment intent ID, its status (succeeded, requires action, or canceled), and the captured amount."},{"name":"manage-subscription","description":"Create a Stripe subscription, manage its cancellation, or resume a paused subscription.","content":"# Manage Subscription\\n\\nHandle the lifecycle of a recurring subscription.\\n\\n## Steps\\n1. To start a subscription, run Create Subscription with the customer and price items.\\n2. Use Update Subscription with cancel_at_period_end to schedule or reverse a cancellation before it takes effect. Use Cancel Subscription only for immediate cancellation. Resume Subscription applies only to a paused subscription; it does not restart a canceled subscription.\\n3. Confirm the current state with Retrieve Subscription.\\n\\n## Output\\nReturn the subscription ID, its status, and the returned subscription items, and note exactly what changed."},{"name":"issue-invoice","description":"Create, finalize, and send a Stripe invoice to a customer, then track payment.","content":"# Issue Invoice\\n\\nBill a customer with a Stripe invoice.\\n\\n## Steps\\n1. Run Create Invoice for the customer. This tool does not add line items; add them in Stripe and verify the draft with Retrieve Invoice before finalizing.\\n2. Run Finalize Invoice to lock it, then Send Invoice to deliver it to the customer.\\n3. Track payment with Retrieve Invoice, or run Pay Invoice to charge a saved payment method. Use Void Invoice to cancel an unpaid invoice.\\n\\n## Output\\nReturn the invoice ID, its status (draft, open, paid, or void), the amount due, and the hosted invoice URL when available."},{"name":"find-customer-activity","description":"Look up a Stripe customer and search their charges and payments for a financial summary.","content":"# Find Customer Activity\\n\\nBuild a payment history view for a single customer.\\n\\n## Steps\\n1. Run Search Customers or Retrieve Customer to identify the customer and their ID.\\n2. Run Search Charges or List Charges filtered to that customer to pull their transactions.\\n3. Optionally run Search Payment Intents and List Invoices for a complete picture.\\n\\n## Output\\nReturn the customer ID and email plus a summary of their charges and invoices, including total amount, successful versus failed payments, and any refunds."}],"templates":[{"title":"AgentPhone collections reminder","prompt":"Build a workflow that picks up Stripe overdue invoices, sends a polite AgentPhone SMS payment reminder with the amount due, and reads the customer reply to update the invoice record.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"agentphone","name":"AgentPhone"}]},{"title":"Clerk org-management automator","prompt":"Create a workflow that on a new enterprise plan via Stripe creates a Clerk organization, invites the admin by email, and writes the Clerk org ID back to the Stripe customer.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"clerk","name":"Clerk"}]},{"title":"Google Ads + Stripe ROAS tracker","prompt":"Create a scheduled workflow that joins Google Ads spend with Stripe revenue only where an explicit campaign ID or UTM mapping was captured, reports unmatched revenue separately, calculates attributed ROAS with that limitation, and posts the per-channel breakdown to Slack each morning.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"google_ads","name":"Google Ads"},{"id":"slack","name":"Slack"}]},{"title":"Google Sheets to Stripe payouts","prompt":"Create a workflow that reads a Google Sheets payouts ledger, validates each row, processes Stripe payouts in batches, and writes the result and Stripe ID back.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Google Slides exec metrics deck","prompt":"Create a scheduled monthly workflow that generates a Google Slides executive metrics deck from BigQuery and Stripe data, swaps the cover with the month, and shares it with leadership.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"google_slides","name":"Google Slides"},{"id":"google_bigquery","name":"Google BigQuery"}]},{"title":"Hex + Stripe revenue notebook","prompt":"Build a scheduled workflow that runs a Hex notebook over Stripe payment data daily, captures MRR, churn, and expansion metrics, and posts a summary with the notebook link to a Slack data channel.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"hex","name":"Hex"},{"id":"slack","name":"Slack"}]},{"title":"Excel financial close automator","prompt":"Build a scheduled workflow that closes the books each period — pulls Stripe and accounting data, updates a Microsoft Excel close workbook, and emails the controller the reconciled file.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"microsoft_excel","name":"Microsoft Excel"},{"id":"gmail","name":"Gmail"}]},{"title":"Teams weekly metrics digest","prompt":"Create a scheduled weekly workflow that aggregates key business metrics from Stripe and HubSpot, formats them into a polished Microsoft Teams adaptive card, and posts to the leadership channel.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"microsoft_teams","name":"Microsoft Teams"},{"id":"hubspot","name":"HubSpot"}]},{"title":"PostHog cohort enrichment","prompt":"Create a workflow that pulls a PostHog cohort, enriches each user with HubSpot lifecycle stage and Stripe LTV, and writes the enriched cohort to a tables-based targeting view.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"posthog","name":"PostHog"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Stripe weekly metrics report","prompt":"Build a scheduled workflow that pulls data from Stripe and my database every Monday, calculates key metrics like MRR, churn, new subscriptions, and failed payments, writes results to Google Sheets, and sends the team a Slack summary with week-over-week trends.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"google_sheets","name":"Google Sheets"},{"id":"slack","name":"Slack"}]},{"title":"Stripe revenue dashboard","prompt":"Create a scheduled daily workflow that pulls payment data from Stripe, calculates MRR, net revenue, failed payments, and new subscriptions, logs everything to a table with historical tracking, and sends a daily Slack summary with trends and anomalies.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Stripe failed payment recovery","prompt":"Build a workflow that listens for Stripe failed-payment events, looks up the customer, classifies the failure reason, drafts a tailored recovery email and a Slack alert to the success team, and logs the attempt in a tracking table so recovery rate can be measured.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Stripe churn flagger","prompt":"Create a scheduled daily workflow that lists Stripe subscriptions canceled or scheduled for cancellation, enriches each customer with usage and support history, scores the churn risk, and logs the cohort to a table with recommended save plays for the success team.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Stripe invoice chaser","prompt":"Build a scheduled workflow that lists Stripe invoices overdue by more than seven days, sends a polite chase email tailored to the customer history, escalates to a Slack alert at thirty days, and writes every action into a collections tracking table.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"},{"id":"slack","name":"Slack"}]},{"title":"Stripe customer welcome flow","prompt":"Create a workflow triggered when a new Stripe customer is created. Send a personalized welcome email, create their onboarding checklist in a table, schedule a follow-up meeting via Calendly, and post a Slack notification to the customer success channel.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"},{"id":"calendly","name":"Calendly"},{"id":"slack","name":"Slack"}]},{"title":"Stripe refund pattern analyzer","prompt":"Build a scheduled weekly workflow that lists Stripe charge and dispute events, classifies each refund or dispute by reason and product, identifies recurring patterns or fraud signals, writes a narrative report file, and Slacks finance with the top concerns and recommended actions.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"slack","name":"Slack"}]},{"title":"Supabase customer record sync","prompt":"Build a workflow that listens for Stripe new-customer events and upserts a row into a Supabase customers table with the correct plan and metadata, then emails a welcome message.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"supabase","name":"Supabase"},{"id":"gmail","name":"Gmail"}]},{"title":"Twilio payment-failure outreach","prompt":"Create a workflow triggered by a Stripe failed-payment event that sends the customer a Twilio SMS with a secure update-payment link and logs the recovery attempt to a table.","integrations":[{"id":"stripe","name":"Stripe"},{"id":"twilio_sms","name":"Twilio SMS"}]}]},{"id":"supabase","type":"supabase","slug":"supabase","name":"Supabase","description":"Use Supabase database","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/supabase","authType":"api-key","connections":[],"operations":[{"name":"Get Many Rows","description":"Query data from a Supabase table"},{"name":"Get a Row","description":"Get a single row from a Supabase table based on filter criteria"},{"name":"Create a Row","description":"Insert data into a Supabase table"},{"name":"Update a Row","description":"Update rows in a Supabase table based on filter criteria"},{"name":"Delete a Row","description":"Delete rows from a Supabase table based on filter criteria"},{"name":"Upsert a Row","description":"Insert or update data in a Supabase table (upsert operation)"},{"name":"Count Rows","description":"Count rows in a Supabase table"},{"name":"Full-Text Search","description":"Perform full-text search on a Supabase table"},{"name":"Vector Search","description":"Perform similarity search using pgvector in a Supabase table"},{"name":"Call RPC Function","description":"Call a PostgreSQL function in Supabase"},{"name":"Invoke Edge Function","description":"Invoke a Supabase Edge Function over HTTP"},{"name":"Introspect Schema","description":"Introspect Supabase database schema from its OpenAPI spec to get table and column structures (best-effort primary/foreign key detection)"},{"name":"Storage: Upload File","description":"Upload a file to a Supabase storage bucket"},{"name":"Storage: Download File","description":"Download a file from a Supabase storage bucket"},{"name":"Storage: List Files","description":"List files in a Supabase storage bucket"},{"name":"Storage: Delete Files","description":"Delete files from a Supabase storage bucket"},{"name":"Storage: Move File","description":"Move a file within a Supabase storage bucket"},{"name":"Storage: Copy File","description":"Copy a file within a Supabase storage bucket"},{"name":"Storage: Get Public URL","description":"Get the public URL for a file in a Supabase storage bucket"},{"name":"Storage: Create Signed URL","description":"Create a temporary signed URL for a file in a Supabase storage bucket"},{"name":"Storage: Create Signed Upload URL","description":"Create a temporary signed URL a client can use to upload directly to a Supabase storage bucket"},{"name":"Storage: Create Bucket","description":"Create a new storage bucket in Supabase"},{"name":"Storage: Update Bucket","description":"Update the configuration of an existing Supabase storage bucket"},{"name":"Storage: Empty Bucket","description":"Delete all objects inside a Supabase storage bucket without deleting the bucket itself"},{"name":"Storage: List Buckets","description":"List all storage buckets in Supabase"},{"name":"Storage: Delete Bucket","description":"Delete a storage bucket in Supabase"}],"triggers":[],"skills":[{"name":"query-table-rows","description":"Read rows from a Supabase table with PostgREST filters, ordering, and pagination.","content":"# Query Supabase Table Rows\\n\\nFetch records from a Supabase table using PostgREST filters so downstream steps work with exactly the rows they need.\\n\\n## Steps\\n1. Use the Get Many Rows operation with the project ID, service role secret, and target table.\\n2. Set Select Columns to the fields you need (for example id,name,email) instead of returning every column.\\n3. Add a PostgREST Filter such as status=eq.active or created_at=gte.2024-01-01 to narrow the result set.\\n4. Set Order By (for example created_at DESC) plus Limit and Offset for predictable pagination.\\n5. For a single record use Get a Row with a filter like id=eq.123.\\n\\n## Output\\nReturn the matched rows as structured JSON. Note how many rows came back and surface the key fields each consumer needs."},{"name":"upsert-record","description":"Insert a new Supabase row or update it if it already exists in one idempotent call.","content":"# Upsert a Supabase Record\\n\\nWrite a record without first checking whether it exists, so repeated runs stay idempotent.\\n\\n## Steps\\n1. Choose the Upsert a Row operation with the project ID, service role secret, and table.\\n2. Provide the Data as a JSON object whose keys match the table columns, including the conflict key (such as id or email).\\n3. Supabase inserts the row when the conflict key is new and updates the existing row otherwise.\\n4. For a guaranteed new row use Create a Row instead; for a known existing row use Update a Row with a filter like id=eq.123.\\n\\n## Output\\nConfirm whether the row was inserted or updated and report the resulting record fields back to the caller."},{"name":"semantic-vector-search","description":"Run pgvector similarity search against a Supabase table to retrieve the closest embeddings.","content":"# Semantic Vector Search in Supabase\\n\\nFind the most relevant rows by embedding similarity, the retrieval step for a RAG agent.\\n\\n## Steps\\n1. Generate an embedding for the query text with your model and capture it as a numeric array.\\n2. Use the Vector Search operation, pointing Function Name at your pgvector match function (for example match_documents).\\n3. Pass the embedding into Query Embedding as a JSON array like [0.1, 0.2, 0.3].\\n4. Tune Match Threshold (for example 0.78) and Match Count (for example 10) to balance precision and recall.\\n\\n## Output\\nReturn the matched rows with their similarity scores, ordered by closeness, ready to feed an answer-generation step."},{"name":"upload-file-to-storage","description":"Upload a file to a Supabase Storage bucket and return a public or signed URL.","content":"# Upload a File to Supabase Storage\\n\\nStore a generated or received file in a bucket and hand back a shareable link.\\n\\n## Steps\\n1. Use Storage: Upload File with the bucket name, file name, and the file reference from a previous block.\\n2. Set an optional Folder Path and Content Type, and enable Upsert if you want to overwrite an existing object.\\n3. For a permanent link on a public bucket use Storage: Get Public URL with the file path.\\n4. For private buckets use Storage: Create Signed URL with an Expires In value such as 3600 seconds.\\n\\n## Output\\nReturn the stored object path plus the public or signed URL so later steps can reference or share the file."},{"name":"invoke-edge-function","description":"Call a deployed Supabase Edge Function over HTTP and use its JSON response.","content":"# Invoke a Supabase Edge Function\\n\\nRun server-side logic deployed as a Supabase Edge Function and feed its result into the workflow.\\n\\n## Steps\\n1. Use the Invoke Edge Function operation with the project ID, service role secret, and the function name (for example hello-world).\\n2. Choose the HTTP Method (defaults to POST) and provide a JSON Request Body the function expects.\\n3. Add optional custom Headers as a JSON object when the function reads specific headers.\\n4. This is different from Call RPC Function, which runs a PostgreSQL function inside the database rather than deployed function code.\\n\\n## Output\\nReturn the function response body as JSON so downstream steps can branch on or transform the result."}],"templates":[{"title":"Supabase customer record sync","prompt":"Build a workflow that listens for Stripe new-customer events and upserts a row into a Supabase customers table with the correct plan and metadata, then emails a welcome message.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"stripe","name":"Stripe"},{"id":"gmail","name":"Gmail"}]},{"title":"Supabase nightly export to S3","prompt":"Create a scheduled workflow that runs each night, exports key Supabase tables to compressed JSON in S3 with date partitions, and writes the manifest to an audit table.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"s3","name":"S3"}]},{"title":"Supabase row-level audit log","prompt":"Build a scheduled workflow that polls Supabase sensitive tables for recently changed rows, captures the diff against the last snapshot into an audit log table, and pings Slack on unusual write patterns.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"slack","name":"Slack"}]},{"title":"Supabase high-priority row alerter","prompt":"Create a scheduled workflow that polls Supabase frequently for high-priority rows — new orders, fraud flags — and posts a Slack alert with context for each new row it finds.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"slack","name":"Slack"}]},{"title":"Supabase storage cleanup","prompt":"Build a scheduled workflow that finds Supabase storage objects older than the retention policy or unreferenced in the database, deletes them, and writes a cleanup report.","integrations":[{"id":"supabase","name":"Supabase"}]},{"title":"Supabase analytics digest","prompt":"Create a scheduled daily workflow that queries Supabase for new signups, active users, and key feature usage, and posts a digest to Slack with week-over-week trend.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"slack","name":"Slack"}]},{"title":"Supabase + Algolia search sync","prompt":"Build a scheduled workflow that mirrors Supabase tables into an Algolia index, propagates new and changed rows on each run, and writes sync lag to a tables-based monitor.","integrations":[{"id":"supabase","name":"Supabase"},{"id":"algolia","name":"Algolia"}]}]},{"id":"tailscale","type":"tailscale","slug":"tailscale","name":"Tailscale","description":"Manage devices and network settings in your Tailscale tailnet","category":"Security","docsUrl":"https://docs.sim.ai/integrations/tailscale","authType":"api-key","connections":[],"operations":[{"name":"List Devices","description":"List devices in the tailnet"},{"name":"Get Device","description":"Get details of a specific device"},{"name":"Set Device Name","description":"Rename a device or reset its name to the OS hostname"},{"name":"Delete Device","description":"Remove a device from the tailnet"},{"name":"Authorize Device","description":"Authorize or deauthorize a device on the tailnet"},{"name":"Set Device Tags","description":"Replace the tags assigned to a device"},{"name":"Get Device Routes","description":"Get the advertised and approved subnet routes for a device"},{"name":"Set Device Routes","description":"Replace the enabled subnet routes for a device"},{"name":"Update Device Key","description":"Enable or disable device key expiry"},{"name":"Expire Device Key","description":"Immediately expire a device node key so the device must reauthenticate"},{"name":"Get Device Attributes","description":"Get device posture attributes and their expiry times"},{"name":"Set Device Attribute","description":"Create or update a custom device posture attribute with an optional expiry"},{"name":"Delete Device Attribute","description":"Remove a custom posture attribute from a device"},{"name":"List DNS Nameservers","description":"Get the global DNS nameservers configured for the tailnet"},{"name":"Set DNS Nameservers","description":"Replace the global DNS nameservers for the tailnet"},{"name":"Get DNS Preferences","description":"Get the MagicDNS preference for the tailnet"},{"name":"Set DNS Preferences","description":"Enable or disable MagicDNS for the tailnet"},{"name":"Get DNS Search Paths","description":"Get the DNS search domains configured for the tailnet"},{"name":"Set DNS Search Paths","description":"Replace the DNS search domains for the tailnet"},{"name":"Get Split DNS","description":"Get split DNS resolvers"},{"name":"Update Split DNS","description":"Update selected split DNS resolvers"},{"name":"Set Split DNS","description":"Replace all split DNS resolvers"},{"name":"Get DNS Configuration","description":"Get tailnet DNS configuration"},{"name":"Set DNS Configuration","description":"Replace the full tailnet DNS configuration"},{"name":"List Users","description":"List users in the tailnet"},{"name":"Get User","description":"Get details of a specific user"},{"name":"Set User Role","description":"Change a tailnet user’s role"},{"name":"Approve User","description":"Approve a pending user to join the tailnet"},{"name":"Suspend User","description":"Suspend a user’s access to the tailnet"},{"name":"Restore User","description":"Restore a suspended user’s access to the tailnet"},{"name":"Delete User","description":"Delete a user from the tailnet"},{"name":"Create Auth Key","description":"Create a device enrollment auth key"},{"name":"List Keys","description":"List active auth keys, API access tokens, and trust credentials in the tailnet"},{"name":"Get Auth Key","description":"Get a key’s type, owner, scopes, expiry, and device enrollment capabilities"},{"name":"Delete Auth Key","description":"Revoke an auth key, API access token, or trust credential"},{"name":"Get ACL","description":"Get the tailnet policy file"},{"name":"Validate ACL","description":"Validate a policy file or run ACL tests without changing the tailnet policy"},{"name":"Set ACL","description":"Replace the tailnet policy file"},{"name":"Get Tailnet Settings","description":"Get tailnet settings"},{"name":"Update Tailnet Settings","description":"Update selected tailnet settings"}],"triggers":[],"skills":[{"name":"synchronize-device-posture","description":"Publish custom device posture signals with an expiry so access rules can use current compliance data.","content":"# Synchronize Device Posture\\n\\n1. Find the device nodeId with List Devices.\\n2. Use Get Device Attributes to inspect the current signals.\\n3. Use Set Device Attribute with a custom: key and a JSON scalar value from your compliance source. Set Attribute Expiry so stale signals disappear automatically, and add an audit comment.\\n4. Read the attributes again to verify the value and expiry; use Delete Device Attribute to remove a signal.\\n\\nReturn the device ID, attribute value, and expiry."},{"name":"manage-private-dns-routes","description":"Maintain split DNS resolvers for private domains without replacing unrelated DNS routes.","content":"# Manage Private DNS Routes\\n\\n1. Use Get Split DNS to read the current domain-to-resolver map.\\n2. Use Update Split DNS with only the domains being changed. Supply null for a domain to remove it.\\n3. Use Get DNS Configuration when resolver behavior with exit nodes or overrideLocalDNS matters.\\n4. Read the configuration again and report the affected domains and resolvers.\\n\\nUse Set Split DNS or Set DNS Configuration only when replacing the full corresponding configuration is intended."},{"name":"audit-tailnet-devices","description":"List every device in the tailnet and flag stale, unauthorized, or update-pending nodes.","content":"# Audit Tailnet Devices\\n\\nProduce a clean inventory of the devices on your tailnet and surface the ones that need attention.\\n\\n## Steps\\n1. Use the List Devices operation with your API key and tailnet (use \\"-\\" for the default tailnet).\\n2. For each device review lastSeen, authorized, updateAvailable, and the assigned tags.\\n3. Flag nodes not seen in 30+ days, devices still pending authorization, and any with an update available.\\n4. Use Get Device with a deviceId to pull full detail on anything suspicious.\\n\\n## Output\\nReturn a table of devices with hostname, user, OS, last seen, and authorization status, plus a short list of nodes that need review."},{"name":"provision-auth-key","description":"Create a scoped Tailscale auth key with the right tags, reusability, and expiry for onboarding.","content":"# Provision a Tailscale Auth Key\\n\\nGenerate an auth key so a new device or user can join the tailnet with the correct access.\\n\\n## Steps\\n1. Use the Create Auth Key operation with your API key and tailnet.\\n2. Set Tags (for example tag:server,tag:production) so devices joining with the key get the intended ACL access.\\n3. Choose Reusable, Ephemeral, and Preauthorized values to match the use case (ephemeral for short-lived CI nodes).\\n4. Set an Expiry in seconds (for example 7776000 for 90 days) and a clear Description.\\n\\n## Output\\nReturn the generated key value once (it is only shown at creation), the key ID, its tags, and the expiry timestamp."},{"name":"offboard-device","description":"Deauthorize or remove a departing user\'s devices and auth keys, then suspend or delete their tailnet account.","content":"# Offboard a Tailscale Device\\n\\nRemove a device from the tailnet during offboarding so access is cut cleanly.\\n\\n## Steps\\n1. Use List Devices to find the deviceId tied to the departing user.\\n2. To immediately cut access use Authorize Device set to Deauthorize, or Delete Device to remove it entirely.\\n3. Use List Keys and filter for keyType auth and the departing userId before revoking any enrollment keys with Delete Auth Key.\\n4. Use List Users to find the userId, then Suspend User to freeze access reversibly, or Delete User to remove the account entirely.\\n5. Capture the device detail with Get Device before deletion if you need an audit record.\\n\\n## Output\\nConfirm the device was deauthorized or deleted, the auth keys were revoked, and the user account was suspended or deleted for the offboarding audit log."},{"name":"update-tailnet-acl","description":"Push an updated ACL policy file to the tailnet using ETag-guarded writes to avoid clobbering concurrent edits.","content":"# Update the Tailnet ACL as Policy-as-Code\\n\\nApply a reviewed ACL change programmatically instead of editing it by hand in the admin console.\\n\\n## Steps\\n1. Use Get ACL to fetch the current policy file and its etag.\\n2. Compute or generate the new policy JSON from your source of truth (git, agent-authored rules, etc.).\\n3. Run Validate ACL with the proposed policy, then use Set ACL with the new ACL Policy JSON, passing the etag from step 1 in If-Match to guard against concurrent updates (use \\"ts-default\\" instead if you only want to replace an untouched default policy).\\n4. If the write fails with a precondition error, re-fetch the ACL and retry.\\n\\n## Output\\nReturn the updated ACL JSON and its new etag, plus a summary of what changed for the change-management record."},{"name":"lock-down-compromised-device","description":"Immediately expire a suspected-compromised device\'s node key so it must re-authenticate before rejoining the tailnet.","content":"# Lock Down a Compromised Device\\n\\nCut off a device the moment it looks compromised, without waiting for its key to expire naturally.\\n\\n## Steps\\n1. Use Get Device or List Devices to confirm the deviceId and review its tags, addresses, and lastSeen.\\n2. Use Expire Device Key to immediately invalidate the device\'s node key so it can no longer connect until it re-authenticates.\\n3. For a harder block, follow up with Authorize Device set to Deauthorize, or Delete Device to remove it outright.\\n4. Log the deviceId, hostname, and user in the incident record.\\n\\n## Output\\nConfirm the key was expired (and the device deauthorized/deleted if applicable) for the security incident log."}],"templates":[{"title":"Tailscale device inventory","prompt":"Build a scheduled workflow that pulls Tailscale device inventory daily, identifies stale or non-compliant nodes, and writes a security review table.","integrations":[{"id":"tailscale","name":"Tailscale"}]},{"title":"Tailscale ACL drift detector","prompt":"Create a scheduled workflow that diffs Tailscale ACLs against the source of truth, validates the proposed policy with Validate ACL, alerts on drift to Slack, and, on approval, pushes the corrected policy back with Set ACL.","integrations":[{"id":"tailscale","name":"Tailscale"},{"id":"slack","name":"Slack"}]},{"title":"Tailscale new-hire provisioner","prompt":"Build a workflow that on a Workday new-hire event creates a scoped Tailscale auth key for the engineer, sets the right device tags, and writes the access record.","integrations":[{"id":"tailscale","name":"Tailscale"},{"id":"workday","name":"Workday"}]},{"title":"Tailscale offboarder","prompt":"Create a workflow that on a Workday termination deletes the departing engineer\'s Tailscale devices, revokes their auth keys, suspends their tailnet user account, and writes the security audit log.","integrations":[{"id":"tailscale","name":"Tailscale"},{"id":"workday","name":"Workday"}]},{"title":"Tailscale unauthorized-tag watcher","prompt":"Build a scheduled workflow that polls Tailscale device tags and the ACL for unauthorized changes, posts a Slack alert to the security channel, and writes the audit.","integrations":[{"id":"tailscale","name":"Tailscale"},{"id":"slack","name":"Slack"}]},{"title":"Tailscale key-expiry sweeper","prompt":"Create a scheduled workflow that lists Tailscale auth keys expiring in 14 days, notifies owners, and rotates keys past their grace period.","integrations":[{"id":"tailscale","name":"Tailscale"},{"id":"slack","name":"Slack"}]},{"title":"Tailscale access audit","prompt":"Build a scheduled monthly workflow that produces a Tailscale access-review report — devices, tags, ACL effective access — for the security team.","integrations":[{"id":"tailscale","name":"Tailscale"}]}]},{"id":"tavily","type":"tavily","slug":"tavily","name":"Tavily","description":"Search and extract information","category":"Search","docsUrl":"https://docs.sim.ai/integrations/tavily","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Perform AI-powered web searches using Tavily\'s search API. Returns structured results with titles, URLs, snippets, and optional raw content, optimized for relevance and accuracy."},{"name":"Extract Content","description":"Extract raw content from multiple web pages simultaneously using Tavily\'s extraction API. Supports basic and advanced extraction depths with detailed error reporting for failed URLs."},{"name":"Crawl Website","description":"Systematically crawl and extract content from websites using Tavily\'s crawl API. Supports depth control, path filtering, domain restrictions, and natural language instructions for targeted crawling."},{"name":"Map Website","description":"Discover and visualize website structure using Tavily\'s map API. Maps out all accessible URLs from a base URL with depth control, path filtering, and domain restrictions."}],"triggers":[],"skills":[{"name":"answer-with-web-citations","description":"Search the web with Tavily and return a grounded answer with linked source citations.","content":"# Answer a Question with Web Citations\\n\\nGround an answer in fresh web results so it is current and verifiable.\\n\\n## Steps\\n1. Use the Search operation with the question as the Search Query.\\n2. Set Include Answer to Advanced, Search Depth to advanced, and Max Results to about 5 for good coverage.\\n3. Pick the Topic (news or finance) when the question is time-sensitive, and set Time Range (day, week, month) to keep results recent.\\n4. Use Include Domains or Exclude Domains to keep results on trusted sources.\\n\\n## Output\\nReturn the synthesized answer followed by a numbered list of the source titles and URLs used to support it."},{"name":"extract-article-content","description":"Pull clean main content from one or more URLs with Tavily Extract for summarization.","content":"# Extract Clean Article Content\\n\\nTurn a messy web page into clean text or markdown that an agent can summarize.\\n\\n## Steps\\n1. Use the Extract Content operation and pass the page URL into the URL field.\\n2. Set Extract Depth to advanced for content-heavy pages and choose Markdown or Text as the Format.\\n3. Enable Include Images only if downstream steps need the media.\\n4. Feed the extracted content to an agent to summarize the key points.\\n\\n## Output\\nReturn the page title, source URL, and the cleaned content, plus any failed URLs so they can be retried."},{"name":"crawl-site-section","description":"Crawl a website section with Tavily and gather page content matching path rules.","content":"# Crawl a Website Section\\n\\nWalk a site beginning at a root URL and collect content from matching pages.\\n\\n## Steps\\n1. Use the Crawl Website operation with the root Website URL.\\n2. Give natural-language Instructions describing what to collect (for example \\"gather all product documentation pages\\").\\n3. Bound the crawl with Max Depth, Max Breadth, and Limit so it stays focused.\\n4. Use Select Paths and Exclude Paths regex patterns (for example /docs/.* to include, /admin/.* to exclude) to target the right section.\\n\\n## Output\\nReturn the crawled pages with their URLs and extracted content, ready to index into a knowledge base or summarize."},{"name":"map-site-structure","description":"Map a website URL structure with Tavily without extracting full page content.","content":"# Map a Website Structure\\n\\nDiscover the URL layout of a site quickly without pulling full page bodies.\\n\\n## Steps\\n1. Use the Map Website operation with the root Website URL.\\n2. Set Max Depth and Max Breadth to control how far the mapper explores.\\n3. Apply Select Paths or Exclude Paths regex patterns to focus on the sections you care about.\\n4. Toggle Allow External Links only if you want links that leave the root domain.\\n\\n## Output\\nReturn the discovered list of URLs so you can pick targets for a later crawl or extract pass."}],"templates":[{"title":"Perplexity multi-source research","prompt":"Create an agent that triangulates a topic across Perplexity, Exa, and Tavily, deduplicates findings, and produces a consensus brief with confidence scores per claim.","integrations":[{"id":"tavily","name":"Tavily"},{"id":"perplexity","name":"Perplexity"},{"id":"exa","name":"Exa"}]},{"title":"Tavily research-augmented agent","prompt":"Create an agent that grounds every answer in fresh Tavily web search results, returns answers with inline citations, and saves long-form research to a knowledge base for re-use.","integrations":[{"id":"tavily","name":"Tavily"}]},{"title":"Tavily competitive monitor","prompt":"Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, logs the top hits to a tables-based competitive log, and posts highlights to Slack.","integrations":[{"id":"tavily","name":"Tavily"},{"id":"slack","name":"Slack"}]},{"title":"Tavily research-augmented chat","prompt":"Build a chat agent that grounds each answer in fresh Tavily web search results, returns inline citations, and saves long-form answers to a knowledge base for re-use.","integrations":[{"id":"tavily","name":"Tavily"}]},{"title":"Tavily news watcher","prompt":"Create a scheduled daily workflow that runs Tavily searches for topics I follow, summarizes the top hits with citations, and posts a digest to Slack.","integrations":[{"id":"tavily","name":"Tavily"},{"id":"slack","name":"Slack"}]},{"title":"Tavily account refresher","prompt":"Build a workflow that walks accounts in the CRM, runs Tavily research on each for new funding, hiring, or product launches, and writes the digest back to the account record.","integrations":[{"id":"tavily","name":"Tavily"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Tavily competitor mention log","prompt":"Create a scheduled workflow that runs Tavily searches for competitor mentions weekly, scores each by relevance, and writes a competitive log to a table.","integrations":[{"id":"tavily","name":"Tavily"}]},{"title":"Tavily URL content extractor","prompt":"Build a workflow that reads a table of article URLs, uses Tavily extract to pull the clean main content from each page, summarizes the key points with an agent, and writes the summary back to the row.","integrations":[{"id":"tavily","name":"Tavily"}]}]},{"id":"telegram","type":"telegram","slug":"telegram","name":"Telegram","description":"Interact with Telegram","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/telegram","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send a text message through the Telegram Bot API. Markdown is converted to Telegram HTML before sending; the response includes the sent message and recipient chat."},{"name":"Send Photo","description":"Send photos to Telegram channels or users through the Telegram Bot API."},{"name":"Send Video","description":"Send videos to Telegram channels or users through the Telegram Bot API."},{"name":"Send Audio","description":"Send audio files to Telegram channels or users through the Telegram Bot API."},{"name":"Send Animation","description":"Send animations (GIFs) to Telegram channels or users through the Telegram Bot API."},{"name":"Send Document","description":"Send documents (PDF, ZIP, DOC, etc.) to Telegram channels or users through the Telegram Bot API."},{"name":"Send Location","description":"Send a point on the map to a Telegram chat through the Telegram Bot API."},{"name":"Send Contact","description":"Send a phone contact to a Telegram chat through the Telegram Bot API."},{"name":"Send Poll","description":"Send a native poll to a Telegram chat through the Telegram Bot API."},{"name":"Send Chat Action","description":"Show a status action such as a typing indicator in a Telegram chat through the Telegram Bot API."},{"name":"Edit Message Text","description":"Edit the text of an existing message in a Telegram chat or channel through the Telegram Bot API."},{"name":"Forward Message","description":"Forward a message from one Telegram chat to another through the Telegram Bot API."},{"name":"Copy Message","description":"Copy a message to another Telegram chat without a forward header through the Telegram Bot API."},{"name":"Delete Message","description":"Delete messages in Telegram channels or chats through the Telegram Bot API. Requires the message ID of the message to delete."},{"name":"Pin Message","description":"Pin a message in a Telegram chat through the Telegram Bot API."},{"name":"Unpin Message","description":"Unpin a pinned message in a Telegram chat through the Telegram Bot API. Unpins the most recent pinned message when no message ID is given."},{"name":"Set Message Reaction","description":"Set or remove an emoji reaction on a message in a Telegram chat through the Telegram Bot API."},{"name":"Get Chat","description":"Get up-to-date information about a Telegram chat through the Telegram Bot API."},{"name":"Get Chat Member","description":"Get information about a member of a Telegram chat through the Telegram Bot API."}],"triggers":[{"id":"telegram_webhook","name":"Telegram Webhook","description":"Trigger workflow from Telegram bot messages and events"}],"skills":[{"name":"send-alert-message","description":"Post a formatted alert or notification to a Telegram chat or channel.","content":"# Send a Telegram Alert\\n\\nDeliver a timely notification to a Telegram chat, group, or channel.\\n\\n## Steps\\n1. Use the Send Message operation with your Bot Token and the target Chat ID.\\n2. Compose the Message with the essentials up front: what happened, severity, and a link for follow-up.\\n3. To find a Chat ID, add the bot to the chat, send a message, then read the chat field from the getUpdates response.\\n4. For recurring alerts, build the message from upstream block outputs so each notification carries live context.\\n\\n## Output\\nReturn the sent message ID and chat ID so the run can be traced or the message later deleted."},{"name":"send-media-message","description":"Send a photo, video, document, or audio file to a Telegram chat with a caption.","content":"# Send Media to Telegram\\n\\nDeliver a file such as a chart, report, or image to a Telegram chat.\\n\\n## Steps\\n1. Pick the matching operation: Send Photo, Send Video, Send Audio, Send Animation, or Send Document.\\n2. Provide the Bot Token and Chat ID.\\n3. Upload the file directly, or reference a file produced by a previous block (for example a generated PDF or chart image).\\n4. Add an optional Caption describing the attachment.\\n\\n## Output\\nConfirm delivery and return the message ID so the media post can be referenced later."},{"name":"route-incoming-message","description":"Trigger a workflow when a Telegram message arrives and act on its content.","content":"# Route an Incoming Telegram Message\\n\\nUse Telegram as a trigger so the workflow runs whenever a user messages the bot.\\n\\n## Steps\\n1. Enable the Telegram webhook trigger so incoming messages start the workflow.\\n2. Read the trigger outputs: text, from_username, chat_id, and chat_type.\\n3. Branch on the message content (for example detect a command or a support question) to decide the next action.\\n4. Reply with the Send Message operation using the chat_id from the trigger.\\n\\n## Output\\nReturn the parsed incoming message fields and confirm the reply that was sent back to the user."},{"name":"run-a-poll","description":"Post a poll to a Telegram chat to collect a quick vote from members.","content":"# Run a Telegram Poll\\n\\nGather a fast decision or sentiment check from a chat or channel.\\n\\n## Steps\\n1. Use the Send Poll operation with your Bot Token and the target Chat ID.\\n2. Set the Poll Question and add one answer option per line (2-10 options).\\n3. In advanced settings, choose whether the poll is anonymous and whether multiple answers are allowed.\\n4. Send the poll, then read replies from the chat to act on the outcome.\\n\\n## Output\\nReturn the sent message ID so the poll post can be referenced or pinned later."},{"name":"pin-and-react-to-messages","description":"Pin an important message and add an emoji reaction in a Telegram chat.","content":"# Pin and React to a Telegram Message\\n\\nHighlight a key message and acknowledge it with a reaction.\\n\\n## Steps\\n1. Capture the message ID to act on, for example from the Send Message output or the incoming message trigger.\\n2. Use the Pin Message operation with the Bot Token, Chat ID, and Message ID to pin it for the whole chat.\\n3. Use the Set Message Reaction operation with an emoji to acknowledge a message, or send an empty reaction to remove one.\\n4. Use the Unpin Message operation later to clear the pinned message when it is no longer relevant.\\n\\n## Output\\nConfirm the pin and reaction succeeded so the chat keeps the important context surfaced."}],"templates":[{"title":"Telegram alert relay","prompt":"Build a workflow that listens for critical alerts from Sentry or PagerDuty and forwards a concise summary with severity, link, and the on-call person to a Telegram group.","integrations":[{"id":"telegram","name":"Telegram"},{"id":"sentry","name":"Sentry"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Telegram price-action notifier","prompt":"Create a scheduled workflow that watches tracked assets in a table for price thresholds and pushes a Telegram message with the trigger, price, and a link to the chart.","integrations":[{"id":"telegram","name":"Telegram"}]},{"title":"Telegram support bot","prompt":"Build a Telegram bot that answers product questions using a knowledge base with citations, escalates to a human via Intercom when it cannot answer, and logs every conversation to a table.","integrations":[{"id":"telegram","name":"Telegram"},{"id":"intercom","name":"Intercom"}]},{"title":"Telegram daily standup poller","prompt":"Create a scheduled workflow that posts a daily standup prompt to a Telegram group, collects the replies, and writes a structured standup digest to a Google Doc.","integrations":[{"id":"telegram","name":"Telegram"},{"id":"google_docs","name":"Google Docs"}]},{"title":"Telegram broadcast scheduler","prompt":"Build a workflow that reads a tables-based content calendar and posts scheduled Telegram channel messages with formatted text, images, and links at the right time.","integrations":[{"id":"telegram","name":"Telegram"}]},{"title":"Telegram form-reply collector","prompt":"Create a workflow that asks structured questions in Telegram one at a time, parses replies into fields, and saves the completed response as a row in a Sim table.","integrations":[{"id":"telegram","name":"Telegram"}]},{"title":"Telegram + WhatsApp dual-channel notifier","prompt":"Build a workflow that sends critical operational alerts via both Telegram and WhatsApp based on user preference per recipient, and writes delivery status to a table.","integrations":[{"id":"telegram","name":"Telegram"},{"id":"whatsapp","name":"WhatsApp"}]},{"title":"Zoom + Telegram recap pusher","prompt":"Create a workflow that runs after a Zoom meeting, summarizes the transcript, and pushes the recap to a chosen Telegram channel for asynchronous review.","integrations":[{"id":"telegram","name":"Telegram"},{"id":"zoom","name":"Zoom"}]}]},{"id":"temporal","type":"temporal","slug":"temporal","name":"Temporal","description":"Start, signal, query, and manage Temporal workflow executions","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/temporal","authType":"api-key","connections":[],"operations":[{"name":"Start Workflow","description":"Start a new workflow execution on a Temporal cluster."},{"name":"Signal Workflow","description":"Send a signal to a running Temporal workflow execution."},{"name":"Signal With Start","description":"Atomically signal a Temporal workflow execution, starting it first if it is not already running."},{"name":"Query Workflow","description":"Run a synchronous query against the state of a Temporal workflow execution and return the result."},{"name":"Update Workflow","description":"Invoke an update handler on a running Temporal workflow and wait for its result. Unlike a signal, an update is validated by the workflow and returns a response."},{"name":"Describe Workflow","description":"Get the current state of a Temporal workflow execution, including status, timing, memo, search attributes, and pending activities."},{"name":"List Workflows","description":"List workflow executions in a Temporal namespace, optionally filtered with a visibility query."},{"name":"Count Workflows","description":"Count workflow executions in a Temporal namespace matching a visibility query, with optional GROUP BY aggregation."},{"name":"Get Workflow History","description":"Fetch the event history of a Temporal workflow execution, optionally filtered to just the close event."},{"name":"Cancel Workflow","description":"Request cooperative cancellation of a running Temporal workflow execution. The workflow decides how to respond to the request."},{"name":"Terminate Workflow","description":"Forcefully terminate a Temporal workflow execution immediately, without giving the workflow a chance to react."},{"name":"Reset Workflow","description":"Reset a Temporal workflow execution to a past workflow task, terminating the current run and replaying from the reset point in a new run."},{"name":"Describe Task Queue","description":"List the workers currently polling a Temporal task queue, to check whether a workflow or activity has live workers."},{"name":"Create Schedule","description":"Create a Temporal schedule that starts a workflow on a cron or interval cadence."},{"name":"List Schedules","description":"List schedules in a Temporal namespace."},{"name":"Describe Schedule","description":"Get the configuration and current state of a Temporal schedule, including its spec, recent actions, and upcoming run times."},{"name":"Pause Schedule","description":"Pause a Temporal schedule so it stops taking actions until unpaused."},{"name":"Unpause Schedule","description":"Unpause a Temporal schedule so it resumes taking actions."},{"name":"Trigger Schedule","description":"Trigger an immediate action of a Temporal schedule, outside its normal spec."},{"name":"Delete Schedule","description":"Delete a Temporal schedule. Workflows already started by the schedule keep running."}],"triggers":[],"skills":[{"name":"start-workflow-execution","description":"Start a Temporal workflow execution with the right input and report the workflow and run IDs.","content":"# Start a Temporal Workflow\\n\\nKick off a workflow execution on the cluster.\\n\\n## Steps\\n1. Confirm the workflow type, task queue, and a unique workflow ID.\\n2. Assemble the JSON input arguments for the workflow.\\n3. Start the workflow and capture the run ID.\\n4. Describe the execution to confirm it is running.\\n\\n## Output\\nA confirmation with the workflow ID, run ID, and initial status."},{"name":"investigate-failed-workflow","description":"Describe a failed Temporal workflow and pull its close event to explain why it failed.","content":"# Investigate a Failed Temporal Workflow\\n\\nDiagnose a workflow failure.\\n\\n## Steps\\n1. Describe the workflow to confirm its status and timing.\\n2. Fetch the history filtered to the close event to get the failure details.\\n3. If needed, fetch earlier history pages to trace the failing activity.\\n4. Summarize the root cause.\\n\\n## Output\\nA failure summary with the failing event, error message, and a recommendation."},{"name":"signal-running-workflow","description":"Send a signal to a running Temporal workflow and confirm it was delivered.","content":"# Signal a Temporal Workflow\\n\\nDeliver data or a decision to a running execution.\\n\\n## Steps\\n1. Find the target execution by workflow ID (or list executions to locate it).\\n2. Send the signal with the JSON payload.\\n3. Query or describe the workflow to confirm the signal took effect.\\n\\n## Output\\nA confirmation with the workflow ID, signal name, and resulting state."},{"name":"audit-running-workflows","description":"List running Temporal executions and surface long-running or stuck workflows.","content":"# Audit Running Temporal Workflows\\n\\nFind executions that need attention.\\n\\n## Steps\\n1. List executions filtered to ExecutionStatus = \\"Running\\".\\n2. Sort by start time and flag the longest-running executions.\\n3. Describe flagged executions to inspect pending activities and retry counts.\\n4. Recommend cancellation or escalation for stuck workflows.\\n\\n## Output\\nA per-workflow report with age, pending activities, and a recommended action."}],"templates":[{"title":"Temporal order approval gate","prompt":"Create a workflow that receives an approval decision from a form, signals the matching Temporal order workflow with the decision, and posts a confirmation to Slack with the workflow ID and current status.","integrations":[{"id":"temporal","name":"Temporal"},{"id":"slack","name":"Slack"}]},{"title":"Temporal failed workflow digest","prompt":"Build a scheduled daily workflow that lists Temporal executions that failed or timed out in the last 24 hours, pulls the close event from each history to extract the failure, and posts a digest to Slack grouped by workflow type.","integrations":[{"id":"temporal","name":"Temporal"},{"id":"slack","name":"Slack"}]},{"title":"Temporal stuck workflow watcher","prompt":"Create a scheduled workflow that lists running Temporal executions, describes each one to inspect pending activities, flags workflows whose activities are retrying with high attempt counts, and opens a Linear ticket with the failure details.","integrations":[{"id":"temporal","name":"Temporal"},{"id":"linear","name":"Linear"}]},{"title":"Temporal kickoff from intake form","prompt":"Build a workflow that starts a Temporal workflow execution with input assembled from an intake form submission, polls describe until the execution closes, and writes the final status and timing to a tracking table.","integrations":[{"id":"temporal","name":"Temporal"}]},{"title":"Temporal status lookup agent","prompt":"Create an agent that answers \\"where is my order\\" questions by querying the matching Temporal workflow for its current state and summarizing the progress, falling back to the latest history events when no query handler responds.","integrations":[{"id":"temporal","name":"Temporal"}]},{"title":"Temporal runaway workflow janitor","prompt":"Build a scheduled weekly workflow that lists Temporal executions running longer than seven days, describes each to confirm it is stalled, requests cancellation with a recorded reason, and terminates any execution that ignores the cancellation after a grace period.","integrations":[{"id":"temporal","name":"Temporal"}]},{"title":"Temporal incident escalation bridge","prompt":"Create a workflow that signals a Temporal incident-response workflow with escalation details when a monitoring alert fires, using signal-with-start so a new incident workflow is created if one is not already running.","integrations":[{"id":"temporal","name":"Temporal"},{"id":"pagerduty","name":"PagerDuty"}]}]},{"id":"thrive","type":"thrive","slug":"thrive","name":"Thrive","description":"Manage users, audiences, learning and CPD on Thrive","category":"HR","docsUrl":"https://docs.sim.ai/integrations/thrive","authType":"api-key","connections":[],"operations":[{"name":"Create User","description":"Create a new user in Thrive."},{"name":"Update User","description":"Update an existing user in Thrive by ref. Only the fields provided are changed."},{"name":"Delete User","description":"Permanently delete (obfuscate) a user in Thrive by ref while retaining training history."},{"name":"Suspend User","description":"Suspend a user in Thrive by ref, marking the account inactive."},{"name":"Search Users","description":"Search users in Thrive and return basic user information with pagination."},{"name":"Get User by ID","description":"Get a single user in Thrive by their ID and return basic user information."},{"name":"Get User by Ref","description":"Get a single user in Thrive by their ref and return basic user information."},{"name":"List Audiences","description":"List audiences and structures in Thrive with pagination."},{"name":"Create Audience","description":"Create a new audience or structure in Thrive."},{"name":"Get Audience","description":"Get a single audience or structure in Thrive by id or reference."},{"name":"Update Audience","description":"Update an audience in Thrive, optionally moving it to a new parent."},{"name":"Delete Audience","description":"Delete an audience in Thrive (only if it has no child audiences)."},{"name":"List Audience Members","description":"List the members of a Thrive audience with pagination."},{"name":"Add Audience Members","description":"Add members to a Thrive audience by email, ref, or id."},{"name":"Replace Audience Members","description":"Replace a Thrive audience\'s entire members list with the given users (does not support an empty array)."},{"name":"Remove Audience Member","description":"Remove a single member from a Thrive audience."},{"name":"List Audience Managers","description":"List the managers of a Thrive audience."},{"name":"Add Audience Managers","description":"Add managers to a Thrive audience with their permissions."},{"name":"Replace Audience Managers","description":"Replace a Thrive audience\'s entire manager list with the given managers (does not support an empty array)."},{"name":"Remove Audience Manager","description":"Remove a single manager from a Thrive audience."},{"name":"List Assignments","description":"List compliance assignments in Thrive, optionally filtered by audience."},{"name":"Create Assignment","description":"Create a compliance assignment in Thrive for an audience and content item."},{"name":"Get Assignment","description":"Get a single compliance assignment in Thrive by its ID."},{"name":"Update Assignment","description":"Update a compliance assignment in Thrive."},{"name":"Delete Assignment","description":"Delete a compliance assignment in Thrive."},{"name":"List Enrolments","description":"List enrolments for a compliance assignment in Thrive."},{"name":"Get Enrolment","description":"Get a single enrolment for a compliance assignment in Thrive."},{"name":"List Completions","description":"List learning completion records in Thrive, optionally filtered by user or content."},{"name":"Get Completion","description":"Get a single learning completion record in Thrive by its ID."},{"name":"Create Completion","description":"Record a learning completion in Thrive for a user and content item."},{"name":"Query Content","description":"Query content records in Thrive with pagination and filtering options."},{"name":"Get Content","description":"Get a single content record in Thrive by its ID."},{"name":"Query Activities","description":"Query activity records in Thrive with pagination and filtering options."},{"name":"Get Activity","description":"Get a single activity record in Thrive by its ID."},{"name":"Query CPD Categories","description":"Query CPD categories in Thrive and return results with pagination."},{"name":"Get CPD Category","description":"Get a single CPD category in Thrive by its ID."},{"name":"Query CPD Entries","description":"Query CPD log entries in Thrive and return results with pagination."},{"name":"Get CPD Entry","description":"Get a single CPD log entry in Thrive by its ID."},{"name":"Query CPD Requirements","description":"Query CPD requirement summaries in Thrive and return results with pagination."},{"name":"Get CPD Requirement","description":"Get a single CPD requirement summary in Thrive by its ID."},{"name":"Query CPD User Summaries","description":"Query CPD user log summaries in Thrive and return results with pagination."},{"name":"List Tags","description":"List tags in Thrive and return tag information with pagination."},{"name":"Get Tag","description":"Get a single tag in Thrive by its ID."},{"name":"Add User Tags","description":"Add one or more tags to a learner in Thrive."},{"name":"Remove User Tags","description":"Remove one or more tags from a learner in Thrive."},{"name":"Update User Skills","description":"Update skills and levels for a learner in Thrive."},{"name":"Get Skill Levels","description":"Get the available skill levels configured in Thrive."}],"triggers":[],"skills":[],"templates":[{"title":"Onboard new hires into Thrive","prompt":"Build a workflow that, when a new employee row is added to a Google Sheet, creates the user in Thrive with their ref, name, email, job title, and manager, then adds them to the relevant onboarding audience.","integrations":[{"id":"thrive","name":"Thrive"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Thrive compliance digest","prompt":"Create a scheduled weekly workflow that lists Thrive enrolments for a compliance assignment, filters those still open or overdue, and posts a Slack summary to the people-ops channel.","integrations":[{"id":"thrive","name":"Thrive"},{"id":"slack","name":"Slack"}]},{"title":"Suspend leavers in Thrive","prompt":"Build a workflow that reads terminated employees from an HRIS export and suspends each matching user in Thrive with their end date, then logs the result to a table.","integrations":[{"id":"thrive","name":"Thrive"}]},{"title":"Import completions into Thrive","prompt":"Create a workflow that reads a CSV of prior learning records and creates a completion in Thrive for each user and content item with the completion date.","integrations":[{"id":"thrive","name":"Thrive"}]},{"title":"Assign Thrive training to an audience","prompt":"Build a workflow that creates a Thrive content assignment for a chosen audience and primary content, sets a 30-day completion period, and reports how many learners were enrolled.","integrations":[{"id":"thrive","name":"Thrive"}]},{"title":"Thrive CPD shortfall report","prompt":"Create a scheduled monthly workflow that queries Thrive CPD user summaries for a date range, compares logged minutes against each audience CPD requirement, and emails managers a list of learners below target.","integrations":[{"id":"thrive","name":"Thrive"},{"id":"gmail","name":"Gmail"}]},{"title":"Tag Thrive learners by skill","prompt":"Build a workflow that searches Thrive users by status, then adds skill tags and updates skill levels for each learner based on a mapping in a spreadsheet.","integrations":[{"id":"thrive","name":"Thrive"},{"id":"google_sheets","name":"Google Sheets"}]},{"title":"Thrive trending content to Slack","prompt":"Create a scheduled workflow that queries recently updated Thrive content and activity records, summarises the most engaged-with learning, and posts a weekly highlight to Slack.","integrations":[{"id":"thrive","name":"Thrive"},{"id":"slack","name":"Slack"}]}]},{"id":"tiktok","type":"tiktok","slug":"tiktok","name":"TikTok","description":"Access TikTok profiles and videos, and upload inbox drafts","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/tiktok","authType":"oauth","connections":[{"id":"tiktok","kind":"oauth","label":"Connect with OAuth","providerId":"tiktok","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/tiktok","requiredScopes":[{"id":"user.info.basic","label":"Read a user\'s profile info (open id, avatar, display name)"},{"id":"user.info.profile","label":"Read a user\'s profile info (bio, verification status, username)"},{"id":"user.info.stats","label":"Read a user\'s stats (follower, following, likes, and video counts)"},{"id":"video.upload","label":"Share content to a creator\'s account as a draft for further edit and post"},{"id":"video.list","label":"Read a user\'s public TikTok videos"}],"fields":[]}],"operations":[{"name":"Get User Info","description":"Get the authenticated TikTok user profile information including display name, avatar, bio, follower count, and video statistics."},{"name":"List Videos","description":"Get a list of the authenticated user\'s TikTok videos with cover images, titles, and metadata. Supports pagination."},{"name":"Query Videos","description":"Query specific TikTok videos by their IDs to get fresh metadata including cover images, embed links, and video details."},{"name":"Upload Video Draft","description":"Send an uploaded video to the authenticated user\'s TikTok inbox for manual editing and posting. The user must open TikTok and tap the inbox notification to complete the post. Rate limit: 6 requests per minute per user."},{"name":"Get Post Status","description":"Check the status of a video draft upload. Use the publishId returned from Upload Video Draft to track progress."}],"triggers":[{"id":"tiktok_post_publish_complete","name":"TikTok Post Publish Complete","description":"Trigger when a TikTok Content Posting publish completes"},{"id":"tiktok_post_publish_failed","name":"TikTok Post Publish Failed","description":"Trigger when a TikTok Content Posting publish fails"},{"id":"tiktok_post_inbox_delivered","name":"TikTok Post Inbox Delivered","description":"Trigger when a draft notification is delivered to the creator inbox"},{"id":"tiktok_post_publicly_available","name":"TikTok Post Publicly Available","description":"Trigger when a published post becomes publicly viewable on TikTok"},{"id":"tiktok_post_no_longer_public","name":"TikTok Post No Longer Public","description":"Trigger when a post is no longer publicly viewable on TikTok"},{"id":"tiktok_authorization_removed","name":"TikTok Authorization Removed","description":"Trigger when a user deauthorizes your TikTok app"}],"skills":[{"name":"send-video-draft-to-inbox","description":"Send a video to the user\'s TikTok inbox for manual review before posting.","content":"# Send a TikTok Video Draft\\n\\nDeliver a video to the connected account\'s TikTok inbox so a human can review, edit, and publish it from the app.\\n\\n## Steps\\n1. Use the Upload Video Draft operation with a connected TikTok Account.\\n2. Provide a Video File: upload one, or reference a file from a previous block.\\n3. Submit the draft — no caption or privacy level is set here, since the user finishes the post manually in the TikTok app.\\n4. Use Get Post Status with the returned Publish ID to see when the user has acted on the inbox notification (SEND_TO_USER_INBOX until they do).\\n\\n## Output\\nReturn the Publish ID so the draft\'s status can be tracked or referenced later."},{"name":"check-tiktok-post-status","description":"Poll the status of a TikTok inbox draft until it completes or fails.","content":"# Check TikTok Draft Status\\n\\nTrack the outcome of a video submitted to the TikTok inbox for human review.\\n\\n## Steps\\n1. Capture the Publish ID returned by Upload Video Draft.\\n2. Call Get Post Status with that Publish ID.\\n3. Branch on the returned status: PROCESSING_UPLOAD/PROCESSING_DOWNLOAD means still in progress, SEND_TO_USER_INBOX means the draft is waiting on the user, PUBLISH_COMPLETE means the user published it, and FAILED means it did not complete (read failReason for why).\\n4. Repeat on a delay for in-progress statuses until a terminal state is reached.\\n\\n## Output\\nReturn the final status, failReason (if any), and the publiclyAvailablePostId once published."},{"name":"summarize-tiktok-video-performance","description":"List a creator\'s recent TikTok videos and summarize engagement for reporting.","content":"# Summarize TikTok Video Performance\\n\\nPull a creator\'s recent videos and turn the metadata into a readable report.\\n\\n## Steps\\n1. Use List Videos with a connected TikTok Account to fetch recent videos (paginate with the Cursor if more than one page is needed).\\n2. For specific videos already known by ID, use Query Videos instead to refresh their metadata.\\n3. Ask an agent to summarize the results — highlight top performers by duration/engagement signals available in the metadata and note any patterns.\\n4. Optionally use Get User Info alongside this to report overall follower and like counts.\\n\\n## Output\\nA structured summary or table of videos with their titles, share URLs, and key metadata, suitable for posting to a report or chat."}],"templates":[{"title":"TikTok content calendar drafts","prompt":"Create a scheduled workflow that reads the next due row from a Tables-based content calendar, uploads the matching video to the creator’s TikTok inbox as a draft, and notifies them to review and publish it in TikTok.","integrations":[{"id":"tiktok","name":"TikTok"}]},{"title":"TikTok performance reporter","prompt":"Build a workflow that lists recent TikTok videos, summarizes view and engagement trends with an agent, and posts the digest to Slack every week.","integrations":[{"id":"tiktok","name":"TikTok"},{"id":"slack","name":"Slack"}]},{"title":"TikTok draft review pipeline","prompt":"Create a workflow that uploads a new video to a TikTok inbox draft for review, then notifies the marketing team on Slack to approve and post it from the TikTok app.","integrations":[{"id":"tiktok","name":"TikTok"},{"id":"slack","name":"Slack"}]}]},{"id":"tinybird","type":"tinybird","slug":"tinybird","name":"Tinybird","description":"Send events, query data, and manage Data Sources with Tinybird","category":"Analytics","docsUrl":"https://docs.sim.ai/integrations/tinybird","authType":"api-key","connections":[],"operations":[{"name":"Send Events","description":"Send events to a Tinybird Data Source using the Events API. Supports JSON and NDJSON formats with optional gzip compression."},{"name":"Query","description":"Execute SQL queries against Tinybird Pipes and Data Sources using the Query API."},{"name":"Query Pipe Endpoint","description":"Call a published Tinybird Pipe API Endpoint by name, passing dynamic parameters and receiving structured JSON results."},{"name":"Append Data Source (from URL)","description":"Append data to a Tinybird Data Source from a remote file URL (CSV, NDJSON, Parquet)."},{"name":"Truncate Data Source","description":"Delete all rows from a Tinybird Data Source."},{"name":"Delete Data Source Rows","description":"Delete rows from a Tinybird Data Source matching a SQL condition."},{"name":"Get Job Status","description":"Check the status of an asynchronous Tinybird job (import, delete, etc.) by ID."}],"triggers":[],"skills":[{"name":"ingest-events","description":"Stream JSON or NDJSON events into a Tinybird Data Source via the Events API.","content":"# Ingest Events into Tinybird\\n\\nStream realtime events into a Data Source so they are queryable within seconds.\\n\\n## Steps\\n1. Use the Send Events operation with your Base URL and API Token.\\n2. Set the Data Source name that matches your target table.\\n3. Provide the events in the Data field, using NDJSON (one JSON object per line) for batches or JSON for a single object.\\n4. Enable Wait for Acknowledgment when you need confirmation the rows landed before continuing.\\n\\n## Output\\nReturn the count of successful_rows and quarantined_rows so you can confirm ingestion and catch rows that failed validation."},{"name":"query-pipe-endpoint","description":"Call a published Tinybird Pipe API Endpoint with dynamic parameters and return the result.","content":"# Query a Tinybird Pipe Endpoint\\n\\nCall a published Pipe by name to get analytics results shaped by dynamic parameters.\\n\\n## Steps\\n1. Use the Query Pipe Endpoint operation with the Base URL, API Token, and the Pipe Name (for example top_pages).\\n2. Pass dynamic Parameters as a JSON object whose keys match the parameters the Pipe expects (for example start_date and limit).\\n3. Optionally add SQL on top of the Pipe result using the advanced SQL field, selecting from _ to post-process.\\n\\n## Output\\nReturn the result rows as JSON along with the column metadata and row count, ready to write to a table or summarize."},{"name":"run-sql-query","description":"Run an ad-hoc SQL query against Tinybird with the Query API and return results.","content":"# Run a Tinybird SQL Query\\n\\nExecute SQL directly against your Tinybird data for ad-hoc analysis.\\n\\n## Steps\\n1. Use the Query operation with the Base URL and API Token.\\n2. Write the SQL Query and append FORMAT JSON to get structured rows back (other formats return raw text).\\n3. Reference Data Sources or Pipes by name in the FROM clause.\\n\\n## Output\\nReturn the result data as an array of objects plus the column metadata, row count, and execution statistics."},{"name":"manage-datasource-rows","description":"Append from a URL, truncate, or delete rows by condition in a Tinybird Data Source.","content":"# Manage Tinybird Data Source Rows\\n\\nMaintain a Data Source by loading, clearing, or pruning its rows.\\n\\n## Steps\\n1. To load data, use Append Data Source (from URL) with the Data Source name, a Source File URL, and the source format (CSV, NDJSON, or Parquet).\\n2. To clear everything, use Truncate Data Source with the Data Source name.\\n3. To remove specific rows, use Delete Data Source Rows with a SQL Delete Condition such as event_date < \'2024-01-01\'.\\n4. Enable Dry Run on a delete first to preview how many rows would be removed.\\n\\n## Output\\nReturn the job ID and status for append and delete operations so you can poll with Get Job Status, or confirm the truncate succeeded."},{"name":"poll-job-status","description":"Check the status of an asynchronous Tinybird job, such as an append import or a delete-by-condition job.","content":"# Poll a Tinybird Job\\n\\nAppend Data Source and Delete Data Source Rows start asynchronous jobs that need to be polled for completion.\\n\\n## Steps\\n1. Take the Job ID returned by Append Data Source or Delete Data Source Rows.\\n2. Use the Get Job Status operation with the Base URL, API Token, and Job ID.\\n3. Loop or wait until status is \\"done\\" (or \\"error\\"), checking again on a delay if still \\"waiting\\" or \\"working\\".\\n\\n## Output\\nReturn the job kind, status, and full job details so you can confirm completion or surface the error message."}],"templates":[{"title":"Athena + Tinybird real-time bridge","prompt":"Build a workflow that combines historical Athena queries with realtime Tinybird endpoints into a unified reporting view, writes results to a dashboard table.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"athena","name":"Athena"}]},{"title":"Hex + Tinybird realtime data app","prompt":"Create a workflow that powers a Hex data app with Tinybird realtime data, refreshes the dashboard on schedule, and writes usage analytics to a table.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"hex","name":"Hex"}]},{"title":"MongoDB + Tinybird feeder","prompt":"Build a scheduled workflow that batches new MongoDB records into a Tinybird pipe on a short interval, exposes the data to downstream apps, and writes the load metrics to a table.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"mongodb","name":"MongoDB"}]},{"title":"Tinybird pipe-as-API endpoint","prompt":"Create a workflow that calls a Tinybird published pipe with parameters on a schedule, normalizes the results, and writes them into a Sim table for downstream consumers.","integrations":[{"id":"tinybird","name":"Tinybird"}]},{"title":"Tinybird realtime metric watcher","prompt":"Build a workflow that polls a Tinybird pipe every minute for a realtime KPI, compares against a rolling baseline, and pages PagerDuty when the metric crosses a SLO threshold.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Tinybird user-segment exporter","prompt":"Create a workflow that calls a Tinybird published endpoint with segment parameters, writes the user list to a table, and feeds it to a Loops campaign for targeted activation messaging.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"loops","name":"Loops"}]},{"title":"Tinybird usage-meter dashboard","prompt":"Build a workflow that exposes a Tinybird endpoint reporting per-customer usage for billing, refreshes a Sim table hourly, and surfaces top consumers to Slack.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"slack","name":"Slack"}]},{"title":"Tinybird funnel analytics digest","prompt":"Create a scheduled workflow that queries a Tinybird pipe for daily signup, activation, and conversion counts, calculates step-over-step drop-off, and posts a funnel digest with week-over-week deltas to the growth Slack channel.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"slack","name":"Slack"}]},{"title":"Tinybird anomaly investigator","prompt":"Build a workflow triggered by an alert that calls a Tinybird pipe to pull the surrounding event data for the affected metric, has an agent summarize the likely cause, and opens a Linear issue with the supporting query results attached.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"linear","name":"Linear"}]},{"title":"Tinybird executive KPI report","prompt":"Create a scheduled weekly workflow that queries several Tinybird pipes for the company’s headline KPIs, assembles them into a Markdown report file with trend commentary, and emails it to the leadership team.","integrations":[{"id":"tinybird","name":"Tinybird"},{"id":"gmail","name":"Gmail"}]}]},{"id":"tinyfish","type":"tinyfish","slug":"tinyfish","name":"TinyFish","description":"Automate and read the live web","category":"AI","docsUrl":"https://docs.sim.ai/integrations/tinyfish","authType":"api-key","connections":[],"operations":[{"name":"Run Agent","description":"Run a TinyFish web agent against a website and wait for it to finish, returning the structured result it extracted"},{"name":"Start Agent Run","description":"Queue a TinyFish web agent run and return its run ID immediately, without waiting for the automation to finish"},{"name":"Get Run","description":"Get the status, extracted result, and step history of a TinyFish automation run by its ID"},{"name":"Cancel Run","description":"Cancel a queued or in-progress TinyFish automation run by its ID"},{"name":"List Runs","description":"List TinyFish automation runs, optionally filtered by status, goal text, or creation date"},{"name":"Search","description":"Search the web with TinyFish and get ranked results with titles, snippets, and URLs"},{"name":"Fetch URLs","description":"Fetch up to 10 URLs with TinyFish, rendering JavaScript when needed, and return clean extracted content"},{"name":"List Vault Items","description":"List the credentials available from password managers connected to TinyFish, with the URIs an agent run can be scoped to"},{"name":"List Browser Profiles","description":"List the Browser Context Profiles saved on the TinyFish account, with the ids an agent run can start from to reuse a logged-in session"}],"triggers":[],"skills":[{"name":"extract-structured-data-from-site","description":"Drive a TinyFish web agent to navigate a site and return data matching a JSON schema. Use to pull records — prices, listings, table rows — from pages that have no API.","content":"# Extract Structured Data From Site\\n\\nUse the TinyFish Run Agent operation to read a website and return structured data.\\n\\n## Steps\\n1. Set Website URL to the page the agent should start on. Starting closer to the data costs fewer steps.\\n2. Write a Goal that names exactly what to collect and where, e.g. \\"open the pricing page and collect every plan name and monthly price\\".\\n3. Provide an Output Schema (JSON Schema draft-07) describing the fields you want back. TinyFish re-prompts the agent when the result does not match and reports the mismatches in `schemaValidation`.\\n4. Raise Max Steps for deeper flows; switch Browser Engine to Stealth when the site blocks automation.\\n\\n## Output\\nReturn the extracted `result` object. Check `schemaValidation.valid` before trusting it, and report any field the agent could not find rather than filling it in."},{"name":"automate-web-task","description":"Have a TinyFish agent complete a multi-step task on a website — logging in, navigating, filling and submitting forms. Use when a site has no API and a person would normally do the clicks.","content":"# Automate Web Task\\n\\nUse the TinyFish Run Agent operation to complete a goal-oriented task on the web.\\n\\n## Steps\\n1. Set Website URL to the entry point and write a Goal that states the steps and the success condition, e.g. \\"log in, open Billing, download the latest invoice\\".\\n2. Turn on Use Browser Profile to start from a session that is already logged in, and give a Browser Profile ID to pick one. Turn on Use Vault Credentials when the task needs to log in itself, and scope it with Vault Credential URIs so only the intended credential is available. Pairing both lets TinyFish repair a profile whose session has expired.\\n3. Use Agent Mode \\"strict\\" when the run is a test that should fail fast instead of improvising.\\n4. Enable Use Proxy and pick a Proxy Country when the site is geo-restricted.\\n\\n## Output\\nReport whether the run completed, what the agent extracted, and the step count. On failure, quote the `error` message and category — AGENT_FAILURE means the goal needs rewording, SYSTEM_FAILURE is worth retrying."},{"name":"search-and-read-the-web","description":"Search the web with TinyFish and fetch the winning pages as clean markdown. Use to gather current sources before writing or answering.","content":"# Search And Read The Web\\n\\nPair the TinyFish Search and Fetch URLs operations to gather sources.\\n\\n## Steps\\n1. Run Search with a specific Query. Set Location and Language when the answer is regional.\\n2. Pick the result URLs worth reading — position and snippet tell you which.\\n3. Run Fetch URLs with up to 10 of those URLs and Format \\"markdown\\". Turn on Extract Links when you need to follow deeper pages.\\n4. Per-URL failures land in `errors` and never fail the whole call, so check it before assuming a page was read.\\n\\n## Output\\nSummarize from the fetched text and cite each claim with the source URL. Say which URLs failed instead of quietly dropping them."},{"name":"scope-a-run-to-one-vault-credential","description":"Find the TinyFish vault credential URI for a site and scope a single agent run to it. Use when a run needs one specific login and must not see the rest of the vault.","content":"# Scope A Run To One Vault Credential\\n\\nUse List Vault Items to discover credential URIs, then pass one to a run.\\n\\n## Steps\\n1. Run the List Vault Items operation. It returns display-safe metadata only — `itemId`, `label`, `vaultName`, `domains`, and whether the credential carries a TOTP. No secret values ever leave TinyFish.\\n2. Pick the item whose `domains` match the site you are automating and copy its `itemId` (it looks like `cred:conn-abc:Work:item-123`).\\n3. On the Run Agent operation, turn on Use Vault Credentials and paste that `itemId` into Vault Credential URIs. Leaving the field empty exposes every enabled item to the run instead.\\n4. Write the goal to reference the login by intent — \\"sign in and open Billing\\" — not by pasting any credential.\\n\\n## Output\\nReport which credential the run used by label, and whether the login succeeded. Never echo credential values; they are not returned and must not be reconstructed. If `hasTotp` is false and the site demands a second factor, say so rather than retrying."},{"name":"diagnose-a-failed-run","description":"Read a failed TinyFish run and decide whether to retry, reword the goal, or escalate. Use when an automation returns FAILED or a workflow keeps burning steps without a result.","content":"# Diagnose A Failed Run\\n\\nA failed automation comes back as a normal 200 response with the failure inside the run, so read `status` before trusting `result`.\\n\\n## Steps\\n1. Read `error.category`. `AGENT_FAILURE` means the goal or the page is the problem — reword the goal or start the run closer to the target. `SYSTEM_FAILURE` is TinyFish-side; wait `error.retryAfter` seconds and retry the same input. `BILLING_FAILURE` means the TinyFish wallet is empty and no retry will help. `UNKNOWN` should be treated as retryable once.\\n2. Read `profileHint` whenever it is set — TinyFish attaches it only when a Browser Context Profile would likely fix the run, so it outranks the category above. `reason` is `auth_wall` (the agent hit a login) or `bot_challenge` (the site blocked automation); the fix is to set up a profile for that domain and rerun with Use Browser Profile on, not to reword the goal.\\n3. Compare `numOfSteps` against the Max Steps you set. Hitting the cap means the agent was still working, so raise the cap or narrow the goal. If the run instead stopped early on a slow page, set Max Duration.\\n4. If an Output Schema was set, read `schemaValidation.errors` — a run can reach the right page and still fail on one mistyped field, and `rePromptAttempts` shows how hard TinyFish already tried to repair it.\\n5. For an async run, call Get Run and read the `steps` list to find the last action before the failure. `videoUrl` gives a recording, but the link expires 15 minutes after it is issued.\\n\\n## Output\\nState the category, the concrete cause, and the single next action. Quote `error.message` rather than paraphrasing it, and do not retry a `BILLING_FAILURE` or an `AGENT_FAILURE` without changing the input first."},{"name":"queue-and-track-long-runs","description":"Queue a TinyFish agent run without waiting, then poll or cancel it by ID. Use for automations too long to hold a workflow step open.","content":"# Queue And Track Long Runs\\n\\nUse Start Agent Run, then Get Run, Cancel Run, and List Runs to manage work asynchronously.\\n\\n## Steps\\n1. Start Agent Run with the URL and Goal. It returns a `runId` immediately. Set a Webhook URL if something should be notified on completion.\\n2. Store the `runId`, then call Get Run to read `status`, `result`, and the step history. `numOfSteps` stays null while the run is in progress.\\n3. Call Cancel Run to stop a queued or running automation. It is idempotent — a run that already finished comes back with its terminal status and a message saying so.\\n4. Use List Runs with a status or goal filter to find runs you did not record the ID for.\\n\\n## Output\\nReport the run status and, once COMPLETED, the extracted `result`. Note that these operations always need your own TinyFish API key — they are not covered by Sim’s hosted key."}],"templates":[{"title":"TinyFish competitor pricing watch","prompt":"Create a scheduled workflow that runs a TinyFish agent weekly against three competitor pricing pages, extracts every plan name and monthly price into a fixed output schema, diffs it against the table from last week, and posts the changes to Slack.","integrations":[{"id":"tinyfish","name":"TinyFish"},{"id":"slack","name":"Slack"}]},{"title":"TinyFish supplier portal collector","prompt":"Build a workflow that uses a TinyFish agent with vault credentials to log into supplier portals that have no API, download the outstanding invoices, and write the invoice metadata to a finance table.","integrations":[{"id":"tinyfish","name":"TinyFish"}]},{"title":"TinyFish research briefing","prompt":"Create a workflow that uses TinyFish Search to find the top sources on a topic, fetches each one as clean markdown, and has an agent write a cited briefing to a file.","integrations":[{"id":"tinyfish","name":"TinyFish"}]},{"title":"TinyFish lead site enrichment","prompt":"Build a workflow that reads company domains from a table, fetches each homepage and pricing page with TinyFish, extracts positioning and price points into a schema, and writes the enriched rows back.","integrations":[{"id":"tinyfish","name":"TinyFish"}]},{"title":"TinyFish long-running run tracker","prompt":"Create a workflow that queues a TinyFish agent run asynchronously, stores the run ID in a table, and a second scheduled workflow that polls each open run, writes the extracted result back, and cancels runs older than an hour.","integrations":[{"id":"tinyfish","name":"TinyFish"}]},{"title":"TinyFish signup flow QA","prompt":"Build a workflow that runs a TinyFish agent in strict mode against the staging signup flow every morning, checks that account creation succeeds end to end, and opens a Linear issue with the failing step when it does not.","integrations":[{"id":"tinyfish","name":"TinyFish"},{"id":"linear","name":"Linear"}]},{"title":"TinyFish review monitor","prompt":"Create a scheduled workflow that uses TinyFish Search to find new reviews mentioning your product, fetches each review page, classifies sentiment with an agent, and writes notable reviews to a tracking table.","integrations":[{"id":"tinyfish","name":"TinyFish"}]},{"title":"TinyFish regulatory filing digest","prompt":"Build a workflow that fetches a regulator’s notices page with TinyFish every morning, extracts new filings into a schema, and emails a digest of anything matching your watch list.","integrations":[{"id":"tinyfish","name":"TinyFish"},{"id":"gmail","name":"Gmail"}]}]},{"id":"trello","type":"trello","slug":"trello","name":"Trello","description":"Manage Trello lists, cards, checklists, and activity","category":"Productivity","docsUrl":"https://docs.sim.ai/integrations/trello","authType":"oauth","connections":[{"id":"trello","kind":"oauth","label":"Connect with OAuth","providerId":"trello","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/trello","requiredScopes":[{"id":"read","label":"Read boards, lists, cards, and workspaces"},{"id":"write","label":"Create and update boards, lists, and cards"}],"fields":[]},{"id":"trello-service-account","kind":"service_account","providerId":"trello-service-account","label":"Add API token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/trello-service-account","fields":[{"id":"apiToken","label":"API token","placeholder":"Paste API token","secret":true}]}],"operations":[{"name":"Get Lists","description":"List all lists on a Trello board"},{"name":"List Cards","description":"List cards from a Trello board or list"},{"name":"Search","description":"Search Trello cards and boards by keyword"},{"name":"Create Card","description":"Create a new card in a Trello list"},{"name":"Get Card","description":"Retrieve a single Trello card by ID"},{"name":"Update Card","description":"Update an existing card on Trello"},{"name":"Delete Card","description":"Permanently delete a Trello card"},{"name":"Get Actions","description":"Get activity/actions from a board or card"},{"name":"Add Comment","description":"Add a comment to a Trello card"},{"name":"Add Checklist","description":"Add a checklist to a Trello card"},{"name":"Add Checklist Item","description":"Add an item to a Trello checklist"},{"name":"Update Checklist Item","description":"Check off, uncheck, or rename a Trello checklist item"},{"name":"Add Label","description":"Attach an existing label to a Trello card"},{"name":"Remove Label","description":"Detach a label from a Trello card"},{"name":"Add Member","description":"Assign a member to a Trello card"},{"name":"Remove Member","description":"Unassign a member from a Trello card"},{"name":"List Members","description":"List members of a Trello board"},{"name":"Create Board","description":"Create a new Trello board"},{"name":"Get Board","description":"Retrieve a single Trello board by ID"},{"name":"Create List","description":"Create a new list on a Trello board"},{"name":"Update List","description":"Rename, move, archive, or reopen a Trello list"}],"triggers":[],"skills":[{"name":"create-card","description":"Create a Trello card in a list with a description, due date, and labels.","content":"# Create a Trello Card\\n\\nAdd a new card to a list so work is captured on the right board.\\n\\n## Steps\\n1. Use the Create Card operation and select your Trello account.\\n2. Provide the List ID where the card should land and the Card Name.\\n3. Add an optional Description, a Due Date (natural language like \\"next Friday\\" works), and Label IDs.\\n4. Set Position to top or bottom to control where the card appears in the list.\\n\\n## Output\\nReturn the created card including its id, url, and list, so it can be linked or updated later."},{"name":"triage-and-move-cards","description":"List cards on a board or list, classify them, and move each to the correct list.","content":"# Triage and Route Trello Cards\\n\\nRead incoming cards, decide where each belongs, and route them automatically.\\n\\n## Steps\\n1. Use Get Lists with the Board ID to learn the available lists and their IDs.\\n2. Use List Cards with the board or list ID to pull the cards needing triage.\\n3. Classify each card by its name and description (topic, priority, owner).\\n4. Use Update Card with the Move to List ID to route each card to its destination list.\\n\\n## Output\\nReturn a summary of how many cards were moved and the destination list for each."},{"name":"comment-on-card","description":"Add a comment to a Trello card to leave a note, nudge, or status update.","content":"# Comment on a Trello Card\\n\\nLeave a comment on a card to record context or nudge an owner.\\n\\n## Steps\\n1. Use the Add Comment operation and select your Trello account.\\n2. Provide the Card ID of the target card.\\n3. Write the Comment text, including any links or mentions the team needs.\\n\\n## Output\\nReturn the created comment action with its id and date so the note can be referenced."},{"name":"review-card-activity","description":"Pull the recent action history for a Trello board or card and summarize it.","content":"# Review Trello Card Activity\\n\\nInspect what has happened recently on a board or card to build a digest or audit.\\n\\n## Steps\\n1. Use the Get Actions operation with either a Board ID or a Card ID (one or the other, not both).\\n2. Set an Action Filter such as commentCard,updateCard,createCard to focus on the events you care about.\\n3. Use Board Action Limit and Action Page to page through longer histories.\\n\\n## Output\\nReturn the actions with their type, date, author, and text, summarized into a short activity recap."},{"name":"build-and-track-checklist","description":"Add a checklist to a card, populate it with items, and check items off as work completes.","content":"# Build and Track a Trello Checklist\\n\\nGive a card a task list and keep it up to date as steps finish.\\n\\n## Steps\\n1. Use Add Checklist on the target Card ID to create an empty checklist, and note the returned Checklist ID.\\n2. Use Add Checklist Item once per task, providing the Checklist ID and Item Name.\\n3. As each task completes, use Update Checklist Item with the Card ID and Checklist Item ID, setting State to Complete.\\n\\n## Output\\nReturn the checklist and item IDs created, and confirm which items were marked complete."},{"name":"find-and-clean-up-cards","description":"Search Trello for cards matching a query, then delete or archive the ones that no longer belong.","content":"# Find and Clean Up Trello Cards\\n\\nLocate cards by keyword without already knowing their IDs, then remove the ones that should not remain.\\n\\n## Steps\\n1. Use the Search operation with a Search Query (Trello operators like board:, list:, or due: are supported) and optionally restrict to specific Board IDs.\\n2. Review the matching cards and decide which should be archived (Update Card with Archive Status) or permanently removed (Delete Card).\\n3. Use Delete Card only for cards that should be gone for good — prefer archiving when the history should be kept.\\n\\n## Output\\nReturn how many cards matched, and which were archived versus deleted."}],"templates":[{"title":"Trello card auto-router","prompt":"Build a scheduled workflow that polls a Trello inbox list, classifies each new card by topic, and moves it to the right list based on the classification.","integrations":[{"id":"trello","name":"Trello"}]},{"title":"Trello + Linear bridge","prompt":"Create a workflow that mirrors Trello cards in a chosen list into Linear issues, keeps status and comments in sync, and writes the link back to the Trello card.","integrations":[{"id":"trello","name":"Trello"},{"id":"linear","name":"Linear"}]},{"title":"Trello SLA monitor","prompt":"Build a workflow that watches Trello cards for due-date breaches, sends reminders, and escalates to managers via Slack when items slip more than 2 days.","integrations":[{"id":"trello","name":"Trello"},{"id":"slack","name":"Slack"}]},{"title":"Trello content pipeline","prompt":"Create a workflow that reads a Trello editorial board, publishes the cards in the \\"ready\\" list to WordPress on schedule, and moves the card to \\"live\\" with the URL attached.","integrations":[{"id":"trello","name":"Trello"},{"id":"wordpress","name":"WordPress"}]},{"title":"Trello weekly digest","prompt":"Build a scheduled weekly workflow that summarizes Trello board movements — cards completed, blocked, in-progress — and emails the digest to the project owner.","integrations":[{"id":"trello","name":"Trello"},{"id":"gmail","name":"Gmail"}]},{"title":"Trello stale-card sweeper","prompt":"Create a scheduled workflow that scans a Trello board for cards with no activity in 30 days, comments a nudge on each, and posts a stale-card list to Slack for the project owner.","integrations":[{"id":"trello","name":"Trello"},{"id":"slack","name":"Slack"}]},{"title":"Trello onboarding seeder","prompt":"Build a workflow that creates the standard onboarding cards in a Trello list for each new hire, sets due dates by step, and tailors the card set to their role.","integrations":[{"id":"trello","name":"Trello"}]}]},{"id":"trigger_dev","type":"trigger_dev","slug":"trigger-dev","name":"Trigger.dev","description":"Trigger tasks and manage runs and schedules","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/trigger_dev","authType":"api-key","connections":[],"operations":[{"name":"Trigger Task","description":"Trigger a Trigger.dev task by its identifier with an optional JSON payload. Returns the ID of the created run."},{"name":"Batch Trigger Task","description":"Batch trigger a Trigger.dev task with up to 1,000 payloads. All items in the batch run the same task. Returns the batch ID and the created run IDs."},{"name":"Get Batch","description":"Retrieve a Trigger.dev batch by its ID, including its status, run IDs, and success and failure counts."},{"name":"Get Batch Results","description":"Retrieve the execution results of every run in a Trigger.dev batch, including outputs and error details."},{"name":"Get Run","description":"Retrieve a Trigger.dev run by its ID, including status, payload, output, attempts, and timing details."},{"name":"Get Run Result","description":"Retrieve the result of a Trigger.dev run: whether it succeeded, its output, and error details. Lighter than Get Run when only the outcome is needed."},{"name":"Get Run Events","description":"Retrieve the log and span events of a Trigger.dev run, including messages, levels, durations, and error events."},{"name":"Get Run Trace","description":"Retrieve the OpenTelemetry trace of a Trigger.dev run as a tree of spans with timing, errors, and nested children."},{"name":"List Runs","description":"List Trigger.dev runs in the environment of the API key, with optional filters for status, task, version, tags, schedule, and creation time."},{"name":"Cancel Run","description":"Cancel an in-progress Trigger.dev run. Has no effect if the run is already completed."},{"name":"Replay Run","description":"Replay a Trigger.dev run, creating a new run with the same payload and options as the original."},{"name":"Reschedule Run","description":"Reschedule a delayed Trigger.dev run with a new delay. Only valid while the run is in the DELAYED state."},{"name":"Add Run Tags","description":"Add tags to an existing Trigger.dev run. Runs can have up to 10 tags."},{"name":"Update Run Metadata","description":"Replace the metadata of a Trigger.dev run with a new JSON object."},{"name":"Create Schedule","description":"Create an imperative cron schedule that triggers a Trigger.dev task on a recurring basis."},{"name":"Get Schedule","description":"Retrieve a Trigger.dev schedule by its ID."},{"name":"List Schedules","description":"List Trigger.dev schedules in the project, with page-based pagination."},{"name":"Update Schedule","description":"Update an imperative Trigger.dev schedule by its ID, replacing its task, cron expression, timezone, and external ID."},{"name":"Delete Schedule","description":"Delete an imperative Trigger.dev schedule by its ID."},{"name":"Activate Schedule","description":"Activate an imperative Trigger.dev schedule so it resumes triggering its task."},{"name":"Deactivate Schedule","description":"Deactivate an imperative Trigger.dev schedule so it stops triggering its task."},{"name":"List Env Vars","description":"List the environment variables of a Trigger.dev project environment. Values are returned in plaintext and will appear in workflow outputs and run history — scope this operation carefully."},{"name":"Create Env Var","description":"Create an environment variable in a Trigger.dev project environment."},{"name":"Get Env Var","description":"Retrieve an environment variable from a Trigger.dev project environment. The value is returned in plaintext and will appear in workflow outputs and run history."},{"name":"Update Env Var","description":"Update the value of an environment variable in a Trigger.dev project environment."},{"name":"Delete Env Var","description":"Delete an environment variable from a Trigger.dev project environment."},{"name":"Import Env Vars","description":"Upload multiple environment variables to a Trigger.dev project environment in one request."},{"name":"Get Queue","description":"Retrieve a Trigger.dev queue by ID, task identifier, or custom queue name, including its running and queued counts."},{"name":"List Queues","description":"List the queues in the environment of the API key, including running and queued counts, with page-based pagination."},{"name":"Pause Queue","description":"Pause a Trigger.dev queue so no new runs start. Runs that are currently executing continue to completion."},{"name":"Resume Queue","description":"Resume a paused Trigger.dev queue so new runs can start again."},{"name":"Override Queue Concurrency","description":"Override the concurrency limit of a Trigger.dev queue with a new value."},{"name":"Reset Queue Concurrency","description":"Reset the concurrency limit of a Trigger.dev queue back to its base value, removing any override."},{"name":"List Deployments","description":"List Trigger.dev deployments in the environment of the API key, with optional status and creation-time filters."},{"name":"Get Deployment","description":"Retrieve a Trigger.dev deployment by its ID, including its status, version, and registered tasks."},{"name":"Get Latest Deployment","description":"Retrieve the latest Trigger.dev deployment in the environment of the API key."},{"name":"Promote Deployment","description":"Promote a Trigger.dev deployment version so new runs execute on it (e.g., to roll back to a previous version)."},{"name":"Execute Query","description":"Execute a TRQL (SQL-like) query against Trigger.dev run data for reporting and analytics."},{"name":"Get Query Schema","description":"Retrieve the TRQL query schema: the tables and columns available for Execute Query, with types and allowed values."},{"name":"Create Waitpoint Token","description":"Create a Trigger.dev waitpoint token that a task can wait on until it is completed from outside (e.g., a human approval)."},{"name":"Complete Waitpoint Token","description":"Complete a Trigger.dev waitpoint token, resuming any task waiting on it and passing it optional JSON data."},{"name":"Get Waitpoint Token","description":"Retrieve a Trigger.dev waitpoint token by its ID, including its status, timeout, and completion data."},{"name":"List Waitpoint Tokens","description":"List Trigger.dev waitpoint tokens in the environment of the API key, with optional status, tag, and creation-time filters."},{"name":"List Timezones","description":"List the IANA timezones supported by Trigger.dev schedules, for use as the timezone of a cron schedule."}],"triggers":[],"skills":[{"name":"trigger-task-and-wait","description":"Trigger a Trigger.dev background task with a payload and poll until the run completes, returning its output.","content":"# Trigger Task and Wait\\n\\nKick off a Trigger.dev background task and collect its result.\\n\\n## Steps\\n1. Use the Trigger Task operation with the task identifier and a JSON payload. Set an idempotency key when the same event might arrive twice.\\n2. Poll the Get Run operation with the returned run ID until the status is COMPLETED, FAILED, CANCELED, CRASHED, or another terminal state.\\n3. On COMPLETED, read the run output. On failure states, read the attempts to surface the error message.\\n\\n## Output\\nReturn the run ID, final status, duration, and the run output — or the error details if the run did not complete."},{"name":"monitor-failed-runs","description":"List recent failed Trigger.dev runs, group them by task, and produce a failure digest. Use for run health monitoring.","content":"# Monitor Failed Runs\\n\\nReview recent Trigger.dev failures and summarize what needs attention.\\n\\n## Steps\\n1. Use the List Runs operation with a status filter of FAILED, CRASHED, SYSTEM_FAILURE and a created-within period (e.g., 1h or 1d).\\n2. Group the runs by task identifier and count failures per task.\\n3. For the most affected tasks, fetch a representative run with Get Run and pull the attempt error message.\\n\\n## Output\\nReport failures per task with counts, representative error messages, and run IDs. If nothing failed, say so briefly."},{"name":"replay-transient-failures","description":"Inspect failed Trigger.dev runs and replay the ones whose errors look transient (timeouts, rate limits, network).","content":"# Replay Transient Failures\\n\\nRetry failed Trigger.dev runs that are safe to run again.\\n\\n## Steps\\n1. List runs with status FAILED for the relevant period and task filter.\\n2. For each run, use Get Run and inspect the attempt errors. Treat timeouts, rate limits, and network errors as transient; treat validation and logic errors as permanent.\\n3. Use the Replay Run operation on transient failures only, and record the new run IDs.\\n\\n## Output\\nList the replayed runs (old run ID to new run ID) and the runs skipped as permanent failures, with the reason for each decision."},{"name":"human-approval-waitpoint","description":"Create a Trigger.dev waitpoint token for a task to wait on, then complete it with approval data once a human decides.","content":"# Human Approval Waitpoint\\n\\nGate a Trigger.dev task on an external decision using waitpoint tokens.\\n\\n## Steps\\n1. Use Create Waitpoint Token with a timeout (e.g., 1d) and an idempotency key tied to the request, and pass the token ID to the task that should wait.\\n2. When the decision arrives, use Complete Waitpoint Token with the token ID and a JSON payload like {\\"status\\": \\"approved\\"} so the waiting run resumes with that data.\\n3. Use Get Waitpoint Token or List Waitpoint Tokens to check for tokens that are still WAITING or have TIMED_OUT.\\n\\n## Output\\nReport the token ID, its status, and the completion data passed to the run. Flag tokens that timed out without a decision."},{"name":"manage-cron-schedules","description":"Create, update, activate, deactivate, or delete Trigger.dev cron schedules for a task, scoped by external ID.","content":"# Manage Cron Schedules\\n\\nKeep Trigger.dev schedules in sync with the desired cadence.\\n\\n## Steps\\n1. Use List Schedules to find existing schedules for the task, matching on external ID when schedules are per customer or per resource.\\n2. Create a schedule with the task identifier, cron expression, timezone, and a deduplication key so reruns do not create duplicates.\\n3. Update the cron or timezone on an existing schedule by ID, and use Activate or Deactivate to pause and resume without deleting.\\n4. Delete schedules that are no longer needed.\\n\\n## Output\\nReport the schedule ID, task, cron expression, timezone, active state, and next run time after the change."}],"templates":[{"title":"Trigger.dev job kickoff","prompt":"Build a workflow that receives an event from another system, triggers the matching Trigger.dev background task with a JSON payload, and returns the run ID for tracking.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev failed-run monitor","prompt":"Build a scheduled workflow that lists Trigger.dev runs with status FAILED or CRASHED from the last hour, summarizes the failures per task, and posts a digest to the engineering Slack channel.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"},{"id":"slack","name":"Slack"}]},{"title":"Trigger.dev auto-retry agent","prompt":"Create an agent that lists failed Trigger.dev runs, inspects each run error to decide whether the failure looks transient, and replays the runs that are safe to retry.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev run-output collector","prompt":"Build a workflow that triggers a Trigger.dev task, polls Get Run until the run completes, and writes the run output and timing details into a results table.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev schedule manager","prompt":"Create an agent that manages Trigger.dev cron schedules per customer — creating a schedule with the customer ID as external ID on signup, and deactivating or deleting it on churn.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"}]},{"title":"Trigger.dev stuck-run janitor","prompt":"Build a scheduled workflow that lists Trigger.dev runs still executing past their expected duration, cancels the stuck runs, and posts the canceled run IDs to Slack.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"},{"id":"slack","name":"Slack"}]},{"title":"Trigger.dev compute cost reporter","prompt":"Create a weekly scheduled workflow that uses Trigger.dev Execute Query to aggregate compute cost and duration per task for the past week, and emails a cost report to the team.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"},{"id":"gmail","name":"Gmail"}]},{"title":"Trigger.dev human approval gate","prompt":"Build a workflow where a Trigger.dev task waits on a waitpoint token, an approver reviews the request in Slack, and the workflow completes the waitpoint token with the approval decision so the task resumes.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"},{"id":"slack","name":"Slack"}]},{"title":"Trigger.dev deploy watchdog","prompt":"Create a workflow that checks the latest Trigger.dev deployment after each release, and if the deployment failed or new runs start crashing, promotes the previous deployment version and alerts the on-call channel.","integrations":[{"id":"trigger_dev","name":"Trigger.dev"},{"id":"slack","name":"Slack"}]}]},{"id":"twilio_sms","type":"twilio_sms","slug":"twilio-sms","name":"Twilio SMS","description":"Send SMS messages","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/twilio_sms","authType":"api-key","connections":[],"operations":[{"name":"Twilio Send SMS","description":"Send text messages to single or multiple recipients using the Twilio API."}],"triggers":[{"id":"twilio_sms_received","name":"Twilio SMS Received","description":"Trigger workflow when an inbound SMS or MMS message is received via Twilio"},{"id":"twilio_sms_status","name":"Twilio Message Status","description":"Trigger workflow when a Twilio message status changes (sent, delivered, failed)"}],"skills":[{"name":"send-sms-notification","description":"Send an SMS notification to one or more phone numbers via Twilio.","content":"# Send an SMS Notification\\n\\nDeliver a text message to one or more recipients through your Twilio number.\\n\\n## Steps\\n1. Enter the Recipient Phone Numbers in E.164 format with country code (for example +14155551234), one per line for multiple recipients.\\n2. Write the Message text, keeping it concise since long messages split into multiple segments.\\n3. Provide your Twilio Account SID, Auth Token, and the verified From Twilio Phone Number.\\n\\n## Output\\nReturn the success status, the Twilio message SID, and the delivery status (queued, sent, delivered) so the send can be confirmed."},{"name":"send-personalized-reminder","description":"Send a personalized SMS reminder built from upstream data such as appointment or order details.","content":"# Send a Personalized SMS Reminder\\n\\nText each recipient a reminder tailored with their own details.\\n\\n## Steps\\n1. Pull the recipient details from an upstream block (a table row, CRM record, or order event).\\n2. Build the Message using those fields, for example the appointment time or tracking number, plus any link.\\n3. Set the Recipient Phone Numbers to the customer number from the source record.\\n4. Provide the Account SID, Auth Token, and From Twilio Phone Number.\\n\\n## Output\\nReturn the message SID and status for each send so delivery can be logged back to the source record."},{"name":"send-verification-code","description":"Send a one-time verification code over SMS for two-factor authentication.","content":"# Send a Verification Code over SMS\\n\\nDeliver a one-time code to a user for two-factor authentication or confirmation.\\n\\n## Steps\\n1. Generate or receive the one-time code from an upstream step.\\n2. Compose the Message with the code and a short note (for example \\"Your code is 482913. It expires in 10 minutes.\\").\\n3. Set the Recipient Phone Numbers to the user number and provide the Account SID, Auth Token, and From number.\\n4. Log the send outcome for audit.\\n\\n## Output\\nReturn the message SID and delivery status so the verification send can be tracked and audited."}],"templates":[{"title":"Calendar SMS appointment reminders","prompt":"Create a scheduled workflow that checks Google Calendar each morning for appointments in the next 24 hours, and sends an SMS reminder to each attendee via Twilio with the meeting time, location, and any prep notes.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Twilio appointment reminders","prompt":"Build a scheduled workflow that reads tomorrow’s appointments from a table and sends each customer a personalized Twilio SMS reminder with the time and a reschedule link.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Twilio order-status notifier","prompt":"Create a workflow triggered when an order ships that looks up the customer’s phone number and sends a Twilio SMS with the tracking number and estimated delivery date.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"},{"id":"shopify","name":"Shopify"}]},{"title":"Twilio incident escalation alerts","prompt":"Build a workflow triggered by a PagerDuty incident that sends a Twilio SMS to the on-call engineer with the service name and severity so critical alerts reach them even when they are away from Slack.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Twilio lead speed-to-text","prompt":"Create a workflow that fires when a new lead submits a form, drafts a friendly intro message, and sends it via Twilio SMS within seconds so reps engage hot leads while they are still interested.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"},{"id":"typeform","name":"Typeform"}]},{"title":"Twilio two-factor code sender","prompt":"Build a workflow that receives a verification request from an application, generates a one-time code, sends it to the user via Twilio SMS, and logs the send for audit.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Twilio payment-failure outreach","prompt":"Create a workflow triggered by a Stripe failed-payment event that sends the customer a Twilio SMS with a secure update-payment link and logs the recovery attempt to a table.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"},{"id":"stripe","name":"Stripe"}]},{"title":"Twilio daily standup nudge","prompt":"Build a scheduled workflow that sends each team member a Twilio SMS prompting their async standup update every weekday morning, with a link to where to post it.","integrations":[{"id":"twilio_sms","name":"Twilio SMS"}]}]},{"id":"twilio_voice","type":"twilio_voice","slug":"twilio-voice","name":"Twilio Voice","description":"Make and manage phone calls","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/twilio_voice","authType":"api-key","connections":[],"operations":[{"name":"Make Call","description":"Make an outbound phone call using Twilio Voice API."},{"name":"List Calls","description":"Retrieve a list of calls made to and from an account."},{"name":"Get Recording","description":"Retrieve call recording information and transcription (if enabled via TwiML)."}],"triggers":[{"id":"twilio_voice_webhook","name":"Twilio Voice Webhook","description":"Trigger workflow when phone calls are received via Twilio Voice"}],"skills":[{"name":"place-outbound-call","description":"Place an outbound Twilio Voice call that speaks a message or plays audio via TwiML.","content":"# Place an Outbound Voice Call\\n\\nDial a number and play a spoken message or audio using TwiML.\\n\\n## Steps\\n1. Use the Make Call operation with your Account SID and Auth Token.\\n2. Set the To Phone Number and the From Twilio Number, both in E.164 format.\\n3. Provide TwiML Instructions describing what the call should say or do (use square brackets like [Say]Hello[/Say]), or point a TwiML URL at hosted instructions.\\n4. Enable Record Call and set a Timeout if you need the recording or a ring limit, and add Machine Detection to handle voicemail.\\n\\n## Output\\nReturn the call SID and status so the call can be tracked or its recording retrieved later."},{"name":"collect-keypad-response","description":"Place a call that asks a question and captures the caller keypad or speech response.","content":"# Collect a Keypad or Speech Response\\n\\nCall a recipient, ask a question, and capture their response for branching logic.\\n\\n## Steps\\n1. Use the Make Call operation with the To and From numbers and your credentials.\\n2. In the TwiML Instructions, use [Gather] to collect input, for example [Gather input=\\"dtmf\\" numDigits=\\"1\\"][Say]Press 1 to confirm, 2 to cancel[/Say][/Gather].\\n3. For surveys, gather a rating digit; for confirmations, gather a single yes or no digit.\\n4. Enable Record Call when you also want the audio.\\n\\n## Output\\nReturn the captured digits or speech result from the webhook so a later step can branch on the caller response."},{"name":"retrieve-call-recording","description":"Fetch a Twilio Voice call recording and its transcription by recording SID.","content":"# Retrieve a Call Recording\\n\\nPull the recording and transcript of a completed call for QA or CRM logging.\\n\\n## Steps\\n1. Use the Get Recording operation with your Account SID and Auth Token.\\n2. Provide the Recording SID (it begins with RE) from the call you want.\\n3. If the original call TwiML used [Record transcribe=\\"true\\"], the transcription text is returned alongside the audio.\\n\\n## Output\\nReturn the media URL to download the recording, its duration, and the transcription text and status so the call can be summarized or archived."},{"name":"review-recent-calls","description":"List recent Twilio Voice calls filtered by number, status, and date range.","content":"# Review Recent Voice Calls\\n\\nPull a filtered list of calls to build a report or feed a follow-up workflow.\\n\\n## Steps\\n1. Use the List Calls operation with your Account SID and Auth Token.\\n2. Filter by To Number, From Number, or Status (for example completed or no-answer).\\n3. Narrow the window with After and Before dates (natural language like \\"last week\\" works), and set a Page Size.\\n\\n## Output\\nReturn the array of matching calls with their SIDs, status, direction, and duration, plus the total count for reporting."}],"templates":[{"title":"Twilio Voice IVR router","prompt":"Create a workflow that handles inbound Twilio Voice calls with an IVR menu, captures caller intent, routes to the right queue, and writes the call summary to a support table.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Twilio Voice outbound dialer","prompt":"Build a workflow that reads a callbacks table, places Twilio Voice calls in batches, plays a recorded message or connects to an agent, and logs the call outcome back to the row.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Twilio Voice incident dialer","prompt":"Create a workflow that on a PagerDuty severity-1 incident places a Twilio Voice call to the on-call engineer with an automated message, escalates to backup if no answer, and logs the cascade.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Twilio Voice transcript-to-CRM","prompt":"Build a workflow that runs after a Twilio Voice call ends, transcribes the recording, summarizes the conversation, and writes the summary plus action items to the linked Salesforce account.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Twilio Voice survey collector","prompt":"Create a workflow that places Twilio Voice survey calls to recent customers, captures their NPS rating via key press, and writes results to a feedback table for analysis.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Twilio Voice spam-call filter","prompt":"Build a workflow that screens inbound Twilio Voice calls, classifies likely spam using number reputation plus a spoken challenge captured via Gather DTMF — press a digit to continue — and routes only verified callers to the support queue.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"}]},{"title":"Twilio Voice call QA reviewer","prompt":"Create a scheduled workflow that lists yesterday\'s Twilio Voice calls, pulls each recording, transcribes and scores it for tone, compliance phrases, and resolution, and writes a QA scorecard to a table while flagging low-scoring calls to the team lead in Slack.","integrations":[{"id":"twilio_voice","name":"Twilio Voice"},{"id":"slack","name":"Slack"}]}]},{"id":"typeform","type":"typeform","slug":"typeform","name":"Typeform","description":"Interact with Typeform","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/typeform","authType":"api-key","connections":[],"operations":[{"name":"Retrieve Responses","description":"Retrieve form responses from Typeform"},{"name":"Download File","description":"Download files uploaded in Typeform responses"},{"name":"Form Insights","description":"Retrieve insights and analytics for Typeform forms"},{"name":"List Forms","description":"Retrieve a list of all forms in your Typeform account"},{"name":"Get Form Details","description":"Retrieve complete details and structure of a specific form"},{"name":"Create Form","description":"Create a new form with fields and settings"},{"name":"Update Form","description":"Update an existing form using JSON Patch operations"},{"name":"Delete Form","description":"Permanently delete a form and all its responses"}],"triggers":[{"id":"typeform_webhook","name":"Typeform Webhook","description":"Trigger workflow when a Typeform submission is received"}],"skills":[{"name":"retrieve-form-responses","description":"Fetch Typeform responses for a form with date and completion filters.","content":"# Retrieve Typeform Responses\\n\\nPull submitted responses from a form so an agent can analyze or route them.\\n\\n## Steps\\n1. Use the Retrieve Responses operation with the Form ID and your personal access token.\\n2. Filter with Since and Until dates (natural language like \\"last week\\" works) to get only recent submissions.\\n3. Set Completed to Only Completed to skip partial responses, and set Page Size for batch size.\\n4. Use the Before and After cursor tokens to page through large result sets.\\n\\n## Output\\nReturn the response items with their answers and metadata, plus the total count, ready for analysis or logging."},{"name":"analyze-survey-responses","description":"Pull form responses and categorize them by theme and sentiment for a digest.","content":"# Analyze Survey Responses\\n\\nTurn raw form submissions into structured insights.\\n\\n## Steps\\n1. Use Retrieve Responses with the Form ID, narrowing by Since to the new batch.\\n2. For each response, classify the free-text answers by theme and sentiment with an agent.\\n3. Aggregate counts per theme and capture notable quotes.\\n4. Optionally use Form Insights to pull completion and drop-off metrics for context.\\n\\n## Output\\nReturn a structured summary of themes, sentiment breakdown, and standout responses suitable for a table row or a Slack digest."},{"name":"create-form","description":"Create a new Typeform form or quiz with fields and settings.","content":"# Create a Typeform Form\\n\\nSpin up a new form or quiz programmatically.\\n\\n## Steps\\n1. Use the Create Form operation with your personal access token.\\n2. Set the Form Title and choose the Form Type (form or quiz).\\n3. Provide Fields as a JSON array of field objects (type, title, ref, validations) and optional Settings as JSON.\\n4. Set a Workspace ID and Theme ID to place and style the form.\\n\\n## Output\\nReturn the new form id and its links so you can share it or store the reference."},{"name":"download-uploaded-file","description":"Download a file a respondent uploaded through a Typeform file-upload field.","content":"# Download an Uploaded Typeform File\\n\\nRetrieve a file that a respondent attached in their submission.\\n\\n## Steps\\n1. Use the Download File operation with the Form ID and your personal access token.\\n2. Provide the Response ID (the response token), the file-upload Field ID, and the exact Filename.\\n3. Use these IDs from a Retrieve Responses result that contains file-upload answers.\\n\\n## Output\\nReturn the downloaded file and its content type so it can be stored, forwarded, or processed by a later step."}],"templates":[{"title":"Sendblue lead speed-to-text","prompt":"Build a workflow that fires when a new lead submits a form, drafts a friendly intro, and sends it as an iMessage via Sendblue within seconds so reps reach hot leads while they are still interested.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"sendblue","name":"Sendblue"}]},{"title":"Twilio lead speed-to-text","prompt":"Create a workflow that fires when a new lead submits a form, drafts a friendly intro message, and sends it via Twilio SMS within seconds so reps engage hot leads while they are still interested.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"twilio_sms","name":"Twilio SMS"}]},{"title":"Typeform survey summarizer","prompt":"Create a workflow that pulls new Typeform responses daily, categorizes feedback by theme and sentiment, logs structured results to a table, and sends a Slack digest when a new batch of responses comes in with the key takeaways.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"slack","name":"Slack"}]},{"title":"Typeform NPS pipeline","prompt":"Build a workflow that collects Typeform NPS responses, classifies each as promoter/passive/detractor, writes the rolled-up score to a tracking table, and pings Slack on detractor spikes.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"slack","name":"Slack"}]},{"title":"Typeform lead enricher","prompt":"Create a workflow that watches Typeform lead-gen submissions, enriches each lead with company size and tech stack via Apollo, and pushes the enriched lead into Salesforce.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"apollo","name":"Apollo"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Typeform candidate screener","prompt":"Build a workflow that captures Typeform applicant responses, scores them against the role rubric with an agent, and creates a Greenhouse candidate with the score attached.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"greenhouse","name":"Greenhouse"}]},{"title":"Typeform event survey analyzer","prompt":"Create a workflow that processes Typeform event survey responses, summarizes feedback themes, writes structured insights to a feedback table, and emails the organizer the digest.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"gmail","name":"Gmail"}]},{"title":"Typeform onboarding follow-up","prompt":"Build a workflow that collects Typeform onboarding-flow responses, segments responders by job-to-be-done, and triggers tailored Loops email sequences for each segment.","integrations":[{"id":"typeform","name":"Typeform"},{"id":"loops","name":"Loops"}]},{"title":"Typeform research analyzer","prompt":"Create a workflow that pulls Typeform research responses, clusters answers by theme, and writes a tables-based research insight log for the product team.","integrations":[{"id":"typeform","name":"Typeform"}]}]},{"id":"upstash","type":"upstash","slug":"upstash","name":"Upstash","description":"Serverless Redis with Upstash","category":"Databases","docsUrl":"https://docs.sim.ai/integrations/upstash","authType":"api-key","connections":[],"operations":[{"name":"Get","description":"Get the value of a key from Upstash Redis."},{"name":"Set","description":"Set the value of a key in Upstash Redis with an optional expiration time in seconds."},{"name":"Delete","description":"Delete a key from Upstash Redis."},{"name":"List Keys","description":"List keys matching a pattern in Upstash Redis. Defaults to listing all keys (*)."},{"name":"HSET","description":"Set a field in a hash stored at a key in Upstash Redis."},{"name":"HGET","description":"Get the value of a field in a hash stored at a key in Upstash Redis."},{"name":"HGETALL","description":"Get all fields and values of a hash stored at a key in Upstash Redis."},{"name":"INCR","description":"Atomically increment the integer value of a key by one in Upstash Redis. If the key does not exist, it is set to 0 before incrementing."},{"name":"INCRBY","description":"Increment the integer value of a key by a given amount. Use a negative value to decrement. If the key does not exist, it is set to 0 before the operation."},{"name":"EXISTS","description":"Check if a key exists in Upstash Redis. Returns true if the key exists, false otherwise."},{"name":"SETNX","description":"Set the value of a key only if it does not already exist. Returns true if the key was set, false if it already existed."},{"name":"LPUSH","description":"Prepend a value to the beginning of a list in Upstash Redis. Creates the list if it does not exist."},{"name":"LRANGE","description":"Get a range of elements from a list in Upstash Redis. Use 0 and -1 for start and stop to get all elements."},{"name":"EXPIRE","description":"Set a timeout on a key in Upstash Redis. After the timeout, the key is deleted."},{"name":"TTL","description":"Get the remaining time to live of a key in Upstash Redis. Returns -1 if the key has no expiration, -2 if the key does not exist."},{"name":"Command","description":"Execute an arbitrary Redis command against Upstash Redis. Pass the full command as a JSON array (e.g., [\\"HSET\\", \\"myhash\\", \\"field1\\", \\"value1\\"])."}],"triggers":[],"skills":[{"name":"cache-value-with-ttl","description":"Store a value in Upstash Redis under a key with an expiration so it auto-evicts.","content":"# Cache a Value with TTL\\n\\nWrite a computed or fetched value into Redis so hot paths read it fast and it expires automatically.\\n\\n## Steps\\n1. Use the Set operation with your REST URL and REST Token.\\n2. Provide the Key (for example user:123:profile) and the Value to store.\\n3. Set the Expiration (seconds) so the entry self-evicts after the TTL.\\n4. To avoid overwriting an existing entry, use SETNX instead, which only sets when the key is absent.\\n\\n## Output\\nReturn the set result so the cache write can be confirmed before downstream reads."},{"name":"read-cached-value","description":"Read a value from Upstash Redis by key, returning a cache hit or miss.","content":"# Read a Cached Value\\n\\nLook up a key in Redis and branch on whether it is present.\\n\\n## Steps\\n1. Use the Get operation with the REST URL, REST Token, and the Key.\\n2. To check presence first without fetching, use EXISTS, or use TTL to see how long the entry has left.\\n3. On a cache miss (no value), fall through to recompute and write it back with Set.\\n\\n## Output\\nReturn the retrieved value, or an empty result on a miss, so the workflow can serve cached data or recompute."},{"name":"increment-counter","description":"Atomically increment an Upstash Redis counter for rate limits or usage metering.","content":"# Increment a Redis Counter\\n\\nMaintain an atomic counter for usage tracking, rate limiting, or tallies.\\n\\n## Steps\\n1. Use the INCR operation with the REST URL, REST Token, and the counter Key to add one.\\n2. Use INCRBY with an Increment amount to add (or subtract with a negative value) a specific number.\\n3. Pair with the EXPIRE operation on the key to create a time-windowed counter (for example per-minute rate limits).\\n\\n## Output\\nReturn the new counter value after the increment so the workflow can check it against a threshold."},{"name":"push-and-read-list","description":"Push items onto an Upstash Redis list and read a range back for a simple queue.","content":"# Push and Read a Redis List\\n\\nUse a Redis list as a lightweight queue or activity log.\\n\\n## Steps\\n1. Use the LPUSH operation with the REST URL, REST Token, Key, and Value to add an item to the list head.\\n2. Use the LRANGE operation with a Start Index (0) and Stop Index (-1 for all) to read items back.\\n3. For raw or unsupported operations, use the Command operation with a JSON array like [\\"RPOP\\", \\"myqueue\\"].\\n\\n## Output\\nReturn the list length after a push and the list elements from a range read so the workflow can process queued items."}],"templates":[{"title":"Upstash key TTL hygiene","prompt":"Build a scheduled workflow that pulls Upstash Redis keys without TTLs, flags those that should expire, and either sets a TTL or routes to engineering for review.","integrations":[{"id":"upstash","name":"Upstash"}]},{"title":"Upstash counter digest","prompt":"Create a scheduled daily workflow that reads Upstash Redis counter keys for the day, summarizes the totals, and posts a usage digest to Slack.","integrations":[{"id":"upstash","name":"Upstash"},{"id":"slack","name":"Slack"}]},{"title":"Upstash queue drain","prompt":"Build a scheduled workflow that pops queued jobs from an Upstash Redis list with LRANGE, transforms each into structured rows, and writes them into a downstream Sim table for further automation.","integrations":[{"id":"upstash","name":"Upstash"}]},{"title":"Upstash + Vercel cache invalidator","prompt":"Create a workflow triggered by a Vercel production deploy that flushes targeted Upstash cache keys for changed routes, so users never see stale responses post-deploy.","integrations":[{"id":"upstash","name":"Upstash"},{"id":"vercel","name":"Vercel"}]},{"title":"Upstash key integrity check","prompt":"Build a scheduled workflow that reads a set of critical Upstash Redis keys, compares each value against the expected baseline in a table, and writes a mismatch report to an SRE audit table.","integrations":[{"id":"upstash","name":"Upstash"}]},{"title":"Upstash cache warmer","prompt":"Create a scheduled workflow that precomputes expensive query results and writes them into Upstash Redis with a TTL using SET, so hot paths stay warm and pages PagerDuty if a warm-up run fails.","integrations":[{"id":"upstash","name":"Upstash"},{"id":"pagerduty","name":"PagerDuty"}]},{"title":"Upstash + DynamoDB hybrid store","prompt":"Create a workflow that uses Upstash for hot keys and DynamoDB for cold storage, transparently promotes/demotes records based on access frequency.","integrations":[{"id":"upstash","name":"Upstash"},{"id":"dynamodb","name":"Amazon DynamoDB"}]}]},{"id":"uptimerobot","type":"uptimerobot","slug":"uptimerobot","name":"UptimeRobot","description":"Monitor uptime, manage incidents, maintenance windows, and status pages","category":"Observability","docsUrl":"https://docs.sim.ai/integrations/uptimerobot","authType":"api-key","connections":[],"operations":[{"name":"List Monitors","description":"List monitors in your UptimeRobot account, with optional filters and pagination"},{"name":"Get Monitor","description":"Get the details of a single UptimeRobot monitor by ID"},{"name":"Create Monitor","description":"Create a new monitor in UptimeRobot"},{"name":"Update Monitor","description":"Update an existing UptimeRobot monitor. Only the provided fields are changed."},{"name":"Delete Monitor","description":"Permanently delete an UptimeRobot monitor by ID"},{"name":"Pause Monitor","description":"Pause an UptimeRobot monitor so it stops running checks"},{"name":"Start Monitor","description":"Resume a paused UptimeRobot monitor so it starts running checks again"},{"name":"List Incidents","description":"List incidents across your UptimeRobot account (last 24 hours by default), with optional filters"},{"name":"Get Incident","description":"Get the details of a single UptimeRobot incident by ID"},{"name":"List Maintenance Windows","description":"List maintenance windows in your UptimeRobot account"},{"name":"Get Maintenance Window","description":"Get the details of a single UptimeRobot maintenance window by ID"},{"name":"Create Maintenance Window","description":"Create a new maintenance window to suppress alerts during planned downtime"},{"name":"Update Maintenance Window","description":"Update an existing maintenance window. Only the provided fields are changed."},{"name":"Delete Maintenance Window","description":"Permanently delete an UptimeRobot maintenance window by ID"},{"name":"List Alert Contacts","description":"List the personal alert contacts in your UptimeRobot account"},{"name":"Get Alert Contact","description":"Get the details of a single UptimeRobot alert contact by ID"},{"name":"Create Alert Contact","description":"Create an email alert contact in UptimeRobot. The contact must be confirmed via email before it can receive alerts."},{"name":"Delete Alert Contact","description":"Permanently delete an UptimeRobot alert contact by ID"},{"name":"List Status Pages","description":"List the public status pages in your UptimeRobot account"},{"name":"Get Status Page","description":"Get the details of a single UptimeRobot public status page by ID"},{"name":"Create Status Page","description":"Create a public status page in UptimeRobot, optionally with a logo and icon image"},{"name":"Update Status Page","description":"Update a public status page in UptimeRobot. Only the provided fields are changed; logo and icon images can be replaced."},{"name":"Delete Status Page","description":"Permanently delete an UptimeRobot public status page by ID"},{"name":"Get Account","description":"Get details about the authenticated UptimeRobot account, including plan and limits"}],"triggers":[],"skills":[{"name":"alert-on-active-downtime","description":"Detect services that are currently down and notify the team. Use to turn UptimeRobot incidents into actionable alerts.","content":"# Alert On Active Downtime\\n\\nSurface services that are currently down and notify the team.\\n\\n## Steps\\n1. Use List Incidents (optionally filtered by a recent Started After timestamp) to get recent incidents.\\n2. Keep only incidents that are not resolved (no resolvedAt) — these are still active.\\n3. For richer context, use Get Incident on each active incident to read its cause, reason, and root-cause URL.\\n4. Format an alert with the affected monitor name, how long it has been down (duration), and the cause.\\n\\n## Output\\nReturn a concise alert per active incident: monitor name, started time, duration, and cause. If nothing is active, report that all monitored services are healthy."},{"name":"create-uptime-monitor","description":"Add a new HTTP, keyword, ping, or port monitor for a service so it is tracked for uptime. Use when onboarding a new endpoint.","content":"# Create Uptime Monitor\\n\\nStart monitoring a new service endpoint.\\n\\n## Steps\\n1. Decide the monitor type (HTTP for most web services, KEYWORD to assert page content, PING/PORT for hosts).\\n2. Use Create Monitor with a friendly name, the URL or host, and a check interval in seconds (minimum 30; 300 is a sensible default).\\n3. For keyword monitors, also set the keyword type and value. For HTTP, optionally set the method, success codes, and SSL checks.\\n4. Confirm the returned monitor id and status.\\n\\n## Output\\nReturn the new monitor id, friendly name, type, and current status. Note the check interval so the user knows how often it runs."},{"name":"publish-status-page","description":"Create a public status page for a set of monitors, optionally with a logo, and share the public URL. Use to communicate service health externally.","content":"# Publish Status Page\\n\\nStand up a public status page for chosen monitors.\\n\\n## Steps\\n1. Identify the monitor ids to include (use List Monitors if needed).\\n2. Use Create Status Page with a friendly name, the comma-separated monitor ids, and status ENABLED to publish it.\\n3. Optionally upload a logo and icon image, and set a custom domain or password.\\n4. Read the returned urlKey to build the shareable status page link.\\n\\n## Output\\nReturn the status page id, friendly name, status, and the public URL key. Mention whether a logo and custom domain were applied."},{"name":"schedule-maintenance-window","description":"Suppress alerts during planned maintenance by creating a maintenance window over the affected monitors. Use before a deploy or migration.","content":"# Schedule Maintenance Window\\n\\nSuppress alerts during planned downtime.\\n\\n## Steps\\n1. Use Create Maintenance Window with a name, recurrence (once/daily/weekly/monthly), start date (YYYY-MM-DD), start time (HH:mm:ss), and a duration in minutes.\\n2. Assign the affected monitor ids, or enable auto-add monitors.\\n3. For one-off maintenance, use recurrence \\"once\\".\\n4. Optionally pause specific monitors directly with Pause Monitor, then Start Monitor when finished.\\n\\n## Output\\nReturn the maintenance window id, schedule (date/time/duration), and the monitors it covers. Confirm that alerts will be suppressed during the window."},{"name":"incident-triage-report","description":"Compile a report of recent incidents with their causes and durations for a postmortem or daily review. Use to summarize reliability.","content":"# Incident Triage Report\\n\\nSummarize recent incidents for review.\\n\\n## Steps\\n1. Use List Incidents over the desired time range (set Started After / Started Before).\\n2. For each incident, use Get Incident to pull the cause, reason, root-cause URL, and HTTP response code.\\n3. Group incidents by monitor and compute total downtime per service from the durations.\\n4. Highlight the longest and most frequent outages.\\n\\n## Output\\nReturn a structured report: per-monitor incident counts, total downtime, and the top incidents with cause and duration. Call out any still-active incidents at the top."}],"templates":[{"title":"UptimeRobot downtime alert to Slack","prompt":"Build a scheduled workflow that lists UptimeRobot incidents from the last hour, filters to ones that are still active, and posts a formatted Slack alert with the affected monitor name, cause, and how long it has been down.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"},{"id":"slack","name":"Slack"}]},{"title":"UptimeRobot monitors from a table","prompt":"Create a workflow that reads a list of service URLs from a table and creates an HTTP UptimeRobot monitor for each one with a 5-minute interval, then writes the new monitor IDs back to the table.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"UptimeRobot incident to Linear","prompt":"Build a scheduled workflow that polls UptimeRobot for active incidents, and for any new incident creates a Linear ticket with the monitor name, cause, and root-cause URL, then posts the ticket link to Slack.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"},{"id":"linear","name":"Linear"},{"id":"slack","name":"Slack"}]},{"title":"UptimeRobot maintenance window","prompt":"Create a workflow that, before a planned deploy, creates a one-time UptimeRobot maintenance window covering the affected monitors for the next 30 minutes so alerts are suppressed during the rollout.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"Daily UptimeRobot digest","prompt":"Build a scheduled daily workflow that lists all UptimeRobot monitors, summarizes how many are up versus down, lists any currently in a down state, and emails a morning availability digest to the on-call team.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"UptimeRobot status page","prompt":"Create a workflow that builds a public status page in UptimeRobot for a chosen set of monitors, uploads the company logo, and returns the public URL key so it can be shared.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"Pause UptimeRobot monitors","prompt":"Build a workflow that, when triggered, pauses a specific UptimeRobot monitor, waits for an upstream maintenance task to finish, then starts the monitor again and confirms it is back to a running state.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]},{"title":"Onboard UptimeRobot contacts","prompt":"Create a workflow that reads a list of team email addresses and adds each one as an UptimeRobot alert contact, then assigns them to the critical production monitors.","integrations":[{"id":"uptimerobot","name":"UptimeRobot"}]}]},{"id":"vanta","type":"vanta","slug":"vanta","name":"Vanta","description":"Query compliance status and manage evidence in Vanta","category":"Security","docsUrl":"https://docs.sim.ai/integrations/vanta","authType":"oauth","connections":[{"id":"vanta-service-account","kind":"service_account","providerId":"vanta-service-account","label":"Add application","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/vanta","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true},{"id":"scope","label":"Permissions","placeholder":"Select permissions","secret":false,"optional":true,"options":[{"value":"vanta-api.all:read","label":"Read only"},{"value":"vanta-api.all:read vanta-api.all:write","label":"Read and write"},{"value":"vanta-api.all:read vanta-api.all:write vanta-api.documents:upload","label":"Read, write, and upload documents"}]},{"id":"dataCenter","label":"Deployment","placeholder":"Select a deployment","secret":false,"optional":true,"options":[{"value":"us","label":"Standard (US, EU, Australia)"},{"value":"gov","label":"Vanta Government"}]}]}],"operations":[{"name":"List Frameworks","description":"List the compliance frameworks (e.g., SOC 2, ISO 27001) available in a Vanta account with completion counts"},{"name":"Get Framework","description":"Get a Vanta compliance framework by ID, including its requirement categories and mapped controls"},{"name":"List Framework Controls","description":"List the controls that belong to a specific Vanta compliance framework"},{"name":"List Controls","description":"List the security controls in a Vanta account, optionally filtered by framework"},{"name":"Get Control","description":"Get a Vanta security control by ID, including its status and evidence pass/fail counts"},{"name":"List Control Tests","description":"List the automated tests mapped to a specific Vanta control"},{"name":"List Control Documents","description":"List the evidence documents mapped to a specific Vanta control"},{"name":"List Tests","description":"List the automated compliance tests in a Vanta account, with filters for status, framework, integration, control, owner, and category"},{"name":"Get Test","description":"Get a Vanta automated compliance test by ID, including its status and remediation info"},{"name":"List Test Entities","description":"List the failing or deactivated resource entities for a specific Vanta test, useful for finding exactly which resources need remediation"},{"name":"List Documents","description":"List the evidence documents in a Vanta account, optionally filtered by framework or document status"},{"name":"Get Document","description":"Get a Vanta evidence document by ID, including its renewal schedule and deactivation status"},{"name":"List Document Uploads","description":"List the files uploaded to a specific Vanta evidence document"},{"name":"Upload Document File","description":"Upload an evidence file to a Vanta document. Requires credentials with the vanta-api.documents:upload scope."},{"name":"Download Document File","description":"Download a file previously uploaded to a Vanta evidence document and store it in execution files"},{"name":"Submit Document","description":"Submit a Vanta document collection for review so uploaded evidence becomes visible to auditors. Requires credentials with write access."},{"name":"List People","description":"List the people tracked in a Vanta account with employment status, group membership, and security task completion"},{"name":"Get Person","description":"Get a person tracked in Vanta by ID, including employment, leave, and security task status"},{"name":"List Policies","description":"List the security policies in a Vanta account with approval status and version info"},{"name":"Get Policy","description":"Get a Vanta security policy by ID, including its approval status and latest approved version documents"},{"name":"List Vendors","description":"List the vendors tracked in a Vanta account with risk levels, contract dates, and security review schedules"},{"name":"Get Vendor","description":"Get a Vanta vendor by ID, including risk levels, contract details, and authentication info"},{"name":"List Monitored Computers","description":"List the monitored computers in a Vanta account with screenlock, disk encryption, password manager, and antivirus check outcomes"},{"name":"List Vulnerabilities","description":"List the vulnerabilities detected across a Vanta account with filters for severity, fixability, SLA deadlines, package, and integration"},{"name":"List Vulnerability Remediations","description":"List remediated vulnerabilities in a Vanta account with detection, SLA deadline, and remediation dates"},{"name":"List Vulnerable Assets","description":"List the assets associated with vulnerabilities in a Vanta account (servers, repositories, workstations, and more)"},{"name":"Get Vulnerable Asset","description":"Get a vulnerable asset in Vanta by ID, including the scanners reporting it and per-scanner asset details"},{"name":"List Risk Scenarios","description":"List the risk scenarios in a Vanta risk register with likelihood/impact scores, treatment decisions, and review status"},{"name":"Get Risk Scenario","description":"Get a Vanta risk scenario by ID, including its scores, treatment decision, and review status"}],"triggers":[],"skills":[{"name":"triage-failing-vanta-tests","description":"Find failing Vanta tests, pull their failing entities, and produce a prioritized remediation list.","content":"# Triage Failing Vanta Tests\\n\\nTurn the current Vanta test status into an actionable remediation list.\\n\\n## Steps\\n1. Use List Tests with Test Status set to Needs Attention to find failing tests. Narrow with Framework ID or Integration ID if asked.\\n2. For each failing test, use List Test Entities with Entity Status set to Failing to get the exact resources that fail.\\n3. Read each test’s failure description and remediation description from the output to explain what is wrong and how to fix it.\\n4. Group results by test category and order by the number of failing entities.\\n\\n## Output\\nReturn a prioritized list: test name, why it fails, the failing resources, and the documented remediation steps."},{"name":"upload-vanta-evidence","description":"Attach an evidence file to a Vanta document and submit the collection for review.","content":"# Upload Evidence to Vanta\\n\\nAttach a file to the right evidence document and make it visible to auditors.\\n\\n## Steps\\n1. Use List Documents (filter by framework or status \\"Needs document\\" / \\"Needs update\\") to find the target document and note its ID.\\n2. Use Upload Document File with the document ID, the file, a clear Description (e.g., \\"Q3 access review evidence\\"), and optionally an Effective Date.\\n3. Use Submit Document with the same document ID so the evidence moves out of draft and becomes visible to auditors.\\n4. Confirm with Get Document that the upload status is now OK.\\n\\n## Output\\nReturn the uploaded file metadata and the document’s final status."},{"name":"vanta-compliance-snapshot","description":"Summarize framework, control, and test completion across a Vanta account.","content":"# Vanta Compliance Snapshot\\n\\nProduce a concise status report across all frameworks.\\n\\n## Steps\\n1. Use List Frameworks to get every framework with its control, document, and test completion counts.\\n2. For frameworks that are behind, use List Framework Controls and Get Control to find controls with failing or missing evidence.\\n3. Use List Tests with Test Status set to Needs Attention to count open issues per framework.\\n4. Compute completion percentages from the numeric outputs (numControlsCompleted / numControlsTotal, etc.).\\n\\n## Output\\nReturn a per-framework table: completion percentages, failing test count, and the controls that need attention."},{"name":"vanta-vulnerability-sla-report","description":"List Vanta vulnerabilities approaching their SLA deadlines with affected assets.","content":"# Vulnerabilities Approaching SLA\\n\\nFind what must be remediated soon and where.\\n\\n## Steps\\n1. Use List Vulnerabilities with SLA Deadline Before set to the cutoff date (e.g., 7 days from now) and SLA Deadline After set to today.\\n2. Narrow with Severity (CRITICAL or HIGH first) and Fix Available set to Yes for quick wins.\\n3. Use List Vulnerable Assets to find the affected server, repository, or workstation. Use Get Vulnerable Asset only with an asset ID returned by that list; a vulnerability targetId identifies an underlying resource and is not an asset ID.\\n4. Use List Vulnerability Remediations with Remediated On Time set to No to report recent SLA misses.\\n\\n## Output\\nReturn vulnerabilities grouped by severity with remediate-by dates, fixed versions when available, and the affected assets."},{"name":"vanta-people-task-audit","description":"Find people with overdue security tasks in Vanta and report their task summary status and due date.","content":"# Audit Outstanding Security Tasks\\n\\nIdentify who is blocking compliance and why.\\n\\n## Steps\\n1. Use List People with Task Summary Statuses set to OVERDUE,DUE_SOON and Employment Status set to Current.\\n2. Read each person’s tasksSummary output for the due date, and use Task Types to narrow to a specific obligation (e.g., COMPLETE_TRAININGS or ACCEPT_POLICIES) when asked.\\n3. Use Get Person for any individual to confirm employment, group membership, and leave status before escalating.\\n\\n## Output\\nReturn each person’s name, email, task summary status, and due date, ordered by how overdue they are. The output does not include individual task details."}],"templates":[{"title":"Vanta failing test alerts","prompt":"Create a scheduled workflow that lists Vanta tests with status NEEDS_ATTENTION each morning, fetches the failing entities for each test, and posts a remediation digest to a Slack channel.","integrations":[{"id":"vanta","name":"Vanta"},{"id":"slack","name":"Slack"}]},{"title":"Vanta evidence uploader","prompt":"Build a workflow that takes a generated report file, uploads it as evidence to the matching Vanta document with a description and effective date, and then submits the document collection for review.","integrations":[{"id":"vanta","name":"Vanta"}]},{"title":"Vanta vulnerability SLA watcher","prompt":"Create a scheduled workflow that lists Vanta vulnerabilities with SLA deadlines in the next 7 days, groups them by severity and vulnerable asset, and emails the security team a prioritized remediation list.","integrations":[{"id":"vanta","name":"Vanta"},{"id":"gmail","name":"Gmail"}]},{"title":"Vanta compliance status report","prompt":"Build a scheduled workflow that lists Vanta frameworks with their control and test completion counts, has an agent summarize progress and gaps per framework, and writes a weekly compliance report to a table.","integrations":[{"id":"vanta","name":"Vanta"}]},{"title":"Vanta onboarding task chaser","prompt":"Create a scheduled workflow that lists current Vanta people with overdue security tasks and sends each person a direct Slack reminder with their task summary status and due date, asking them to review outstanding tasks in Vanta.","integrations":[{"id":"vanta","name":"Vanta"},{"id":"slack","name":"Slack"}]},{"title":"Vanta vendor review pipeline","prompt":"Build a scheduled workflow that lists Vanta vendors whose next security review is due within 30 days, looks up each vendor’s risk levels and contract dates, and creates a review task in the team’s project tracker.","integrations":[{"id":"vanta","name":"Vanta"},{"id":"linear","name":"Linear"}]},{"title":"Vanta compliance Q&A agent","prompt":"Create an agent that answers compliance questions by querying Vanta: it can look up framework progress, control status, failing tests and their entities, policy approval status, and risk scenarios, and grounds every answer in the returned data.","integrations":[{"id":"vanta","name":"Vanta"}]}]},{"id":"vercel","type":"vercel","slug":"vercel","name":"Vercel","description":"Manage Vercel deployments, projects, and infrastructure","category":"DevOps","docsUrl":"https://docs.sim.ai/integrations/vercel","authType":"api-key","connections":[],"operations":[{"name":"List Deployments","description":"List deployments for a Vercel project or team"},{"name":"Get Deployment","description":"Get details of a specific Vercel deployment"},{"name":"Create Deployment","description":"Create a new deployment or redeploy an existing one"},{"name":"Cancel Deployment","description":"Cancel a running Vercel deployment"},{"name":"Delete Deployment","description":"Delete a Vercel deployment"},{"name":"Get Deployment Logs","description":"Get build and runtime events for a Vercel deployment"},{"name":"List Deployment Files","description":"List files in a Vercel deployment"},{"name":"Promote Deployment","description":"Promote a deployment by pointing the production deployment to the given deployment"},{"name":"List Projects","description":"List all projects in a Vercel team or account"},{"name":"Get Project","description":"Get details of a specific Vercel project"},{"name":"Create Project","description":"Create a new Vercel project"},{"name":"Update Project","description":"Update an existing Vercel project"},{"name":"Delete Project","description":"Delete a Vercel project"},{"name":"Pause Project","description":"Pause a Vercel project"},{"name":"Unpause Project","description":"Unpause a Vercel project"},{"name":"List Project Domains","description":"List all domains for a Vercel project"},{"name":"Add Project Domain","description":"Add a domain to a Vercel project"},{"name":"Update Project Domain","description":"Update a project domain\'s configuration on Vercel"},{"name":"Verify Project Domain","description":"Verify a Vercel project domain by checking its verification challenge"},{"name":"Remove Project Domain","description":"Remove a domain from a Vercel project"},{"name":"Get Environment Variables","description":"Retrieve environment variables for a Vercel project"},{"name":"Create Environment Variable","description":"Create an environment variable for a Vercel project"},{"name":"Update Environment Variable","description":"Update an environment variable for a Vercel project"},{"name":"Delete Environment Variable","description":"Delete an environment variable from a Vercel project"},{"name":"List Domains","description":"List all domains in a Vercel account or team"},{"name":"Get Domain","description":"Get information about a specific domain in a Vercel account"},{"name":"Add Domain","description":"Add a new domain to a Vercel account or team"},{"name":"Delete Domain","description":"Delete a domain from a Vercel account or team"},{"name":"Get Domain Config","description":"Get the configuration for a domain in a Vercel account"},{"name":"List DNS Records","description":"List all DNS records for a domain in a Vercel account"},{"name":"Create DNS Record","description":"Create a DNS record for a domain in a Vercel account"},{"name":"Update DNS Record","description":"Update an existing DNS record for a domain in a Vercel account"},{"name":"Delete DNS Record","description":"Delete a DNS record for a domain in a Vercel account"},{"name":"List Aliases","description":"List aliases for a Vercel project or team"},{"name":"Get Alias","description":"Get details about a specific alias by ID or hostname"},{"name":"Create Alias","description":"Assign an alias (domain/subdomain) to a deployment"},{"name":"Delete Alias","description":"Delete an alias by its ID"},{"name":"List Edge Configs","description":"List all Edge Config stores for a team"},{"name":"Get Edge Config","description":"Get details about a specific Edge Config store"},{"name":"Create Edge Config","description":"Create a new Edge Config store"},{"name":"Get Edge Config Items","description":"Get all items in an Edge Config store"},{"name":"Update Edge Config Items","description":"Create, update, upsert, or delete items in an Edge Config store"},{"name":"Delete Edge Config","description":"Delete an Edge Config store by ID"},{"name":"List Webhooks","description":"List webhooks for a Vercel project or team"},{"name":"Get Webhook","description":"Get details about a specific Vercel webhook"},{"name":"Create Webhook","description":"Create a new webhook for a Vercel team"},{"name":"Delete Webhook","description":"Delete a webhook from a Vercel team"},{"name":"List Checks","description":"List all checks for a deployment"},{"name":"Get Check","description":"Get details of a specific deployment check"},{"name":"Create Check","description":"Create a new deployment check"},{"name":"Update Check","description":"Update an existing deployment check"},{"name":"Rerequest Check","description":"Rerequest a deployment check"},{"name":"List Teams","description":"List all teams in a Vercel account"},{"name":"Get Team","description":"Get information about a specific Vercel team"},{"name":"List Team Members","description":"List all members of a Vercel team"},{"name":"Get User","description":"Get information about the authenticated Vercel user"}],"triggers":[{"id":"vercel_deployment_created","name":"Vercel Deployment Created","description":"Trigger workflow when a new deployment is created"},{"id":"vercel_deployment_ready","name":"Vercel Deployment Ready","description":"Trigger workflow when a deployment is ready to serve traffic"},{"id":"vercel_deployment_error","name":"Vercel Deployment Error","description":"Trigger workflow when a deployment fails"},{"id":"vercel_deployment_canceled","name":"Vercel Deployment Canceled","description":"Trigger workflow when a deployment is canceled"},{"id":"vercel_project_created","name":"Vercel Project Created","description":"Trigger workflow when a new project is created"},{"id":"vercel_project_removed","name":"Vercel Project Removed","description":"Trigger workflow when a project is removed"},{"id":"vercel_domain_created","name":"Vercel Domain Created","description":"Trigger workflow when a domain is created"},{"id":"vercel_webhook","name":"Vercel Webhook (Common Events)","description":"Trigger on a curated set of common Vercel events (deployments, projects, domains, edge config). Pick a specific trigger to listen to one event type only."}],"skills":[{"name":"monitor-deployments","description":"List recent Vercel deployments, surface failed builds, and pull their logs.","content":"# Monitor Vercel Deployments\\n\\nKeep an eye on builds so failures are caught fast.\\n\\n## Steps\\n1. Use the List Deployments operation with your access token, optionally filtering by Project ID, Target (production), and State (ERROR).\\n2. For any failed or stuck deployment, use Get Deployment Logs with the Deployment ID to pull the build events.\\n3. Summarize the failure cause from the log events.\\n4. Use Get Deployment for full detail including the deployment URL and state.\\n\\n## Output\\nReturn the list of deployments with their state, plus a short summary of any failed build and a link to investigate."},{"name":"rollback-deployment","description":"Promote the last known good Vercel deployment to instantly roll back a bad release.","content":"# Roll Back a Vercel Deployment\\n\\nRecover production by instantly promoting a previous good deployment back to production.\\n\\n## Steps\\n1. Use List Deployments filtered to the project, Target production, and State READY to find the last good deployment.\\n2. Use the Promote Deployment operation with the Project ID and that good deployment ID to restore it to production instantly, with no rebuild.\\n3. Optionally use Cancel Deployment on the broken build that is still running.\\n\\n## Output\\nReturn the promoted deployment ID and confirmation so the rollback can be announced."},{"name":"manage-env-vars","description":"Read, create, or update environment variables on a Vercel project.","content":"# Manage Vercel Environment Variables\\n\\nKeep a project configuration correct across environments.\\n\\n## Steps\\n1. Use Get Environment Variables with the Project ID to read the current variables.\\n2. To add one, use Create Environment Variable with the Key, Value, Target Environments (for example production,preview), and Variable Type.\\n3. To change one, use Update Environment Variable with the Env Variable ID and the new value.\\n4. Use Delete Environment Variable with the Env Variable ID to remove a stale key.\\n\\n## Output\\nReturn the resulting variable list or confirmation of the create, update, or delete so configuration changes are auditable."},{"name":"audit-domains-and-dns","description":"Inventory Vercel domains and DNS records and manage records for a domain.","content":"# Audit Vercel Domains and DNS\\n\\nTrack domains and DNS so changes never go unnoticed.\\n\\n## Steps\\n1. Use List Domains for the account inventory, and List DNS Records with a Domain to see its records.\\n2. To add a record, use Create DNS Record with the Domain, Record Name, Record Type (A, CNAME, TXT, etc.), and Value.\\n3. To remove one, use Delete DNS Record with the Domain and Record ID.\\n4. Use Get Domain Config to verify a domain is correctly configured.\\n\\n## Output\\nReturn the domain and DNS record inventory, or confirmation of any record change, for the tracking log."}],"templates":[{"title":"Cloudflare cache purge on deploy","prompt":"Build a workflow that fires when a Vercel deployment succeeds on production, purges the Cloudflare cache for the affected hostnames, verifies the new content is being served, and posts a confirmation message to Slack with the purged paths.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"cloudflare","name":"Cloudflare"},{"id":"slack","name":"Slack"}]},{"title":"PageSpeed pre-deploy gate","prompt":"Build a workflow triggered by a Vercel preview deployment that runs Google PageSpeed Insights against the preview URL, posts the scores as a GitHub PR comment, and fails the check if scores drop below threshold.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"google_pagespeed","name":"Google PageSpeed"},{"id":"github","name":"GitHub"}]},{"title":"Sentry release health gate","prompt":"Create a workflow that runs after a Vercel deploy, checks Sentry release health, and rolls back the deploy if the error rate exceeds the threshold, posting an alert to Slack.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"sentry","name":"Sentry"},{"id":"slack","name":"Slack"}]},{"title":"Upstash + Vercel cache invalidator","prompt":"Create a workflow triggered by a Vercel production deploy that flushes targeted Upstash cache keys for changed routes, so users never see stale responses post-deploy.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"upstash","name":"Upstash"}]},{"title":"Vercel deployment monitor","prompt":"Build a scheduled workflow that polls Vercel for the latest deployments across my projects every five minutes, detects failed or stuck builds, fetches the build logs, summarizes the failure cause, and posts an actionable alert to Slack with a deep link to the deployment.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]},{"title":"Vercel preview deploy reviewer","prompt":"Build a workflow that watches GitHub pull requests, finds the matching Vercel preview deployment, captures the preview URL, runs a smoke check against critical pages, and posts a status comment on the pull request with the preview link and any issues found.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"github","name":"GitHub"}]},{"title":"Vercel env variable auditor","prompt":"Create a scheduled weekly workflow that pulls environment variables from every Vercel project, compares them to a reference list in a table, flags drift, missing keys, and stale values, and emails a remediation report to the platform team.","integrations":[{"id":"vercel","name":"Vercel"}]},{"title":"Vercel domain and DNS inventory","prompt":"Build a scheduled workflow that lists every domain and DNS record across my Vercel account weekly, logs them into a tracking table, and sends a Slack diff of any added, removed, or modified records so DNS changes never go unnoticed.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]},{"title":"Vercel project pause guard","prompt":"Build a scheduled workflow that scans Vercel projects daily for low-traffic or stale candidates flagged in a table, pauses projects that meet the criteria, and Slacks a digest of paused and unpaused projects to the platform team for review.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]},{"title":"Vercel deploy log triage","prompt":"Create a workflow that fires after each Vercel deployment, fetches the build and runtime logs, classifies warnings and errors with an agent, groups recurring issues, and opens a Linear ticket per cluster so platform regressions get addressed early.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"linear","name":"Linear"}]},{"title":"Vercel failed deploy recovery","prompt":"Build a workflow that watches Vercel for failed production deployments, identifies the last known good production deployment, promotes it back to production for an instant rollback, and posts a Slack incident summary with the failure cause and rollback confirmation.","integrations":[{"id":"vercel","name":"Vercel"},{"id":"slack","name":"Slack"}]}]},{"id":"wealthbox","type":"wealthbox","slug":"wealthbox","name":"Wealthbox","description":"Interact with Wealthbox","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/wealthbox","authType":"oauth","connections":[{"id":"wealthbox","kind":"oauth","label":"Connect with OAuth","providerId":"wealthbox","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/wealthbox","requiredScopes":[{"id":"login","label":"Access Wealthbox account"},{"id":"data","label":"Access Wealthbox data"}],"fields":[]},{"id":"wealthbox-service-account","kind":"service_account","providerId":"wealthbox-service-account","label":"Add access token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/wealthbox-service-account","fields":[{"id":"apiToken","label":"API access token","placeholder":"Paste API access token","secret":true}]}],"operations":[{"name":"Read Note","description":"Read content from a Wealthbox note"},{"name":"Write Note","description":"Create or update a Wealthbox note"},{"name":"Read Contact","description":"Read content from a Wealthbox contact"},{"name":"Write Contact","description":"Create a new Wealthbox contact"},{"name":"Read Task","description":"Read content from a Wealthbox task"},{"name":"Write Task","description":"Create or update a Wealthbox task"}],"triggers":[],"skills":[{"name":"log-client-note","description":"Write a note to a Wealthbox contact record to capture meeting or call details.","content":"# Log a Wealthbox Client Note\\n\\nRecord a note on a client record so the interaction history stays complete.\\n\\n## Steps\\n1. Use the Write Note operation and select your Wealthbox account.\\n2. Select the Contact the note belongs to (or enter the Contact ID in advanced mode).\\n3. Write the note Content, summarizing the meeting, call, or decision.\\n\\n## Output\\nReturn the created note with its ID and linked contact so the entry can be referenced later."},{"name":"create-followup-task","description":"Create a follow-up task on a Wealthbox contact with a title and due date.","content":"# Create a Wealthbox Follow-up Task\\n\\nAdd a task to a client record so an advisor follow-up is not missed.\\n\\n## Steps\\n1. Use the Write Task operation and select your Wealthbox account.\\n2. Select the Contact the task is for.\\n3. Set the Title, the Content describing the work, and a Due Date (natural language like \\"tomorrow at 2pm\\" works).\\n\\n## Output\\nReturn the created task with its ID and due date so it can be tracked to completion."},{"name":"upsert-contact","description":"Create or read a Wealthbox contact with name, email, and background information.","content":"# Manage a Wealthbox Contact\\n\\nAdd a new client or pull an existing client record.\\n\\n## Steps\\n1. To add a client, use the Write Contact operation with First Name, Last Name, and optionally Email Address and Background Information.\\n2. To read a client, use the Read Contact operation and select the Contact or enter its Contact ID.\\n3. Select your Wealthbox account for either operation.\\n\\n## Output\\nReturn the contact record including name, email, and background info so downstream steps can use it."},{"name":"prepare-client-brief","description":"Read a Wealthbox contact plus their recent notes and tasks to build a meeting brief.","content":"# Prepare a Wealthbox Client Brief\\n\\nGather everything about a client ahead of a meeting.\\n\\n## Steps\\n1. Use Read Contact with the Contact ID to pull the client profile and background.\\n2. Use Read Note to retrieve recent notes for the contact.\\n3. Use Read Task to pull open and recent tasks tied to the client.\\n4. Have an agent synthesize the records into a concise prep brief.\\n\\n## Output\\nReturn a brief covering the client profile, recent notes, and outstanding tasks, ready to email to the advisor."}],"templates":[{"title":"Wealthbox CRM mirror","prompt":"Build a scheduled workflow that reads the Wealthbox contacts and tasks listed by ID in a Sim table, refreshes each row with the latest details, and keeps the table in sync for unified reporting.","integrations":[{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Wealthbox client review prep","prompt":"Create a workflow that runs the morning of each Wealthbox client meeting, gathers recent emails, notes, and tasks for that client, and emails the advisor a prep brief.","integrations":[{"id":"wealthbox","name":"Wealthbox"},{"id":"gmail","name":"Gmail"}]},{"title":"Wealthbox task auto-creator","prompt":"Build a workflow that listens for Gmail messages tagged \\"client action\\", classifies the action, and creates a matching task on the Wealthbox client record.","integrations":[{"id":"wealthbox","name":"Wealthbox"},{"id":"gmail","name":"Gmail"}]},{"title":"Wealthbox compliance audit","prompt":"Create a scheduled workflow that reads each Wealthbox contact listed in a tracking table monthly, checks for missing KYC fields or stale notes, and writes a compliance backlog to a table.","integrations":[{"id":"wealthbox","name":"Wealthbox"}]},{"title":"Wealthbox birthday reminder","prompt":"Build a scheduled workflow that runs daily, reads the Wealthbox contacts tracked in a table to find birthdays in the next 7 days, and emails advisors a reminder with a personalized message draft.","integrations":[{"id":"wealthbox","name":"Wealthbox"},{"id":"gmail","name":"Gmail"}]},{"title":"Wealthbox book-of-business digest","prompt":"Create a scheduled weekly workflow that reads the contacts and open tasks for each advisor from a tracking table, summarizes the book-of-business activity, and posts the digest to leadership in Slack.","integrations":[{"id":"wealthbox","name":"Wealthbox"},{"id":"slack","name":"Slack"}]},{"title":"Wealthbox referral tracker","prompt":"Build a scheduled workflow that polls Wealthbox notes for new referrals, captures the source and prospect, writes the referral chain into a CRM table, and pings the advisor in Slack.","integrations":[{"id":"wealthbox","name":"Wealthbox"},{"id":"slack","name":"Slack"}]}]},{"id":"webflow","type":"webflow","slug":"webflow","name":"Webflow","description":"Manage Webflow CMS collections","category":"Marketing","docsUrl":"https://docs.sim.ai/integrations/webflow","authType":"oauth","connections":[{"id":"webflow","kind":"oauth","label":"Connect with OAuth","providerId":"webflow","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/webflow","requiredScopes":[{"id":"cms:read","label":"View CMS content"},{"id":"cms:write","label":"Manage CMS content"},{"id":"sites:read","label":"View Webflow sites"},{"id":"sites:write","label":"Manage webhooks and site settings"},{"id":"forms:read","label":"View form submissions"}],"fields":[]},{"id":"webflow-service-account","kind":"service_account","providerId":"webflow-service-account","label":"Add site token","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/webflow-service-account","fields":[{"id":"apiToken","label":"Site API token","placeholder":"Paste site API token","secret":true}]}],"operations":[{"name":"List Items","description":"List items from a Webflow CMS collection"},{"name":"Get Item","description":"Get a single item from a Webflow CMS collection"},{"name":"Create Item","description":"Create a new item in a Webflow CMS collection"},{"name":"Update Item","description":"Update an existing item in a Webflow CMS collection"},{"name":"Delete Item","description":"Delete an item from a Webflow CMS collection"}],"triggers":[{"id":"webflow_collection_item_created","name":"Collection Item Created","description":"Trigger workflow when a new item is created in a Webflow CMS collection (requires Webflow credentials)"},{"id":"webflow_collection_item_changed","name":"Collection Item Changed","description":"Trigger workflow when an item is updated in a Webflow CMS collection (requires Webflow credentials)"},{"id":"webflow_collection_item_deleted","name":"Collection Item Deleted","description":"Trigger workflow when an item is deleted from a Webflow CMS collection (requires Webflow credentials)"},{"id":"webflow_form_submission","name":"Form Submission","description":"Trigger workflow when a form is submitted on a Webflow site (requires Webflow credentials)"}],"skills":[{"name":"publish-cms-item","description":"Create a new item in a Webflow CMS collection from supplied or generated field data.","content":"# Publish a Webflow CMS Item\\n\\nTurn structured content into a live Webflow CMS collection item.\\n\\n## Steps\\n1. Identify the target site and collection. If unknown, list collections to confirm the collection ID and its field schema.\\n2. Map the incoming content to the collection fields, including required fields like name and slug. Generate a URL-safe slug if one is not provided.\\n3. Call the create-item operation with the assembled fieldData JSON.\\n4. Confirm the new item ID and slug returned by the API.\\n\\n## Output\\nReport the created item ID, slug, and the live or staged URL. If a required field was missing, name it explicitly rather than guessing a value."},{"name":"update-cms-item","description":"Find a Webflow CMS item and update specific fields without disturbing the rest.","content":"# Update a Webflow CMS Item\\n\\nApply targeted edits to an existing collection item.\\n\\n## Steps\\n1. Resolve the item by ID, or list items in the collection and match on slug or name.\\n2. Get the current item so existing field values are known.\\n3. Build fieldData containing only the fields that change, merged onto the current values so untouched fields are preserved.\\n4. Call the update-item operation and confirm the change took effect.\\n\\n## Output\\nList exactly which fields changed and their new values. Note the item ID and whether the change is live or staged."},{"name":"audit-collection-content","description":"List items in a Webflow collection and flag missing or stale fields for cleanup.","content":"# Audit a Webflow Collection\\n\\nReview a CMS collection for content-quality gaps.\\n\\n## Steps\\n1. List all items in the target collection, paging through with offset and limit until complete.\\n2. For each item, check for empty required fields such as meta description, image, or publish date.\\n3. Flag items that are missing key SEO or display fields, or whose dates look stale.\\n4. Summarize the findings as a remediation backlog.\\n\\n## Output\\nReturn a table of flagged items with item ID, slug, and the specific gap found. End with a short prioritized list of what to fix first."}],"templates":[{"title":"Webflow lead capture pipeline","prompt":"Create a workflow that monitors new Webflow form submissions, enriches each lead with company and contact data using Apollo and web search, adds them to a tracking table with a lead score, and sends a Slack notification to the sales team for high-potential leads.","integrations":[{"id":"webflow","name":"Webflow"},{"id":"apollo","name":"Apollo"},{"id":"slack","name":"Slack"}]},{"title":"Webflow CMS publisher","prompt":"Create a workflow that reads a draft articles table, generates an SEO-optimized post, publishes it as a Webflow CMS item, and writes the live URL back to the row.","integrations":[{"id":"webflow","name":"Webflow"}]},{"title":"Webflow form-to-CRM","prompt":"Build a workflow that watches Webflow form submissions, enriches each with Apollo company data, and pushes qualifying leads into HubSpot with the right owner and source.","integrations":[{"id":"webflow","name":"Webflow"},{"id":"apollo","name":"Apollo"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Webflow content auditor","prompt":"Create a scheduled monthly workflow that audits Webflow CMS items for missing meta descriptions, broken links, or stale dates, and writes a remediation backlog.","integrations":[{"id":"webflow","name":"Webflow"}]},{"title":"Webflow CMS backup","prompt":"Build a scheduled workflow that exports every item from a Webflow CMS collection to S3 nightly with versioning, and writes the backup manifest to a tracking table.","integrations":[{"id":"webflow","name":"Webflow"},{"id":"s3","name":"S3"}]},{"title":"Webflow product catalog sync","prompt":"Create a scheduled workflow that mirrors Shopify products and pricing into a Webflow CMS product collection, keeps both in sync, and posts conflict alerts to Slack.","integrations":[{"id":"webflow","name":"Webflow"},{"id":"shopify","name":"Shopify"},{"id":"slack","name":"Slack"}]},{"title":"Webflow + Hubspot lead-magnet","prompt":"Build a workflow that triggers on a Webflow form submission for a lead magnet, sends the asset via Loops, and writes the engagement to the matching HubSpot contact.","integrations":[{"id":"webflow","name":"Webflow"},{"id":"loops","name":"Loops"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"whatsapp","type":"whatsapp","slug":"whatsapp","name":"WhatsApp","description":"Send WhatsApp messages","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/whatsapp","authType":"api-key","connections":[],"operations":[{"name":"Send Message","description":"Send a free-form text message through the WhatsApp Cloud API. Only works inside the 24-hour customer service window — use Send Template to start a conversation."},{"name":"Send Template","description":"Send a pre-approved WhatsApp template message. Required to start a conversation or to message a user outside the 24-hour customer service window."},{"name":"Send Media","description":"Send an image, document, video, audio, or sticker message. Accepts an uploaded file, a media ID, or a public link."},{"name":"Send Interactive","description":"Send an interactive WhatsApp message with reply buttons or a selectable list."},{"name":"Send Reaction","description":"React to a WhatsApp message with an emoji. Send an empty emoji to remove an existing reaction."},{"name":"Mark As Read","description":"Mark a received WhatsApp message as read so the sender sees blue checkmarks, optionally showing a typing indicator."},{"name":"Upload Media","description":"Upload a file to WhatsApp and get a media ID for sending. Uploaded media is retained for 30 days and can back many sends."},{"name":"Download Media","description":"Download media a customer sent you. Takes the media ID from an incoming WhatsApp message and stores the file in the workflow."}],"triggers":[{"id":"whatsapp_webhook","name":"WhatsApp Webhook","description":"Trigger workflow from WhatsApp incoming messages and message status webhooks"}],"skills":[{"name":"send-appointment-reminder","description":"Send a WhatsApp template message reminding a contact of an upcoming appointment or booking.","content":"# Send a WhatsApp Appointment Reminder\\n\\nNotify a contact about an upcoming appointment over WhatsApp.\\n\\nA reminder is business-initiated, so it almost always falls outside the 24-hour customer service window. Use the Send Template operation with a pre-approved template — a free-form text message will be rejected unless the contact messaged you within the last 24 hours.\\n\\n## Steps\\n1. Gather the recipient phone number with the plus sign and country calling code (e.g. +14155552671).\\n2. Pick the approved appointment-reminder template and its language code (e.g. en_US).\\n3. Fill the template components positionally — the parameters map to {{1}}, {{2}}, ... in the order the template declares them (date, time, location or link).\\n4. Send with Send Template and capture the returned message ID.\\n\\n## Output\\nConfirm the recipient, the template used, and the message ID. If the send was rejected, report the WhatsApp error code and message rather than retrying blindly — a template rejection usually means the template name, language, or parameter count is wrong."},{"name":"send-order-update","description":"Notify a customer over WhatsApp about an order status change such as shipment or delivery.","content":"# Send a WhatsApp Order Update\\n\\nKeep a customer informed about their order via WhatsApp.\\n\\n## Steps\\n1. Collect the customer phone number with the plus sign and country calling code, plus the order details (number, status, tracking, ETA).\\n2. Choose the operation by conversation state: if the customer messaged you within the last 24 hours, Send Message works; otherwise use Send Template with an approved shipping-update template.\\n3. State what changed and include the tracking link if available.\\n4. Send and record the message ID.\\n\\n## Output\\nReport which customer was notified, the order referenced, and the message ID. Flag any number that could not be reached, including the WhatsApp error code."},{"name":"broadcast-to-segment","description":"Send a personalized WhatsApp template message to each contact in an audience list, one at a time.","content":"# Broadcast a WhatsApp Message to a Segment\\n\\nDeliver a personalized message to every contact in a list.\\n\\nBroadcasts are business-initiated, so every send must use the Send Template operation with a pre-approved marketing or utility template. Free-form text will fail for any contact who has not messaged you in the last 24 hours.\\n\\n## Steps\\n1. Read the audience list, each row holding a phone number and any personalization fields.\\n2. For each contact, build the template components by filling the positional parameters with that row\'s values.\\n3. Send one template message per contact, pacing them to stay within the account throughput limit.\\n4. Track which sends succeeded and which failed.\\n\\n## Output\\nReturn counts of messages sent and failed, plus a short list of failed recipients with the WhatsApp error code for each."},{"name":"send-interactive-menu","description":"Ask a WhatsApp contact to choose from reply buttons or a selectable list, then act on the reply.","content":"# Send a WhatsApp Interactive Menu\\n\\nOffer a contact a set of tappable choices instead of asking them to type a reply.\\n\\n## Steps\\n1. Decide the variant: reply buttons for up to 3 short choices, a list for up to 10 options grouped into sections.\\n2. Write the body text and give every choice a stable id — the webhook reports that id back when the contact taps it, so it is what your workflow branches on.\\n3. Respect the limits: button titles 20 characters, list row titles 24, row descriptions 72, list menu button 20.\\n4. Send with Send Interactive and record the message ID.\\n5. Handle the reply in a workflow triggered by the WhatsApp webhook, matching on the returned id.\\n\\n## Output\\nConfirm the choices offered and the message ID. When a reply arrives, report which option the contact selected."},{"name":"acknowledge-incoming-message","description":"Mark an incoming WhatsApp message as read, show a typing indicator, and react to it.","content":"# Acknowledge an Incoming WhatsApp Message\\n\\nGive a contact immediate feedback that their message landed while a longer reply is being prepared.\\n\\n## Steps\\n1. Take the message ID (wamid) from the WhatsApp webhook trigger payload.\\n2. Call Mark As Read with that message ID so the sender sees blue checkmarks. Enable the typing indicator when a reply is coming — it clears once you respond or after 25 seconds.\\n3. Optionally use Send Reaction with an emoji to acknowledge the message inline. Reactions are not delivered for messages over 30 days old, deleted messages, or other reactions.\\n4. Send the substantive reply with Send Message — the incoming message opened the 24-hour window, so free-form text is allowed here.\\n\\n## Output\\nConfirm the message was marked read and report the reply that was sent."}],"templates":[{"title":"Telegram + WhatsApp dual-channel notifier","prompt":"Build a workflow that sends critical operational alerts via both Telegram and WhatsApp based on user preference per recipient, and writes delivery status to a table.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"telegram","name":"Telegram"}]},{"title":"WhatsApp appointment confirmations","prompt":"Build a workflow that reads upcoming Google Calendar appointments each morning and sends a WhatsApp confirmation with date, time, and a one-tap reschedule link.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"WhatsApp order tracking","prompt":"Create a workflow that watches Shopify shipment events and sends customers a WhatsApp message with the tracking number, ETA, and a follow-up review request after delivery.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"shopify","name":"Shopify"}]},{"title":"WhatsApp customer support agent","prompt":"Build a WhatsApp business agent that answers customer questions using a knowledge base, hands off to a human in Zendesk on complex tickets, and writes the conversation back to the contact record.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"zendesk","name":"Zendesk"}]},{"title":"WhatsApp lead qualifier","prompt":"Create a workflow that engages new leads via WhatsApp with a guided qualification script, scores them based on responses, and pushes qualified leads into Salesforce with the conversation log attached.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"salesforce","name":"Salesforce"}]},{"title":"WhatsApp campaign sender","prompt":"Build a workflow that reads a segmented audience from a table and sends a personalized WhatsApp template message to each, throttling to stay under provider limits.","integrations":[{"id":"whatsapp","name":"WhatsApp"}]},{"title":"WhatsApp event RSVP collector","prompt":"Create a workflow that messages contacts about an upcoming event on WhatsApp, parses yes/no/maybe replies, and updates the RSVP table with the attendee count and dietary notes.","integrations":[{"id":"whatsapp","name":"WhatsApp"}]},{"title":"WhatsApp + Zoom meeting confirmer","prompt":"Build a workflow that sends a WhatsApp confirmation when a Zoom meeting is booked, with the join link and a one-tap reschedule option for the attendee.","integrations":[{"id":"whatsapp","name":"WhatsApp"},{"id":"zoom","name":"Zoom"}]}]},{"id":"wikipedia","type":"wikipedia","slug":"wikipedia","name":"Wikipedia","description":"Search and retrieve content from Wikipedia","category":"Search","docsUrl":"https://docs.sim.ai/integrations/wikipedia","authType":"none","connections":[],"operations":[{"name":"Get Page Summary","description":"Get a summary and metadata for a specific Wikipedia page."},{"name":"Search Pages","description":"Search for Wikipedia pages by title or content."},{"name":"Get Page Content","description":"Get the full HTML content of a Wikipedia page."},{"name":"Random Page","description":"Get a random Wikipedia page."}],"triggers":[],"skills":[{"name":"research-topic-brief","description":"Search Wikipedia for a topic and assemble a concise, sourced background brief.","content":"# Build a Wikipedia Topic Brief\\n\\nProduce a quick, reliable background brief on a subject.\\n\\n## Steps\\n1. Search pages for the topic to find the best-matching article title.\\n2. Get the page summary for a fast overview, then get full page content if more depth is needed.\\n3. Extract the key facts, dates, and definitions, ignoring tangential detail.\\n4. Assemble a short brief in your own words.\\n\\n## Output\\nReturn a brief with a one-line definition, three to five key points, and the Wikipedia page title used as the source."},{"name":"disambiguate-entity","description":"Resolve an ambiguous name to the correct Wikipedia entity using surrounding context.","content":"# Disambiguate an Entity via Wikipedia\\n\\nPick the right Wikipedia entity for an ambiguous name.\\n\\n## Steps\\n1. Search pages for the name to retrieve candidate matches.\\n2. For the top candidates, get the page summary.\\n3. Compare each summary against the context provided (industry, location, role) and choose the best fit.\\n4. If nothing matches confidently, say so rather than forcing a choice.\\n\\n## Output\\nReturn the chosen canonical page title with a one-line justification, plus a confidence note and any close alternatives."},{"name":"verify-claim","description":"Check whether a stated claim is supported by Wikipedia content and flag unsupported claims.","content":"# Verify a Claim Against Wikipedia\\n\\nFact-check a claim using Wikipedia as a reference source.\\n\\n## Steps\\n1. Identify the entity or topic the claim is about and search for its page.\\n2. Get the page summary or content covering the relevant section.\\n3. Compare the claim against the article text and decide if it is supported, contradicted, or not addressed.\\n\\n## Output\\nReturn a verdict of supported, contradicted, or unverified, with the supporting sentence quoted and the page title cited. Do not treat absence of mention as proof either way."}],"templates":[{"title":"Wikipedia background-research helper","prompt":"Build a workflow that for a chosen topic queries Wikipedia, extracts the lead and infobox, and writes a structured background brief file for the user.","integrations":[{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wikipedia entity disambiguator","prompt":"Create a workflow that for an ambiguous person or company name queries Wikipedia, identifies the most likely entity given context, and writes the canonical reference back.","integrations":[{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wikipedia knowledge-base seeder","prompt":"Build a workflow that for tracked topics fetches Wikipedia articles, chunks and embeds them, and seeds a knowledge base with canonical context.","integrations":[{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wikipedia citation validator","prompt":"Create a workflow that checks if claims drafted by an agent are supported by Wikipedia content, flags claims without strong sources, and writes a quality score.","integrations":[{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wikipedia infobox extractor","prompt":"Build a workflow that takes a list of entity names, extracts the Wikipedia infobox fields for each, and writes structured rows for downstream analytics.","integrations":[{"id":"wikipedia","name":"Wikipedia"}]},{"title":"Wikipedia related-topic graph","prompt":"Create a workflow that for a topic explores related Wikipedia pages, builds a topic graph in Neo4j, and surfaces adjacent themes.","integrations":[{"id":"wikipedia","name":"Wikipedia"},{"id":"neo4j","name":"Neo4j"}]},{"title":"Wikipedia summary alerter","prompt":"Build a scheduled workflow that monitors Wikipedia pages for tracked entities, detects significant edits, and posts a summary diff to Slack.","integrations":[{"id":"wikipedia","name":"Wikipedia"},{"id":"slack","name":"Slack"}]}]},{"id":"windchill","type":"windchill","slug":"windchill","name":"Windchill","description":"Manage documents, revisions, and content in PTC Windchill","category":"Documents","docsUrl":"https://docs.sim.ai/integrations/windchill","authType":"api-key","connections":[],"operations":[{"name":"List Documents","description":"List documents with an OData query, sorting, and pagination"},{"name":"Get Document","description":"Get a WT.Document by OID"},{"name":"Get Document Structure","description":"Retrieve recursive document usage links and their parent and child documents"},{"name":"Get Valid State Transitions","description":"Get lifecycle states a document can transition to from its current state"},{"name":"Get Primary Content","description":"Get primary-content metadata for a document"},{"name":"List Attachments","description":"List attachment metadata for a document"},{"name":"Create Document","description":"Create one WT.Document"},{"name":"Create Documents","description":"Create several documents in one atomic Windchill request"},{"name":"Update Document","description":"Update one document\'s editable attributes"},{"name":"Update Common Properties","description":"Update a document\'s Name, Number, and other common properties"},{"name":"Update Documents","description":"Update several documents\' editable attributes in one atomic request"},{"name":"Delete Document","description":"Delete one document"},{"name":"Delete Documents","description":"Delete multiple documents atomically"},{"name":"Check Out Document","description":"Check out one document"},{"name":"Check Out Documents","description":"Check out multiple documents atomically"},{"name":"Check In Document","description":"Check in one document"},{"name":"Check In Documents","description":"Check in multiple documents atomically"},{"name":"Undo Check Out Document","description":"Undo checkout for one document"},{"name":"Undo Check Out Documents","description":"Undo checkout for multiple documents atomically"},{"name":"Revise Document","description":"Create a new revision of one document"},{"name":"Revise Documents","description":"Create new revisions of multiple documents atomically"},{"name":"Set Lifecycle State","description":"Transition a document to a valid lifecycle state"},{"name":"Update Document Security Labels","description":"Update installed security-label attributes for one or more documents"},{"name":"Download Primary Content","description":"Download primary content into a canonical UserFile"},{"name":"Upload Primary Content","description":"Upload a primary-content file to a document that has none"},{"name":"Download Attachment","description":"Download a document attachment into a canonical UserFile"},{"name":"Upload Attachments","description":"Upload one or more files as document attachments"}],"triggers":[],"skills":[{"name":"find-latest-controlled-documents","description":"Find current Windchill documents with bounded filters, selected fields, and pagination.","content":"# Find Latest Controlled Documents\\n\\nLocate the current Windchill documents that match a business or lifecycle condition without loading an unbounded result set.\\n\\n## Steps\\n1. Use List Documents with an OData filter, a maximum result count no larger than 200, and Latest Version Only enabled.\\n2. Select only the normalized fields needed for the request, such as ID, Number, Name, Version, State, and FolderLocation.\\n3. If more results are needed, follow the returned nextLink one page at a time until the requested scope is satisfied.\\n4. Use Get Document for any item that needs a focused follow-up check.\\n\\n## Output\\nReturn the matching document OIDs, numbers, names, versions, lifecycle states, and the next-page URL when more results remain."},{"name":"release-controlled-document","description":"Validate a Windchill document and move it through a permitted lifecycle transition.","content":"# Release Controlled Document\\n\\nValidate a document before moving it to a requested Windchill lifecycle state.\\n\\n## Steps\\n1. Use Get Document to retrieve the current revision, state, checkout status, and required metadata.\\n2. If the document is checked out, use Check In Document with a meaningful note before attempting a state change.\\n3. Use Get Valid State Transitions and confirm the requested state appears in the returned values. Each entry is a value/display pair.\\n4. Use Set Lifecycle State only after the transition is confirmed, passing both State Value and State Display from that same pair - Windchill rejects the call if either is missing.\\n5. Some Windchill configurations route releases through a Promotion Request instead of a direct state change. If Set Lifecycle State is refused, report that rather than retrying.\\n\\n## Output\\nReport the document OID, prior state, resulting state, revision, and any validation issue that prevented release."},{"name":"audit-document-structure","description":"Inspect a Windchill document structure recursively and summarize child-document readiness.","content":"# Audit Document Structure\\n\\nInspect a document and its recursively expanded child usage links for version or lifecycle issues.\\n\\n## Steps\\n1. Use Get Document Structure with the requested depth, keeping the depth as small as the audit needs.\\n2. Traverse every returned children array and record each child document OID, number, version, and state.\\n3. Flag missing metadata, non-latest versions, duplicate child references, or documents outside the requested lifecycle state.\\n\\n## Output\\nReturn a hierarchical summary of the structure plus a concise list of issues, including the affected document OIDs."},{"name":"manage-document-content-package","description":"Upload or retrieve a Windchill document primary file and its supporting attachments.","content":"# Manage Document Content Package\\n\\nTransfer a document primary-content file and its supporting attachments while preserving a clear audit result.\\n\\n## Steps\\n1. Use Get Primary Content and List Attachments to inspect the current content before changing it.\\n2. Use Upload Primary Content for the authoritative document file and Upload Attachments for supporting files. Upload at most 10 attachments per call.\\n3. When retrieval is requested, use Download Primary Content or Download Attachment with the exact document and content OIDs.\\n\\n## Output\\nReport the document OID, accepted or downloaded file names, content roles, and any file that failed to transfer."},{"name":"prepare-document-revision","description":"Check out, update, check in, and revise a Windchill document through a controlled change cycle.","content":"# Prepare Document Revision\\n\\nApply a controlled metadata change and prepare the document for its next Windchill revision.\\n\\n## Steps\\n1. Use Get Document to confirm the document OID, current version, lifecycle state, and checkout state.\\n2. Use Check Out Document with a concise note, then read document.id from the response.\\n3. If document.id differs from the OID you checked out, Windchill returned a working-copy identifier: use it for Update Document and Check In Document. If it matches, keep using the original OID. Never assume which - always read it back. Update only the editable attributes that must change, then check in with a change summary.\\n4. Use Revise Document only when a new revision is requested, supplying a target version ID only when the Windchill installation requires one.\\n\\n## Output\\nReport the OID you checked out, the OID you actually edited, the original version, the resulting version or revision, changed attribute names, and final checkout and lifecycle states."},{"name":"retire-superseded-documents","description":"Move superseded Windchill documents to an obsolete lifecycle state instead of deleting them.","content":"# Retire Superseded Documents\\n\\nPLM practice is to obsolete controlled documents rather than delete them, so history and references survive.\\n\\n## Steps\\n1. Use List Documents to gather the retirement population, selecting ID, Number, Name, Version, and State.\\n2. For each candidate, use Get Valid State Transitions and confirm the obsolete state is reachable. Skip and report any document that cannot make the transition rather than forcing it.\\n3. Use Set Lifecycle State with the value/display pair returned in step 2.\\n4. Use Update Document only if the installation records a retirement reason or date as an editable attribute. Do not attempt to change Name, Number, or Organization.\\n5. Prefer Set Lifecycle State over Delete Document. Delete only when the request explicitly asks for removal.\\n\\n## Output\\nReport each document OID with its prior and resulting state, and list every document skipped along with the reason."},{"name":"reclaim-stale-checkouts","description":"Find Windchill documents left checked out and release the locks in bounded batches.","content":"# Reclaim Stale Checkouts\\n\\nDocuments left checked out by someone unavailable block everyone else. Release those locks deliberately.\\n\\n## Steps\\n1. Use List Documents with Select including ID, Number, Name, and CheckoutState. Do NOT put checkout state in the Filter field - Windchill does not allow filtering on it and the request will fail.\\n2. Filter the returned rows for a checked-out state in the workflow itself, following the next-page URL until the requested scope is covered.\\n3. Confirm the intended scope with the requester before releasing anything. Undoing a checkout discards that working copy and any uncommitted edits.\\n4. Use Undo Check Out Documents in batches of at most 100. The action is all-or-nothing: if it fails for one document the whole batch rolls back, so retry with the failing document removed.\\n\\n## Output\\nReport the documents found checked out, which locks were released, and any batch that rolled back together with the document that caused it."}],"templates":[{"title":"Windchill document approval intake","prompt":"Build a workflow that creates a Windchill document from an approved intake form, uploads its primary content, and sends the resulting document identifier to the requester.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill lifecycle readiness review","prompt":"Create a workflow that reads a Windchill document and its valid lifecycle transitions, checks required metadata, and produces a readiness report before release.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill structure change summary","prompt":"Build a workflow that retrieves a Windchill document structure and generates a concise summary of child-document names, versions, states, and missing metadata.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill controlled document release","prompt":"Create a workflow that checks in a Windchill document, validates an allowed lifecycle transition, and moves it to the approved release state.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill attachment package","prompt":"Build a workflow that uploads a set of inspection files as Windchill document attachments and returns the accepted file names for an audit record.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill revision preparation","prompt":"Create a workflow that checks out a Windchill document, updates selected attributes, checks it in with notes, and revises it for the next change cycle.","integrations":[{"id":"windchill","name":"Windchill"}]},{"title":"Windchill document inventory","prompt":"Build a scheduled workflow that pages through Windchill documents, records their numbers, versions, states, and folder locations in a table, and flags stale checked-out documents.","integrations":[{"id":"windchill","name":"Windchill"}]}]},{"id":"wiza","type":"wiza","slug":"wiza","name":"Wiza","description":"Find, enrich, and verify B2B contact data with Wiza","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/wiza","authType":"api-key","connections":[],"operations":[{"name":"Prospect Search","description":"Search Wiza\'s database of prospects using person, company, and financial filters"},{"name":"Company Enrichment","description":"Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data"},{"name":"Individual Reveal","description":"Reveal a contact by LinkedIn URL, name plus company/domain, or email. Starts the reveal and polls at two-second intervals for up to 60 attempts, failing if it remains incomplete. Wiza charges 2 credits for a valid email, 5 for a phone, or 1 for a matched profile-only reveal."},{"name":"Get Credits","description":"Retrieve the remaining credits on your Wiza account"}],"triggers":[],"skills":[{"name":"find-prospects","description":"Run a Wiza prospect search with filters to build a list of verified B2B contacts.","content":"# Find B2B Prospects with Wiza\\n\\nBuild a targeted list of verified prospects from an ideal-customer profile.\\n\\n## Steps\\n1. Translate the ideal-customer profile into Wiza filters: job title, seniority, company size, industry, and location.\\n2. Run the prospect-search operation with those filters and a sensible result limit.\\n3. Choose how much contact data to reveal (email only, phone, or full) based on the outreach plan and credit budget.\\n4. Collect the returned prospects with their verified contact fields.\\n\\n## Output\\nReturn the matched prospects with name, title, company, and verified email or phone. Note the total matches and how many credits the reveal consumed."},{"name":"enrich-company","description":"Enrich a company by domain or name to retrieve firmographic data from Wiza.","content":"# Enrich a Company with Wiza\\n\\nFill in firmographic detail for a target account.\\n\\n## Steps\\n1. Gather the company identifier you have, typically a domain or company name.\\n2. Call the company-enrichment operation.\\n3. Extract the returned firmographics: industry, size, location, revenue band, and website.\\n\\n## Output\\nReturn the enriched company record as structured fields. If the company could not be matched, say so and report the input used."},{"name":"reveal-contact-details","description":"Reveal verified email and phone for a known individual using Wiza individual reveal.","content":"# Reveal a Contact with Wiza\\n\\nGet verified contact details for a specific person.\\n\\n## Steps\\n1. Provide the person identifiers you have, such as name and company or a LinkedIn profile.\\n2. Decide the reveal level needed: email only, phone, or full contact.\\n3. Call the individual-reveal operation.\\n4. Capture the verified email, phone, and current role returned.\\n\\n## Output\\nReturn the verified contact fields with a note on validation status. If credits are low, check the get-credits operation first and warn before spending."}],"templates":[{"title":"Wiza prospect builder","prompt":"Build a workflow that runs a Wiza prospect search against my ICP filters, reveals verified emails and phone numbers for each match, and writes the prospect list into a sender table.","integrations":[{"id":"wiza","name":"Wiza"}]},{"title":"Wiza contact reveal","prompt":"Create a workflow that watches a leads table for new rows, runs a Wiza individual reveal to surface verified email and phone, and writes the contact details back to each row.","integrations":[{"id":"wiza","name":"Wiza"}]},{"title":"Wiza company enricher","prompt":"Build a workflow that takes a list of company domains, runs Wiza company enrichment, and writes firmographics and headcount into a tables-based research base.","integrations":[{"id":"wiza","name":"Wiza"}]},{"title":"Wiza + Email Bison outbound","prompt":"Create a workflow that uses Wiza to find and reveal verified prospect emails, drafts a personalized first-touch message, and pushes valid prospects into an Email Bison campaign.","integrations":[{"id":"wiza","name":"Wiza"},{"id":"emailbison","name":"Email Bison"}]},{"title":"Wiza CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing verified phone numbers, runs a Wiza reveal to fill the gaps, and updates each contact record.","integrations":[{"id":"wiza","name":"Wiza"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Wiza credit monitor","prompt":"Create a scheduled workflow that checks the remaining Wiza credit balance each morning, logs the daily usage to a table, and posts a Slack alert when credits fall below the threshold so reveals never silently stall mid-campaign.","integrations":[{"id":"wiza","name":"Wiza"},{"id":"slack","name":"Slack"}]},{"title":"Wiza to HubSpot pipeline","prompt":"Build a workflow that runs a Wiza prospect search for my target segment, reveals verified emails and phones for each match, and creates or updates the matching HubSpot contacts with the enriched fields and a lead-source tag.","integrations":[{"id":"wiza","name":"Wiza"},{"id":"hubspot","name":"HubSpot"}]}]},{"id":"wordpress","type":"wordpress","slug":"wordpress","name":"WordPress","description":"Manage WordPress content","category":"Marketing","docsUrl":"https://docs.sim.ai/integrations/wordpress","authType":"oauth","connections":[{"id":"wordpress","kind":"oauth","label":"Connect with OAuth","providerId":"wordpress","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/wordpress","requiredScopes":[{"id":"global","label":"Full access to every WordPress.com site the account can manage"}],"fields":[]}],"operations":[{"name":"Create Post","description":"Create a new blog post in WordPress.com"},{"name":"Update Post","description":"Update an existing blog post in WordPress.com"},{"name":"Delete Post","description":"Delete a blog post from WordPress.com"},{"name":"Get Post","description":"Get a single blog post from WordPress.com by ID"},{"name":"List Posts","description":"List blog posts from WordPress.com with optional filters"},{"name":"Create Page","description":"Create a new page in WordPress.com"},{"name":"Update Page","description":"Update an existing page in WordPress.com"},{"name":"Delete Page","description":"Delete a page from WordPress.com"},{"name":"Get Page","description":"Get a single page from WordPress.com by ID"},{"name":"List Pages","description":"List pages from WordPress.com with optional filters"},{"name":"Upload Media","description":"Upload a media file (image, video, document) to WordPress.com"},{"name":"Get Media","description":"Get a single media item from WordPress.com by ID"},{"name":"List Media","description":"List media items from the WordPress.com media library"},{"name":"Delete Media","description":"Delete a media item from WordPress.com"},{"name":"Create Comment","description":"Create a new comment on a WordPress.com post"},{"name":"List Comments","description":"List comments from WordPress.com with optional filters"},{"name":"Update Comment","description":"Update a comment in WordPress.com (content or status)"},{"name":"Delete Comment","description":"Delete a comment from WordPress.com"},{"name":"Create Category","description":"Create a new category in WordPress.com"},{"name":"Update Category","description":"Update an existing category in WordPress.com"},{"name":"Delete Category","description":"Delete a category from WordPress.com"},{"name":"Get Category","description":"Get a single category from WordPress.com by ID"},{"name":"List Categories","description":"List categories from WordPress.com"},{"name":"Create Tag","description":"Create a new tag in WordPress.com"},{"name":"Update Tag","description":"Update an existing tag in WordPress.com"},{"name":"Delete Tag","description":"Delete a tag from WordPress.com"},{"name":"Get Tag","description":"Get a single tag from WordPress.com by ID"},{"name":"List Tags","description":"List tags from WordPress.com"},{"name":"Get Current User","description":"Get information about the currently authenticated WordPress.com user"},{"name":"List Users","description":"List users from WordPress.com (requires admin privileges)"},{"name":"Get User","description":"Get a specific user from WordPress.com by ID"},{"name":"Search Content","description":"Search across all content types in WordPress.com (posts, pages, media)"}],"triggers":[],"skills":[{"name":"publish-blog-post","description":"Create a WordPress post from a draft, assign categories and tags, and set its publish state.","content":"# Publish a WordPress Post\\n\\nTurn a finished draft into a WordPress post.\\n\\n## Steps\\n1. Prepare the title, body HTML, and excerpt for the post.\\n2. Resolve or create the categories and tags by listing existing ones and matching by name.\\n3. Decide the status: draft for review or publish to go live.\\n4. Call the create-post operation with the content, taxonomy, and status.\\n\\n## Output\\nReport the new post ID, status, and the post URL. List the categories and tags applied. If publishing directly, confirm the live link."},{"name":"update-existing-post","description":"Find a WordPress post and update its content, status, or taxonomy without overwriting the rest.","content":"# Update a WordPress Post\\n\\nApply targeted edits to a published or draft post.\\n\\n## Steps\\n1. Locate the post by ID, or list or search posts and match on title.\\n2. Get the current post to know its existing content and metadata.\\n3. Build an update containing only the fields that change, such as body, status, or tags.\\n4. Call the update-post operation and confirm the change.\\n\\n## Output\\nState which fields changed and the post ID. Confirm the resulting status and URL."},{"name":"upload-and-attach-media","description":"Upload an image or file to the WordPress media library for use in a post.","content":"# Upload Media to WordPress\\n\\nAdd an image or file to the media library.\\n\\n## Steps\\n1. Provide the file to upload along with a descriptive title and alt text.\\n2. Call the upload-media operation.\\n3. Capture the returned media ID and source URL.\\n4. If the media is for a specific post, reference the media ID or URL when creating or updating that post.\\n\\n## Output\\nReturn the media ID, the file URL, and the alt text set. Note whether it was attached to a post."},{"name":"moderate-comments","description":"List recent WordPress comments and approve, hold, spam, or trash them by policy.","content":"# Moderate WordPress Comments\\n\\nKeep the comment queue clean and on-policy.\\n\\n## Steps\\n1. List comments, optionally filtering by status such as hold.\\n2. For each comment, judge it against the moderation policy: legitimate, spam, or abusive.\\n3. Update each comment to the right status: approved, hold, spam, or trash.\\n\\n## Output\\nReturn a summary of how many comments were approved, held, marked spam, or trashed, with the comment IDs grouped by action taken."},{"name":"organize-taxonomy","description":"Clean up WordPress categories and tags: rename, re-slug, re-parent, or remove unused ones.","content":"# Organize WordPress Taxonomy\\n\\nKeep categories and tags tidy and consistent.\\n\\n## Steps\\n1. List existing categories and tags to see the current taxonomy, including each item post count.\\n2. Decide the target structure: rename to a consistent style, fix slugs, set parents for hierarchy, or remove duplicates and empties.\\n3. For renames or re-parenting, update the category or tag by ID with the new name, slug, or parent.\\n4. To remove one, get it first to confirm it is the right term and low-usage, then delete it (deletion is permanent for terms).\\n\\n## Output\\nReport what changed for each term: renamed, re-slugged, re-parented, or deleted, with the term IDs. Note any term skipped because it still had many posts."},{"name":"audit-site-content","description":"Inventory WordPress content by searching and listing posts and pages to find gaps or issues.","content":"# Audit WordPress Content\\n\\nBuild an inventory of what is on the site.\\n\\n## Steps\\n1. Use search across content, or list posts and pages with filters such as status and date order.\\n2. Page through results using the total and totalPages counts so nothing is missed.\\n3. Group findings by status, category, or age to spot drafts left unpublished, stale posts, or thin content.\\n\\n## Output\\nReturn a structured inventory: counts by status and type, plus a list of flagged items (IDs, titles, and URLs) that need attention."}],"templates":[{"title":"Airtable content calendar publisher","prompt":"Build a workflow that reads an Airtable content calendar, publishes due posts to WordPress with proper formatting, and writes the live URL back to the row.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"airtable","name":"Airtable"}]},{"title":"Algolia content indexer","prompt":"Build a workflow that watches a content source — WordPress, knowledge base — and upserts records into an Algolia index, removing deleted items for accurate search.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"algolia","name":"Algolia"}]},{"title":"Notion content calendar publisher","prompt":"Build a scheduled workflow that queries a Notion content-calendar database for posts marked ready today, formats each one, and publishes it to the blog while updating the Notion page status to published.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"notion","name":"Notion"}]},{"title":"Trello content pipeline","prompt":"Create a workflow that reads a Trello editorial board, publishes the cards in the \\"ready\\" list to WordPress on schedule, and moves the card to \\"live\\" with the URL attached.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"trello","name":"Trello"}]},{"title":"WordPress blog auto-publisher","prompt":"Build a workflow that takes a draft document, optimizes it for SEO by researching target keywords, formats it for WordPress with proper headings and meta description, and publishes it as a draft post for final review.","integrations":[{"id":"wordpress","name":"WordPress"}]},{"title":"WordPress release-notes publisher","prompt":"Create a scheduled workflow that runs every Friday, pulls merged GitHub PRs for the week, drafts a user-facing changelog, and publishes it as a WordPress post.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"github","name":"GitHub"}]},{"title":"WordPress comment moderator","prompt":"Build a scheduled workflow that polls new WordPress comments, classifies each as spam, question, or constructive, auto-moderates spam, and replies to questions using a knowledge base.","integrations":[{"id":"wordpress","name":"WordPress"}]},{"title":"WordPress SEO refresher","prompt":"Create a scheduled monthly workflow that finds underperforming WordPress posts, runs Ahrefs keyword analysis, drafts refreshed sections, and stages the update as a draft revision.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"ahrefs","name":"Ahrefs"}]},{"title":"WordPress newsletter republisher","prompt":"Build a workflow that publishes a new WordPress post and then drafts an adapted Mailchimp newsletter version, links back to the post, and queues it for the editor’s review.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"mailchimp","name":"Mailchimp"}]},{"title":"WordPress broken-link sweeper","prompt":"Create a scheduled workflow that scans WordPress posts for broken outbound links, proposes replacement URLs via web search, and stages each as a draft revision for approval.","integrations":[{"id":"wordpress","name":"WordPress"}]},{"title":"WordPress media-rich post builder","prompt":"Build a workflow that takes a draft article and its image files, uploads each image to the WordPress media library, generates a hero image with an image generator, assigns the right categories and tags, and publishes the fully illustrated post as a draft for review.","integrations":[{"id":"wordpress","name":"WordPress"}]},{"title":"YouTube upload-to-blog","prompt":"Create a scheduled workflow that polls a YouTube channel for new uploads, pulls each video’s details and description, generates a long-form blog post with proper SEO structure, and stages it as a WordPress draft.","integrations":[{"id":"wordpress","name":"WordPress"},{"id":"youtube","name":"YouTube"}]}]},{"id":"workday","type":"workday","slug":"workday","name":"Workday","description":"Manage workers, hiring, onboarding, and HR operations in Workday","category":"HR","docsUrl":"https://docs.sim.ai/integrations/workday","authType":"none","connections":[],"operations":[{"name":"Get Worker","description":"Retrieve a specific worker profile including personal, employment, and organization data."},{"name":"List Workers","description":"List or search workers with optional filtering and pagination."},{"name":"Create Pre-Hire","description":"Create a new pre-hire (applicant) record in Workday. This is typically the first step before hiring an employee."},{"name":"Hire Employee","description":"Hire a pre-hire into an employee position. Converts an applicant into an active employee record with position, start date, and manager assignment."},{"name":"Update Personal Information","description":"Update fields on an existing worker record in Workday."},{"name":"Assign Onboarding Plan","description":"Create or update an onboarding plan assignment for a worker. Sets up onboarding stages and manages the assignment lifecycle."},{"name":"Get Organizations","description":"Retrieve organizations, departments, and cost centers from Workday."},{"name":"Change Job","description":"Perform a job change for a worker including transfers, promotions, demotions, and lateral moves."},{"name":"Get Compensation","description":"Retrieve compensation plan details for a specific worker."},{"name":"Terminate Worker","description":"Initiate a worker termination in Workday. Triggers the Terminate Employee business process."}],"triggers":[],"skills":[{"name":"look-up-worker","description":"Find a worker in Workday and return their core profile and employment details.","content":"# Look Up a Worker in Workday\\n\\nRetrieve a worker record for HR review or downstream use.\\n\\n## Steps\\n1. Resolve the worker by ID, or list workers and match on name or email.\\n2. Call the get-worker operation for the matched worker.\\n3. Extract the relevant fields: name, position, organization, manager, and status.\\n\\n## Output\\nReturn the worker profile as structured fields. If multiple workers matched the search, list the candidates and ask which one before fetching full detail."},{"name":"onboard-new-hire","description":"Create a pre-hire, hire the employee, and assign an onboarding plan in Workday.","content":"# Onboard a New Hire in Workday\\n\\nMove a candidate from pre-hire to onboarded employee.\\n\\n## Steps\\n1. Create the pre-hire record with the candidate personal and contact details.\\n2. Hire the employee using the pre-hire, setting position, organization, start date, and worker type.\\n3. Assign the onboarding plan for the new worker.\\n4. Confirm each step succeeded before moving to the next.\\n\\n## Output\\nReport the new worker ID, position, start date, and the onboarding plan assigned. Stop and surface the error if any step fails rather than continuing."},{"name":"process-job-change","description":"Apply a job change such as a transfer or promotion to an existing Workday worker.","content":"# Process a Job Change in Workday\\n\\nUpdate a worker position with a transfer, promotion, or reassignment.\\n\\n## Steps\\n1. Look up the worker and confirm their current position and organization.\\n2. Determine the new position, organization, or compensation involved in the change.\\n3. Call the change-job operation with the change details and effective date.\\n4. Optionally fetch compensation to confirm the new package.\\n\\n## Output\\nReport the worker ID, the old and new position, the effective date, and confirmation the change was recorded."},{"name":"update-worker-info","description":"Update a Workday worker personal information record with validated field changes.","content":"# Update Worker Personal Information\\n\\nApply validated personal-information changes for a worker.\\n\\n## Steps\\n1. Look up the worker to confirm the record and current values.\\n2. Validate the requested changes against expected formats before applying.\\n3. Build the fields JSON with only the values that change.\\n4. Call the update-worker operation and confirm acceptance.\\n\\n## Output\\nReport which fields changed for the worker ID and confirm the update succeeded. Reject and explain any field that failed validation."}],"templates":[{"title":"Google Contacts new-hire onboarder","prompt":"Build a workflow that on a new hire in Workday adds the new employee to relevant Google Contacts groups based on department and team.","integrations":[{"id":"workday","name":"Workday"},{"id":"google_contacts","name":"Google Contacts"}]},{"title":"Google Groups departure cleanup","prompt":"Create a workflow that watches Workday or Rippling for terminations and removes the departing user from every Google Group they belonged to, writing the change to a security audit log.","integrations":[{"id":"workday","name":"Workday"},{"id":"google_groups","name":"Google Groups"},{"id":"rippling","name":"Rippling"}]},{"title":"Identity Center new-hire onboarder","prompt":"Create a workflow that on a Workday new-hire event provisions AWS Identity Center permission sets based on role, and writes the assignment to a tracking table.","integrations":[{"id":"workday","name":"Workday"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Identity Center offboarder","prompt":"Build a workflow that on a Workday termination revokes the user’s AWS Identity Center assignments and writes the action log to the security audit table.","integrations":[{"id":"workday","name":"Workday"},{"id":"identity_center","name":"AWS Identity Center"}]},{"title":"Infisical env bootstrapper","prompt":"Build a workflow that on a Workday new-hire event creates the standard set of Infisical secrets for the new engineer’s scoped dev environment from a template, and writes the provisioning record to a table.","integrations":[{"id":"workday","name":"Workday"},{"id":"infisical","name":"Infisical"}]},{"title":"Infisical offboarding rotation","prompt":"Create a workflow that on a Workday termination rotates the shared Infisical secrets the departing engineer had access to by generating new values and updating them across environments, then writes the action log to a table.","integrations":[{"id":"workday","name":"Workday"},{"id":"infisical","name":"Infisical"}]},{"title":"Azure AD provisioning","prompt":"Build a workflow that on a Workday new-hire event creates the Azure AD user account, assigns the right group memberships, and writes the provisioning record to an audit table.","integrations":[{"id":"workday","name":"Workday"},{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Azure AD offboarding sweep","prompt":"Create a workflow that on a Workday termination disables the Azure AD account, removes its group memberships, and writes the security audit record.","integrations":[{"id":"workday","name":"Workday"},{"id":"microsoft_ad","name":"Azure AD"}]},{"title":"Monday onboarding kickoff","prompt":"Create a workflow that on a new hire in Workday creates a personalized Monday onboarding board, seeds the role-specific tasks, and invites the new hire and buddy.","integrations":[{"id":"workday","name":"Workday"},{"id":"monday","name":"Monday"}]},{"title":"Neo4j org-chart sync","prompt":"Build a workflow that pulls Workday or Rippling worker data, upserts employees and reporting relationships into Neo4j, and exposes a queryable org graph for downstream tools.","integrations":[{"id":"workday","name":"Workday"},{"id":"neo4j","name":"Neo4j"},{"id":"rippling","name":"Rippling"}]},{"title":"Okta orphan-account sweeper","prompt":"Create a scheduled workflow that compares Okta users against HRIS data, finds accounts for departed employees, disables them, and writes the sweep log to an audit table.","integrations":[{"id":"workday","name":"Workday"},{"id":"okta","name":"Okta"}]},{"title":"Okta new-hire provisioning","prompt":"Build a workflow that polls Workday for new hires, creates the matching Okta user, adds them to the right groups for their role, and emails IT a provisioning summary.","integrations":[{"id":"workday","name":"Workday"},{"id":"okta","name":"Okta"},{"id":"gmail","name":"Gmail"}]},{"title":"Okta SSO group sync","prompt":"Create a scheduled workflow that mirrors org structure from Workday into Okta groups, ensuring group memberships stay in sync as employees change roles.","integrations":[{"id":"workday","name":"Workday"},{"id":"okta","name":"Okta"}]},{"title":"OneDrive new-hire kit deployer","prompt":"Create a workflow triggered by a Workday new hire that creates a OneDrive new-hire folder, uploads the standard onboarding documents into it, and writes the folder link into the onboarding tracker.","integrations":[{"id":"workday","name":"Workday"},{"id":"onedrive","name":"OneDrive"}]},{"title":"1Password offboarding sweep","prompt":"Create a workflow that on a Workday termination rotates the shared 1Password secrets the departing employee had access to, updates the affected items, and writes the action log.","integrations":[{"id":"workday","name":"Workday"},{"id":"onepassword","name":"1Password"}]},{"title":"1Password onboarding kit","prompt":"Build a workflow that when a new hire is provisioned creates their starter 1Password items based on role and team, and writes the access record to the onboarding table.","integrations":[{"id":"workday","name":"Workday"},{"id":"onepassword","name":"1Password"}]},{"title":"SharePoint onboarding hub","prompt":"Build a workflow triggered by a new hire in Workday that creates a personalized SharePoint onboarding hub with role-relevant docs and shares it with the hire and their manager.","integrations":[{"id":"workday","name":"Workday"},{"id":"sharepoint","name":"SharePoint"}]},{"title":"Tailscale new-hire provisioner","prompt":"Build a workflow that on a Workday new-hire event creates a scoped Tailscale auth key for the engineer, sets the right device tags, and writes the access record.","integrations":[{"id":"workday","name":"Workday"},{"id":"tailscale","name":"Tailscale"}]},{"title":"Tailscale offboarder","prompt":"Create a workflow that on a Workday termination deletes the departing engineer\'s Tailscale devices, revokes their auth keys, suspends their tailnet user account, and writes the security audit log.","integrations":[{"id":"workday","name":"Workday"},{"id":"tailscale","name":"Tailscale"}]},{"title":"Workday new-hire kickoff","prompt":"Build a scheduled workflow that polls Workday for newly hired employees, gathers each one’s position and start date, kicks off provisioning in downstream tools, assigns an onboarding plan, schedules introductions on Google Calendar, and notifies the team in Slack.","integrations":[{"id":"workday","name":"Workday"},{"id":"slack","name":"Slack"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Workday pre-hire pipeline","prompt":"Create a workflow exposed as a form that captures candidate details from recruiters, validates required fields, creates a pre-hire record in Workday, returns the pre-hire identifier, and logs the submission in a recruiting tracking table.","integrations":[{"id":"workday","name":"Workday"}]},{"title":"Workday job change orchestrator","prompt":"Build a workflow that watches a Sim table of approved promotions, transfers, and demotions, performs the Workday change-job action for each row, updates downstream tools and Slack channel membership, and writes the outcome back to the table for audit.","integrations":[{"id":"workday","name":"Workday"},{"id":"slack","name":"Slack"}]},{"title":"Workday comp review prep","prompt":"Create a scheduled workflow that pulls Workday workers and their current compensation, joins with a performance ratings table, drafts manager-by-manager compensation review packets as files, and emails each manager their packet ahead of the cycle.","integrations":[{"id":"workday","name":"Workday"},{"id":"gmail","name":"Gmail"}]},{"title":"Workday termination workflow","prompt":"Build a workflow triggered by an approved offboarding request that initiates the Workday Terminate Employee business process, deactivates downstream accounts, schedules an exit interview on Google Calendar, and writes a compliance record to an audit table.","integrations":[{"id":"workday","name":"Workday"},{"id":"google_calendar","name":"Google Calendar"}]},{"title":"Workday org structure snapshot","prompt":"Create a scheduled weekly workflow that pulls Workday workers and organizations, builds an org chart file with departments and cost centers, diffs against last week to highlight structural changes, and emails the result to people leadership.","integrations":[{"id":"workday","name":"Workday"}]},{"title":"Workday personal-info self-service","prompt":"Build a workflow exposed as a chat or form endpoint that takes employee-submitted personal info changes, validates the request, calls the Workday Update Personal Information action, confirms back to the employee, and logs the change in a people-operations audit table.","integrations":[{"id":"workday","name":"Workday"}]}]},{"id":"x","type":"x","slug":"x","name":"X","description":"Interact with X","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/x","authType":"oauth","connections":[{"id":"x","kind":"oauth","label":"Connect with OAuth","providerId":"x","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/x","requiredScopes":[{"id":"tweet.read","label":"Read tweets and timeline"},{"id":"tweet.write","label":"Post, repost, and delete tweets"},{"id":"tweet.moderate.write","label":"Hide and unhide replies to tweets"},{"id":"users.read","label":"Read user profiles and account information"},{"id":"follows.read","label":"View followers and following lists"},{"id":"follows.write","label":"Follow and unfollow users"},{"id":"bookmark.read","label":"View bookmarked tweets"},{"id":"bookmark.write","label":"Add and remove bookmarks"},{"id":"like.read","label":"View liked tweets and liking users"},{"id":"like.write","label":"Like and unlike tweets"},{"id":"block.read","label":"View blocked users"},{"id":"block.write","label":"Block and unblock users"},{"id":"mute.read","label":"View muted users"},{"id":"mute.write","label":"Mute and unmute users"},{"id":"offline.access","label":"Access account when not using the application"}],"fields":[]}],"operations":[{"name":"Create Tweet","description":"Create a new tweet, reply, or quote tweet on X"},{"name":"Delete Tweet","description":"Delete a tweet authored by the authenticated user"},{"name":"Search Tweets","description":"Search for recent tweets using keywords, hashtags, or advanced query operators"},{"name":"Get Tweets by IDs","description":"Look up multiple tweets by their IDs (up to 100)"},{"name":"Get Quote Tweets","description":"Get tweets that quote a specific tweet"},{"name":"Hide Reply","description":"Hide or unhide a reply to a tweet authored by the authenticated user"},{"name":"Get User Tweets","description":"Get tweets authored by a specific user"},{"name":"Get User Mentions","description":"Get tweets that mention a specific user"},{"name":"Get User Timeline","description":"Get the reverse chronological home timeline for the authenticated user"},{"name":"Like / Unlike","description":"Like or unlike a tweet on X"},{"name":"Retweet / Unretweet","description":"Retweet or unretweet a tweet on X"},{"name":"Get Liked Tweets","description":"Get tweets liked by a specific user"},{"name":"Get Liking Users","description":"Get the list of users who liked a specific tweet"},{"name":"Get Retweeted By","description":"Get the list of users who retweeted a specific tweet"},{"name":"Get Bookmarks","description":"Get bookmarked tweets for the authenticated user"},{"name":"Create Bookmark","description":"Bookmark a tweet for the authenticated user"},{"name":"Delete Bookmark","description":"Remove a tweet from the authenticated user\'s bookmarks"},{"name":"Get My Profile","description":"Get the authenticated user\'s profile information"},{"name":"Search Users","description":"Search for X users by name, username, or bio"},{"name":"Get Followers","description":"Get the list of followers for a user"},{"name":"Get Following","description":"Get the list of users that a user is following"},{"name":"Follow / Unfollow","description":"Follow or unfollow a user on X"},{"name":"Block / Unblock","description":"Block or unblock a user on X"},{"name":"Get Blocked Users","description":"Get the list of users blocked by the authenticated user"},{"name":"Mute / Unmute","description":"Mute or unmute a user on X"},{"name":"Get Trends by Location","description":"Get trending topics for a specific location by WOEID (e.g., 1 for worldwide, 23424977 for US)"},{"name":"Get Personalized Trends","description":"Get personalized trending topics for the authenticated user"},{"name":"Get API Usage","description":"Get the API usage data for your X project"}],"triggers":[],"skills":[{"name":"post-tweet","description":"Compose and publish a tweet on X, optionally as a reply or with reply restrictions.","content":"# Post a Tweet on X\\n\\nPublish a single tweet or a reply.\\n\\n## Steps\\n1. Draft the tweet text, keeping it within the character limit and on-brand.\\n2. If it is a reply, identify the tweet ID being replied to. Set reply restrictions if the post should be limited to following or mentioned users.\\n3. Call the create-tweet operation.\\n4. Capture the returned tweet ID.\\n\\n## Output\\nReturn the posted tweet text and its tweet ID with a link. Confirm whether it was a standalone post or a reply."},{"name":"monitor-mentions","description":"Fetch recent mentions of a user on X and summarize what needs a response.","content":"# Monitor X Mentions\\n\\nTrack who is talking to a profile and surface what matters.\\n\\n## Steps\\n1. Resolve the target user, using get-my-profile or search-users to confirm the user ID.\\n2. Call get-user-mentions to fetch recent mentions.\\n3. Classify each mention: question, complaint, praise, or noise.\\n4. Highlight mentions that need a reply.\\n\\n## Output\\nReturn a grouped summary of mentions by type, with the tweet IDs and authors for any that need a human response, ranked by urgency."},{"name":"search-and-analyze-tweets","description":"Search X for tweets matching a query and summarize themes, sentiment, and notable posts.","content":"# Search and Analyze Tweets on X\\n\\nUnderstand the conversation around a topic or keyword.\\n\\n## Steps\\n1. Build a focused search query and choose recency or relevancy sorting.\\n2. Call search-tweets with a sensible result limit.\\n3. Read the results and identify recurring themes, overall sentiment, and high-engagement posts.\\n\\n## Output\\nReturn a short report: dominant themes, sentiment split, and a few notable tweets with their IDs. Note the query and time window covered."},{"name":"curate-bookmarks-digest","description":"Pull saved X bookmarks, group them by theme, and produce a curated reading digest.","content":"# Curate an X Bookmarks Digest\\n\\nTurn saved bookmarks into an organized reading list.\\n\\n## Steps\\n1. Call get-bookmarks to retrieve saved tweets.\\n2. Fetch the full text of each bookmarked tweet where needed using get-tweets-by-IDs.\\n3. Group the bookmarks by theme and write a short note on why each cluster matters.\\n4. Optionally delete-bookmark for items once they are processed.\\n\\n## Output\\nReturn a themed digest with each tweet linked by ID and a one-line takeaway per item. State how many bookmarks were processed."}],"templates":[{"title":"Gamma weekly content carousel","prompt":"Create a scheduled workflow that turns the week’s top blog posts into a multi-slide Gamma carousel, then queues the export for X and LinkedIn posting.","integrations":[{"id":"x","name":"X"},{"id":"gamma","name":"Gamma"},{"id":"linkedin","name":"LinkedIn"}]},{"title":"Reddit mention tracker","prompt":"Create a scheduled workflow that monitors Reddit and X for mentions of my brand and competitors, scores each mention by sentiment and reach, logs them to a table, and sends a daily Slack digest of notable mentions.","integrations":[{"id":"x","name":"X"},{"id":"reddit","name":"Reddit"},{"id":"slack","name":"Slack"}]},{"title":"X (Twitter) brand mention triage","prompt":"Build a scheduled workflow that polls X mentions of the brand, classifies each as praise, support request, or complaint, and routes complaints to the support team with one-tap context.","integrations":[{"id":"x","name":"X"},{"id":"slack","name":"Slack"}]},{"title":"X engagement digest","prompt":"Create a scheduled daily workflow that summarizes top X engagement on the brand account, identifies high-influence engagers, and writes them to a sales-prospect table.","integrations":[{"id":"x","name":"X"},{"id":"salesforce","name":"Salesforce"}]},{"title":"X content scheduler","prompt":"Build a workflow that reads a tables-based X content calendar and posts scheduled tweets with media at the right time, retrying transient failures.","integrations":[{"id":"x","name":"X"}]},{"title":"X thread expander","prompt":"Create a workflow that takes a long-form article or blog and drafts a multi-tweet X thread with hooks, key points, and a call-to-action, then queues it for review before posting.","integrations":[{"id":"x","name":"X"}]},{"title":"X competitor watcher","prompt":"Build a scheduled workflow that tracks tweets from competitor handles and key industry voices, captures notable posts in a table, and surfaces high-engagement items to Slack.","integrations":[{"id":"x","name":"X"},{"id":"slack","name":"Slack"}]},{"title":"X support ticket creator","prompt":"Create a scheduled workflow that polls X for tweets directed at the brand support handle, classifies each as a support request, and opens a Zendesk ticket with the tweet context and customer profile.","integrations":[{"id":"x","name":"X"},{"id":"zendesk","name":"Zendesk"}]},{"title":"X bookmark research digest","prompt":"Create a scheduled weekly workflow that pulls my saved X bookmarks, fetches the full text of each bookmarked tweet, groups them by theme, writes a curated reading digest, and emails it to me before clearing the processed bookmarks.","integrations":[{"id":"x","name":"X"}]}]},{"id":"youcom","type":"youcom","slug":"you-com","name":"You.com","description":"Search, read, and research the web with You.com","category":"Search","docsUrl":"https://docs.sim.ai/integrations/youcom","authType":"api-key","connections":[],"operations":[{"name":"Search","description":"Search the web and news with You.com, returning LLM-ready results with optional query-relevant highlights or full page content."},{"name":"Get Contents","description":"Fetch the HTML, Markdown, and page metadata of one or more web pages with You.com."},{"name":"Answer","description":"Get a synthesized answer to a question with numbered citations and the web results used to write it."},{"name":"Research","description":"Run multi-step web research on a question and get a thorough, cited answer, or start it as a background task."},{"name":"Get Research Task","description":"Get the status of a background research task and, once completed, its cited answer and sources."},{"name":"Finance Research","description":"Research a financial question across earnings reports, SEC filings, analyst coverage, and market news, and get a cited answer."},{"name":"Search Images","description":"Find image URLs for a query with You.com. Beta, and limited to You.com early-access API keys."},{"name":"Get Account Balance","description":"Get the remaining You.com API credit balance for the account or organization that owns the API key."}],"triggers":[],"skills":[{"name":"ground-answer-with-web-search","description":"Search the live web with You.com and ground a response in query-relevant highlights.","content":"# Ground an Answer with Web Search\\n\\nUse You.com Search to collect current, citable evidence before answering.\\n\\n## Steps\\n1. Use the Search operation with a focused query. Search operators such as site: and filetype: are supported.\\n2. Set Result Content to Highlights to get only the passages that address the query, which keeps context small.\\n3. Use freshness (day, week, month, year, or a date range) for time-sensitive questions, and include or exclude domains to control sources.\\n4. Read the web and news results; cite each claim with its URL.\\n\\n## Output\\nReturn the answer with inline source URLs. Say when results are thin or conflicting."},{"name":"answer-question-with-citations","description":"Use You.com Answer to get a synthesized answer with verbatim supporting excerpts.","content":"# Answer a Question with Citations\\n\\nGet a direct answer to a factual question, backed by sources.\\n\\n## Steps\\n1. Use the Answer operation and pass the question in natural language.\\n2. Add freshness for recent events and include domains when only specific sources are trusted.\\n3. Check the citations array: each entry has a source URL and the excerpts that support the answer.\\n\\n## Output\\nReturn the answer and a numbered list of cited sources. Flag any claim without a supporting excerpt."},{"name":"run-deep-research-report","description":"Use You.com Research to investigate a complex question and produce a cited report.","content":"# Run a Deep Research Report\\n\\nAnswer a question that needs many searches and cross-referencing.\\n\\n## Steps\\n1. Use the Research operation and write the input as a full instruction: what to find and how to report it.\\n2. Pick an effort: lite for quick answers, standard for most questions, deep or exhaustive when accuracy matters more than speed.\\n3. For structured fields, supply an output schema (every property required, additionalProperties false); content is then an object.\\n4. For frontier effort or very long runs, enable Run in Background and fetch the result later with Get Research Task.\\n\\n## Output\\nReturn the Markdown report (or structured object) and its sources. Mention any warnings returned."},{"name":"research-company-financials","description":"Use You.com Finance Research for earnings analysis and competitive benchmarking with citations.","content":"# Research Company Financials\\n\\nAnswer financial questions from earnings reports, SEC filings, analyst coverage, and market news.\\n\\n## Steps\\n1. Use the Finance Research operation. Name the companies and tickers, the metrics, and the periods explicitly.\\n2. Use deep effort for most questions and exhaustive for multi-company comparisons.\\n3. Check that every figure in the answer has a citation in sources.\\n\\n## Output\\nReturn the cited answer with a short table of key figures where useful, plus the source list."},{"name":"extract-web-page-content","description":"Use You.com Get Contents to pull clean Markdown or HTML from a set of URLs.","content":"# Extract Web Page Content\\n\\nRead full pages for summarizing, indexing, or analysis.\\n\\n## Steps\\n1. Use the Get Contents operation with the target URLs, comma-separated.\\n2. Select Markdown for text an agent will read, HTML when layout matters, and Metadata for site name and favicon.\\n3. Set a max cache age (in seconds) when the page must be re-fetched rather than served from cache.\\n\\n## Output\\nReturn each page URL and title with its content. Flag any URL that returned no content."}],"templates":[{"title":"You.com grounded answers","prompt":"Build an agent that takes a question from Chat, uses You.com Answer to get a cited answer from the live web, and replies with the answer plus the source links.","integrations":[{"id":"youcom","name":"You.com"}]},{"title":"You.com research brief","prompt":"Build a workflow that takes a topic, runs You.com Research at deep effort, and saves the cited Markdown report as a file for the team.","integrations":[{"id":"youcom","name":"You.com"}]},{"title":"You.com earnings analyst","prompt":"Create a scheduled workflow that runs You.com Finance Research on each ticker in a watchlist table after earnings season, summarizes revenue drivers with citations, and writes the summary back to the table.","integrations":[{"id":"youcom","name":"You.com"}]},{"title":"You.com news monitor","prompt":"Build a scheduled daily workflow that runs You.com Search with day freshness for my competitors, extracts highlights from each news result, and posts a short digest to Slack.","integrations":[{"id":"youcom","name":"You.com"},{"id":"slack","name":"Slack"}]},{"title":"You.com knowledge loader","prompt":"Create a workflow that takes a list of documentation URLs, fetches each page as Markdown with You.com Get Contents, and adds the pages to a knowledge base so agents can answer from them.","integrations":[{"id":"youcom","name":"You.com"}]},{"title":"You.com structured lead research","prompt":"Build a workflow that reads company names from a table, runs You.com Research with an output schema for headquarters, headcount, and recent funding, and writes each structured result to its row.","integrations":[{"id":"youcom","name":"You.com"}]},{"title":"You.com long-running research","prompt":"Create a workflow that starts You.com Research in the background at frontier effort, then a scheduled workflow that checks the task with Get Research Task and emails the report when it completes.","integrations":[{"id":"youcom","name":"You.com"},{"id":"gmail","name":"Gmail"}]},{"title":"You.com credit alert","prompt":"Build a scheduled workflow that checks the You.com account balance every morning and sends a Slack alert when remaining credits fall below a set threshold.","integrations":[{"id":"youcom","name":"You.com"},{"id":"slack","name":"Slack"}]}]},{"id":"youtube","type":"youtube","slug":"youtube","name":"YouTube","description":"Interact with YouTube videos, channels, and playlists","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/youtube","authType":"api-key","connections":[],"operations":[{"name":"Search Videos","description":"Search for videos on YouTube using the YouTube Data API. Supports advanced filtering by channel, date range, duration, category, quality, captions, live streams, and more."},{"name":"Get Trending Videos","description":"Get the most popular/trending videos on YouTube. Can filter by region and video category."},{"name":"Get Video Details","description":"Get detailed information about a specific YouTube video including statistics, content details, live streaming info, and metadata."},{"name":"Get Video Categories","description":"Get a list of video categories available on YouTube. Use this to discover valid category IDs for filtering search and trending results."},{"name":"Get Channel Info","description":"Get detailed information about a YouTube channel including statistics, branding, and content details."},{"name":"Get Channel Videos","description":"Search for videos from a specific YouTube channel with sorting options. For complete channel video list, use channel_info to get uploadsPlaylistId, then use playlist_items."},{"name":"Get Channel Playlists","description":"Get all public playlists from a specific YouTube channel."},{"name":"Get Playlist Items","description":"Get videos from a YouTube playlist. Can be used with a channel uploads playlist to get all channel videos."},{"name":"Get Video Comments","description":"Get top-level comments from a YouTube video with author details and engagement."}],"triggers":[],"skills":[{"name":"find-videos-on-topic","description":"Search YouTube for videos on a topic with filters for duration, recency, and quality.","content":"# Find YouTube Videos on a Topic\\n\\nSurface the most relevant videos for a subject.\\n\\n## Steps\\n1. Build a search query and choose filters: order (relevance, date, view count), duration, and definition.\\n2. Call the search operation with a result limit.\\n3. For promising results, get video details to read title, channel, view count, and publish date.\\n4. Rank the results by relevance and signal.\\n\\n## Output\\nReturn a ranked list of videos with title, channel, URL, view count, and publish date. Note the query and filters applied."},{"name":"analyze-channel","description":"Pull a YouTube channel profile and recent uploads to summarize its content and cadence.","content":"# Analyze a YouTube Channel\\n\\nProfile a channel and its recent output.\\n\\n## Steps\\n1. Get channel info to retrieve subscriber count, total views, and description.\\n2. Get channel videos to list recent uploads.\\n3. Summarize the content themes, upload cadence, and the best-performing recent videos.\\n\\n## Output\\nReturn a channel summary with key stats, dominant content themes, posting frequency, and the top recent videos by views. Cite the channel and video IDs used."},{"name":"summarize-video-comments","description":"Fetch comments on a YouTube video and summarize sentiment, questions, and recurring feedback.","content":"# Summarize YouTube Video Comments\\n\\nUnderstand audience reaction to a video.\\n\\n## Steps\\n1. Identify the video ID, searching or using video details if only a title is known.\\n2. Call the comments operation to fetch top or recent comments.\\n3. Group comments into sentiment, recurring questions, and feature or content requests.\\n\\n## Output\\nReturn a summary with sentiment breakdown, the most common questions, and notable feedback themes. Quote a few representative comments and cite the video ID."}],"templates":[{"title":"YouTube content repurposer","prompt":"Build a workflow that takes a YouTube video URL, pulls the video details and description, researches the topic on the web for additional context, and generates a Twitter thread, LinkedIn post, and blog summary optimized for each platform.","integrations":[{"id":"youtube","name":"YouTube"}]},{"title":"YouTube video audio brief","prompt":"Build a workflow that takes a YouTube URL, pulls the video details and top comments, summarizes them with an agent, narrates the summary with ElevenLabs, and saves the audio file for distribution.","integrations":[{"id":"youtube","name":"YouTube"},{"id":"elevenlabs","name":"ElevenLabs"}]},{"title":"YouTube channel performance digest","prompt":"Create a scheduled weekly workflow that pulls a YouTube channel’s public stats and recent videos, ranks the top performers by views, writes a digest file, and emails it to the content team.","integrations":[{"id":"youtube","name":"YouTube"},{"id":"gmail","name":"Gmail"}]},{"title":"YouTube comment triage","prompt":"Build a scheduled workflow that pulls recent YouTube comments on a video, classifies each as helpful, question, or spam, drafts suggested answers to questions using a knowledge base, and routes them to the community team in Slack for review.","integrations":[{"id":"youtube","name":"YouTube"},{"id":"slack","name":"Slack"}]},{"title":"YouTube upload-to-blog","prompt":"Create a scheduled workflow that polls a YouTube channel for new uploads, pulls each video’s details and description, generates a long-form blog post with proper SEO structure, and stages it as a WordPress draft.","integrations":[{"id":"youtube","name":"YouTube"},{"id":"wordpress","name":"WordPress"}]},{"title":"YouTube competitor watcher","prompt":"Build a scheduled workflow that monitors competitor YouTube channels, flags videos that exceed average performance, and writes outline of their format to a content-research table.","integrations":[{"id":"youtube","name":"YouTube"}]},{"title":"YouTube video curation finder","prompt":"Create a workflow that reads a tables-based topic list, finds matching YouTube videos via search, scores each for relevance, writes the candidates back to the table, and pings the editorial team for the final cut.","integrations":[{"id":"youtube","name":"YouTube"}]},{"title":"YouTube video recap to Notion","prompt":"Build a workflow that takes a YouTube video URL, pulls the video details, description, and top comments, summarizes the highlights and audience reaction, and saves a recap to a Notion page for the marketing team.","integrations":[{"id":"youtube","name":"YouTube"},{"id":"notion","name":"Notion"}]}]},{"id":"zendesk","type":"zendesk","slug":"zendesk","name":"Zendesk","description":"Manage support tickets, users, and organizations in Zendesk","category":"Support","docsUrl":"https://docs.sim.ai/integrations/zendesk","authType":"api-key","connections":[],"operations":[{"name":"Get Tickets","description":"Retrieve a list of tickets from Zendesk with optional filtering"},{"name":"Get Ticket","description":"Get a single ticket by ID from Zendesk"},{"name":"Create Ticket","description":"Create a new ticket in Zendesk with support for custom fields"},{"name":"Create Tickets Bulk","description":"Create multiple tickets in Zendesk at once (max 100)"},{"name":"Update Ticket","description":"Update an existing ticket in Zendesk with support for custom fields"},{"name":"Update Tickets Bulk","description":"Update multiple tickets in Zendesk at once (max 100)"},{"name":"Delete Ticket","description":"Delete a ticket from Zendesk"},{"name":"Merge Tickets","description":"Merge multiple tickets into a target ticket"},{"name":"Get Users","description":"Retrieve a list of users from Zendesk with optional filtering"},{"name":"Get User","description":"Get a single user by ID from Zendesk"},{"name":"Get Current User","description":"Get the currently authenticated user from Zendesk"},{"name":"Search Users","description":"Search for users in Zendesk using a query string"},{"name":"Create User","description":"Create a new user in Zendesk"},{"name":"Create Users Bulk","description":"Create multiple users in Zendesk using bulk import"},{"name":"Update User","description":"Update an existing user in Zendesk"},{"name":"Update Users Bulk","description":"Update multiple users in Zendesk using bulk update"},{"name":"Delete User","description":"Delete a user from Zendesk"},{"name":"Get Organizations","description":"Retrieve a list of organizations from Zendesk"},{"name":"Get Organization","description":"Get a single organization by ID from Zendesk"},{"name":"Autocomplete Organizations","description":"Autocomplete organizations in Zendesk by name prefix (for name matching/autocomplete)"},{"name":"Create Organization","description":"Create a new organization in Zendesk"},{"name":"Create Organizations Bulk","description":"Create multiple organizations in Zendesk using bulk import"},{"name":"Update Organization","description":"Update an existing organization in Zendesk"},{"name":"Delete Organization","description":"Delete an organization from Zendesk"},{"name":"Search","description":"Unified search across tickets, users, and organizations in Zendesk"},{"name":"Search Count","description":"Count the number of search results matching a query in Zendesk"}],"triggers":[{"id":"zendesk_ticket_created","name":"Zendesk Ticket Created","description":"Trigger workflow when a new ticket is created in Zendesk"},{"id":"zendesk_ticket_status_changed","name":"Zendesk Ticket Status Changed","description":"Trigger workflow when a ticket status changes in Zendesk"},{"id":"zendesk_ticket_comment_added","name":"Zendesk Ticket Comment Added","description":"Trigger workflow when a comment is added to a Zendesk ticket"},{"id":"zendesk_ticket_priority_changed","name":"Zendesk Ticket Priority Changed","description":"Trigger workflow when a ticket priority changes in Zendesk"},{"id":"zendesk_webhook","name":"Zendesk Ticket Event","description":"Trigger workflow from any Zendesk ticket event"}],"skills":[{"name":"triage-new-ticket","description":"Read a Zendesk ticket, classify it, and update priority, tags, and assignee accordingly.","content":"# Triage a Zendesk Ticket\\n\\nClassify an incoming ticket and route it correctly.\\n\\n## Steps\\n1. Get the ticket by ID to read the subject, description, and requester.\\n2. Classify the issue type, urgency, and the team or queue it belongs to.\\n3. Update the ticket with the right priority, tags, and assignee or group.\\n4. Optionally add an internal note explaining the triage decision.\\n\\n## Output\\nReport the ticket ID, the classification, and the priority, tags, and assignee set. Note anything that needs human review."},{"name":"create-support-ticket","description":"Create a Zendesk ticket from an inbound request, linking it to the right requester.","content":"# Create a Zendesk Ticket\\n\\nLog an inbound issue as a support ticket.\\n\\n## Steps\\n1. Gather the subject, description, and requester details.\\n2. Look up the requester with search-users, creating the user if they do not exist.\\n3. Call create-ticket with the subject, body, requester, priority, and any tags.\\n4. Capture the new ticket ID.\\n\\n## Output\\nReturn the created ticket ID, its priority, and the requester it is linked to. Confirm whether a new user was created."},{"name":"search-tickets","description":"Run a Zendesk search to find tickets matching status, requester, or keyword criteria.","content":"# Search Zendesk Tickets\\n\\nFind tickets that match a set of conditions.\\n\\n## Steps\\n1. Express the criteria as a Zendesk search query, for example status, tags, requester, or keyword.\\n2. Call the search operation, choosing the right sort order.\\n3. Read the results and pull the fields needed for the task.\\n\\n## Output\\nReturn the matching tickets with ID, subject, status, priority, and assignee. State the query used and the total count via search-count if a volume figure is needed."},{"name":"sync-organization","description":"Create or update a Zendesk organization and its associated users for account hygiene.","content":"# Sync a Zendesk Organization\\n\\nKeep an organization record and its users accurate.\\n\\n## Steps\\n1. Look up the organization with get-organizations or autocomplete-organizations to check if it exists.\\n2. Create the organization, or update it with the latest name, domains, and details.\\n3. Reconcile the associated users, creating or updating them so they map to the organization.\\n\\n## Output\\nReport the organization ID and whether it was created or updated, plus a count of users created or updated. List any conflicts found."}],"templates":[{"title":"AgentPhone call-to-ticket logger","prompt":"Create a scheduled workflow that lists recent AgentPhone calls, pulls each transcript, and opens a Zendesk ticket summarizing the issue so no call goes untracked.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"agentphone","name":"AgentPhone"}]},{"title":"Downdetector support deflection","prompt":"Create a workflow triggered when a support ticket arrives that checks the Downdetector status of the affected service and, if there is a confirmed outage, replies to the customer that the issue is a known provider outage.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"downdetector","name":"Downdetector"}]},{"title":"Google Forms support intake","prompt":"Create a workflow that turns Google Forms support submissions into Zendesk tickets, prioritizes them with an agent, and posts the new ticket to the support Slack channel.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"google_forms","name":"Google Forms"},{"id":"slack","name":"Slack"}]},{"title":"Intercom-Zendesk migration mirror","prompt":"Build a workflow that mirrors new Intercom conversations into Zendesk as tickets during a migration window, syncs status and replies in both directions, and writes a table of every mapped conversation-to-ticket pair for audit.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"intercom","name":"Intercom"}]},{"title":"Logfire customer issue triage","prompt":"Build a workflow triggered by a support ticket that pulls the customer request ID from the ticket, searches Logfire for records matching that ID, fetches the full trace when one is found, and replies in Zendesk with whether the failure was user error or a backend fault.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"logfire","name":"Logfire"}]},{"title":"LogRocket session triage from support tickets","prompt":"Build a workflow that triggers on a new Zendesk ticket, requests LogRocket session highlights for the reporting user, polls until the result is ready, and posts the session summary back onto the ticket as an internal note.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"logrocket","name":"LogRocket"}]},{"title":"Mem0 customer-preference store","prompt":"Build a workflow that captures customer preferences from support interactions into Mem0 keyed by account, so future automations reference the real preferences.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"mem0","name":"Mem0"}]},{"title":"Teams ticket-bridge for Zendesk","prompt":"Create a workflow that mirrors high-priority Zendesk tickets into Microsoft Teams channels, keeps replies synced both ways, and closes the Teams thread when the ticket is resolved.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"microsoft_teams","name":"Microsoft Teams"}]},{"title":"Outlook customer escalation to Zendesk","prompt":"Create a workflow that reads new Outlook emails from customers, classifies whether each one is a support issue, and when it is, creates a Zendesk ticket with the email body, attachments, and contact details, then replies from Outlook with the ticket number.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"outlook","name":"Outlook"}]},{"title":"Pinecone support knowledge retriever","prompt":"Build a workflow that fetches each new Zendesk ticket, embeds the question with OpenAI, queries a Pinecone index of resolved tickets and docs, and drafts a suggested reply citing the most relevant matches for the agent to approve.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"pinecone","name":"Pinecone"},{"id":"embeddings","name":"Embeddings"}]},{"title":"Qdrant support-answer retriever","prompt":"Build a workflow that embeds each new Zendesk ticket with OpenAI, runs a filtered Qdrant search scoped to the customer’s product, and drafts a cited reply from the closest matching resolved tickets for the agent to approve.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"qdrant","name":"Qdrant"},{"id":"embeddings","name":"Embeddings"}]},{"title":"RevenueCat Google Play refund","prompt":"Create a workflow that takes a refund approval from a support ticket, calls the RevenueCat Google Play refund operation with the right transaction identifier, revokes access, posts the outcome back on the ticket, and logs the action in a compliance table.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"revenuecat","name":"RevenueCat"}]},{"title":"WhatsApp customer support agent","prompt":"Build a WhatsApp business agent that answers customer questions using a knowledge base, hands off to a human in Zendesk on complex tickets, and writes the conversation back to the contact record.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"whatsapp","name":"WhatsApp"}]},{"title":"X support ticket creator","prompt":"Create a scheduled workflow that polls X for tweets directed at the brand support handle, classifies each as a support request, and opens a Zendesk ticket with the tweet context and customer profile.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"x","name":"X"}]},{"title":"Zendesk ticket knowledge search","prompt":"Create a knowledge base connected to my Zendesk account so all past tickets, resolutions, and agent notes are automatically synced and searchable. Then build an agent my support team can ask things like \\"how do we usually resolve the SSO login issue?\\" or \\"has anyone reported this billing bug before?\\" to find past solutions instantly.","integrations":[{"id":"zendesk","name":"Zendesk"}]},{"title":"Zendesk auto-classifier","prompt":"Build a scheduled workflow that polls Zendesk for new tickets, classifies each one by product area, severity, and intent, applies the matching tags, sets priority, and assigns it to the right group so triage happens automatically.","integrations":[{"id":"zendesk","name":"Zendesk"}]},{"title":"Zendesk SLA breach alert","prompt":"Create a scheduled workflow that searches Zendesk every 15 minutes for tickets at risk of breaching first-response or resolution SLA, summarizes each one, and posts a Slack alert to the responsible group with deep links to the tickets.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"slack","name":"Slack"}]},{"title":"Zendesk ticket deflector","prompt":"Create a knowledge base from help center articles and past ticket resolutions, then build a scheduled workflow that polls for new Zendesk tickets, drafts a public reply using the knowledge base with citations, and posts it as an internal note for agents to send with one click.","integrations":[{"id":"zendesk","name":"Zendesk"}]},{"title":"Zendesk to Jira engineering bridge","prompt":"Build a scheduled workflow that searches Zendesk for tickets newly tagged as a bug, creates a linked Jira issue with the ticket details and customer impact, and posts the Jira link back as an internal note on the Zendesk ticket.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"jira","name":"Jira"}]},{"title":"Zendesk weekly CX pulse","prompt":"Create a scheduled weekly workflow that pulls Zendesk ticket volume, CSAT, top tags, and recurring issues, generates a narrative CX pulse with week-over-week deltas, and posts it to Slack with links to the standout tickets.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"slack","name":"Slack"}]},{"title":"Zendesk customer record sync","prompt":"Build a workflow that watches my CRM for new or updated accounts, searches Zendesk for the matching user and organization, and creates or updates them in bulk so support agents always see the latest company, plan, and contact details on every ticket.","integrations":[{"id":"zendesk","name":"Zendesk"},{"id":"salesforce","name":"Salesforce"}]}]},{"id":"zep","type":"zep","slug":"zep","name":"Zep","description":"Long-term memory for AI agents","category":"AI","docsUrl":"https://docs.sim.ai/integrations/zep","authType":"api-key","connections":[],"operations":[{"name":"Create Thread","description":"Start a new conversation thread in Zep"},{"name":"Add Messages","description":"Add messages to an existing thread"},{"name":"Get Context","description":"Retrieve user context from a thread with summary or basic mode"},{"name":"Get Messages","description":"Retrieve messages from a thread"},{"name":"Get Threads","description":"List all conversation threads"},{"name":"Delete Thread","description":"Delete a conversation thread from Zep"},{"name":"Add User","description":"Create a new user in Zep"},{"name":"Get User","description":"Retrieve user information from Zep"},{"name":"Get User Threads","description":"List all conversation threads for a specific user"}],"triggers":[],"skills":[{"name":"persist-conversation-turn","description":"Record the latest user and agent messages into a Zep thread so memory builds over time.","content":"# Persist a Conversation Turn in Zep\\n\\nSave each exchange so the agent remembers it later.\\n\\n## Steps\\n1. Ensure a user exists for the person, adding the user if this is their first interaction.\\n2. Ensure a thread exists for this conversation, creating one if needed and tying it to the user.\\n3. Add the latest messages to the thread, tagging roles as user or assistant.\\n4. Confirm the messages were stored.\\n\\n## Output\\nReturn the thread ID and user ID used, and confirm how many messages were added. These IDs are reused on the next turn."},{"name":"recall-user-context","description":"Fetch the assembled memory context for a Zep thread to ground the next agent response.","content":"# Recall User Context from Zep\\n\\nPull relevant long-term memory before the agent replies.\\n\\n## Steps\\n1. Identify the thread for the current conversation, and the user behind it.\\n2. Call get-context for the thread, choosing summary mode for natural language or basic mode for raw facts.\\n3. Use the returned context block to inform the next response, since it spans all of this user prior threads.\\n\\n## Output\\nReturn the context block as relevant facts and history about the user. Note the thread and user it was drawn from, and feed it into the agent prompt rather than echoing it to the user."},{"name":"review-user-memory","description":"List a user threads and messages in Zep to inspect what the agent remembers about them.","content":"# Review What Zep Remembers\\n\\nInspect the stored memory for a user.\\n\\n## Steps\\n1. Get the user to confirm they exist and read their profile.\\n2. Get the user threads to see every conversation tied to them.\\n3. Get messages from a thread of interest to read the stored history.\\n\\n## Output\\nReturn a summary of the user threads with counts and key facts surfaced, plus the messages from any thread inspected. Cite the user ID and thread IDs."}],"templates":[{"title":"Mem0 + Zep hybrid memory agent","prompt":"Create a chat agent that uses Mem0 for persistent user preferences and Zep for in-session continuity, so the agent recalls long-term context while staying coherent turn-to-turn.","integrations":[{"id":"zep","name":"Zep"},{"id":"mem0","name":"Mem0"}]},{"title":"Zep session memory for chat","prompt":"Create a chat agent that stores every turn in Zep with user metadata, retrieves the most relevant prior context on each new question, and answers with continuity instead of forgetting.","integrations":[{"id":"zep","name":"Zep"}]},{"title":"Zep + knowledge base support bot","prompt":"Build a support agent that combines Zep session memory with a knowledge base, so it remembers what the customer has already tried while still grounding answers in product docs.","integrations":[{"id":"zep","name":"Zep"}]},{"title":"Zep + Salesforce account memory","prompt":"Build a workflow that for each Salesforce account writes meeting and email context into Zep keyed by account, so any future agent interaction has full history.","integrations":[{"id":"zep","name":"Zep"},{"id":"salesforce","name":"Salesforce"}]},{"title":"Zep + Intercom support continuity","prompt":"Create a Zep-backed support agent for Intercom that remembers what each customer has tried before, prefers, or escalated, so support conversations never restart from scratch.","integrations":[{"id":"zep","name":"Zep"},{"id":"intercom","name":"Intercom"}]},{"title":"Zep evaluation harness","prompt":"Build a scheduled workflow that evaluates Zep memory recall accuracy weekly against a labeled eval set, captures regressions, and writes a quality report.","integrations":[{"id":"zep","name":"Zep"}]},{"title":"Zep personal-assistant memory","prompt":"Create a personal assistant agent that records preferences, recurring tasks, and prior decisions in Zep, then retrieves the relevant facts on each request so it stays consistent across days instead of asking the same questions again.","integrations":[{"id":"zep","name":"Zep"}]},{"title":"Zep + Slack team-context bot","prompt":"Build a Slack bot that stores each conversation in Zep keyed by channel and user, retrieves the relevant prior context when someone asks a follow-up, and answers in thread with continuity across the whole team’s history.","integrations":[{"id":"zep","name":"Zep"},{"id":"slack","name":"Slack"}]}]},{"id":"zerobounce","type":"zerobounce","slug":"zerobounce","name":"ZeroBounce","description":"Validate email deliverability and check account credits","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/zerobounce","authType":"api-key","connections":[],"operations":[{"name":"Verify Email","description":"Validate an email address deliverability in real time. Uses one validation credit."},{"name":"Get Remaining Credits","description":"Retrieve the remaining validation credits for the authenticated account."}],"triggers":[],"skills":[],"templates":[]},{"id":"zoho_desk","type":"zoho_desk","slug":"zoho-desk","name":"Zoho Desk","description":"Manage Zoho Desk tickets, replies, contacts, and accounts","category":"Support","docsUrl":"https://docs.sim.ai/integrations/zoho_desk","authType":"oauth","connections":[{"id":"zoho-desk","kind":"oauth","label":"Connect with OAuth","providerId":"zoho-desk","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/zoho_desk","requiredScopes":[{"id":"Desk.tickets.READ","label":"View tickets, threads, comments, and attachments"},{"id":"Desk.tickets.CREATE","label":"Create support tickets"},{"id":"Desk.tickets.UPDATE","label":"Update tickets, send replies, and manage comments"},{"id":"Desk.contacts.READ","label":"View contacts"},{"id":"Desk.contacts.CREATE","label":"Create contacts"},{"id":"Desk.contacts.UPDATE","label":"Update contacts"},{"id":"Desk.accounts.READ","label":"View customer accounts"},{"id":"Desk.accounts.CREATE","label":"Create customer accounts"},{"id":"Desk.accounts.UPDATE","label":"Update customer accounts"},{"id":"Desk.search.READ","label":"Search tickets, contacts, and accounts"},{"id":"Desk.departments.READ","label":"View departments"},{"id":"Desk.articles.READ","label":"View knowledge base articles"},{"id":"Desk.organization.READ","label":"View organization details"},{"id":"Desk.agents.READ","label":"View agents"},{"id":"Desk.basic.READ","label":"View basic data such as organizations, agents, and departments"},{"id":"Desk.webhooks.CREATE","label":"Create webhooks"},{"id":"Desk.webhooks.DELETE","label":"Delete webhooks"},{"id":"aaaserver.profile.READ","label":"View your Zoho profile"}],"fields":[]},{"id":"zoho-desk-service-account","kind":"service_account","providerId":"zoho-desk-service-account","label":"Add Self Client","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/zoho-desk-service-account","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true},{"id":"orgId","label":"Organization ID","placeholder":"600123456","secret":false,"hint":"Expected a numeric organization ID like 600123456, or a full ZohoDesk.600123456 value."},{"id":"dataCenter","label":"Data center","placeholder":"Select a data center","secret":false,"optional":true,"options":[{"value":"us","label":"United States (accounts.zoho.com)"},{"value":"eu","label":"Europe (accounts.zoho.eu)"},{"value":"in","label":"India (accounts.zoho.in)"},{"value":"au","label":"Australia (accounts.zoho.com.au)"}],"hint":"The region your Zoho account signs in to. New credentials default to the United States."}]}],"operations":[{"name":"List Tickets","description":"List tickets from a Zoho Desk organization with optional filters. Returns a list projection: description, resolution, statusType and classification are only available from Get Ticket."},{"name":"Get Ticket","description":"Retrieve a single Zoho Desk ticket by ID."},{"name":"Update Ticket","description":"Update fields on an existing Zoho Desk ticket."},{"name":"List Comments","description":"List comments on a Zoho Desk ticket."},{"name":"Add Comment","description":"Add a comment to a Zoho Desk ticket."},{"name":"List Threads","description":"List conversation threads on a Zoho Desk ticket, newest first (Zoho sorts by sendDateTime descending by default). Returns a list projection: message bodies (content, summary, to/cc/bcc) come back only from Get Thread."},{"name":"Get Thread","description":"Retrieve the full content of a single Zoho Desk ticket thread."},{"name":"Get Contact","description":"Retrieve a Zoho Desk contact by ID."},{"name":"Get Attachment","description":"Download a Zoho Desk ticket attachment (from its href) as a file."},{"name":"List Organizations","description":"List the Zoho Desk organizations (portals) the connected account can access."},{"name":"Create Ticket","description":"Create Ticket in Zoho Desk."},{"name":"Search Tickets","description":"Search Tickets in Zoho Desk."},{"name":"Move Ticket","description":"Move a ticket to another department."},{"name":"Send Reply","description":"Send an email reply from a configured Zoho Desk sender address."},{"name":"List Contacts","description":"List Contacts in Zoho Desk."},{"name":"Create Contact","description":"Create Contact in Zoho Desk."},{"name":"Update Contact","description":"Update Contact in Zoho Desk."},{"name":"Search Contacts","description":"Search Contacts in Zoho Desk."},{"name":"List Accounts","description":"List Accounts in Zoho Desk."},{"name":"Create Account","description":"Create Account in Zoho Desk."},{"name":"Update Account","description":"Update Account in Zoho Desk."},{"name":"Search Accounts","description":"Search Accounts in Zoho Desk."},{"name":"Get Account","description":"Get Account in Zoho Desk."},{"name":"List Departments","description":"List Departments in Zoho Desk."},{"name":"Get Department","description":"Get Department in Zoho Desk."},{"name":"List Agents","description":"List Agents in Zoho Desk."},{"name":"Get Agent","description":"Get Agent in Zoho Desk."},{"name":"Get Comment","description":"Get Comment in Zoho Desk."},{"name":"Update Comment","description":"Update comment content or attachments; visibility can only be set when creating a comment."},{"name":"Delete Comment","description":"Delete Comment in Zoho Desk."}],"triggers":[{"id":"zoho_desk","name":"Zoho Desk Event","description":"Trigger a workflow when a Zoho Desk event occurs (ticket, comment, thread, contact, agent, task, or article changes)."}],"skills":[{"name":"triage-new-ticket","description":"Read an incoming Zoho Desk ticket, classify it, and set priority, classification, category, and assignee.","content":"# Triage a Zoho Desk Ticket\\n\\nClassify a newly created ticket and route it to the right owner.\\n\\n## Steps\\n1. If the organization ID is unknown, List Organizations and pick the portal to work in.\\n2. Get Ticket for the ticket ID and read subject, descriptionText, channel, and status.\\n3. Decide the urgency and the owning team from the content, and pick a classification — Problem, Request and Question are Zoho\'s system-defined values, but the portal may define its own.\\n4. Update Ticket to set priority, classification, category and subCategory, and the assigneeId or departmentId that should own it.\\n5. Add Comment as an internal note explaining the triage decision so the agent who picks it up has the reasoning.\\n\\n## Output\\nReport the ticket ID and number, the classification and priority set, the assignee or department it was routed to, and anything ambiguous that needs a human decision."},{"name":"escalate-overdue-tickets","description":"Find Zoho Desk tickets past or near their response due date and escalate them with a higher priority and an owner.","content":"# Escalate Overdue Tickets\\n\\nCatch tickets that are breaching or about to breach their response commitment.\\n\\n## Steps\\n1. List Tickets filtered to open statuses, sorted by responseDueDate so the soonest-due tickets come first. Page with from and limit if the queue is large.\\n2. Compare responseDueDate and dueDate against the current time to separate already-breached tickets from ones due shortly.\\n3. For each breached ticket, Update Ticket to raise priority and reassign to the escalation owner via assigneeId or departmentId.\\n4. Add Comment as an internal note recording that the ticket was escalated, how overdue it was, and who now owns it.\\n\\n## Output\\nA list of escalated tickets with ticket number, how far past due each was, the new priority, and the new owner. Include a separate at-risk list of tickets due soon but not yet breached."},{"name":"daily-ticket-digest","description":"Summarize the current Zoho Desk queue by status, priority, and age into a digest for the support team.","content":"# Daily Ticket Digest\\n\\nProduce a morning read on where the support queue stands.\\n\\n## Steps\\n1. List Tickets for the department, filtering by the statuses you care about such as \\"Open,On Hold\\". Page with from and limit until the queue is covered.\\n2. Group the results by status, priority, and assignee, and compute counts for each group.\\n3. Flag unassigned tickets, tickets past responseDueDate, and anything that has sat untouched since createdTime.\\n4. Write a short narrative of what changed and what needs attention today.\\n\\n## Output\\nA digest with counts by status and priority, load per assignee, and a callout list of unassigned and overdue tickets by ticket number. State the filters used so the numbers are reproducible."},{"name":"draft-reply-as-internal-note","description":"Read a Zoho Desk ticket conversation and post a suggested reply as a private comment for an agent to review.","content":"# Draft a Reply as an Internal Note\\n\\nPrepare a response an agent can review and send, without messaging the customer directly.\\n\\n## Steps\\n1. Get Ticket to read the subject, descriptionText, status, and priority.\\n2. List Threads for the ticket and Get Thread on the most recent customer message to read its full content.\\n3. List Comments to check what has already been discussed internally so the draft does not repeat prior advice.\\n4. Write a reply that answers the latest customer message, and Add Comment with isPublic set to false so it posts as an internal draft. Use plainText unless the draft genuinely contains markup.\\n\\n## Output\\nThe ticket number, the comment ID of the posted draft, and a note on any facts the draft assumes that an agent must verify before sending. This posts an internal note only, never a reply to the customer."},{"name":"enrich-ticket-with-customer-context","description":"Pull the contact behind a Zoho Desk ticket and post a customer context summary as an internal note.","content":"# Enrich a Ticket With Customer Context\\n\\nGive the assigned agent the customer background before they start working the ticket.\\n\\n## Steps\\n1. Get Ticket with include set to contacts so the related contact record comes back with the ticket.\\n2. Get Contact for the ticket contactId to read the full contact record, including accountId, job title, email, and phone.\\n3. Search Tickets filtered by contactId or accountId to find related tickets, paging within the documented search limit.\\n4. Add Comment as an internal note summarizing who the customer is, their account, and any related open or recent tickets.\\n\\n## Output\\nThe ticket number, the contact and account identified, a list of related tickets by number, and the internal note that was posted. Say explicitly if no contact is linked to the ticket."},{"name":"package-ticket-for-engineering","description":"Assemble a Zoho Desk ticket conversation and its attachments into a bug report, then record the escalation on the ticket.","content":"# Package a Ticket for Engineering\\n\\nTurn a support ticket into a developer-ready bug report.\\n\\n## Steps\\n1. Get Ticket to read the subject, descriptionText, priority, and classification.\\n2. List Threads and Get Thread on the relevant messages to extract reproduction steps, error text, and environment details.\\n3. For each attachment referenced on a thread or comment, Get Attachment with its href to download the screenshot or log.\\n4. Write the bug report with a summary, steps to reproduce, expected versus actual behavior, and the attached evidence.\\n5. Update Ticket to set classification to Problem and record the tracker key in a custom field via customFields, then Add Comment as an internal note linking the escalation.\\n\\n## Output\\nThe assembled bug report, the ticket number it came from, the attachments downloaded, and confirmation of the custom field and internal note written back to the ticket."},{"name":"ticket-knowledge-gap-report","description":"Scan recent Zoho Desk tickets for recurring themes and propose the knowledge base articles that would deflect them.","content":"# Ticket Knowledge Gap Report\\n\\nFind the questions customers keep asking that no article answers.\\n\\n## Steps\\n1. List Tickets across the statuses and departments in scope, paging with from and limit to cover a meaningful window.\\n2. Read each subject, category, and subCategory, and Get Ticket for descriptionText when needed to group recurring themes.\\n3. Rank themes by ticket volume, and for the top ones Get Ticket and List Threads on a couple of examples to understand what the customer actually needed.\\n4. For each theme, propose a knowledge base article with a working title and the questions it must answer.\\n\\n## Output\\nA ranked table of themes with ticket counts and example ticket numbers, plus the proposed article titles and outlines. Note which themes are one-off incidents rather than genuine documentation gaps."}],"templates":[{"title":"Zoho Desk new-ticket Slack alert","prompt":"When a new ticket is created in Zoho Desk, send a formatted Slack message to my support channel with the subject, priority, requester, and a link to the ticket.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"},{"id":"slack","name":"Slack"}]},{"title":"Zoho Desk AI ticket triage","prompt":"When a Zoho Desk ticket is created, read the subject and description, classify the priority and category, and update the ticket with the suggested priority and a triage comment.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk AI draft reply","prompt":"When a customer adds a new thread to a Zoho Desk ticket, fetch the full thread, draft a helpful reply grounded in my knowledge base, and post it as a private comment for an agent to review.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk escalation watcher","prompt":"Create a scheduled workflow that lists open high-priority Zoho Desk tickets with no agent response, and pings the on-call engineer in Slack with the ticket details.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"},{"id":"slack","name":"Slack"}]},{"title":"Zoho Desk daily support digest","prompt":"Build a scheduled workflow that searches Zoho Desk tickets using modifiedTimeRange for the last 24 hours, summarizes volume by status and priority, and emails a digest to the support lead.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk contact enrichment","prompt":"When a Zoho Desk ticket is created, look up the contact, enrich it with data from our CRM, and add a comment summarizing the customer context for the agent.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk knowledge search","prompt":"Create a knowledge base from my resolved Zoho Desk tickets and threads so I can ask an agent questions like \\"how did we resolve the billing sync issue?\\" and get answers with ticket citations.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"}]},{"title":"Zoho Desk attachment archiver","prompt":"When a Zoho Desk ticket thread includes an attachment, download the file and upload it to Google Drive in a folder named after the ticket number.","integrations":[{"id":"zoho_desk","name":"Zoho Desk"},{"id":"google_drive","name":"Google Drive"}]}]},{"id":"zoom","type":"zoom","slug":"zoom","name":"Zoom","description":"Create and manage Zoom meetings and recordings","category":"Communication","docsUrl":"https://docs.sim.ai/integrations/zoom","authType":"oauth","connections":[{"id":"zoom","kind":"oauth","label":"Connect with OAuth","providerId":"zoom","setup":"oauth","docsUrl":"https://docs.sim.ai/integrations/zoom","requiredScopes":[{"id":"user:read:user","label":"View Zoom profile information"},{"id":"meeting:write:meeting","label":"Create Zoom meetings"},{"id":"meeting:read:meeting","label":"View Zoom meeting details"},{"id":"meeting:read:list_meetings","label":"List Zoom meetings"},{"id":"meeting:update:meeting","label":"Update Zoom meetings"},{"id":"meeting:delete:meeting","label":"Delete Zoom meetings"},{"id":"meeting:read:invitation","label":"View Zoom meeting invitations"},{"id":"meeting:read:list_past_participants","label":"View past meeting participants"},{"id":"cloud_recording:read:list_user_recordings","label":"List Zoom cloud recordings"},{"id":"cloud_recording:read:list_recording_files","label":"View recording files"},{"id":"cloud_recording:delete:recording_file","label":"Delete individual cloud recording files"}],"fields":[]},{"id":"zoom-service-account","kind":"service_account","providerId":"zoom-service-account","label":"Add server-to-server app","setup":"fields","docsUrl":"https://docs.sim.ai/integrations/zoom-service-account","fields":[{"id":"clientId","label":"Client ID","placeholder":"Paste the client ID","secret":false},{"id":"clientSecret","label":"Client secret","placeholder":"Paste the client secret","secret":true},{"id":"orgId","label":"Account ID","placeholder":"Paste the account ID","secret":false}]}],"operations":[{"name":"Create Meeting","description":"Create a new Zoom meeting"},{"name":"List Meetings","description":"List all meetings for a Zoom user"},{"name":"Get Meeting","description":"Get details of a specific Zoom meeting"},{"name":"Update Meeting","description":"Update an existing Zoom meeting"},{"name":"Delete Meeting","description":"Delete or cancel a Zoom meeting"},{"name":"Get Meeting Invitation","description":"Get the meeting invitation text for a Zoom meeting"},{"name":"List Recordings","description":"List all cloud recordings for a Zoom user"},{"name":"Get Meeting Recordings","description":"Get all recordings for a specific Zoom meeting"},{"name":"Delete Recording","description":"Delete cloud recordings for a Zoom meeting"},{"name":"List Past Participants","description":"List participants from a past Zoom meeting"}],"triggers":[{"id":"zoom_meeting_started","name":"Zoom Meeting Started","description":"Trigger workflow when a Zoom meeting starts"},{"id":"zoom_meeting_ended","name":"Zoom Meeting Ended","description":"Trigger workflow when a Zoom meeting ends"},{"id":"zoom_participant_joined","name":"Zoom Participant Joined","description":"Trigger workflow when a participant joins a Zoom meeting"},{"id":"zoom_participant_left","name":"Zoom Participant Left","description":"Trigger workflow when a participant leaves a Zoom meeting"},{"id":"zoom_recording_completed","name":"Zoom Recording Completed","description":"Trigger workflow when a Zoom cloud recording is completed"},{"id":"zoom_webhook","name":"Zoom Webhook (All Events)","description":"Trigger workflow on any Zoom webhook event"}],"skills":[{"name":"schedule-meeting","description":"Create a Zoom meeting with a topic, time, and settings, and return the join details.","content":"# Schedule a Zoom Meeting\\n\\nBook a meeting and capture its join link.\\n\\n## Steps\\n1. Gather the host user ID, meeting topic, start time, duration, and timezone.\\n2. Choose the meeting type, typically scheduled, and set options like recording and waiting room.\\n3. Call the create-meeting operation.\\n4. Capture the meeting ID, join URL, and passcode returned.\\n\\n## Output\\nReturn the meeting ID, join URL, passcode, and start time. If you need formatted invite text, fetch the meeting invitation."},{"name":"reschedule-meeting","description":"Find a Zoom meeting and update its time, topic, or settings without recreating it.","content":"# Reschedule a Zoom Meeting\\n\\nMove or adjust an existing meeting.\\n\\n## Steps\\n1. Locate the meeting by ID, or list meetings for the host and match on topic.\\n2. Get the meeting to read its current settings.\\n3. Call update-meeting with only the fields that change, such as start time or duration.\\n4. Confirm the update and re-fetch the join details if they changed.\\n\\n## Output\\nReport the meeting ID, the old and new time, and confirm the join URL is unchanged or updated. Note who should be re-notified."},{"name":"fetch-meeting-recordings","description":"Retrieve cloud recordings for a past Zoom meeting and return the download links.","content":"# Fetch Zoom Meeting Recordings\\n\\nCollect the recordings from a completed meeting.\\n\\n## Steps\\n1. Identify the meeting ID, or use list-recordings to find recent recorded meetings.\\n2. Call get-meeting-recordings for the chosen meeting.\\n3. Collect the recording files, their types (video, audio, transcript), and download URLs.\\n\\n## Output\\nReturn each recording file with its type, size, and download URL, plus the meeting topic and date. Note if no recordings exist for the meeting."}],"templates":[{"title":"WhatsApp + Zoom meeting confirmer","prompt":"Build a workflow that sends a WhatsApp confirmation when a Zoom meeting is booked, with the join link and a one-tap reschedule option for the attendee.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"whatsapp","name":"WhatsApp"}]},{"title":"Zoom recording recap","prompt":"Build a workflow that runs after a Zoom meeting ends, pulls the cloud recording transcript, summarizes decisions and action items, and posts the recap to the linked Slack channel.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"slack","name":"Slack"}]},{"title":"Zoom meeting prep brief","prompt":"Create a scheduled workflow that runs each morning, lists today’s Zoom meetings, researches attendees with Apollo and the web, and emails a prep brief 30 minutes before each meeting.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"apollo","name":"Apollo"},{"id":"gmail","name":"Gmail"}]},{"title":"Zoom webinar follow-up","prompt":"Build a workflow that runs after a Zoom webinar, pulls the registrant and attendee lists, sends a follow-up email with the recording link, and writes attendance into HubSpot for marketing scoring.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"hubspot","name":"HubSpot"},{"id":"gmail","name":"Gmail"}]},{"title":"Zoom + Notion meeting notes","prompt":"Create a workflow that watches for Zoom recordings, transcribes, and writes a structured meeting-notes page to Notion under the right team space, with action items linked to owners.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"notion","name":"Notion"}]},{"title":"Zoom sales-call deal updater","prompt":"Build a workflow that runs after a Zoom sales call, summarizes objections, next steps, and stage signals from the transcript, and updates the linked Salesforce or HubSpot opportunity.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"salesforce","name":"Salesforce"},{"id":"hubspot","name":"HubSpot"}]},{"title":"Zoom recurring 1:1 logger","prompt":"Create a workflow that captures Zoom 1:1 meeting recaps, appends them to a per-employee log file, and surfaces talking points for the next 1:1 to the manager in Slack.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"slack","name":"Slack"}]},{"title":"Zoom + Telegram recap pusher","prompt":"Create a workflow that runs after a Zoom meeting, summarizes the transcript, and pushes the recap to a chosen Telegram channel for asynchronous review.","integrations":[{"id":"zoom","name":"Zoom"},{"id":"telegram","name":"Telegram"}]}]},{"id":"zoominfo","type":"zoominfo","slug":"zoominfo","name":"ZoomInfo","description":"Search and enrich B2B company and contact data with ZoomInfo.","category":"Sales","docsUrl":"https://docs.sim.ai/integrations/zoominfo","authType":"api-key","connections":[],"operations":[{"name":"Search Companies","description":"Search the ZoomInfo company database by name, industry, location, and size."},{"name":"Search Contacts","description":"Search ZoomInfo for contacts (people) by name, job title, company, and other filters. Does not return emails or phone numbers — use Enrich Contacts for engagement data."},{"name":"Enrich Companies","description":"Enrich up to 25 companies in one request with detailed firmographics, industry, financials, and more."},{"name":"Enrich Contacts","description":"Enrich up to 25 contacts in one request with verified emails, phone numbers, job details, and more."},{"name":"Search Intent","description":"Search for companies showing intent signals on specific topics."},{"name":"Search News","description":"Search ZoomInfo news articles by category, URL, or date range."}],"triggers":[],"skills":[{"name":"enrich-contact","description":"Enrich a known person with ZoomInfo to fill in verified title, email, and company data.","content":"# Enrich a Contact with ZoomInfo\\n\\nFill in verified detail for a known person.\\n\\n## Steps\\n1. Gather the identifiers you have, such as name and company, email, or a profile URL.\\n2. Call the enrich-contacts operation.\\n3. Extract the returned fields: verified email, direct phone, title, seniority, and company.\\n\\n## Output\\nReturn the enriched contact as structured fields with a match-confidence note. If no match was found, report the input used rather than fabricating values."},{"name":"build-target-account-list","description":"Search ZoomInfo companies by firmographic filters to build a list of target accounts.","content":"# Build a Target Account List with ZoomInfo\\n\\nAssemble accounts that fit the ideal-customer profile.\\n\\n## Steps\\n1. Translate the profile into company filters: industry, revenue band, employee size, and location.\\n2. Call search-companies with those filters and a result limit, choosing a sort order.\\n3. For top accounts, optionally enrich-companies to pull full firmographics.\\n\\n## Output\\nReturn the matched accounts with company name, domain, industry, size, and revenue band. State the filters used and the total match count."},{"name":"find-decision-makers","description":"Search ZoomInfo contacts at a target company by title and seniority to find decision makers.","content":"# Find Decision Makers with ZoomInfo\\n\\nLocate the right people inside a target account.\\n\\n## Steps\\n1. Identify the company, then set contact filters for title, department, and seniority.\\n2. Call search-contacts scoped to that company.\\n3. Enrich the chosen contacts to retrieve verified email and phone.\\n\\n## Output\\nReturn the decision makers with name, title, seniority, and verified contact details. Group by department and note which contacts have verified direct dials."},{"name":"compile-account-briefing","description":"Combine ZoomInfo firmographics, intent signals, and news into a pre-meeting account brief.","content":"# Compile a ZoomInfo Account Briefing\\n\\nProduce a one-page brief before an account meeting.\\n\\n## Steps\\n1. Enrich the company to pull firmographics: size, revenue, industry, and location.\\n2. Search intent signals for the account to see what topics they are researching.\\n3. Search news for recent company developments.\\n4. Synthesize these into a concise briefing.\\n\\n## Output\\nReturn a brief with company snapshot, top intent topics, recent news headlines, and two or three suggested talking points. Cite the company referenced."}],"templates":[{"title":"ZoomInfo contact enricher","prompt":"Build a workflow that watches CRM contacts, enriches each via ZoomInfo with title, seniority, and verified contact details, and writes the enriched data back.","integrations":[{"id":"zoominfo","name":"ZoomInfo"},{"id":"salesforce","name":"Salesforce"}]},{"title":"ZoomInfo account builder","prompt":"Create a workflow that runs a ZoomInfo company search against my ICP filters, enriches each match with firmographics, and writes the target account list into a tables-based research base.","integrations":[{"id":"zoominfo","name":"ZoomInfo"}]},{"title":"ZoomInfo intent monitor","prompt":"Build a scheduled workflow that pulls ZoomInfo intent signals for tracked accounts, ranks accounts surging on relevant topics, and posts a daily Slack alert for the sales team.","integrations":[{"id":"zoominfo","name":"ZoomInfo"},{"id":"slack","name":"Slack"}]},{"title":"ZoomInfo news digest","prompt":"Create a scheduled weekly workflow that searches ZoomInfo news for tracked accounts, summarizes notable events with an agent, and writes a per-account briefing for the sales team.","integrations":[{"id":"zoominfo","name":"ZoomInfo"}]},{"title":"ZoomInfo CRM gap-filler","prompt":"Build a scheduled workflow that finds Salesforce contacts missing firmographic or contact fields, runs ZoomInfo enrichment to fill the gaps, and writes coverage metrics to a hygiene table.","integrations":[{"id":"zoominfo","name":"ZoomInfo"},{"id":"salesforce","name":"Salesforce"}]},{"title":"ZoomInfo buying-committee builder","prompt":"Build a workflow that takes a target account, runs a ZoomInfo contact search to find the decision-makers by title and department, enriches each with verified email and phone, and writes the mapped buying committee into a sales table for outreach.","integrations":[{"id":"zoominfo","name":"ZoomInfo"}]},{"title":"ZoomInfo account briefing pack","prompt":"Create a workflow that takes an upcoming meeting account, pulls ZoomInfo company firmographics, recent intent signals, and the latest news for that company, and assembles a one-page pre-meeting briefing document the rep reads before the call.","integrations":[{"id":"zoominfo","name":"ZoomInfo"}]}]}]' +) diff --git a/apps/sim/platform/lib/integrations/center-model.ts b/apps/sim/platform/lib/integrations/center-model.ts index 588eda5e904..625693b137e 100644 --- a/apps/sim/platform/lib/integrations/center-model.ts +++ b/apps/sim/platform/lib/integrations/center-model.ts @@ -1,3 +1,5 @@ +import type { ComponentType } from 'react' + export type IntegrationTab = 'apps' | 'skills' | 'mcps' | 'credentials' type IntegrationScope = 'shared' | 'personal' @@ -16,9 +18,9 @@ export interface AppSummary { category: string href: string connected: boolean - status?: string searchable?: string people?: readonly IntegrationPerson[] + peopleTotal?: number scope?: IntegrationScope } @@ -41,9 +43,9 @@ export type IntegrationResource = ResourceIdentity & export interface IntegrationCenterData { viewer: IntegrationPerson + workspaces: readonly { id: string; name: string; memberIds: readonly string[] }[] people: IntegrationPerson[] appPeople: Record + appUsageTotal: Record resources: IntegrationResource[] } - -import type { ComponentType } from 'react' diff --git a/apps/sim/platform/lib/integrations/center-navigation.ts b/apps/sim/platform/lib/integrations/center-navigation.ts index ff237bb94c7..54780b10c1f 100644 --- a/apps/sim/platform/lib/integrations/center-navigation.ts +++ b/apps/sim/platform/lib/integrations/center-navigation.ts @@ -18,39 +18,6 @@ export const centerParams = { export const serializeCenter = createSerializer(centerParams) -/** Discovery categories describe providers, independently of their connection or sharing state. */ -export function appCategory(provider: string): string { - if ( - [ - 'gmail', - 'outlook', - 'google_calendar', - 'google-calendar', - 'slack', - 'microsoft_teams', - 'fireflies', - 'zoom', - ].includes(provider) - ) - return 'Communication' - if ( - [ - 'google_drive', - 'google-drive', - 'notion', - 'confluence', - 'coda', - 'sharepoint', - 'dropbox', - ].includes(provider) - ) - return 'Knowledge' - if (['github', 'gitlab', 'linear', 'jira'].includes(provider)) return 'Development' - if (['hubspot', 'salesforce', 'attio', 'intercom', 'zendesk'].includes(provider)) - return 'Customers' - return 'Productivity' -} - const loadCenter = createLoader(centerParams) /** Keep directory filters through a provider detail or credential round trip. */ diff --git a/apps/sim/platform/lib/integrations/credential-display.ts b/apps/sim/platform/lib/integrations/credential-display.ts new file mode 100644 index 00000000000..8903dc90f05 --- /dev/null +++ b/apps/sim/platform/lib/integrations/credential-display.ts @@ -0,0 +1,12 @@ +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' + +/** Keep a credential's supporting copy distinct from its display name. */ +export function credentialDescription(credential: IntegrationCredential, providerName?: string) { + const name = credential.displayName.trim().toLowerCase() + const description = [credential.description, credential.accountLabel].find( + (value) => value?.trim() && value.trim().toLowerCase() !== name + ) + if (description) return description + const scope = credential.scope.kind === 'personal' ? 'Personal' : credential.scope.name + return providerName ? `${providerName} · ${scope}` : scope +} diff --git a/apps/sim/platform/lib/integrations/credential-model.ts b/apps/sim/platform/lib/integrations/credential-model.ts new file mode 100644 index 00000000000..a560a4943b2 --- /dev/null +++ b/apps/sim/platform/lib/integrations/credential-model.ts @@ -0,0 +1,58 @@ +import type { IntegrationPerson } from '@/platform/lib/integrations/center-model' +import type { IntegrationAccount } from '@/platform/lib/integrations/fixture-model' + +export interface CredentialMember extends IntegrationPerson { + userId: string + email?: string + role: 'admin' | 'member' + roleSource: 'explicit' | 'workspace-admin' + explicitAdmin: boolean + status: 'active' | 'pending' | 'revoked' +} + +/** UI metadata only: provider secrets and tokens never enter the product session. */ +export interface IntegrationCredential { + id: string + appId: string + providerId: string + type: 'oauth' | 'service_account' | 'personal_token' | 'mcp' | 'slack' + displayName: string + description: string + accountLabel?: string + instanceUrl?: string + role: 'admin' | 'member' + status: 'active' | 'needs_reauth' + canReconnect: boolean + scope: + | { kind: 'workspace'; id: string; name: string } + | { kind: 'personal'; ownerId: string } + | { kind: 'organization-managed'; id: string; name: string } + members: readonly CredentialMember[] + permissions?: IntegrationAccount['permissions'] +} + +export interface CredentialField { + id: string + label: string + placeholder?: string + hint?: string + secret?: boolean + multiline?: boolean + optional?: boolean + defaultValue?: string + options?: readonly { value: string; label: string }[] + visibleWhen?: { field: string; values: readonly string[] } +} + +/** Public enrollment requirements projected from the existing connection definitions. */ +export interface CredentialConnection { + id: string + kind: IntegrationCredential['type'] + label: string + providerId: string + setup: 'oauth' | 'fields' | 'google-json' | 'slack-bot' | 'oracle-database' + docsUrl?: string + requiredScopes?: readonly { id: string; label: string }[] + fields: readonly CredentialField[] + personalOnly?: boolean +} diff --git a/apps/sim/platform/lib/integrations/fixture-model.ts b/apps/sim/platform/lib/integrations/fixture-model.ts index f51697179e5..7aaf8341549 100644 --- a/apps/sim/platform/lib/integrations/fixture-model.ts +++ b/apps/sim/platform/lib/integrations/fixture-model.ts @@ -1,5 +1,6 @@ import { platformHref } from '@/platform/design-system/navigation' import { integrationCenterHref } from '@/platform/lib/integrations/center-navigation' +import type { IntegrationCredential } from '@/platform/lib/integrations/credential-model' import type { MemberSecretSource } from '@/platform/lib/integrations/member-secret-source' export type AccountMethod = 'oauth' | 'mcp' | 'slack' @@ -30,16 +31,25 @@ export interface OrganizationIntegration { providerId: string name: string description: string + category?: string setupGuideUrl: string searchResource: string | null searchReads: readonly { id: string; label: string }[] requestedScopes: readonly { id: string; label: string }[] | null accessDescription: string - availability: 'ready' | 'managed' | 'unconfigured' | 'disabled' | 'paused' | 'unavailable' + availability: + | 'ready' + | 'managed' + | 'unconfigured' + | 'disabled' + | 'paused' + | 'unavailable' + | 'catalog' connectableMethod: AccountMethod | null - connectionCandidate?: IntegrationAccount fixtureAuthorization?: true - account: IntegrationAccount | null + canAddCredential: boolean + credentialProviders: readonly string[] + credentials: IntegrationCredential[] } export interface IntegrationsData { @@ -54,20 +64,3 @@ export function memberIntegrationHref( ) { return integrationCenterHref(platformHref(path, search), search, query) } - -export function memberStatus(item: OrganizationIntegration) { - switch (item.availability) { - case 'managed': - return 'Organization managed' - case 'unconfigured': - return 'Not configured' - case 'disabled': - return 'Disabled by your organization' - case 'paused': - return 'Connections paused' - case 'unavailable': - return 'Currently unavailable' - } - if (item.account?.status === 'needs_reauth' && item.account.canReconnect) - return 'Reconnect needed' -} diff --git a/apps/sim/platform/lib/integrations/metadata.generated.ts b/apps/sim/platform/lib/integrations/metadata.generated.ts index aefa29519bb..aeb19548655 100644 --- a/apps/sim/platform/lib/integrations/metadata.generated.ts +++ b/apps/sim/platform/lib/integrations/metadata.generated.ts @@ -4,6 +4,7 @@ export const providerMetadata = [ id: 'coda', name: 'Coda', description: 'Read and write Coda docs, pages, tables, and rows', + category: 'Documents', setupGuideUrl: 'https://docs.sim.ai/search/coda', searchResource: 'Documents', searchReads: [ @@ -18,6 +19,7 @@ export const providerMetadata = [ id: 'confluence', name: 'Confluence', description: 'Manage Confluence pages, comments, and attachments', + category: 'Documents', setupGuideUrl: 'https://docs.sim.ai/search/confluence', searchResource: 'Spaces', searchReads: [], @@ -74,6 +76,7 @@ export const providerMetadata = [ id: 'fireflies', name: 'Fireflies', description: 'Interact with Fireflies.ai meeting transcripts and recordings', + category: 'Productivity', setupGuideUrl: 'https://docs.sim.ai/search/fireflies', searchResource: 'Meetings', searchReads: [ @@ -87,6 +90,7 @@ export const providerMetadata = [ id: 'github', name: 'GitHub', description: 'Interact with GitHub or trigger workflows from GitHub events', + category: 'DevOps', setupGuideUrl: 'https://docs.sim.ai/search/github', searchResource: 'Repositories', searchReads: [], @@ -96,6 +100,7 @@ export const providerMetadata = [ id: 'gitlab', name: 'GitLab', description: 'Interact with GitLab projects, issues, merge requests, and pipelines', + category: 'DevOps', setupGuideUrl: 'https://docs.sim.ai/search/gitlab', searchResource: 'Projects', searchReads: [], @@ -106,6 +111,7 @@ export const providerMetadata = [ name: 'Gmail', description: 'Send, read, search, and move Gmail messages or trigger workflows from Gmail events', + category: 'Email', setupGuideUrl: 'https://docs.sim.ai/search/gmail', searchResource: 'Labels', searchReads: [], @@ -125,6 +131,7 @@ export const providerMetadata = [ id: 'google_calendar', name: 'Google Calendar', description: 'Manage Google Calendar events', + category: 'Productivity', setupGuideUrl: 'https://docs.sim.ai/search/google-calendar', searchResource: 'Calendars', searchReads: [], @@ -139,6 +146,7 @@ export const providerMetadata = [ id: 'google_drive', name: 'Google Drive', description: 'Manage files, folders, and permissions', + category: 'Documents', setupGuideUrl: 'https://docs.sim.ai/search/google-drive', searchResource: 'Folders and shared drives', searchReads: [], @@ -160,6 +168,7 @@ export const providerMetadata = [ id: 'google_meet', name: 'Google Meet', description: 'Create and manage Google Meet meetings', + category: 'Communication', setupGuideUrl: 'https://docs.sim.ai/search/google-meet', searchResource: 'Meetings', searchReads: [], @@ -181,6 +190,7 @@ export const providerMetadata = [ id: 'granola', name: 'Granola', description: 'Access meeting notes, transcripts, and audit events from Granola', + category: 'Productivity', setupGuideUrl: 'https://docs.sim.ai/search/granola', searchResource: 'Meetings', searchReads: [ @@ -195,6 +205,7 @@ export const providerMetadata = [ id: 'hubspot', name: 'HubSpot', description: 'Interact with HubSpot CRM or trigger workflows from HubSpot events', + category: 'Sales', setupGuideUrl: 'https://docs.sim.ai/search/hubspot', searchResource: 'CRM records', searchReads: [ @@ -207,6 +218,7 @@ export const providerMetadata = [ id: 'jira', name: 'Jira', description: 'Manage Jira issues, comments, attachments, and worklogs', + category: 'Productivity', setupGuideUrl: 'https://docs.sim.ai/search/jira', searchResource: 'Projects', searchReads: [], @@ -322,6 +334,7 @@ export const providerMetadata = [ id: 'linear', name: 'Linear', description: 'Interact with Linear issues, projects, and more', + category: 'Productivity', setupGuideUrl: 'https://docs.sim.ai/search/linear', searchResource: 'Projects', searchReads: [], @@ -337,6 +350,7 @@ export const providerMetadata = [ id: 'lucid', name: 'Lucid', description: 'Search Lucidchart diagrams and Lucidspark boards using your Lucid account', + category: 'Other', setupGuideUrl: 'https://docs.sim.ai/search/lucid', searchResource: 'Documents', searchReads: [ @@ -352,6 +366,7 @@ export const providerMetadata = [ id: 'notion', name: 'Notion', description: 'Manage Notion pages', + category: 'Documents', setupGuideUrl: 'https://docs.sim.ai/search/notion', searchResource: 'Pages', searchReads: [ @@ -369,6 +384,7 @@ export const providerMetadata = [ id: 'salesforce', name: 'Salesforce', description: 'Interact with Salesforce CRM', + category: 'Sales', setupGuideUrl: 'https://docs.sim.ai/search/connect-your-account', searchResource: null, searchReads: [], @@ -383,6 +399,7 @@ export const providerMetadata = [ name: 'Slack', description: 'Manage Slack messages, channels, users, files, Lists, canvases, and Agent Sessions', + category: 'Communication', setupGuideUrl: 'https://docs.sim.ai/search/slack', searchResource: 'Channels', searchReads: [], @@ -409,6 +426,7 @@ export const providerMetadata = [ id: 'zoom', name: 'Zoom', description: 'Create and manage Zoom meetings and recordings', + category: 'Communication', setupGuideUrl: 'https://docs.sim.ai/search/zoom', searchResource: 'Meetings', searchReads: [ @@ -557,3 +575,190 @@ export const memberSecretMetadata = { description: 'Store shared or personal secrets for organization Home conversations', setupGuideUrl: 'https://docs.sim.ai/search/generic-secrets', } as const +export const slackBotCapabilities = [ + { + id: 'trigger_mention', + label: '@mention', + description: 'Trigger the workflow when someone @-mentions your bot.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_dm', + label: 'Direct message', + description: 'Trigger the workflow when a user sends your bot a 1:1 direct message.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_public_channel', + label: 'Public channel message', + description: 'Trigger on messages in public channels your bot has been invited to.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_private_channel', + label: 'Private channel message', + description: 'Trigger on messages in private channels your bot has been invited to.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_reaction', + label: 'Reaction', + description: + 'Trigger when an emoji reaction is added or removed anywhere the bot can see — public, private, or DM. Slack does not allow restricting the reactions scope by channel type.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_file_shared', + label: 'File shared', + description: 'Trigger when a file is shared in a channel your bot can see.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_member_channel', + label: 'Member joined / left channel', + description: 'Trigger when a member joins or leaves a channel your bot is in.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_channel_lifecycle', + label: 'Channel created / archived / renamed', + description: 'Trigger when a channel is created, archived, or renamed.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_pin', + label: 'Pin added / removed', + description: 'Trigger when a message is pinned or unpinned in a channel.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'trigger_team_join', + label: 'Member joined workspace', + description: 'Trigger when a new member joins the workspace.', + defaultChecked: true, + group: 'trigger', + }, + { + id: 'action_lists', + label: 'Manage Lists', + description: + 'Read Lists and column schemas; create, update, and delete rows. Requires a paid Slack plan.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_canvases', + label: 'Manage canvases', + description: 'Create and edit canvases, read metadata, find sections, and delete canvases.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_add_reaction', + label: 'Add reactions', + description: 'Let the bot add emoji reactions to messages.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_read_history', + label: 'Read message history', + description: + 'Let the bot page through channel, thread, and DM history (conversations.history / conversations.replies).', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_read_files', + label: 'Read file attachments', + description: 'Let the bot download file attachments on incoming messages.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_read_users', + label: 'Look up users', + description: 'Resolve user IDs to names, profiles, and email addresses.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_manage_conversations', + label: 'Manage conversations', + description: 'Create, join, update, and manage membership in channels and group DMs.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_write_files', + label: 'Manage files', + description: 'Upload and delete files owned by this bot.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_bookmarks', + label: 'Manage bookmarks', + description: 'Add, update, list, and remove channel bookmarks.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_pins', + label: 'Manage pins', + description: 'Pin and unpin messages, and list pinned items.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_usergroups', + label: 'Manage user groups', + description: 'Create and update user groups and their members.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_profiles', + label: 'Read profiles and set presence', + description: 'Read user profiles and set the bot’s presence.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_workspace_info', + label: 'Read workspace information', + description: 'Read workspace details, custom emoji, and notification status.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_unfurls', + label: 'Unfurl links', + description: 'Attach custom link previews for configured unfurl domains.', + defaultChecked: true, + group: 'action', + }, + { + id: 'action_interactivity', + label: 'Buttons & modals', + description: + 'Let workflows trigger on interactions — button/select clicks and modal submits. Enables the app’s Interactivity Request URL.', + defaultChecked: true, + group: 'action', + }, +] as const +export const slackManagedUserAuthorization = { + id: 'managed_user_authorization', + label: 'Managed user authorization', + description: 'Let people authorize this Slack app for use in Credential Groups.', + defaultChecked: true, +} as const diff --git a/apps/sim/platform/preview/control-specimen.tsx b/apps/sim/platform/preview/control-specimen.tsx index 951e8e66bf4..8ceca98a455 100644 --- a/apps/sim/platform/preview/control-specimen.tsx +++ b/apps/sim/platform/preview/control-specimen.tsx @@ -7,7 +7,6 @@ import { AttachmentGrid, Avatar, AvatarGroup, - AvatarOverflow, BarChart, BrowserActionsMenu, Button, @@ -47,6 +46,7 @@ import { SelectField, SelectionItem, SidebarWorkspaceItems, + Stack, Switch, TextArea, TextAreaField, @@ -381,8 +381,8 @@ export function ControlSpecimen({ master, data, renderChild, location }: Control return case 'AvatarGroup': return - case 'AvatarOverflow': - return + case 'Stack': + return case 'Tooltip': return ( diff --git a/apps/sim/platform/public/provider-marks/catalog.svg b/apps/sim/platform/public/provider-marks/catalog.svg new file mode 100644 index 00000000000..25009fe72b2 --- /dev/null +++ b/apps/sim/platform/public/provider-marks/catalog.svg @@ -0,0 +1,663 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Claude + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Tavily + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bun.lock b/bun.lock index 3aa11c63417..d8c07dd5ae0 100644 --- a/bun.lock +++ b/bun.lock @@ -28,6 +28,7 @@ "pdf-lib": "1.17.1", "postcss": "8.5.30", "react": "19.2.4", + "react-dom": "19.2.4", "remark-gfm": "4.0.1", "remark-parse": "11.0.0", "sharp": "0.35.5", diff --git a/package.json b/package.json index 69ed62f7135..9817b3633e1 100644 --- a/package.json +++ b/package.json @@ -210,6 +210,7 @@ "pdf-lib": "1.17.1", "postcss": "8.5.30", "react": "19.2.4", + "react-dom": "19.2.4", "remark-gfm": "4.0.1", "remark-parse": "11.0.0", "sharp": "0.35.5", diff --git a/scripts/platform-integration-connections.ts b/scripts/platform-integration-connections.ts new file mode 100644 index 00000000000..3cc7300340e --- /dev/null +++ b/scripts/platform-integration-connections.ts @@ -0,0 +1,298 @@ +import { + type ClientCredentialAccountField, + getClientCredentialAccountDescriptor, +} from '../apps/sim/lib/credentials/client-credential-accounts/descriptors' +import { getServiceAccountConnectNoun } from '../apps/sim/lib/credentials/service-account-provider-ids' +import { + getTokenServiceAccountDescriptor, + type TokenServiceAccountField, +} from '../apps/sim/lib/credentials/token-service-accounts/descriptors' +import { + ATLASSIAN_SERVICE_ACCOUNT_PROVIDER_ID, + GOOGLE_SERVICE_ACCOUNT_PROVIDER_ID, + OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID, + ORACLE_DATABASE_SERVICE_ACCOUNT_PROVIDER_ID, + SLACK_CUSTOM_BOT_PROVIDER_ID, +} from '../apps/sim/lib/oauth/types' +import { + getAllOAuthServices, + getScopeDescription, + getServiceConfigByServiceId, +} from '../apps/sim/lib/oauth/utils' +import type { + CredentialConnection, + CredentialField, +} from '../apps/sim/platform/lib/integrations/credential-model' + +interface CatalogSource { + type: string + authType: 'oauth' | 'api-key' | 'none' + oauthServiceId?: string + docsUrl: string +} + +const services = new Map(getAllOAuthServices().map((service) => [service.serviceId, service])) + +function descriptorField( + field: TokenServiceAccountField | ClientCredentialAccountField, + defaultAuthMethod?: string +): CredentialField { + return { + id: field.id, + label: field.label, + placeholder: field.placeholder, + secret: field.secret, + ...('multiline' in field && field.multiline ? { multiline: true } : {}), + ...('optional' in field && field.optional && !field.requiredForAuthMethods + ? { optional: true } + : {}), + ...('options' in field && field.options ? { options: field.options } : {}), + ...('requiredForAuthMethods' in field && field.requiredForAuthMethods + ? { visibleWhen: { field: 'authMethod', values: field.requiredForAuthMethods } } + : {}), + ...(field.id === 'authMethod' && defaultAuthMethod ? { defaultValue: defaultAuthMethod } : {}), + ...('hint' in field && field.hint + ? { hint: field.hint } + : field.hintMessage + ? { hint: field.hintMessage } + : {}), + } +} + +/** Bespoke requirements mirror the existing workspace connection forms. */ +function bespokeSetup( + providerId: string +): Pick | null { + switch (providerId) { + case GOOGLE_SERVICE_ACCOUNT_PROVIDER_ID: + return { + setup: 'google-json', + docsUrl: 'https://docs.sim.ai/integrations/google-service-account', + fields: [ + { + id: 'serviceAccountJson', + label: 'JSON key', + placeholder: 'Paste the service-account JSON key', + secret: true, + multiline: true, + }, + ], + } + case ATLASSIAN_SERVICE_ACCOUNT_PROVIDER_ID: + return { + setup: 'fields', + docsUrl: 'https://docs.sim.ai/integrations/atlassian-service-account', + fields: [ + { id: 'apiToken', label: 'API token', placeholder: 'Paste the API token', secret: true }, + { id: 'domain', label: 'Site domain', placeholder: 'your-team.atlassian.net' }, + ], + } + case SLACK_CUSTOM_BOT_PROVIDER_ID: + return { + setup: 'slack-bot', + docsUrl: 'https://docs.sim.ai/integrations/slack', + fields: [ + { id: 'botToken', label: 'Bot token', placeholder: 'xoxb-...', secret: true }, + { + id: 'signingSecret', + label: 'Signing secret', + placeholder: 'Paste the signing secret', + secret: true, + }, + ], + } + case OCI_API_KEY_SERVICE_ACCOUNT_PROVIDER_ID: + return { + setup: 'fields', + docsUrl: 'https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm', + fields: [ + { id: 'tenancyOcid', label: 'Tenancy OCID', placeholder: 'ocid1.tenancy.oc1..' }, + { id: 'userOcid', label: 'User OCID', placeholder: 'ocid1.user.oc1..' }, + { + id: 'fingerprint', + label: 'Fingerprint', + placeholder: '00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff', + }, + { + id: 'privateKey', + label: 'Private key', + placeholder: '-----BEGIN PRIVATE KEY-----', + secret: true, + multiline: true, + }, + { + id: 'privateKeyPassphrase', + label: 'Private-key passphrase', + secret: true, + optional: true, + }, + { id: 'region', label: 'Region', placeholder: 'us-ashburn-1' }, + ], + } + case ORACLE_DATABASE_SERVICE_ACCOUNT_PROVIDER_ID: + return { + setup: 'oracle-database', + docsUrl: 'https://docs.sim.ai/integrations/oracledb', + fields: [ + { id: 'host', label: 'Host', placeholder: 'db.example.com' }, + { id: 'port', label: 'Port', placeholder: '1521', defaultValue: '1521' }, + { + id: 'protocol', + label: 'Protocol', + defaultValue: 'tcps', + options: [ + { value: 'tcps', label: 'TCPS (TLS)' }, + { value: 'tcp', label: 'TCP' }, + ], + }, + { + id: 'connectionType', + label: 'Connection identifier', + defaultValue: 'serviceName', + options: [ + { value: 'serviceName', label: 'Service name' }, + { value: 'sid', label: 'SID' }, + ], + }, + { + id: 'serviceName', + label: 'Service name', + placeholder: 'FREEPDB1', + visibleWhen: { field: 'connectionType', values: ['serviceName'] }, + }, + { + id: 'sid', + label: 'SID', + placeholder: 'ORCL', + visibleWhen: { field: 'connectionType', values: ['sid'] }, + }, + { id: 'username', label: 'Username', placeholder: 'app_user' }, + { + id: 'password', + label: 'Password', + placeholder: 'Enter the database password', + secret: true, + }, + { + id: 'walletContent', + label: 'PEM wallet', + placeholder: 'Paste ewallet.pem content', + secret: true, + multiline: true, + optional: true, + visibleWhen: { field: 'protocol', values: ['tcps'] }, + }, + { + id: 'walletPassword', + label: 'Wallet password', + placeholder: 'Password for an encrypted PEM wallet', + secret: true, + optional: true, + visibleWhen: { field: 'protocol', values: ['tcps'] }, + }, + ], + } + default: + return null + } +} + +function serviceAccountConnection(providerId: string): CredentialConnection | null { + const token = getTokenServiceAccountDescriptor(providerId) + const client = getClientCredentialAccountDescriptor(providerId) + const descriptor = token ?? client + const setup = descriptor + ? { + setup: 'fields' as const, + docsUrl: descriptor.docsUrl, + fields: descriptor.fields.map((field) => descriptorField(field, client?.defaultAuthMethod)), + } + : bespokeSetup(providerId) + if (!setup) return null + return { + id: providerId, + kind: 'service_account', + providerId, + label: + providerId === SLACK_CUSTOM_BOT_PROVIDER_ID + ? 'Set up a custom bot' + : `Add ${getServiceAccountConnectNoun(providerId)}`, + ...setup, + } +} + +/** Project only declared enrollment methods; a catalog API-key label creates no form by itself. */ +export function integrationConnections(integration: CatalogSource): CredentialConnection[] { + const type = integration.type.replace(/_v\d+$/, '') + if (type === 'gitlab') + return [ + { + id: 'gitlab-personal-token', + kind: 'personal_token', + label: 'Add personal token', + providerId: 'gitlab', + setup: 'fields', + docsUrl: 'https://docs.gitlab.com/user/profile/personal_access_tokens/', + personalOnly: true, + fields: [ + { + id: 'domain', + label: 'GitLab host', + placeholder: 'gitlab.example.com', + defaultValue: 'gitlab.com', + }, + { + id: 'apiToken', + label: 'Personal access token', + placeholder: 'glpat-…', + secret: true, + hint: 'Only you can use this connection.', + }, + ], + }, + ] + const service = services.get(integration.oauthServiceId ?? type) + if (!service) return [] + const config = getServiceConfigByServiceId(service.serviceId) + const methods: CredentialConnection[] = [] + if (integration.authType === 'oauth' && service.authType === 'oauth' && config) { + const providers = [service.providerId, ...(service.additionalProviderIds ?? [])] + for (const providerId of providers) { + const label = + providers.length > 1 ? config.providerIdLabels?.[providerId] : 'Connect with OAuth' + if (!label) throw new Error(`Missing OAuth option label for ${providerId}`) + methods.push({ + id: providerId, + kind: 'oauth', + label, + providerId, + setup: 'oauth', + docsUrl: integration.docsUrl, + requiredScopes: (config.scopes ?? []).map((id) => ({ + id, + label: getScopeDescription(id, providerId), + })), + fields: [ + ...(service.clientConfiguration?.fields ?? []).map((field) => ({ ...field })), + ...(providerId === 'microsoft-dataverse' + ? [ + { + id: 'dataverseEnvironmentUrl', + label: 'Environment URL', + placeholder: 'https://your-org.crm.dynamics.com', + }, + ] + : []), + ], + }) + } + } + const serviceAccountProviderId = + service.serviceAccountProviderId ?? + (service.authType === 'service_account' ? service.providerId : undefined) + if (serviceAccountProviderId) { + const connection = serviceAccountConnection(serviceAccountProviderId) + if (connection) methods.push(connection) + } + return methods +} diff --git a/scripts/sync-platform-integration-metadata.ts b/scripts/sync-platform-integration-metadata.ts index ffb75d7bc3d..cd045ee844c 100644 --- a/scripts/sync-platform-integration-metadata.ts +++ b/scripts/sync-platform-integration-metadata.ts @@ -4,12 +4,20 @@ */ import { readFileSync, writeFileSync } from 'node:fs' import { resolve } from 'node:path' +import { createElement } from 'react' import catalog from '@sim/deployment-config/integrations.json' import { SIM_DOCS_URL } from '@sim/utils/site' import ts from '@typescript/typescript6' import matter from 'gray-matter' +import { renderToStaticMarkup } from 'react-dom/server' import searchDocs from '../apps/docs/content/docs/search/meta.json' import { GmailV2Block } from '../apps/sim/blocks/blocks/gmail' +import { + getBlock, + getSuggestedSkillsForBlock, + getTemplatesForBlock, +} from '../apps/sim/blocks/registry' +import { formatIntegrationType } from '../apps/sim/blocks/types' import { getManagedOAuthConnectorPolicy } from '../apps/sim/lib/auth/connectors/managed-oauth' import { getOrganizationCredentialTypeCatalog } from '../apps/sim/lib/credential-groups/credential-types' import { @@ -33,8 +41,14 @@ import { LIVE_SEARCH_PROVIDER_IDS, type LiveSearchProviderId, } from '../apps/sim/lib/sim-search/live/provider-catalog' +import type { IntegrationCatalogEntry } from '../apps/sim/platform/lib/integrations/catalog-model' import { getToolMetadata } from '../apps/sim/tools/metadata' +import { + SLACK_CAPABILITIES, + SLACK_MANAGED_USER_AUTHORIZATION_CAPABILITY, +} from '../apps/sim/triggers/slack/capabilities' import { formatGeneratedSource } from './format-generated-source' +import { integrationConnections } from './platform-integration-connections' import { sourceProviderCatalog } from './platform-search-source-catalog' const root = resolve(import.meta.dir, '..') @@ -165,6 +179,7 @@ const providers = ids.sort().map((id) => { id, name: source.name, description: source.description, + category: block ? formatIntegrationType(block.integrationType) : 'Other', setupGuideUrl: `${SIM_DOCS_URL}/search/${searchDocs.pages.includes(slug) ? slug : 'connect-your-account'}`, searchResource: LIVE_SEARCH_SCOPE_FIELDS[id]?.label ?? null, searchReads: searchReads(id), @@ -208,6 +223,8 @@ export const credentialTypeCatalog = ${JSON.stringify(getOrganizationCredentialT export const credentialGroupCatalog = ${JSON.stringify(credentialGroupCatalog)} as const export const gmailToolMetadata = ${JSON.stringify(gmailTools)} as const export const memberSecretMetadata = ${JSON.stringify({ name: title, description, setupGuideUrl: `${SIM_DOCS_URL}/search/${secretGuide}` })} as const +export const slackBotCapabilities = ${JSON.stringify(SLACK_CAPABILITIES.map(({ id, label, description, defaultChecked, group }) => ({ id, label, description, defaultChecked, group })))} as const +export const slackManagedUserAuthorization = ${JSON.stringify(SLACK_MANAGED_USER_AUTHORIZATION_CAPABILITY)} as const `, output, root @@ -237,3 +254,99 @@ if (process.argv.includes('--check')) { } else { writeFileSync(sourceOutput, sourceGenerated) } + +const catalogOutput = resolve(root, 'apps/sim/platform/lib/integrations/catalog.generated.ts') +const catalogByType = new Map( + catalog.integrations.map((integration) => [integration.type.replace(/_v\d+$/, ''), integration]) +) +const integrationCatalog: IntegrationCatalogEntry[] = catalog.integrations.map((integration) => { + const { authType } = integration + if (authType !== 'oauth' && authType !== 'api-key' && authType !== 'none') + throw new Error(`Unknown catalog authentication method for ${integration.slug}: ${authType}`) + return { + id: integration.type.replace(/_v\d+$/, ''), + type: integration.type, + slug: integration.slug, + name: integration.name, + description: integration.description, + category: formatIntegrationType(integration.integrationType), + docsUrl: integration.docsUrl, + authType, + connections: integrationConnections({ ...integration, authType }), + operations: integration.operations, + triggers: integration.triggers, + skills: getSuggestedSkillsForBlock(integration.type), + templates: getTemplatesForBlock(integration.type).map(({ title, prompt, otherBlockTypes }) => ({ + title, + prompt, + integrations: [integration.type, ...otherBlockTypes].flatMap((type) => { + const id = type.replace(/_v\d+$/, '') + const related = catalogByType.get(id) + return related ? [{ id, name: related.name }] : [] + }), + })), + } +}) +const catalogGenerated = formatGeneratedSource( + `/** Generated by scripts/sync-platform-integration-metadata.ts. */ +import 'server-only' +import type { IntegrationCatalogEntry } from '@/platform/lib/integrations/catalog-model' +export const integrationCatalog: readonly IntegrationCatalogEntry[] = JSON.parse(${JSON.stringify(JSON.stringify(integrationCatalog))}) +`, + catalogOutput, + root +) +if (process.argv.includes('--check')) { + if (readFileSync(catalogOutput, 'utf8') !== catalogGenerated) + throw new Error( + 'Platform integration catalog is stale. Run bun scripts/sync-platform-integration-metadata.ts' + ) +} else { + writeFileSync(catalogOutput, catalogGenerated) +} + +const spriteOutput = resolve(root, 'apps/sim/platform/public/provider-marks/catalog.svg') +const symbols = integrationCatalog.map(({ id, type }) => { + const icon = getBlock(type)?.icon + if (!icon) throw new Error(`No canonical icon for ${type}`) + const markup = renderToStaticMarkup(createElement(icon), { identifierPrefix: `${id}-` }) + const svg = /^]*)>([\s\S]*)<\/svg>$/.exec(markup) + if (!svg) throw new Error(`Expected an SVG icon for ${type}`) + const attributes = svg[1].replace(/\s(?:id|width|height|class|xmlns)="[^"]*"/g, '') + if (!/\sviewBox="[^"]+"/.test(attributes)) + throw new Error(`Canonical icon for ${type} needs a viewBox`) + const body = svg[2] + .replace(/\sid="([^"]+)"/g, ` id="${id}-$1"`) + .replace(/url\(#([^)]+)\)/g, `url(#${id}-$1)`) + .replace(/((?:xlink:)?href)="#([^"]+)"/g, `$1="#${id}-$2"`) + return `${body}` +}) +const sprite = + `\n${symbols.join('\n')}\n\n`.replace( + /[\t ]+$/gm, + '' + ) +const markIdsOutput = resolve( + root, + 'apps/sim/platform/design-system/components/icon/provider-mark-ids.generated.ts' +) +const markIdsGenerated = formatGeneratedSource( + `/** Generated by scripts/sync-platform-integration-metadata.ts. */ +export const providerMarkIds = ${JSON.stringify(integrationCatalog.map(({ id }) => id))} as const +`, + markIdsOutput, + root +) +for (const [path, source] of [ + [spriteOutput, sprite], + [markIdsOutput, markIdsGenerated], +]) { + if (process.argv.includes('--check')) { + if (readFileSync(path, 'utf8') !== source) + throw new Error( + 'Platform provider marks are stale. Run bun scripts/sync-platform-integration-metadata.ts' + ) + } else { + writeFileSync(path, source) + } +} diff --git a/scripts/sync-platform-recipes.ts b/scripts/sync-platform-recipes.ts index 3aa9ff84cde..1b7ba01c178 100644 --- a/scripts/sync-platform-recipes.ts +++ b/scripts/sync-platform-recipes.ts @@ -201,7 +201,7 @@ for (const [owner, keys] of Object.entries(nativeOwners)) for (const row of registry.components) { const family = row.family.split('/')[0] if (family === 'Avatar' || family === 'AvatarGroup') { - owners.set(row.key, row.family.startsWith('AvatarGroup/Overflow') ? 'AvatarOverflow' : family) + owners.set(row.key, row.family.startsWith('AvatarGroup/Overflow') ? 'Stack' : family) } }