From a14316463c83dbea4c707bbb28e2ff8020c1876d Mon Sep 17 00:00:00 2001 From: Java Julian Date: Wed, 23 Sep 2026 18:18:41 -0400 Subject: [PATCH] docs: Update documentation for tool alignment and behavior corrections - Added a new section in CONTENT-REVIEW.md detailing the tool catalog and behavior alignment as of September 23, 2026, including updates to guide operation lists and trigger semantics. - Enhanced README.md with instructions for keeping tool documentation aligned with Innflow, including commands for syncing and verifying documentation. - Updated various documentation files to reflect changes in trigger handling, variable usage, and node configurations, ensuring clarity and accuracy in user guidance. - Adjusted terminology and descriptions across multiple documents to improve consistency and understanding of features and operations. --- CONTENT-ALIGNMENT.md | 79 + CONTENT-REVIEW.md | 10 + README.md | 20 + content/docs/academy/branching.mdx | 2 +- content/docs/academy/deployment.mdx | 2 +- content/docs/essentials/integrations.mdx | 2 +- content/docs/essentials/nodes.mdx | 7 +- content/docs/essentials/variables.mdx | 79 +- content/docs/essentials/workflows.mdx | 8 +- content/docs/features/assistant.mdx | 43 +- content/docs/features/copilot.mdx | 3 +- content/docs/features/credentials.mdx | 2 +- content/docs/features/executions-inbox.mdx | 2 +- content/docs/features/knowledge-base.mdx | 4 +- content/docs/features/tables.mdx | 2 +- content/docs/features/teams.mdx | 9 +- content/docs/index.mdx | 4 +- content/docs/quickstart.mdx | 2 +- content/docs/tools/agents-protocols.mdx | 31 +- content/docs/tools/ai.mdx | 28 +- content/docs/tools/communication.mdx | 76 +- content/docs/tools/crm-sales.mdx | 59 +- content/docs/tools/forms.mdx | 18 +- content/docs/tools/google-suite.mdx | 82 +- content/docs/tools/logic-utility.mdx | 136 +- content/docs/tools/meta.json | 21 +- content/docs/tools/microsoft.mdx | 74 +- content/docs/tools/project-management.mdx | 74 + content/docs/tools/reference.mdx | 3035 +++ content/docs/tools/search-data.mdx | 73 +- content/docs/tools/social-publishing.mdx | 2 +- content/docs/tools/storage-commerce.mdx | 110 + content/docs/triggers.mdx | 32 +- package.json | 4 +- scripts/check-tool-docs.mjs | 35 + scripts/sync-tool-reference.mjs | 52 + scripts/tool-catalog.snapshot.json | 21642 +++++++++++++++++++ scripts/tool-guide-map.json | 267 + scripts/tool-operation-audit.json | 373 + scripts/verify-build.mjs | 16 + 40 files changed, 26242 insertions(+), 278 deletions(-) create mode 100644 CONTENT-ALIGNMENT.md create mode 100644 content/docs/tools/reference.mdx create mode 100644 scripts/check-tool-docs.mjs create mode 100644 scripts/sync-tool-reference.mjs create mode 100644 scripts/tool-catalog.snapshot.json create mode 100644 scripts/tool-guide-map.json create mode 100644 scripts/tool-operation-audit.json diff --git a/CONTENT-ALIGNMENT.md b/CONTENT-ALIGNMENT.md new file mode 100644 index 0000000..4cd6872 --- /dev/null +++ b/CONTENT-ALIGNMENT.md @@ -0,0 +1,79 @@ +# Documentation alignment audit — September 23, 2026 + +This audit compares the local documentation with the current Innflow application source, including universal search, authoring contracts, execution handlers, navigation, and subscription limits. Application revision at review: `5ab764a564e371633b9cfc4166d84d69353a559c`. Documentation base: `43cc54675dffc41308dc89d5316062dac90312f1`. + +## Implemented changes + +Every item below has been implemented in this checkout. Paths under `src/` refer to the sibling Innflow application; `content/` paths refer to this documentation repository. + +| # | Mismatch or gap | Documentation correction | Application evidence | +| --- | --- | --- | --- | +| 1 | No complete reference tied to universal search | Added a generated reference covering all 94 standard node entries and 309 exact operation IDs | `src/components/universal-search-items.ts`, `src/config/node-registry.ts`, `src/config/tool-operations-registry.ts` | +| 2 | Handwritten configuration summaries omitted many fields | Added complete shared configuration field lists, selectors, conditional-field notes, and secret-field guidance | `src/features/editor/lib/authoring/contracts.ts`, `src/tool-configs/` | +| 3 | No repeatable catalog drift check | Added `docs:sync` and `docs:check`; stale reference or operation lists fail verification | Same registry and authoring-contract sources as items 1–2 | +| 4 | Innflow Trigger had no dedicated guide | Added purpose, typed input, caller selection, and links to trigger/action configuration | `src/features/copilot/lib/trigger-authoring.ts`, `src/features/triggers/lib/entrypoint.ts` | +| 5 | Trigger guide required manual independent-trigger enablement | Replaced with automatic draft upgrade on second-trigger save; retained busy/deployed restrictions | `src/features/triggers/server/automatic-execution-version.ts`, `src/features/editor/hooks/use-add-node.ts` | +| 6 | Nodes/workflows/deployment lesson repeated retired trigger setup | Updated all three entry-point explanations; documented selected-path execution | `src/features/triggers/lib/entrypoint.ts`, `src/inngest/utils.ts` | +| 7 | Manual Trigger claimed to have no output variable/data | Documented variable-picker and active-trigger metadata instead of denying output | `src/features/triggers/lib/entrypoint.ts`, `src/features/copilot/lib/trigger-authoring.ts` | +| 8 | Condition guide described JavaScript expressions as the new-node configuration | Documented typed comparisons, AND/OR combinations, and fixed If/Else outputs; retained a legacy-mode explanation | `src/features/tools/components/condition/executor.ts`, `src/features/editor/lib/authoring/contracts.ts` | +| 9 | Branching lesson implied LLM Condition was the default current form | Distinguished typed new Conditions from saved legacy LLM configurations | Same evidence as item 8 | +| 10 | Router guide omitted first-match semantics | Described best-match and first-match routing, ordered rules, and Else fallback | `src/features/tools/components/router/executor.ts` | +| 11 | Code guide promised the last expression always becomes output | Documented expression/stdout parsing, Python JSON printing, result/log wrappers, and declared output fields | `src/features/tools/components/code/executor.ts`, `src/features/tools/components/code/lib/code-utils.ts` | +| 12 | HTTP Request guide used the wrong picker name and output paths | Added API label, all seven methods, auth/body choices, milliseconds timeout, and `httpResponse` paths | `src/tool-configs/http-request/block.ts`, `src/features/tools/components/http-request/executor.ts` | +| 13 | HTTP failures were not distinguished from HTTP status responses | Documented structured non-2xx responses versus transport/configuration failures | `src/features/tools/components/http-request/server/api-request.ts` | +| 14 | Transform Array described one generic expression for all operations | Documented map expressions, typed filters, aggregations, partial-result behavior, and result/count output | `src/features/tools/components/transform-array/types.ts`, `executor.ts` | +| 15 | Sleep guide omitted the current Wait label and date mode | Added duration/date-time modes and output timestamps | `src/features/tools/components/sleep/executor.ts`, `src/config/node-registry.ts` | +| 16 | Knowledge Base node documented search only | Added Upload, file fields, asynchronous processing, score threshold and correct search output paths | `src/features/tools/components/knowledge-base/executor.ts` | +| 17 | Knowledge Base feature page had an extra output wrapper | Corrected `kb_results.results` and explained upload readiness | Same evidence as item 16 | +| 18 | Variable examples taught a universal output prefix | Replaced with verified node-specific examples and qualified field-specific type handling | API, Code, Knowledge Base, Tavily, Label Fields and Transform Array executors | +| 19 | Quickstart repeated the universal output-prefix assumption | Uses a Tables example and directs readers to actual output schemas | `src/features/tools/components/tables/`, `src/features/editor/lib/authoring/specialized-outputs.ts` | +| 20 | Label Fields examples used `output.name` | Corrected to `extractedData.name` and `extractedData.email` | `src/features/tools/components/label-fields/executor.ts` | +| 21 | Tavily examples used `output.results` | Corrected to direct `results` | `src/features/tools/components/tavily-search/executor.ts` | +| 22 | AI Agent guide assumed a fixed output-text wrapper | Directs readers to the configured agent result and variable picker | `src/features/tools/components/ai-agent/executor.ts` | +| 23 | OpenRouter guide made an unmaintained numeric model-count claim | Defers available choices to the node's current selector | `src/config/node-registry.ts`, `src/features/copilot/lib/node-type-catalog.ts` | +| 24 | Copilot guide advertised per-message model selection | Clarified automatic Copilot model policy versus workflow AI-node model selectors | `src/features/copilot/server/model-experiment.ts`, `src/features/copilot/hooks/use-copilot-chat-go.ts` | +| 25 | Assistant page advertised a separate active chat runtime | Rewrote as retained settings; explained Home redirects and current Copilot usage | `src/app/(dashboard)/(rest)/assistant/page.tsx`, `chat/page.tsx`, `ARCHITECTURE.md` | +| 26 | Landing page repeated the active-Assistant claim | Updated the card to retained Assistant settings | Same evidence as item 25 | +| 27 | Edit Fields and tool-only nodes were described as standard new-node choices | Marked legacy/hidden visibility and gave supported authoring alternatives | `src/config/node-registry.ts`, `src/components/universal-search-items.ts` | +| 28 | Meta was presented as the picker choice | Uses Facebook/Instagram labels while retaining Meta connection terminology | `src/config/node-registry.ts` | +| 29 | Slack Create Canvas was presented as working | Explicitly identifies it as searchable but rejected by Innflow's current implementation; avoids claiming Slack lacks a public API | `src/tools/slack/actions/create-canvas.ts`, `src/features/tools/components/slack/executor.ts` | +| 30 | Slack configuration table listed only messaging operations | Included Create Canvas with the availability limitation above | Slack operation enum, block, and action sources | +| 31 | Calendar guide omitted List Calendars and Word omitted Write | Expanded exact operation lists and Word description | `src/config/tool-operations-registry.ts`, Google Calendar/Microsoft Word node configuration | +| 32 | Numerous integration guides showed partial or outdated operation names | Aligned 53 mapped guide sections with the exact search catalog; added complete reference links | `scripts/tool-operation-audit.json` records the old lists; `scripts/tool-guide-map.json` records each mapping | +| 33 | Basic was used as a current plan label | Updated workflow retention, execution logs, and tables to Pro | `src/config/pricing-tiers.ts`, `src/features/subscriptions/lib/subscription-limits.ts` | +| 34 | Team table claimed obsolete 5–15 seats and Free single-seat limits | Documented current workspace/invitation limits and separated them from billing seats | Same evidence as item 33 | +| 35 | Credentials instructions depended on an outdated settings hierarchy | Linked the actual `/credentials` application route | `src/features/credentials/components/credentials.tsx` | +| 36 | MCP guide used a generic output wrapper | Documented direct `content`/optional `structuredContent`, agentic `text`, and all four execution modes | `src/features/tools/components/mcp/executor.ts` (the older field tooltip still incorrectly says direct `result`) | +| 37 | Google Forms summary claimed metadata retrieval | Limited the action description to its actual Get Responses operation | `src/config/tool-operations-registry.ts`, Google Forms action configuration | + +## Operation-by-operation change list + +`scripts/tool-operation-audit.json` captures each of the 53 affected guide sections, its node type, previous operation text, and resulting operation count. It distinguishes an incomplete existing list from a previously missing list. The current exact values are in `scripts/tool-catalog.snapshot.json`. + +Two source hints need runtime interpretation: the MCP field tooltip still advertises a direct `result` wrapper, and the Code tooltip overgeneralizes expression capture. The docs generator uses executor-backed wording for those fields rather than repeating the stale hints. This documentation task does not change those application tooltips. + +The generated reference intentionally lists discoverability separately from operational readiness. Slack Create Canvas is the known discoverable-but-unimplemented action found in this review. AI Decision is documented separately as a gated capability. An operation appearing in search is not evidence of a successful external provider execution. + +## Maintaining alignment + +From this documentation repository, with the application dependencies installed in the sibling `innflow` checkout: + +```sh +npm run docs:sync +npm run docs:check +npm run build +npm run verify +``` + +Set `INNFLOW_SOURCE=/absolute/path/to/innflow` if the application checkout is elsewhere. The sync reads source definitions without contacting providers, databases, or production. Review its diff; do not automatically publish changes. The check compares the generated reference with fresh application definitions and all 53 mapped operation lists. It also checks regression claims for triggers, output paths, Copilot and Assistant. The standalone verifier checks rendered pages, navigation, local links and fragments, every catalog anchor, search and 404 behavior. + +The snapshot uses standard picker availability (AI Decision disabled), not production environment flags. Conditional fields and live selector options still require editor inspection. This change does not provision a vector index, ingest public MDX into Copilot, run provider actions, deploy the docs, or modify application behavior. + +## Verification + +- `npm run docs:check` passed: 94 standard nodes, 309 exact operation IDs, 53 mapped guide operation lists, and the regression claims. +- `npm run build` passed, including TypeScript checking and MDX compilation. +- `npm run verify` passed against the built standalone server: 60 content pages, navigation, 81 local targets, local fragments, all 94 reference anchors, Innflow Trigger search, Loop search, and unknown-route 404 behavior. +- `git diff --check` passed. +- 28 existing content pages changed and one complete reference page was added. The audit contains 37 implemented changes plus the 53-section operation change inventory. +- No deployment, provider execution, database change, or vector indexing was performed. These are local documentation and rendered-site results, not production verification. diff --git a/CONTENT-REVIEW.md b/CONTENT-REVIEW.md index c4e94ff..4876b11 100644 --- a/CONTENT-REVIEW.md +++ b/CONTENT-REVIEW.md @@ -10,3 +10,13 @@ Reviewed against `innflow-ai/innflow` origin/main commit `7c55d9e58e9927b9f728a7 - Free allowance discrepancy remains unresolved: latest origin/main specifies 500 credits, while the public pricing page advertises 1,200. Docs refer readers to their account allowance instead of choosing an unverified live value. Removed the old $5 and 400-credit claims. This is a focused review, not an accuracy audit of all documentation. The custom domain was transferred to the replacement on 2026-09-18; Mintlify now tracks the preserved archive/mintlify branch. + + +## 2026-09-23: tool catalog and behavior alignment + +See [CONTENT-ALIGNMENT.md](CONTENT-ALIGNMENT.md) for the larger change list and +source evidence. The update adds a generated universal-search reference, aligns +53 guide operation lists, and corrects trigger setup, execution semantics, output +paths, Copilot/Assistant behavior, hidden nodes, and plan terminology. Slack +Create Canvas is explicitly documented as currently rejected by Innflow's +implementation. Source coverage is distinct from live provider validation. diff --git a/README.md b/README.md index e7cc829..1211fce 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,23 @@ docker compose up -d --build The unprivileged Node container runs the standalone Next.js server on `127.0.0.1:8080` through the existing Compose port mapping. Place your HTTPS reverse proxy in front of it. Search requires the server runtime; do not serve this build with the previous static Nginx configuration. The default `npm start` command also runs the built application from a complete checkout. For a standalone bundle, copy `public/` and `.next/static/` into their corresponding locations under `.next/standalone/`, then run its `server.js`. + + +## Keep tool documentation aligned with Innflow + +See [the September 23 alignment audit](CONTENT-ALIGNMENT.md) for corrected behavior, +source evidence, and the operation-level change list. With the application checkout +at `../innflow` (or `INNFLOW_SOURCE` set to its path), run: + +```sh +npm run docs:sync +npm run docs:check +npm run build +npm run verify +``` + +`docs:sync` regenerates the complete tool reference and source snapshot. +`docs:check` compares them with the current application and checks the operation +lists in the handwritten guides. If a guide fails, update that guide to match the +new operation contract before publishing. Review generated changes as well as +handwritten guidance; a listed operation does not guarantee provider readiness. diff --git a/content/docs/academy/branching.mdx b/content/docs/academy/branching.mdx index b817f94..9e5c09b 100644 --- a/content/docs/academy/branching.mdx +++ b/content/docs/academy/branching.mdx @@ -14,7 +14,7 @@ A Condition node branches based on configured conditions. Use rule-based conditi ## Use AI deliberately -The Condition configuration also supports LLM-based evaluation. This can help when a decision depends on the meaning of text, but it needs examples and review. Do not use a model judgment in place of access controls. +New Condition nodes use typed rules and fixed If/Else branches. Use Router when a decision depends on text meaning. Earlier workflows may still contain LLM-based Condition settings; that legacy form is not the default for new nodes. AI Decision is a separate capability with availability controls. If it is enabled for your workspace, read its [reference](/tools/ai-decision) before building around its Decided and Needs review outputs. diff --git a/content/docs/academy/deployment.mdx b/content/docs/academy/deployment.mdx index 8d648fb..b4596ad 100644 --- a/content/docs/academy/deployment.mdx +++ b/content/docs/academy/deployment.mdx @@ -18,7 +18,7 @@ Check required fields, selected credentials, branch destinations, and sample out ## Trigger availability -Workflows start from a configured trigger. Before adding another trigger to a legacy workflow, use **Triggers → Enable independent triggers** and follow the conversion review. The capability must also be enabled in the environment. If the menu is missing or the action is unavailable, contact support or your administrator. See [adding another trigger](/triggers#adding-another-trigger) for the conversion steps and the exact error message. +Add additional triggers directly. Existing drafts switch to independent execution when the second trigger saves; no separate enablement setting is needed. Undeploy and drain active or pending runs before changing entry points. See [adding another trigger](/triggers#adding-another-trigger), then test every intended entry point before redeploying. ## Try it diff --git a/content/docs/essentials/integrations.mdx b/content/docs/essentials/integrations.mdx index ce28755..976ea01 100644 --- a/content/docs/essentials/integrations.mdx +++ b/content/docs/essentials/integrations.mdx @@ -9,7 +9,7 @@ Innflow integrates with dozens of external services. Depending on the service, a - Navigate to **Settings → Credentials** from the sidebar. + Navigate to [Credentials](https://app.innflow.ai/credentials) from the sidebar. Click **New Credential** and choose the service. OAuth integrations redirect you to authorize Innflow; API-based integrations ask for the required credential. Platform-managed integrations do not need a workspace credential. diff --git a/content/docs/essentials/nodes.mdx b/content/docs/essentials/nodes.mdx index 37d372c..d75676e 100644 --- a/content/docs/essentials/nodes.mdx +++ b/content/docs/essentials/nodes.mdx @@ -7,13 +7,14 @@ Nodes are the building blocks of every workflow. Each node performs a specific a ## Trigger Nodes -A trigger starts a workflow run. Legacy workflows cannot add a second trigger until independent triggers are enabled, and multiple-trigger authoring must also be available in the environment. See [adding another trigger](/triggers#adding-another-trigger) for setup details. +A trigger starts a workflow run. Add more triggers directly; saving a second trigger upgrades an existing draft automatically. Each event starts its selected path. See [adding another trigger](/triggers#adding-another-trigger). Run on demand HTTP requests Conversational Recurring + Called by another workflow Custom form Public hosted form Payment events @@ -69,6 +70,8 @@ Action nodes do the work in your workflow. They are organized by category: +The [complete tool and operation reference](/tools/reference) lists every standard universal-search entry and its configuration fields. Search **API** for HTTP requests and **Wait** for duration or date-based pauses. + ## Node Configuration Click or double click any node to open its configuration panel. Common fields include: @@ -89,7 +92,7 @@ Nodes that change external systems can create real side effects during testing. | **Wait** | Pause for a duration or until a specific time | | **Human Approval** | Pause until a workspace member approves or rejects | | **Wait for Event** | Pause until an external callback arrives | -| **Edit Fields** | Reshape an object without writing code | +| **Edit Fields** | Legacy node retained in existing workflows; use Code or Transform Array for new workflows | | **Transform Array** | Map, filter, or reduce a list | ## Node Status diff --git a/content/docs/essentials/variables.mdx b/content/docs/essentials/variables.mdx index 8d81da6..e812a9f 100644 --- a/content/docs/essentials/variables.mdx +++ b/content/docs/essentials/variables.mdx @@ -1,70 +1,37 @@ --- title: "Variables" -description: "Pass data dynamically between nodes using template variables" +description: "Pass actual node outputs into later workflow steps." --- -## Template Variables +## Template variables -Variables let you pass data from one node to another using double-curly-brace template paths. The exact path depends on the node name and its output schema; use the variable picker and inspect a test run instead of guessing an `output` prefix. +Use double curly braces around a path from an upstream node. A node’s **Variable name** determines the first segment; the remaining path depends on its output. There is no universal `output` prefix. -## Basic Syntax +## Verified output examples -Reference any value by wrapping its path in double curly braces: +These examples assume you assigned the variable names shown: -``` -{{nodeName.output.fieldName}} -``` +| Node | Expression | Value | +| --- | --- | --- | +| Tables (Read Table) | `{{tables.rows}}` | Returned rows | +| API | `{{api.httpResponse.data}}` | Response body | +| API | `{{api.httpResponse.status}}` | HTTP status code | +| Code | `{{code.result}}` | Parsed code result | +| Code | `{{code.stdout}}` | Printed output | +| Knowledge Base (Search) | `{{kb.results}}` | Matching passages | +| Tavily | `{{search.results}}` | Search results | +| Label Fields | `{{labels.extractedData.email}}` | An extracted email field, if configured | +| Transform Array | `{{transformArray.result}}` | Mapped/filtered array or reduced value | +| Active trigger | `{{$trigger.nodeId}}` | Entry point selected for this run | -## Common Patterns +Provider responses and operation-specific results can differ. Run the upstream node, inspect its output, and select the value from the variable picker rather than copying a path from another integration. -### Trigger Data +## Variable picker -``` -{{inputTrigger.name}} -{{webhookTrigger.body.email}} -{{chatTrigger.message}} -``` +Supported configuration fields have a variable picker. Use it to insert upstream outputs, trigger data, and [environment variables](/features/environment-variables). Only connected and available upstream values can be used reliably. A branch that did not execute does not produce a usable result for that run. -### Node Output +## Names and types -``` -{{gemini_response.output.text}} -{{search_results.output.results}} -{{http_response.output.data}} -``` +Choose descriptive names such as `customerLookup` or `supportReply`. When multiple triggers are present, keep their output variable names distinct. `$trigger` is reserved for the active entry point. -### Nested Properties - -Use dot notation to access nested values: - -``` -{{airtable.output.record.fields.Name}} -{{gmail.output.messages[0].subject}} -``` - -## Variable Picker - -Every text field in the node configuration panel includes a **variable picker**. Click the `{ }` button to open it. The picker shows: - -- All upstream nodes and their output fields -- Trigger data fields -- [Environment variables](/features/environment-variables) - -Select a variable to insert it at your cursor position. - -## Variable Names - -Each node has a configurable **variable name** that determines how downstream nodes reference its output. Choose descriptive names to keep your workflows readable: - -- ✅ `customer_email` → `{{customer_email.output.text}}` -- ❌ `node_7` → `{{node_7.output.text}}` - -## Type Handling - -Variables are automatically converted to strings when used in text fields. For nodes that expect specific types (numbers, arrays, objects), the raw value is passed through without conversion. - -## Best Practices - -- **Use descriptive variable names** — Makes your workflow self documenting -- **Check for existence** — Some outputs may be undefined if a previous node was skipped -- **Keep paths simple** — If you need deeply nested data, use a Code or Transform Array node to extract it first +A template embedded in a longer string produces text. Some fields preserve an object, list, number, or boolean when the entire value is a template expression; this depends on that field’s parser. Check the expected type in the editor and inspect a test execution. Use Loop for per-item work or Transform Array to reshape a list before passing it on. diff --git a/content/docs/essentials/workflows.mdx b/content/docs/essentials/workflows.mdx index 17bd9a6..6820f3a 100644 --- a/content/docs/essentials/workflows.mdx +++ b/content/docs/essentials/workflows.mdx @@ -11,7 +11,7 @@ A workflow is an automated sequence of actions that executes when triggered. Wor Every workflow consists of: -1. **Trigger** — The starting point that initiates execution. Legacy workflows require **Triggers → Enable independent triggers** before another entry point can be added. Multiple-trigger authoring must also be enabled in the environment. See [adding another trigger](/triggers#adding-another-trigger). +1. **Trigger** — The starting point that initiates execution. Add additional triggers directly; existing drafts switch to independent execution automatically when the second trigger saves. See [adding another trigger](/triggers#adding-another-trigger). 2. **Nodes** — Individual actions or operations (AI generation, sending emails, data lookups, etc.) 3. **Connections** — Links between nodes that define the execution order 4. **Context** — Shared data passed between nodes via [template variables](/essentials/variables) @@ -20,7 +20,7 @@ Every workflow consists of: The editor is a canvas where you build workflows by placing and connecting nodes. Key interactions: -- **Add nodes** — Click the **+** button on any node or drag from the sidebar +- **Add nodes** — Use the node picker, universal search, or the canvas context menu - **Connect nodes** — Drag from an output handle to an input handle - **Configure nodes** — Click or double click a node to open its settings panel on the right - **Move nodes** — Drag nodes to rearrange the layout @@ -37,7 +37,7 @@ Changes autosave while you work. Use Copilot when you want to add, configure, ex When a workflow runs: 1. The trigger node activates -2. Each connected node executes in sequence +2. Execution follows the selected trigger’s connected path; unrelated roots do not run 3. Output from each node is added to the workflow context 4. Subsequent nodes can access previous outputs via [variables](/essentials/variables) 5. Branching nodes select the connected paths according to their configured rules @@ -71,7 +71,7 @@ The Workflows page supports: Each workflow run is logged with the status of every node. Click on a completed execution to see what each node produced. Execution history retention depends on your [plan](/features/billing): - **Free:** 1 day -- **Basic:** 30 days +- **Pro:** 30 days - **Business / Enterprise:** 90 days For workspace-wide logs, live status, debugging, and notifications, see [Executions and Inbox](/features/executions-inbox). diff --git a/content/docs/features/assistant.mdx b/content/docs/features/assistant.mdx index a637563..bb1346b 100644 --- a/content/docs/features/assistant.mdx +++ b/content/docs/features/assistant.mdx @@ -1,43 +1,12 @@ --- -title: "Assistant" -description: "Configure a shared AI assistant with workspace context, skills, and permissions" +title: "Assistant settings" +description: "Understand the relationship between saved Assistant settings and Copilot." --- -The Assistant is a dedicated AI workspace for ongoing conversations grounded in your Innflow resources. Unlike Copilot, which focuses on building and changing workflows, the Assistant is configured as a reusable teammate with persistent context and server-enforced permissions. +Use [Copilot](/features/copilot) from Home or the workflow editor for conversations and workflow actions. The former standalone Assistant chat and Chat routes now open Home; they are not separate active chat runtimes. - - Assistant availability depends on your workspace plan. - +## Saved configuration -## Configure the Assistant +Assistant profile, context, skills, permission, and activity settings remain available at `/assistant/settings`. Existing configuration records are retained. Their presence does not mean a separate Assistant chat is running or that every saved option changes the active Copilot runtime. -In **Exclusive → Assistant**, workspace members with configuration access can set: - -- Name, description, and system instructions -- Default model -- Private or workspace visibility -- Whether the Assistant can search accessible workspace content -- Whether web research is available - -The selected model can also be changed for an individual message without changing the saved default. - -## Persistent knowledge - -Link files, workflows, tables, or knowledge bases to make them available in every conversation. This differs from a one-time chat attachment: linked resources remain part of the Assistant's saved workspace configuration. - -## Skills - -Skills are reusable instruction packages enabled for the Assistant. Workspace administrators control which skills are installed and available. - -## Access and permissions - -Assistant permissions are enforced on the server. Administrators can control workspace visibility and enable or deny tool capabilities by risk level, including actions that modify workspace resources. - -Read-only members can use a shared Assistant but cannot change its configuration. The **Activity** tab records a redacted history of configuration, context, skill, permission, and runtime events. - -## Assistant versus Copilot - -| Surface | Best for | -| --- | --- | -| [Copilot](/features/copilot) | Building, explaining, testing, and repairing a specific workflow | -| **Assistant** | Ongoing workspace questions and permitted actions using persistent shared context | +Use the controls exposed in Copilot for current conversations, attachments, resource references, and workflow actions. Workflow AI nodes have their own model and tool configuration. diff --git a/content/docs/features/copilot.mdx b/content/docs/features/copilot.mdx index f10b82a..3ab13f9 100644 --- a/content/docs/features/copilot.mdx +++ b/content/docs/features/copilot.mdx @@ -9,7 +9,7 @@ Copilot is Innflow's workflow-building assistant. Use it from Home to turn a req The Home composer is the fastest way to start. Describe the system you want, select relevant apps, and attach workspace resources, files, or pasted text. Copilot can draft a workflow or table and hand it into the appropriate editor for review. -You can choose a chat model, dictate a prompt with the microphone, and continue the same conversation as generated artifacts appear. +Copilot uses its configured model automatically. You can dictate a prompt with the microphone and continue the same conversation as generated artifacts appear. Model selectors inside workflow AI nodes configure those nodes, not Copilot itself. ## Editor Copilot @@ -53,7 +53,6 @@ Copilot supports: - Separate conversation threads - File and pasted-text attachments - App and workspace-resource references -- Model selection - Voice dictation - Persistent conversation history - Relevant saved preferences and corrections diff --git a/content/docs/features/credentials.mdx b/content/docs/features/credentials.mdx index 798641c..707f864 100644 --- a/content/docs/features/credentials.mdx +++ b/content/docs/features/credentials.mdx @@ -9,7 +9,7 @@ Credentials are the connections between Innflow and your external accounts. When - Navigate to **Settings → Credentials** from the sidebar. + Navigate to [Credentials](https://app.innflow.ai/credentials) from the sidebar. Click **New Credential** and choose the service you want to connect. diff --git a/content/docs/features/executions-inbox.mdx b/content/docs/features/executions-inbox.mdx index c60d094..99f001c 100644 --- a/content/docs/features/executions-inbox.mdx +++ b/content/docs/features/executions-inbox.mdx @@ -14,7 +14,7 @@ Execution-history retention depends on your [plan](/features/billing): | Plan family | Retention | | --- | --- | | Free | 1 day | -| Basic | 30 days | +| Pro | 30 days | | Business | 90 days | | Enterprise | 90 days | diff --git a/content/docs/features/knowledge-base.mdx b/content/docs/features/knowledge-base.mdx index 2038e6d..b3ebbe3 100644 --- a/content/docs/features/knowledge-base.mdx +++ b/content/docs/features/knowledge-base.mdx @@ -41,9 +41,11 @@ You can search directly from the Knowledge Base detail page using the search bar Add a **Knowledge Base** node to your workflow to search your documents programmatically. Configure it with a query (which can use template variables from previous nodes) and the number of results to return. ``` -{{kb_results.output.results}} +{{kb_results.results}} ``` +The node also supports **Upload** using a file URL, file name, and file type. Upload starts asynchronous document processing; it does not make the document immediately searchable. + This is especially powerful when combined with an AI Agent node — feed the search results into the AI to answer questions grounded in your own data. ## Managing Documents diff --git a/content/docs/features/tables.mdx b/content/docs/features/tables.mdx index 279aecd..83f5a89 100644 --- a/content/docs/features/tables.mdx +++ b/content/docs/features/tables.mdx @@ -62,6 +62,6 @@ Add a **Tables** node to your workflow to interact with your tables programmatic | Plan family | Max Tables | Max Rows per Table | |-------------|------------|--------------------| | Free | 3 | 1,000 | -| Basic | 25 | 5,000 | +| Pro | 25 | 5,000 | | Business | Unlimited | 50,000 | | Enterprise | Unlimited | Custom | diff --git a/content/docs/features/teams.mdx b/content/docs/features/teams.mdx index 46045d9..5040949 100644 --- a/content/docs/features/teams.mdx +++ b/content/docs/features/teams.mdx @@ -33,9 +33,6 @@ Team workspaces are organizations where multiple users can collaborate. Your per ## Plan Limits -| Plan family | Max Workspaces | Seats | -|-------------|----------------|-------| -| Free | Personal workspace | 1 | -| Basic | Up to 3 workspaces | Depends on selected Basic plan | -| Business | Team workspaces | 5-15 included seats, depending on plan size | -| Enterprise | Custom | Custom | +Workspace and invitation limits are enforced by your subscription. Free accounts have one personal workspace and can invite up to two members per workspace. Pro supports up to three workspaces; Business supports unlimited workspaces under the current application limits. + +Included billing seats and invitation permissions are different concepts. Check your subscription settings for the applicable billing terms. diff --git a/content/docs/index.mdx b/content/docs/index.mdx index 6448eb3..d098b88 100644 --- a/content/docs/index.mdx +++ b/content/docs/index.mdx @@ -63,8 +63,8 @@ Innflow helps you automate work by connecting triggers, AI, tools, data, and int Debug runs and respond to workflow notifications. - - Configure a shared AI teammate with persistent context. + + Review retained Assistant profile settings and how they relate to Copilot. Manage your service connections. diff --git a/content/docs/quickstart.mdx b/content/docs/quickstart.mdx index eadc89e..e335e41 100644 --- a/content/docs/quickstart.mdx +++ b/content/docs/quickstart.mdx @@ -55,7 +55,7 @@ description: "Create your first workflow in under five minutes" Drag from one node's output handle to another node's input handle to create connections. Click any node to open its configuration panel on the right side. - Use `{{variableName.output.field}}` syntax to reference data from previous nodes. The variable picker (click the `{ }` icon in any text field) shows all available variables. + Use the variable picker to reference an upstream value, such as `{{tables.rows}}`. Output paths differ by node; do not add an `output` level unless it appears in that node’s actual result. Click the **Run** button in the editor toolbar. You will see each node execute in sequence, with status indicators showing progress. Click any completed node to inspect its output. diff --git a/content/docs/tools/agents-protocols.mdx b/content/docs/tools/agents-protocols.mdx index 1936fa6..34c4e7e 100644 --- a/content/docs/tools/agents-protocols.mdx +++ b/content/docs/tools/agents-protocols.mdx @@ -12,7 +12,16 @@ The MCP node connects Innflow to external Model Context Protocol servers. Use it | Mode | Description | |------|-------------| | **Direct tool execution** | Select a server tool and call it directly from the workflow | -| **Agentic use** | Connect MCP tools to an AI Agent so the agent can choose when to call them | +| **Agentic use** | Let a model discover and call tools from the server | +| **Read resource** | Retrieve a resource by URI | +| **Get prompt** | Retrieve a named server prompt with its arguments | + +**Operations:** + +- **Agentic Mode** (`AGENTIC`) — LLM discovers and calls MCP tools autonomously +- **Call Tool** (`DIRECT`) — Call a specific MCP tool with mapped inputs +- **Read Resource** (`READ_RESOURCE`) — Read a resource exposed by the MCP server +- **Get Prompt** (`GET_PROMPT`) — Render a prompt exposed by the MCP server **Configuration:** @@ -23,7 +32,9 @@ The MCP node connects Innflow to external Model Context Protocol servers. Use it | **Tool** | Tool to call in direct execution mode | | **Input** | Tool input payload, with support for template variables | -**Accessing output:** `{{variableName.output}}` +For a node named `mcp`, a direct tool call exposes `{{mcp.content}}` and optional `{{mcp.structuredContent}}`; agentic execution exposes `{{mcp.text}}`. Resource and prompt modes return the corresponding server payload. Inspect the selected mode’s result for its nested fields. + +[All operations and configuration fields](/tools/reference#mcp). --- @@ -36,6 +47,11 @@ The A2A Agent node delegates work to an external agent that supports the Agent-t - Poll for an agent result before continuing the workflow - Connect Innflow workflows to agent systems owned by another team or vendor +**Operations:** + +- **Polling Mode** (`POLLING`) — Send task and poll for result +- **Streaming Mode** (`STREAMING`) — Receive real-time SSE updates from the agent + **Configuration:** | Field | Description | @@ -47,12 +63,21 @@ The A2A Agent node delegates work to an external agent that supports the Agent-t The node supports polling and streaming modes. Use polling when Innflow should wait for a completed task result, and streaming when the external agent exposes incremental progress. +[All operations and configuration fields](/tools/reference#a2a-agent). + --- ## Browser Agent Browser Agent is a separate workflow node that uses Stagehand and Browserbase for interactive web tasks. It is not an MCP or A2A transport. See [Browser Automation](/tools/browser-automation). +**Operations:** + +- **Run Browser Task** (`RUN_TASK`) — Complete one multi-step task in a fresh browser session +- **Run Browser Sequence** (`RUN_SEQUENCE`) — Run deterministic browser actions in one shared session + +[All operations and configuration fields](/tools/reference#browser-agent). + --- ## Tool-Only Nodes @@ -66,4 +91,4 @@ Some nodes can be connected to AI Agent nodes as callable tools instead of runni | **HTTP Tool** | Let an agent call an HTTP API | | **Exa Tool** | Let an agent search or retrieve web content | -Use tool-only nodes when the model should decide whether a tool call is needed during the agent run. +These legacy tool-only node types are hidden from universal search. Existing workflows can retain them; for new workflows use the tool-connection controls exposed by the AI Agent editor. diff --git a/content/docs/tools/ai.mdx b/content/docs/tools/ai.mdx index decfecd..63ec9d8 100644 --- a/content/docs/tools/ai.mdx +++ b/content/docs/tools/ai.mdx @@ -19,13 +19,19 @@ The AI Agent node runs an agentic loop with tool calling. Use it when the model | **Tools** | Tool nodes connected to the agent | | **Model** | The model used for reasoning and tool calls | -**Accessing output:** `{{variableName.output.text}}` +Inspect the AI Agent’s result in execution details and select the returned field through the variable picker. The result shape depends on the agent configuration. + +[All operations and configuration fields](/tools/reference#ai-agent). --- ## OpenRouter -The OpenRouter node is the general purpose LLM node. It provides access to more than 200 models through one node. Use it for summarization, classification, rewriting, extraction, drafting, and other prompt-based work. +The OpenRouter node is the general purpose LLM node. Choose from the models currently offered by the node’s model selector. Use it for summarization, classification, rewriting, extraction, drafting, and other prompt-based work. + +**Operations:** + +- **Generate Text** (`GENERATE_TEXT`) — Generate text using any of 200+ AI models via OpenRouter **Configuration:** @@ -40,9 +46,11 @@ The OpenRouter node is the general purpose LLM node. It provides access to more ```txt Summarize this support request and identify the next action: -{{gmail.output.body}} +{{inputTrigger.message}} ``` +[All operations and configuration fields](/tools/reference#ai-model). + --- ## Provider Nodes @@ -65,6 +73,10 @@ Provider-specific nodes are available when you want to route work to a specific The Image Generation node creates images with supported Kie.ai image models. Use it for product concepts, campaign assets, thumbnails, and workflow-generated creative. +**Operations:** + +- **Image Generation** (`GENERATE`) — Generate image URLs using Kie.ai + **Configuration:** | Field | Description | @@ -76,6 +88,8 @@ The Image Generation node creates images with supported Kie.ai image models. Use Generated image output can be passed into approval, file-storage, or social-publishing steps. +[All operations and configuration fields](/tools/reference#generate-image). + --- ## Label Fields @@ -92,7 +106,9 @@ The Label Fields node extracts structured data from unstructured text. Define th **Example:** Extract `name`, `email`, and `sentiment` from a customer support email. -**Accessing output:** `{{variableName.output.name}}`, `{{variableName.output.email}}` +**Accessing output:** `{{variableName.extractedData.name}}`, `{{variableName.extractedData.email}}` + +[All operations and configuration fields](/tools/reference#label-fields). --- @@ -101,3 +117,7 @@ The Label Fields node extracts structured data from unstructured text. Define th The Router node uses AI to choose the best branch for an input. Define named routes with descriptions, then connect each route to the workflow path that should run. Router configuration is covered in [Logic and Utility](/tools/logic-utility#router). + +[All operations and configuration fields](/tools/reference#router). + +--- diff --git a/content/docs/tools/communication.mdx b/content/docs/tools/communication.mdx index b0464f0..ec15d51 100644 --- a/content/docs/tools/communication.mdx +++ b/content/docs/tools/communication.mdx @@ -8,20 +8,25 @@ description: "Send messages and emails through Slack, Discord, Gmail, Teams, Tel Send messages to Slack channels or read recent messages from a channel. **Operations:** -- **Send Message** — Post a message to a Slack channel -- **Read Messages** — Fetch recent messages from a channel -- **Create Canvas** — Create a Slack canvas for structured shared content + +- **Send Message** (`SEND_MESSAGE`) — Send a message to a channel +- **Read Messages** (`READ_MESSAGE`) — Read recent messages from a channel +- **Create Canvas** (`CREATE_CANVAS`) — Listed in search, but the current Innflow implementation rejects this operation. **Configuration:** | Field | Description | |-------|-------------| -| **Operation** | Send Message or Read Messages | +| **Operation** | Send Message, Read Messages, or Create Canvas | | **Channel** | The Slack channel to target | -| **Content** | Message text (for Send Message). Supports template variables. | +| **Content** | Message text or the content required by the selected operation; supports template variables. | + +**Availability:** Create Canvas is discoverable but is not executable in the current Innflow implementation. Use Send Message or Read Messages for working Slack actions. **Requires:** Slack OAuth connection +[All operations and configuration fields](/tools/reference#slack). + --- ## Discord @@ -37,6 +42,8 @@ Send messages to Discord channels via webhooks. **Requires:** Discord OAuth connection +[All operations and configuration fields](/tools/reference#discord). + --- ## Gmail @@ -44,11 +51,15 @@ Send messages to Discord channels via webhooks. Send, read, draft, search, move, mark, and archive email through Gmail. **Operations:** -- **Send Email** — Compose and send an email -- **Read Emails** — Fetch recent emails from your inbox -- **Draft Email** — Save a draft without sending it -- **Search Emails** — Find matching messages -- **Move / Mark / Archive** — Organize message state + +- **Send Email** (`SEND_EMAIL`) — Send an email from your Gmail account +- **Read Emails** (`READ_EMAILS`) — Read emails from a label/folder +- **Draft Email** (`DRAFT_EMAIL`) — Create a draft email +- **Search Emails** (`SEARCH_EMAILS`) — Search emails using Gmail query syntax +- **Move Email** (`MOVE_EMAIL`) — Move an email by adding/removing labels +- **Mark as Read** (`MARK_AS_READ`) — Mark a message as read +- **Mark as Unread** (`MARK_AS_UNREAD`) — Mark a message as unread +- **Archive Email** (`ARCHIVE_EMAIL`) — Archive an email (remove from inbox) **Configuration (Send Email):** @@ -60,6 +71,8 @@ Send, read, draft, search, move, mark, and archive email through Gmail. **Requires:** Google OAuth connection +[All operations and configuration fields](/tools/reference#gmail). + --- ## Microsoft Outlook @@ -67,11 +80,12 @@ Send, read, draft, search, move, mark, and archive email through Gmail. Send, read, draft, and search email through Microsoft Outlook. **Operations:** -- **Send Email** — Compose and send an email -- **Read Emails** — Fetch recent emails -- **Read Email** — Retrieve one message -- **Create Draft** — Save a draft without sending -- **Search Emails** — Find matching messages + +- **Send Email** (`SEND_EMAIL`) — Send an email from your Outlook account +- **Read Emails** (`READ_EMAILS`) — Read emails from a folder +- **Read Email** (`READ_EMAIL`) — Read a single email by ID +- **Create Draft** (`CREATE_DRAFT`) — Create a draft email +- **Search Emails** (`SEARCH_EMAILS`) — Search emails using a query **Configuration (Send Email):** @@ -83,12 +97,22 @@ Send, read, draft, and search email through Microsoft Outlook. **Requires:** Microsoft OAuth connection +[All operations and configuration fields](/tools/reference#microsoft-outlook). + --- ## Microsoft Teams Send or read channel messages, list teams and channels, and create a channel. +**Operations:** + +- **Send Message** (`SEND_MESSAGE`) — Send a message to a Teams channel +- **Read Messages** (`READ_MESSAGES`) — Read recent messages from a channel +- **List Channels** (`LIST_CHANNELS`) — List channels in a team +- **List Teams** (`LIST_TEAMS`) — List all teams you belong to +- **Create Channel** (`CREATE_CHANNEL`) — Create a new channel in a team + **Configuration:** | Field | Description | @@ -98,12 +122,24 @@ Send or read channel messages, list teams and channels, and create a channel. **Requires:** Microsoft OAuth connection +[All operations and configuration fields](/tools/reference#microsoft-teams). + --- ## Telegram Send messages, photos, videos, audio, animations, or documents through Telegram, and delete messages when needed. To start a workflow from incoming bot messages, use the [Telegram Trigger](/triggers#telegram-trigger). +**Operations:** + +- **Send Message** (`SEND_MESSAGE`) +- **Send Photo** (`SEND_PHOTO`) +- **Send Video** (`SEND_VIDEO`) +- **Send Audio** (`SEND_AUDIO`) +- **Send Animation** (`SEND_ANIMATION`) +- **Send Document** (`SEND_DOCUMENT`) +- **Delete Message** (`DELETE_MESSAGE`) + **Configuration:** | Field | Description | @@ -112,12 +148,18 @@ Send messages, photos, videos, audio, animations, or documents through Telegram, | **Chat ID** | The Telegram chat, channel, or group to message | | **Content** | Message text | +[All operations and configuration fields](/tools/reference#telegram). + --- ## Resend Send transactional emails using the Resend email API. +**Operations:** + +- **Send Email** (`SEND_EMAIL`) + **Configuration:** | Field | Description | @@ -127,3 +169,7 @@ Send transactional emails using the Resend email API. | **Body** | Email body (HTML supported) | Resend is a good choice when you need to send emails from a custom domain without connecting a personal Gmail or Outlook account. + +[All operations and configuration fields](/tools/reference#resend). + +--- diff --git a/content/docs/tools/crm-sales.mdx b/content/docs/tools/crm-sales.mdx index d7d0fd5..a95231a 100644 --- a/content/docs/tools/crm-sales.mdx +++ b/content/docs/tools/crm-sales.mdx @@ -8,11 +8,12 @@ description: "Connect Airtable, Attio, HubSpot, and Apollo for customer data and Read from or write to Airtable bases. Use Airtable as a lightweight database for your workflows. **Operations:** -- **List Records** — Fetch records from a table -- **Read Record** — Retrieve one record -- **Create Record** — Add a new record -- **Update Record** — Modify an existing record -- **Delete Record** — Remove a record + +- **List Records** (`LIST_RECORDS`) — List records from a table +- **Read Record** (`READ_RECORD`) — Read a single record by ID +- **Create Record** (`CREATE_RECORD`) — Create a new record in a table +- **Update Record** (`UPDATE_RECORD`) — Update an existing record +- **Delete Record** (`DELETE_RECORD`) — Delete a record by ID **Configuration:** @@ -24,6 +25,8 @@ Read from or write to Airtable bases. Use Airtable as a lightweight database for **Requires:** Airtable OAuth connection +[All operations and configuration fields](/tools/reference#airtable). + --- ## HubSpot @@ -32,6 +35,17 @@ Create, read, update, delete, list, and search HubSpot contacts, companies, deal **Requires:** HubSpot OAuth connection +**Operations:** + +- **Create Record** (`CREATE_RECORD`) — Create a new CRM record +- **Read Record** (`READ_RECORD`) — Read a single record by ID +- **Update Record** (`UPDATE_RECORD`) — Update an existing record +- **Delete Record** (`DELETE_RECORD`) — Delete a record by ID +- **List Records** (`LIST_RECORDS`) — List records with optional limit +- **Search Records** (`SEARCH_RECORDS`) — Search records with query or filters + +[All operations and configuration fields](/tools/reference#hubspot). + --- ## Attio @@ -47,6 +61,24 @@ Manage Attio CRM records, notes, tasks, and object metadata. **Requires:** Attio connection +**Operations:** + +- **List Records** (`LIST_RECORDS`) +- **Get Record** (`GET_RECORD`) +- **Update Record** (`UPDATE_RECORD`) +- **Delete Record** (`DELETE_RECORD`) +- **Search Records** (`SEARCH_RECORDS`) +- **Assert Record** (`ASSERT_RECORD`) +- **List Notes** (`LIST_NOTES`) +- **Get Note** (`GET_NOTE`) +- **Create Note** (`CREATE_NOTE`) +- **Delete Note** (`DELETE_NOTE`) +- **List Tasks** (`LIST_TASKS`) +- **Create Task** (`CREATE_TASK`) +- **Get Object** (`GET_OBJECT`) + +[All operations and configuration fields](/tools/reference#attio). + --- ## Apollo @@ -54,3 +86,20 @@ Manage Attio CRM records, notes, tasks, and object metadata. Search and enrich people or organizations, perform bulk enrichment, and create or update Apollo contacts. **Requires:** Apollo API credentials + +**Operations:** + +- **Search People** (`SEARCH_PEOPLE`) — Search for people by title, location, seniority, and company +- **Enrich Person** (`ENRICH_PERSON`) — Get detailed info about a person by email, name, or LinkedIn +- **Bulk Enrich People** (`BULK_ENRICH_PEOPLE`) — Enrich multiple people at once from a JSON array +- **Search Organizations** (`SEARCH_ORGANIZATIONS`) — Search for companies by location, size, and keywords +- **Enrich Organization** (`ENRICH_ORGANIZATION`) — Get detailed info about a company by domain +- **Bulk Enrich Organizations** (`BULK_ENRICH_ORGANIZATIONS`) — Enrich multiple organizations by domain +- **Create Contact** (`CREATE_CONTACT`) — Create a new contact in Apollo CRM +- **Update Contact** (`UPDATE_CONTACT`) — Update an existing contact by ID +- **Search Contacts** (`SEARCH_CONTACTS`) — Search contacts in your Apollo CRM +- **Bulk Create Contacts** (`BULK_CREATE_CONTACTS`) — Create multiple contacts from a JSON array + +[All operations and configuration fields](/tools/reference#apollo). + +--- diff --git a/content/docs/tools/forms.mdx b/content/docs/tools/forms.mdx index 92e5bdf..0807909 100644 --- a/content/docs/tools/forms.mdx +++ b/content/docs/tools/forms.mdx @@ -9,14 +9,20 @@ The Typeform action node manages forms and reads response data through the Typef **Operations:** -- List, get, create, update, and delete forms -- Retrieve form responses -- Read form insights +- **List Forms** (`LIST_FORMS`) — List all forms in your Typeform account +- **Get Form** (`GET_FORM`) — Get the full definition of a specific form +- **Create Form** (`CREATE_FORM`) — Create a new Typeform form with fields and settings +- **Update Form** (`UPDATE_FORM`) — Update an existing form with a new definition +- **Delete Form** (`DELETE_FORM`) — Permanently delete a form +- **Get Responses** (`GET_RESPONSES`) — Retrieve form responses with optional date range filtering +- **Get Form Insights** (`GET_FORM_INSIGHTS`) — Get analytics and insights for a form Use the [Typeform Trigger](/triggers#typeform-trigger) when a new response should start the workflow. **Requires:** Typeform credentials +[All operations and configuration fields](/tools/reference#typeform). + --- ## Google Forms @@ -27,6 +33,12 @@ Use the [Google Forms Trigger](/triggers#google-forms-trigger) when each new sub **Requires:** Google OAuth connection +**Operations:** + +- **Get Responses** (`GET_RESPONSES`) — Retrieve responses from a Google Form + +[All operations and configuration fields](/tools/reference#google-forms). + --- ## Innflow Forms diff --git a/content/docs/tools/google-suite.mdx b/content/docs/tools/google-suite.mdx index a65919a..e967d3b 100644 --- a/content/docs/tools/google-suite.mdx +++ b/content/docs/tools/google-suite.mdx @@ -3,17 +3,18 @@ title: "Google Suite" description: "Work with Google Docs, Sheets, Calendar, Drive, Slides, Forms, and Groups" --- -All Google Suite nodes require a **Google OAuth connection**. Connect your Google account from **Settings → Credentials**. +All Google Suite nodes require a **Google OAuth connection**. Connect your Google account from [Credentials](https://app.innflow.ai/credentials). ## Google Sheets Read from or write to Google Sheets spreadsheets. **Operations:** -- **Read Rows** — Fetch data from a range of cells -- **Append Row** — Add a new row to the end of a sheet -- **Update Row** — Modify an existing row -- **Create Spreadsheet** — Create a new spreadsheet + +- **Read Rows** (`READ_ROWS`) — Read rows from a spreadsheet +- **Append Rows** (`APPEND_ROWS`) — Append rows to a spreadsheet +- **Update Rows** (`UPDATE_ROWS`) — Update existing rows in a spreadsheet +- **Create Spreadsheet** (`CREATE_SPREADSHEET`) — Create a new Google Sheets spreadsheet **Configuration:** @@ -23,25 +24,30 @@ Read from or write to Google Sheets spreadsheets. | **Range** | Cell range in A1 notation (e.g., `Sheet1!A1:D10`) | | **Values** | Data to write (for Append/Update operations) | +[All operations and configuration fields](/tools/reference#google-sheets). + --- ## Google Docs -Create, read, or update Google Docs documents. +Create and read Google Docs documents, or write content to an existing document. **Operations:** -- **Create** — Create a new document with a title and content -- **Read** — Retrieve the content of an existing document -- **Write** — Add or replace document content + +- **Create Document** (`CREATE_DOCUMENT`) — Create a new Google Docs document +- **Read Document** (`READ_DOCUMENT`) — Read content from a Google Docs document +- **Write to Document** (`WRITE_TO_DOCUMENT`) — Write content to an existing Google Docs document **Configuration:** | Field | Description | |-------|-------------| -| **Document ID** | The ID of the document (for Read/Update) | +| **Document ID** | The ID of the document (for Read/Write) | | **Title** | Document title (for Create) | | **Content** | Document content | +[All operations and configuration fields](/tools/reference#google-docs). + --- ## Google Calendar @@ -49,11 +55,13 @@ Create, read, or update Google Docs documents. List calendars and create, read, update, or delete events in Google Calendar. **Operations:** -- **List Events** — Fetch upcoming events from a calendar -- **Create Event** — Add a new event -- **Read Event** — Retrieve one event -- **Update Event** — Change an event -- **Delete Event** — Remove an event + +- **List Calendars** (`LIST_CALENDARS`) — List all calendars for the authenticated user +- **List Events** (`LIST_EVENTS`) — List events from a calendar with optional search +- **Create Event** (`CREATE_EVENT`) — Create a new calendar event +- **Read Event** (`READ_EVENT`) — Get details of a specific event +- **Update Event** (`UPDATE_EVENT`) — Update an existing calendar event +- **Delete Event** (`DELETE_EVENT`) — Delete a calendar event **Configuration:** @@ -64,6 +72,8 @@ List calendars and create, read, update, or delete events in Google Calendar. | **Start Time** | Event start in ISO 8601 format | | **End Time** | Event end in ISO 8601 format | +[All operations and configuration fields](/tools/reference#google-calendar). + --- ## Google Drive @@ -71,9 +81,10 @@ List calendars and create, read, update, or delete events in Google Calendar. Upload, download, or list files in Google Drive. **Operations:** -- **List Files** — Browse files in a folder -- **Upload** — Upload a file to Drive -- **Download** — Download a file by ID + +- **List Files** (`LIST_FILES`) — List files in Google Drive +- **Download File** (`DOWNLOAD_FILE`) — Download a file from Google Drive +- **Upload File** (`UPLOAD_FILE`) — Upload a file to Google Drive **Configuration:** @@ -82,6 +93,8 @@ Upload, download, or list files in Google Drive. | **Folder ID** | Target folder (for List/Upload) | | **File ID** | Specific file (for Download) | +[All operations and configuration fields](/tools/reference#google-drive). + --- ## Google Slides @@ -89,8 +102,9 @@ Upload, download, or list files in Google Drive. Create or read Google Slides presentations. **Operations:** -- **Create** — Create a new presentation -- **Read** — Read slide content from an existing presentation + +- **Create Presentation** (`CREATE_PRESENTATION`) — Create a new Google Slides presentation +- **Read Presentation** (`READ_PRESENTATION`) — Read an existing Google Slides presentation **Configuration:** @@ -99,11 +113,13 @@ Create or read Google Slides presentations. | **Presentation ID** | The presentation to read (for Read) | | **Title** | Presentation title (for Create) | +[All operations and configuration fields](/tools/reference#google-slides). + --- ## Google Forms -Read form responses and metadata from Google Forms. +Retrieve submitted responses from a Google Form. **Requires:** Google OAuth connection @@ -111,6 +127,12 @@ Read form responses and metadata from Google Forms. To trigger a workflow when someone submits a Google Form, use the [Google Forms Trigger](/triggers#google-forms-trigger) instead. +**Operations:** + +- **Get Responses** (`GET_RESPONSES`) — Retrieve responses from a Google Form + +[All operations and configuration fields](/tools/reference#google-forms). + --- ## Google Groups @@ -118,3 +140,21 @@ Read form responses and metadata from Google Forms. List, read, create, update, or delete groups and manage members, roles, and membership checks. **Requires:** Google OAuth connection with admin access + +**Operations:** + +- **List Groups** (`LIST_GROUPS`) — List all groups +- **Get Group** (`GET_GROUP`) — Get group details +- **Create Group** (`CREATE_GROUP`) — Create a new group +- **Update Group** (`UPDATE_GROUP`) — Update group settings +- **Delete Group** (`DELETE_GROUP`) — Delete a group +- **List Members** (`LIST_MEMBERS`) — List group members +- **Get Member** (`GET_MEMBER`) — Get member details +- **Add Member** (`ADD_MEMBER`) — Add a member to a group +- **Update Member Role** (`UPDATE_MEMBER_ROLE`) — Change a member's role +- **Remove Member** (`REMOVE_MEMBER`) — Remove a member from a group +- **Check Membership** (`CHECK_MEMBERSHIP`) — Check if a user is a member of a group + +[All operations and configuration fields](/tools/reference#google-groups). + +--- diff --git a/content/docs/tools/logic-utility.mdx b/content/docs/tools/logic-utility.mdx index e86391c..80607ec 100644 --- a/content/docs/tools/logic-utility.mdx +++ b/content/docs/tools/logic-utility.mdx @@ -5,74 +5,55 @@ description: "Control workflow flow with conditions, routers, code, and more" ## Condition -Branch your workflow based on true/false conditions. The Condition node evaluates a JavaScript expression and routes execution to either the **true** or **false** output. +Use typed comparison rules for exact decisions. Select an upstream value, comparison operator, and comparison value; combine rules with **All rules** or **Any rule**. -**Configuration:** - -| Field | Description | -|-------|-------------| -| **Variable name** | Name for the condition output | -| **Condition** | A JavaScript expression that evaluates to `true` or `false` | +New Condition nodes have fixed **If** and **Else** outputs. Connect both paths and test a matching and non-matching input. For example, compare an order amount with `100` using a numeric greater-than rule, or compare a status with `approved` using an equality rule. You do not need to write JavaScript for these comparisons. -**Example conditions:** -```javascript -{{gmail.output.subject}}.includes("urgent") -``` -```javascript -{{inputTrigger.amount}} > 100 -``` +Older workflows may contain the earlier expression or LLM-based Condition configuration. Those saved variants remain supported, but they are not the new Condition form. For decisions about text meaning, use [Router](#router) or [AI Decision](/tools/ai-decision) when available. -The node has two output handles. Connect the **true** handle to nodes that should run when the condition passes, and the **false** handle to the alternative path. +[All operations and configuration fields](/tools/reference#condition). --- ## Router -AI powered routing that analyzes input and sends it to the most appropriate branch. Define named routes with descriptions, and the router uses AI to decide which route best matches the input. +Use Router to choose a branch from the meaning of an input. Configure the context, route names and instructions, and the model. Router supports best-match selection and first-match routing. In first-match mode, rules are evaluated in order; the first match wins and **Else** is the fallback. Put specific rules before broad ones. -**Configuration:** +Connect each named output to the path that should run. Older workflows can retain the earlier route-selection configuration. Test overlapping rules as well as an input that should reach Else. -| Field | Description | -|-------|-------------| -| **Routes** | Named routes, each with a description of when to use it | -| **Input** | The data to analyze for routing decisions | - -Each route creates a separate output handle on the node. +[All operations and configuration fields](/tools/reference#router). --- ## Code -Execute custom code within your workflow. Write Python, JavaScript, or Java to transform data, perform calculations, or implement custom logic. +Run Python, JavaScript, or Java in a sandbox. Python is the default. Configure the variable name, language, code, timeout in seconds, and optional declared output fields. -**Configuration:** +Read upstream data through `context`. For a structured Python result, print JSON as the final output: -| Field | Description | -|-------|-------------| -| **Variable name** | Name for the code output | -| **Language** | Python, JavaScript, or Java | -| **Code** | Your code to execute | -| **Timeout** | Maximum execution time | +```python +import json +result = {"message": "Ready"} +print(json.dumps(result)) +``` -Your code runs in a sandboxed environment. The result of the last expression is returned as the node output. +The runner first uses a captured expression result when available, then tries to parse the last nonempty stdout line as JSON; otherwise it returns stdout text or null. Do not rely on a bare final expression working identically in every language. + +For a Code node named `code`, the result is `{{code.result}}`. Logs are available as `{{code.stdout}}` and `{{code.stderr}}`. Declared output fields validate the result structure; they do not change that wrapper. Python scripts cannot use `return` outside a function. + +[All operations and configuration fields](/tools/reference#code). --- ## HTTP Request -Make HTTP requests to any API endpoint. Supports all standard HTTP methods. +Find this node as **API** in universal search. Send GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS requests. -**Configuration:** +Configure the URL, query parameters, authorization, headers, body format, and timeout in milliseconds. Authorization supports no auth, bearer token, API key, and basic auth. Bodies can be JSON, plain text, or form URL encoded. -| Field | Description | -|-------|-------------| -| **Variable name** | Name for the response output | -| **URL** | The endpoint to call | -| **Method** | GET, POST, PUT, PATCH, or DELETE | -| **Headers** | Custom request headers (as JSON) | -| **Body** | Request body for POST/PUT/PATCH | +For a node named `api`, use `{{api.httpResponse.data}}` for the body, `{{api.httpResponse.status}}` for the status code, and `{{api.httpResponse.ok}}` to check for a 2xx status. Non-2xx HTTP responses remain structured results; inspect the status before continuing. Transport or configuration errors can fail the node. -**Accessing output:** `{{variableName.output.data}}` for response body, `{{variableName.output.status}}` for status code. +[All operations and configuration fields](/tools/reference#http-request). --- @@ -82,6 +63,8 @@ Pause a workflow until a selected workspace member approves or rejects the reque Use Human Approval before sending customer-facing messages, publishing content, changing important records, or taking another action that needs review. +[All operations and configuration fields](/tools/reference#human-approval). + --- ## Wait for Event @@ -90,26 +73,33 @@ Pause a workflow until an external system sends an event to a unique callback UR The wait request appears in the Inbox. Callback requests are signed when a workflow wait signing secret is configured by the deployment administrator. +[All operations and configuration fields](/tools/reference#wait-for-event). + --- ## Transform Array -Apply map, filter, or reduce operations to arrays of data. +Map, filter, or reduce an input array. Configure **Input Array** and select an operation: -**Configuration:** +- **Map:** transform each item with a template expression. +- **Filter:** choose a field, comparison operator, and comparison value. +- **Reduce:** choose an aggregation such as sum, count, concatenate, first, last, minimum, maximum, or a custom reduction expression. -| Field | Description | -|-------|-------------| -| **Variable name** | Name for the transformed output | -| **Operation** | Map, Filter, or Reduce | -| **Input** | The array to transform (template variable) | -| **Expression** | The transformation expression | +Choose whether an item error stops the node or returns partial results. For a node named `transformArray`, the output is `{{transformArray.result}}`, with `processedCount` and `errorCount` alongside it. + +**Operations:** + +- **Map** (`MAP`) — Transform each item into a new shape +- **Filter** (`FILTER`) — Keep only items matching a condition +- **Reduce** (`REDUCE`) — Aggregate items into a single value + +[All operations and configuration fields](/tools/reference#transform-array). --- ## Edit Fields -Create, rename, remove, and reshape fields for downstream nodes without writing code. Use Edit Fields to normalize an app response or prepare a clean object for a table, webhook, or integration action. +Edit Fields is retained for existing workflows but is hidden from the standard node picker and universal search. For a new workflow, use [Code](#code) to reshape an object or [Transform Array](#transform-array) to reshape items in a list. --- @@ -117,6 +107,8 @@ Create, rename, remove, and reshape fields for downstream nodes without writing Convert data into CSV format for download or further processing. +[All operations and configuration fields](/tools/reference#csv-export). + --- ## Webhook Action @@ -130,17 +122,17 @@ Send data to an external webhook URL. Unlike the Webhook Trigger (which receives | **URL** | The webhook endpoint to call | | **Payload** | Data to send (supports template variables) | +[All operations and configuration fields](/tools/reference#webhook-action). + --- ## Sleep -Pause workflow execution for a specified duration. +Find this node as **Wait** in universal search. Choose **A duration** (for example `5s`, `1m`, or `1h`) or **A date and time**. Include an explicit timezone or UTC offset for date-based waits to avoid ambiguity. This pauses the workflow durably until the chosen time. -**Configuration:** +For a node named `wait`, inspect `{{wait.targetAt}}`, `{{wait.completedAt}}`, and `{{wait.actualDurationMs}}` after it resumes. -| Field | Description | -|-------|-------------| -| **Duration** | How long to wait (e.g., `5s`, `1m`, `1h`) | +[All operations and configuration fields](/tools/reference#sleep). --- @@ -149,11 +141,12 @@ Pause workflow execution for a specified duration. Read from, query, add to, update, or delete rows in your [Innflow Tables](/features/tables) directly from a workflow. **Operations:** -- **Read Table** — Get all rows from a table -- **Query Rows** — Search for specific rows -- **Add Row** — Insert a new row -- **Update Row** — Modify an existing row -- **Delete Row** — Remove a row + +- **Read Table** (`READ_TABLE`) — Read all rows +- **Query Rows** (`QUERY_ROWS`) — Filter rows by column value +- **Add Row** (`ADD_ROW`) — Insert new row(s) +- **Update Row** (`UPDATE_ROW`) — Update an existing row +- **Delete Row** (`DELETE_ROW`) — Remove a row by ID **Configuration:** @@ -165,18 +158,23 @@ Read from, query, add to, update, or delete rows in your [Innflow Tables](/featu | **Row Data** | JSON data for add/update operations | | **Row ID** | Target row for update/delete operations | +[All operations and configuration fields](/tools/reference#tables). + --- ## Knowledge Base Node -Search your uploaded documents using semantic search. Returns the most relevant passages from your [Knowledge Base](/features/knowledge-base). +Use a Knowledge Base node to **Search** an existing base or **Upload** a document to it. -**Configuration:** +For Search, select the knowledge base, query, number of results, and optional score threshold. For Upload, supply the file URL, file name, and supported file type (PDF, TXT, or Markdown). Uploading queues document processing; wait for the document to become ready before expecting it in search results. -| Field | Description | -|-------|-------------| -| **Variable name** | Name for the search results | -| **Query** | What to search for (supports template variables) | -| **Top K** | Number of results to return | +For a search node named `kb`, use `{{kb.results}}`, `{{kb.query}}`, and `{{kb.totalResults}}`. There is no extra `output` level. See [Knowledge Base](/features/knowledge-base). -**Accessing output:** `{{variableName.output.results}}` +**Operations:** + +- **Search** (`SEARCH`) — Search knowledge base for relevant information +- **Upload** (`UPLOAD`) — Upload a document to the knowledge base + +[All operations and configuration fields](/tools/reference#knowledge-base). + +--- diff --git a/content/docs/tools/meta.json b/content/docs/tools/meta.json index 0080c1e..50ea759 100644 --- a/content/docs/tools/meta.json +++ b/content/docs/tools/meta.json @@ -1 +1,20 @@ -{"title": "Nodes & integrations", "pages": ["ai", "ai-decision", "browser-automation", "communication", "forms", "google-suite", "microsoft", "crm-sales", "project-management", "search-data", "storage-commerce", "social-publishing", "agents-protocols", "logic-utility"]} \ No newline at end of file +{ + "title": "Nodes & integrations", + "pages": [ + "reference", + "ai", + "ai-decision", + "browser-automation", + "communication", + "forms", + "google-suite", + "microsoft", + "crm-sales", + "project-management", + "search-data", + "storage-commerce", + "social-publishing", + "agents-protocols", + "logic-utility" + ] +} diff --git a/content/docs/tools/microsoft.mdx b/content/docs/tools/microsoft.mdx index 9485d5c..fd2f9cb 100644 --- a/content/docs/tools/microsoft.mdx +++ b/content/docs/tools/microsoft.mdx @@ -3,16 +3,17 @@ title: "Microsoft" description: "Work with Excel, Word, OneDrive, Outlook, Planner, SharePoint, and Teams" --- -All Microsoft nodes require a **Microsoft OAuth connection**. Connect your Microsoft account from **Settings → Credentials**. +All Microsoft nodes require a **Microsoft OAuth connection**. Connect your Microsoft account from [Credentials](https://app.innflow.ai/credentials). ## Microsoft Excel Read from or write to Excel files stored in OneDrive. **Operations:** -- **Create Spreadsheet** — Create a workbook -- **Read Range** — Fetch data from a range of cells -- **Write Range** — Write data to a range of cells + +- **Create Spreadsheet** (`CREATE_SPREADSHEET`) — Create a new Microsoft Excel spreadsheet +- **Read Rows** (`READ_ROWS`) — Read rows from an Excel spreadsheet +- **Write Rows** (`WRITE_ROWS`) — Write rows to an Excel spreadsheet **Configuration:** @@ -21,15 +22,19 @@ Read from or write to Excel files stored in OneDrive. | **Workbook ID** | The Excel workbook in OneDrive | | **Range** | Cell range to read or write | +[All operations and configuration fields](/tools/reference#microsoft-excel). + --- ## Microsoft Word -Create or read Word documents stored in OneDrive. +Create, read, or write Word documents stored in OneDrive. **Operations:** -- **Create** — Create a new Word document -- **Read** — Read content from an existing document + +- **Create Document** (`CREATE_DOCUMENT`) — Create a new Microsoft Word document +- **Read Document** (`READ_DOCUMENT`) — Read content from a Microsoft Word document +- **Update Document** (`UPDATE_DOCUMENT`) — Update content in an existing Microsoft Word document **Configuration:** @@ -39,6 +44,8 @@ Create or read Word documents stored in OneDrive. | **Title** | Document title (for Create) | | **Content** | Document content | +[All operations and configuration fields](/tools/reference#microsoft-word). + --- ## Microsoft OneDrive @@ -46,10 +53,11 @@ Create or read Word documents stored in OneDrive. List and retrieve files, create folders, or delete files in OneDrive. **Operations:** -- **List Files** — Browse files in a folder -- **Get File** — Retrieve a file -- **Create Folder** — Add a folder -- **Delete File** — Remove a file + +- **List Files** (`LIST_FILES`) — List files in a OneDrive folder +- **Get File** (`GET_FILE`) — Get a file from OneDrive +- **Create Folder** (`CREATE_FOLDER`) — Create a new folder in OneDrive +- **Delete File** (`DELETE_FILE`) — Delete a file from OneDrive **Configuration:** @@ -58,18 +66,40 @@ List and retrieve files, create folders, or delete files in OneDrive. | **Folder ID** | Target folder for listing or creation | | **File ID** | Specific file for retrieval or deletion | +[All operations and configuration fields](/tools/reference#microsoft-onedrive). + --- ## Microsoft Outlook See the [Communication](/tools/communication#microsoft-outlook) page for Outlook email configuration. +**Operations:** + +- **Send Email** (`SEND_EMAIL`) — Send an email from your Outlook account +- **Read Emails** (`READ_EMAILS`) — Read emails from a folder +- **Read Email** (`READ_EMAIL`) — Read a single email by ID +- **Create Draft** (`CREATE_DRAFT`) — Create a draft email +- **Search Emails** (`SEARCH_EMAILS`) — Search emails using a query + +[All operations and configuration fields](/tools/reference#microsoft-outlook). + --- ## Microsoft Teams See the [Communication](/tools/communication#microsoft-teams) page for Teams messaging configuration. +**Operations:** + +- **Send Message** (`SEND_MESSAGE`) — Send a message to a Teams channel +- **Read Messages** (`READ_MESSAGES`) — Read recent messages from a channel +- **List Channels** (`LIST_CHANNELS`) — List channels in a team +- **List Teams** (`LIST_TEAMS`) — List all teams you belong to +- **Create Channel** (`CREATE_CHANNEL`) — Create a new channel in a team + +[All operations and configuration fields](/tools/reference#microsoft-teams). + --- ## Microsoft Planner @@ -78,6 +108,16 @@ List plans and tasks, then create, update, or delete Planner tasks. **Requires:** Microsoft OAuth connection +**Operations:** + +- **List Plans** (`LIST_PLANS`) — List all plans in the group +- **List Tasks** (`LIST_TASKS`) — List tasks in a plan +- **Create Task** (`CREATE_TASK`) — Create a new task in a plan +- **Update Task** (`UPDATE_TASK`) — Update an existing task +- **Delete Task** (`DELETE_TASK`) — Delete a task + +[All operations and configuration fields](/tools/reference#microsoft-planner). + --- ## Microsoft SharePoint @@ -85,3 +125,15 @@ List plans and tasks, then create, update, or delete Planner tasks. List sites and lists, read list items, and create or update list items in SharePoint Online. **Requires:** Microsoft OAuth connection + +**Operations:** + +- **List Sites** (`LIST_SITES`) — Search or list SharePoint sites +- **List Lists** (`LIST_LISTS`) — List all lists in a SharePoint site +- **Get List Items** (`GET_LIST_ITEMS`) — Get items from a SharePoint list +- **Create List Item** (`CREATE_LIST_ITEM`) — Create a new item in a SharePoint list +- **Update List Item** (`UPDATE_LIST_ITEM`) — Update an existing item in a SharePoint list + +[All operations and configuration fields](/tools/reference#microsoft-sharepoint). + +--- diff --git a/content/docs/tools/project-management.mdx b/content/docs/tools/project-management.mdx index 81142f3..4755545 100644 --- a/content/docs/tools/project-management.mdx +++ b/content/docs/tools/project-management.mdx @@ -13,6 +13,19 @@ Read pages and databases, create pages or databases, add database rows, append p To trigger a workflow when Notion content changes, use the [Notion Trigger](/triggers#notion-trigger) instead. +**Operations:** + +- **Read Page** (`READ_PAGE`) — Read a Notion page +- **Read Database** (`READ_DATABASE`) — Read a Notion database +- **Create Page** (`CREATE_PAGE`) — Create a new page +- **Create Database** (`CREATE_DATABASE`) — Create a new database +- **Add Database Row** (`ADD_DATABASE_ROW`) — Add a row to a database +- **Append Content** (`APPEND_CONTENT`) — Append content to a page +- **Query Database** (`QUERY_DATABASE`) — Query a database with filters +- **Search Workspace** (`SEARCH_WORKSPACE`) — Search across the workspace + +[All operations and configuration fields](/tools/reference#notion). + --- ## Trello @@ -21,6 +34,17 @@ Get board lists, list or update cards, create cards, read actions, and add comme **Requires:** Trello OAuth connection +**Operations:** + +- **Get Lists** (`GET_LISTS`) — Get all lists on a board +- **List Cards** (`LIST_CARDS`) — List cards in a list +- **Create Card** (`CREATE_CARD`) — Create a new card +- **Update Card** (`UPDATE_CARD`) — Update an existing card +- **Get Actions** (`GET_ACTIONS`) — Get activity on a card +- **Add Comment** (`ADD_COMMENT`) — Add a comment to a card + +[All operations and configuration fields](/tools/reference#trello). + --- ## GitHub @@ -29,6 +53,18 @@ Create, list, and update issues; create, list, and merge pull requests; and add **Requires:** GitHub OAuth connection +**Operations:** + +- **Create Issue** (`CREATE_ISSUE`) — Create a new issue +- **List Issues** (`LIST_ISSUES`) — List repository issues +- **Update Issue** (`UPDATE_ISSUE`) — Update an existing issue +- **Create Pull Request** (`CREATE_PR`) — Create a new pull request +- **List Pull Requests** (`LIST_PRS`) — List repository pull requests +- **Merge Pull Request** (`MERGE_PR`) — Merge a pull request +- **Create Comment** (`CREATE_COMMENT`) — Add a comment to an issue or PR + +[All operations and configuration fields](/tools/reference#github). + --- ## ClickUp @@ -43,6 +79,20 @@ Create, search, update, and comment on ClickUp work items from your workflows. **Requires:** ClickUp OAuth connection +**Operations:** + +- **Create Task** (`CREATE_TASK`) — Create a new task in a list +- **Get Task** (`GET_TASK`) — Fetch a task by ID +- **Update Task** (`UPDATE_TASK`) — Partially update an existing task +- **Delete Task** (`DELETE_TASK`) — Permanently delete a task +- **List Tasks** (`LIST_TASKS`) — List tasks in a list with optional filters +- **Search Tasks** (`SEARCH_TASKS`) — Search tasks across an entire workspace +- **Add Comment** (`ADD_COMMENT`) — Post a comment on a task +- **Set Custom Field** (`SET_CUSTOM_FIELD`) — Set a single custom field value on a task +- **Get Lists** (`GET_LISTS`) — Fetch lists in a space or folder + +[All operations and configuration fields](/tools/reference#clickup). + --- ## Cal.com @@ -51,6 +101,16 @@ List event types and bookings, then create, cancel, or reschedule bookings. **Requires:** Cal.com API credentials +**Operations:** + +- **List Event Types** (`LIST_EVENT_TYPES`) — Retrieve all configured event types +- **List Bookings** (`LIST_BOOKINGS`) — Retrieve bookings with optional status filter +- **Create Booking** (`CREATE_BOOKING`) — Create a new booking for an event type +- **Cancel Booking** (`CANCEL_BOOKING`) — Cancel an existing booking +- **Reschedule Booking** (`RESCHEDULE_BOOKING`) — Reschedule an existing booking to a new time + +[All operations and configuration fields](/tools/reference#cal-com). + --- ## Calendly @@ -58,3 +118,17 @@ List event types and bookings, then create, cancel, or reschedule bookings. Read the connected user, event types, scheduled events, and invitees, or cancel a scheduled event. **Requires:** Calendly API credentials + +**Operations:** + +- **Get Current User** (`GET_CURRENT_USER`) — Retrieve the authenticated user's profile information +- **List Event Types** (`LIST_EVENT_TYPES`) — List all event types for a user +- **Get Event Type** (`GET_EVENT_TYPE`) — Get details of a specific event type +- **List Scheduled Events** (`LIST_SCHEDULED_EVENTS`) — List scheduled events for a user with optional filters +- **Get Scheduled Event** (`GET_SCHEDULED_EVENT`) — Get details of a specific scheduled event +- **List Event Invitees** (`LIST_EVENT_INVITEES`) — List invitees for a scheduled event +- **Cancel Event** (`CANCEL_EVENT`) — Cancel a scheduled event with an optional reason + +[All operations and configuration fields](/tools/reference#calendly). + +--- diff --git a/content/docs/tools/reference.mdx b/content/docs/tools/reference.mdx new file mode 100644 index 0000000..e4dd617 --- /dev/null +++ b/content/docs/tools/reference.mdx @@ -0,0 +1,3035 @@ +--- +title: "Tool and operation reference" +description: "Every standard node and operation available in universal search, with configuration fields from the application." +--- + +This reference lists the standard universal-search catalog. Availability can also depend on your plan and workspace. [AI Decision](/tools/ai-decision) is separately controlled and is not included in the standard catalog. + +Search includes **94 node entries** and **309 operations**. The category guides explain common workflows; use this reference for the complete operation list. + +Configuration fields may appear only after selecting an operation, account, or mode. Required fields depend on that selection. Account selectors load live choices; do not invent their IDs. Output fields can also depend on configuration and the response from a service—inspect an execution before referencing a value. + + + +## Trigger manually + +Runs the flow on clicking a button. Good for getting started quickly + +Node type: `MANUAL_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | + + + +## Input Trigger + +Define input fields to fill when running. Great for workflows with parameters + +Node type: `INPUT_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| fields | `fields` | Input fields. Each item uses {name, type, defaultValue?}; supported types are string, number, boolean, object, array, and files. IDs are generated when omitted. | + + + +## Innflow Trigger + +Receive typed input when another Innflow workflow calls this workflow + +Node type: `INNFLOW_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| fields | `fields` | Innflow input fields. Each item uses {name, type, required?, defaultValue?}; names must be unique and IDs are generated when omitted. | + + + +## Form + +Host a public form and run the flow when someone submits it + +Node type: `FORM_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| title | `title` | Published form title. | +| description | `description` | Published form description. | +| fields | `fields` | Published fields using {name, label, type, required?, placeholder?, defaultValue?, options?}. Types: short_text, long_text, email, number, checkbox, select, date, file_upload. IDs are generated when omitted. | +| submitLabel | `submitLabel` | Submit button label. | +| redirectUrl | `redirectUrl` | Optional HTTP or HTTPS URL to open after successful submission. Empty string disables redirect. | +| successMessage | `successMessage` | Message shown after a successful submission. | +| appearance | `appearance` | Appearance settings: accentColor, background, backgroundColor, and density. | + + + +## Webhook + +Runs the flow when an HTTP request is received + +Node type: `WEBHOOK_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| name | `name` | Webhook name. | +| description | `description` | Webhook description. | +| requireAuth | `requireAuth` | Require a request authentication header. | +| authHeaderName | `authHeaderName` | Authentication header name. | +| authTokenEnvVar | `authTokenEnvVar` | Existing encrypted environment-variable name. Raw tokens are rejected. Secret; enter through the secure configuration control. | +| inputSchema | `inputSchema` | Expected request fields using {name, type, required?}. | + + + +## Google Form + +Runs the flow when a Google Form is submitted + +Node type: `GOOGLE_FORM_TRIGGER`. + +Connect the account requested by the node. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| connectionId | `connectionId` | ID of a connected Google Forms account. | + + + +## Stripe Event + +Runs the flow when a Stripe Event is captured + +Node type: `STRIPE_TRIGGER`. + +Connect the account requested by the node. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | + + + +## Typeform + +Runs the flow when a Typeform response is submitted + +Node type: `TYPEFORM_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| formId | `formId` | Typeform form ID. | +| accessTokenEnvVar | `accessTokenEnvVar` | Existing encrypted environment-variable name containing a Typeform personal access token. Required only when creating the registration. Secret; enter through the secure configuration control. | +| webhookSecretEnvVar | `webhookSecretEnvVar` | Optional encrypted environment-variable name containing the Typeform webhook secret. Secret; enter through the secure configuration control. | + + + +## Schedule + +Runs the flow on a schedule using cron expressions + +Node type: `SCHEDULER_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| schedule | `schedule` | Five-field cron expression. | +| timezone | `timezone` | IANA timezone, for example America/Toronto. | +| frequency | `frequency` | Optional display frequency. | +| payload | `payload` | Optional input payload for scheduled runs. | + + + +## Notion Event + +Runs the flow when a Notion page or database event is received + +Node type: `NOTION_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| connectionId | `connectionId` | ID of a connected Notion workspace. | +| entityId | `entityId` | Notion page or database ID. | +| entityType | `entityType` | Notion entity type. Choices: page, database | +| eventTypes | `eventTypes` | Notion webhook event types to accept. Choices: page.content_updated, page.properties_updated, page.created, page.deleted, database.row_created, database.row_updated, database.row_deleted, comment.created, comment.updated, comment.deleted | + + + +## Telegram + +Runs the flow when a message is sent to your Telegram bot + +Node type: `TELEGRAM_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | +| botTokenEnvVar | `botTokenEnvVar` | Existing encrypted environment-variable name containing the Telegram bot token. Required only when creating the registration. Secret; enter through the secure configuration control. | + + + +## Chat + +Trigger workflow with chat messages from a conversational interface + +Node type: `CHAT_TRIGGER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| customName | `customName` | Optional user-facing name. Do not change variableName. | + + + +## AI Agent + +Autonomous AI agent with tool calling. Select tools inline. + +Node type: `AI_AGENT`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Model | `model` | Choose which AI model powers the agent. The model must support tool calling. Choices: OpenAI 5.6 Sol, GPT-5.6 Luna, GPT-5.5, GPT-5.4, GPT-5.4 Mini, GPT-5.4 Nano, GPT-4.1, GPT-4.1 Mini, GPT-4o, GPT-4o Mini, o4-mini, o3, o3-mini, Claude Fable 5, Opus 5, Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5, Gemini 3.7 Flash, Gemini 3.6 Flash, Gemini 3.5 Flash, Gemini 3.5 Flash Lite, Gemini 3.1 Pro, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite, DeepSeek V4 Pro, DeepSeek V4.1 Flash, Kimi K3, Kimi K2.6 | +| System Prompt | `systemPrompt` | Instructions that define the agent's behavior. Supports {{variable}} syntax. | +| User Prompt | `userPrompt` | The task/instruction for the agent. Supports {{variable}} syntax. | +| Temperature | `temperature` | Controls randomness. Lower = more deterministic, Higher = more creative. Conditional field. | +| Max Steps | `maxSteps` | Maximum tool-calling rounds (1-20). A final synthesis is added when tools are used. | +| Skills | `skills` | Select instruction skills the agent should follow. | +| Ubuntu Sandbox | `sandboxEnabled` | Explicitly allow isolated shell and filesystem commands. Connected-app credentials are never placed in the sandbox. | +| Tools | `tools` | Select tools the agent can use during execution. | + + + +## Browser Agent + +Run an interactive browser task with Stagehand and Browserbase + +Node type: `BROWSER_AGENT`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Run Browser Task | `RUN_TASK` | Complete one multi-step task in a fresh browser session | +| Run Browser Sequence | `RUN_SEQUENCE` | Run deterministic browser actions in one shared session | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the browser result downstream | +| Mode | `operation` | Choices: Agent task, Action sequence | +| Starting URL | `startUrl` | The public HTTP or HTTPS page where the browser task starts Conditional field. | +| Task | `instruction` | A clear browser task. Supports {{variable}} syntax. Conditional field. | +| Max Steps | `maxSteps` | Maximum browser-agent actions before the task stops (1-20) Conditional field. | +| Actions | `steps` | Conditional field. | + + + +## A2A Agent + +Delegate tasks to external A2A-compatible agents over HTTP + +Node type: `A2A_AGENT`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Polling Mode | `POLLING` | Send task and poll for result | +| Streaming Mode | `STREAMING` | Receive real-time SSE updates from the agent | + +Open this node in the editor for its setup controls. No editable field list is declared in the shared configuration catalog. + + + +## Image Generation + +Generate images with Kie.ai image models + +Node type: `GENERATE_IMAGE`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Image Generation | `GENERATE` | Generate image URLs using Kie.ai | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference generated images downstream | +| Model | `model` | Kie.ai Market image model to run Choices: Nano Banana 2, OpenAI Image Gen 2, Wan 2.7 Image, Qwen 2 | +| Prompt | `prompt` | Prompt sent to Kie.ai. Supports workflow variables. | +| Aspect Ratio | `aspectRatio` | Aspect ratio for the generated image Choices: Auto, 1:1, 1:4, 1:8, 2:3, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 16:9, 9:16, 21:9 | +| Input Image URLs | `inputUrls` | Optional reference image URLs, one per line or comma-separated. Conditional field. | +| Resolution | `resolution` | Choices: 1K, 2K, 4K Conditional field. | +| Seed | `seed` | Optional generation seed for repeatable supported outputs Conditional field. | +| Max Wait | `maxWaitSeconds` | Maximum time to wait for Kie.ai to finish the image task | + + + +## Web Scraper + +Scrape pages or search the web and extract clean page content + +Node type: `WEB_SCRAPER`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Scrape URL | `SCRAPE_URL` | Scrape a single public page | +| Search + Scrape | `SEARCH_AND_SCRAPE` | Search the web and scrape the top results | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference scraped content downstream | +| Operation | `operation` | Choose whether to scrape a known page or search first Choices: Scrape URL, Search + Scrape | +| URL | `url` | The public HTTP or HTTPS page to scrape Conditional field. | +| Search Query | `query` | The web search query to run before scraping results Conditional field. | +| Max Results | `maxResults` | Number of search results to scrape, capped at 10 Conditional field. | +| Output Format | `outputFormat` | Choose whether to include HTML in addition to markdown Choices: Markdown, Markdown + HTML | +| Include Metadata | `includeMetadata` | Include title, description, Open Graph, and page metadata | +| Include Links | `includeLinks` | Include links discovered on scraped pages | + + + +## Tables + +Read, query, and modify rows in internal tables + +Node type: `TABLES`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Read Table | `READ_TABLE` | Read all rows | +| Query Rows | `QUERY_ROWS` | Filter rows by column value | +| Add Row | `ADD_ROW` | Insert new row(s) | +| Update Row | `UPDATE_ROW` | Update an existing row | +| Delete Row | `DELETE_ROW` | Remove a row by ID | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output (e.g. {{tables.rows}}, {{tables.totalRows}}) | +| Table | `tableId` | The table to operate on Choose from options loaded in the editor. | +| Operation | `operation` | Choices: Read Table, Query Rows, Add Row, Update Row, Delete Row | +| Row Limit | `limit` | Maximum number of rows to return. Leave empty for all. Conditional field. | +| Filter Column | `filterColumn` | The column to filter on Choose from options loaded in the editor. Conditional field. | +| Operator | `filterOperator` | Conditional field. | +| Filter Value | `filterValue` | The value to filter by. Supports {{variable}} syntax. Conditional field. | +| Map Columns | `columnMappings` | Map values from earlier nodes or enter a fixed value for each table column. Conditional field. | +| Row Data (JSON) | `rowData` | JSON object mapping column names to values. Supports {{variable}} in string values. Use an array for bulk insert: [{"col": "val"}, ...] Conditional field. | +| Row ID | `rowId` | The ID of the row to modify. Supports {{variable}} syntax. Conditional field. | +| Update Data (JSON) | `updateData` | Advanced fallback: a JSON object with column values to update. Conditional field. | + + + +## API + +Send a request to any public HTTP API + +Node type: `HTTP_REQUEST`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the response in later nodes | +| Method | `method` | Choices: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS | +| URL | `endpoint` | | +| Query parameters | `queryParams` | | +| Authorization | `authType` | Choices: None, Bearer token, API key, Basic auth | +| Bearer token | `bearerToken` | Select an encrypted Secret or a workflow variable. Secret; enter through the secure configuration control. Conditional field. | +| API key name | `apiKeyName` | Conditional field. | +| API key value | `apiKeyValue` | Select an encrypted Secret or a workflow variable. Secret; enter through the secure configuration control. Conditional field. | +| Send API key in | `apiKeyLocation` | Choices: Header, Query parameter Conditional field. | +| Username | `basicUsername` | Conditional field. | +| Password | `basicPassword` | Select an encrypted Secret or a workflow variable. Secret; enter through the secure configuration control. Conditional field. | +| Headers | `headers` | Sensitive header values must use encrypted Secrets. Legacy JSON header objects remain supported. Secret; enter through the secure configuration control. | +| Body | `bodyType` | Choices: None, JSON, Text, Form URL encoded Conditional field. | +| Request body | `body` | Conditional field. | +| Form fields | `formFields` | Conditional field. | +| Timeout (milliseconds) | `timeoutMs` | Between 1 and 60 seconds | + + + +## Webhook + +Send webhook events to external services + +Node type: `WEBHOOK_ACTION`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Mode | `mode` | Direct HTTP sends requests directly; Svix provides managed delivery with retries and logging Choices: Direct HTTP, Svix (Managed) | +| URL | `url` | Conditional field. | +| Method | `method` | Choices: GET, POST, PUT, PATCH, DELETE Conditional field. | +| Headers | `headers` | JSON object with header key-value pairs Conditional field. | +| Svix App ID | `svixAppId` | Your Svix application ID Conditional field. | +| Event Type | `eventType` | Choices: Workflow Completed, Workflow Failed, Step Completed, Custom Conditional field. | +| Body / Payload | `body` | JSON payload to send with the webhook | + + + +## Wait + +Pause for a duration or until a specific time + +Node type: `SLEEP`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Wait Until | `mode` | Choices: A duration, A date and time | +| Duration | `duration` | Supported units: seconds, minutes, hours, days, weeks Conditional field. | +| Date and Time | `untilAt` | Uses your browser's local timezone and stores the instant in the workflow Conditional field. | + + + +## Human Approval + +Pause until a selected workspace member approves or rejects + +Node type: `HUMAN_APPROVAL`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | | +| Approval Title | `title` | | +| Instructions | `instructions` | | +| Reviewers | `reviewerUserIds` | The first selected reviewer to respond resolves the request Choose from options loaded in the editor. | +| Timeout | `timeout` | | +| Additional Notifications | `deliveryChannels` | Inbox notifications are always created Choices: Email reviewers, Slack channel, Microsoft Teams channel | +| Slack Account | `slackAccountId` | | +| Slack Channel | `slackChannelId` | Choose from options loaded in the editor. | +| Teams Account | `teamsConnectionId` | | +| Teams Team ID | `teamsTeamId` | | +| Teams Channel ID | `teamsChannelId` | | + + + +## Wait for Event + +Pause until a unique callback URL receives an event + +Node type: `WAIT_FOR_EVENT`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | | +| Event Name | `title` | | +| Timeout | `timeout` | | +| Additional Inbox Recipients | `recipientUserIds` | The workflow owner always receives the callback URL Choose from options loaded in the editor. | +| Additional Notifications | `deliveryChannels` | Choices: Email recipients, Slack channel, Microsoft Teams channel | +| Slack Account | `slackAccountId` | | +| Slack Channel | `slackChannelId` | Choose from options loaded in the editor. | +| Teams Account | `teamsConnectionId` | | +| Teams Team ID | `teamsTeamId` | | +| Teams Channel ID | `teamsChannelId` | | + + + +## Condition + +Branch workflow based on a condition (If/Else) + +Node type: `CONDITION`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| branches | `branches` | Read only. | +| schemaVersion | `schemaVersion` | | +| conditionType | `conditionType` | | +| combinator | `combinator` | Choices: All rules, Any rule | +| predicates | `predicates` | Use configureCondition for typed comparison rules. | + + + +## Router + +AI-powered routing with multiple dynamic branches + +Node type: `ROUTER`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Context | `context` | The context to analyze for routing decision | +| routes | `routes` | | +| Model | `model` | AI model to use for routing decision Choices: Default, Fastest, Balanced, Smartest, OpenAI 5.6 Sol, GPT-5.5, GPT-5.4, GPT-5.4 Mini, GPT-5.4 Nano, GPT-4.1, GPT-4.1 Mini, GPT-4o, GPT-4o Mini, Claude Fable 5, Opus 5, Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5, Gemini 3.7 Flash, Gemini 3.6 Flash, Gemini 3.5 Flash, Gemini 3.5 Flash Lite, Gemini 3.1 Pro, Gemini 2.5 Flash, Gemini 2.5 Pro, DeepSeek V4 Pro, DeepSeek V4.1 Flash | + + + +## Label Fields + +AI-powered extraction of structured data from unstructured input + +Node type: `LABEL_FIELDS`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Input Source | `inputSource` | The data to extract fields from. Use {{variable}} to reference upstream data. | +| Fields to Extract | `fields` | Define fields as JSON array. Types: string, number, boolean, array, json. | +| AI Model | `model` | Select the AI model for extraction Choices: Default (GPT-5.4 Mini), OpenAI 5.6 Sol, GPT-5.5, GPT-5.4, GPT-5.4 Mini, GPT-5.4 Nano, GPT-4o, GPT-4o mini, Claude Fable 5, Opus 5, Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5, Gemini 3.7 Flash, Gemini 3.6 Flash, Gemini 3.5 Flash, Gemini 3.5 Flash Lite, Gemini 3.1 Pro, Gemini 2.5 Pro, Gemini 2.5 Flash, DeepSeek V4 Pro, DeepSeek V4.1 Flash | +| Additional Instructions | `instructions` | Optional guidance for the AI on how to extract fields | + + + +## Transform Array + +Map, filter, or reduce arrays for data transformation + +Node type: `TRANSFORM_ARRAY`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Map | `MAP` | Transform each item into a new shape | +| Filter | `FILTER` | Keep only items matching a condition | +| Reduce | `REDUCE` | Aggregate items into a single value | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Input Array | `inputArray` | The array to transform. Use {{variable}} to reference upstream data. | +| Operation | `operation` | Choose how to transform the array Choices: Map — Transform each item, Filter — Keep matching items, Reduce — Aggregate into single value | +| Transform Expression | `mapExpression` | Use {{item}} for current item, {{index}} for position Conditional field. | +| Filter Field | `filterField` | Field path to filter on Conditional field. | +| Operator | `filterOperator` | Choices: Equals, Not Equals, Contains, Not Contains, Greater Than, Greater Than or Equal, Less Than, Less Than or Equal, Exists (not null/undefined), Does Not Exist Conditional field. | +| Value | `filterValue` | Conditional field. | +| Reduce Type | `reduceType` | Choices: Sum — Add up numeric values, Count — Count number of items, Concatenate — Join values together, First — Get first item, Last — Get last item, Minimum — Get smallest value, Maximum — Get largest value, Custom — Write custom expression Conditional field. | +| Field to Aggregate | `reduceField` | The field from each item to aggregate Conditional field. | +| Initial Value | `reduceInitial` | Starting value for the accumulator (JSON or string) Conditional field. | +| Reduce Expression | `reduceExpression` | Use {{accumulator}} for running value, {{item}} for current item Conditional field. | +| Error Handling | `errorHandling` | How to handle errors during transformation Choices: Continue — Collect partial results, Fail — Stop on first error | + + + +## Loop + +Run connected nodes once for each item in an array + +Node type: `LOOP`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Items | `inputArray` | The array whose items should run through the loop body. | +| Result | `resultExpression` | Evaluated after each body run. When empty, the current item is collected. | +| If an item fails | `errorHandling` | Choices: Continue and collect the error, Stop the loop and fail the workflow | +| Maximum iterations | `maxIterations` | Must be between 1 and 1,000. | + + + +## CSV Export + +Convert arrays of data into CSV format + +Node type: `CSV_EXPORT`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Data Source | `dataSource` | The array of objects to convert to CSV. Use {{variable}} to reference upstream data. | +| Include Headers | `includeHeaders` | Include column headers as the first row of the CSV | +| Delimiter | `delimiter` | Character used to separate values in each row Choices: Comma (,), Semicolon (;), Tab | +| File Name | `fileName` | Informational label for the exported file (without .csv extension) | + + + +## Code + +Execute JavaScript, Python, or Java code in a secure sandbox + +Node type: `CODE`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Name used to reference this node's output in downstream nodes (e.g. {{code.result}}) | +| Language | `language` | Select the programming language for your code. Python is the default and recommended option. Choices: Python, JavaScript, Java | +| Code | `code` | Read upstream data through context. For Python scripts, print JSON as the last output for a structured result. Use return only inside a function. Captured expression results are used when the runner provides them. | +| Timeout (seconds) | `timeout` | Maximum execution time in seconds (1-300). Default: 30s | +| Output Fields | `outputFields` | Optional declarations used to expose object fields downstream before execution. | + + + +## OpenRouter + +Access 200+ AI models via OpenRouter (GPT, Claude, Llama, Gemini & more) + +Node type: `AI_MODEL`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Generate Text | `GENERATE_TEXT` | Generate text using any of 200+ AI models via OpenRouter | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| variableName | `variableName` | Variable name to store output | +| model | `model` | OpenRouter model ID (e.g. openai/gpt-4o, anthropic/claude-sonnet-5) | +| messages | `messages` | Chat messages (system, user, assistant) | +| apiKey | `apiKey` | OpenRouter API key (optional — platform key used as fallback) | +| temperature | `temperature` | Temperature 0-2 (default 0.7) | +| maxTokens | `maxTokens` | Maximum output tokens (default 4096) | +| jsonMode | `jsonMode` | Enable JSON output mode | +| systemPrompt | `systemPrompt` | Custom system prompt | + + + +## OpenAI + +Uses OpenAI to generate text + +Node type: `OPENAI`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| variableName | `variableName` | Variable name to store output | +| messages | `messages` | Chat messages (system, user, assistant) | +| model | `model` | Model to use Choices: gpt-5.6-sol, gpt-5.5, gpt-5.4-mini, gpt-5.4, gpt-4o, gpt-4o-mini | + + + +## Gemini + +Uses Google Gemini to generate text + +Node type: `GEMINI`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| variableName | `variableName` | Variable name to store output | +| messages | `messages` | Chat messages | +| model | `model` | Model to use Choices: gemini-3.7-flash, gemini-3.6-flash, gemini-3.5-flash, gemini-3.5-flash-lite, gemini-3.1-pro-preview, gemini-2.5-flash, gemini-2.5-pro | + + + +## Anthropic + +Uses Anthropic to generate text + +Node type: `ANTHROPIC`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| variableName | `variableName` | Variable name to store output | +| messages | `messages` | Chat messages | +| model | `model` | Model to use Choices: claude-fable-5, claude-opus-5, claude-sonnet-5, claude-opus-4-8, claude-haiku-4-5-20251001 | + + + +## DeepSeek + +Uses DeepSeek to generate text + +Node type: `DEEPSEEK`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| variableName | `variableName` | Variable name to store output | +| messages | `messages` | Chat messages | +| model | `model` | Model to use Choices: deepseek-v4-pro, deepseek-flash | + + + +## Kimi + +Uses Kimi (Moonshot AI) to generate text + +Node type: `KIMI`. + +No account connection declared. + +Open this node in the editor for its setup controls. No editable field list is declared in the shared configuration catalog. + + + +## Grok + +Uses Grok (xAI) to generate text + +Node type: `GROK`. + +No account connection declared. + +Open this node in the editor for its setup controls. No editable field list is declared in the shared configuration catalog. + + + +## Qwen + +Uses Qwen (Alibaba Cloud) to generate text + +Node type: `QWEN`. + +No account connection declared. + +Open this node in the editor for its setup controls. No editable field list is declared in the shared configuration catalog. + + + +## Tavily + +Search the web for real-time information + +Node type: `TAVILY_SEARCH`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Search | `SEARCH` | | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| API Key | `apiKey` | Tavily API key - set in Settings > BYOK, Settings > Environment, or paste directly Secret; enter through the secure configuration control. | +| Search Query | `query` | | +| Search Depth | `search_depth` | Choices: Basic, Advanced | +| Max Results | `max_results` | | +| Topic | `topic` | Choices: General, News, Finance | +| Include Answer | `include_answer` | Choices: None, Basic, Advanced | +| Include Images | `include_images` | | +| Time Range | `time_range` | Choices: All Time, Day, Week, Month, Year | +| Include Domains | `include_domains` | | +| Exclude Domains | `exclude_domains` | | + + + +## Exa + +AI-powered web search with neural, keyword, and similarity modes + +Node type: `EXA`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Search | `SEARCH` | Search the web with neural/keyword search | +| Find Similar | `FIND_SIMILAR` | Find pages similar to a URL | +| Get Contents | `GET_CONTENTS` | Retrieve full page content | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| API Key | `apiKey` | Exa API key - set in Settings > BYOK, Settings > Environment, or paste directly Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Search, Find Similar, Get Contents | +| Search Query | `query` | Conditional field. | +| Search Type | `searchType` | Choices: Auto, Neural, Keyword Conditional field. | +| Category Filter | `category` | Choices: All, Company, Research Paper, News, PDF, GitHub, Tweet, Personal Site, LinkedIn Profile Conditional field. | +| Use Autoprompt | `useAutoprompt` | Let Exa optimize your query for better results Conditional field. | +| Source URL | `url` | Conditional field. | +| Exclude Source Domain | `excludeSourceDomain` | Conditional field. | +| URLs | `urls` | Comma or newline separated URLs (max 100) Conditional field. | +| Summary Focus | `summaryQuery` | Conditional field. | +| Number of Results | `numResults` | Conditional field. | +| Include Domains | `includeDomains` | Comma-separated list of domains to limit results to Conditional field. | +| Exclude Domains | `excludeDomains` | Conditional field. | +| Published After | `startPublishedDate` | Conditional field. | +| Published Before | `endPublishedDate` | Conditional field. | +| Include Highlights | `includeHighlights` | Conditional field. | +| Include Full Text | `includeText` | | +| Include AI Summary | `includeSummary` | Conditional field. | + + + +## Perplexity + +AI-powered search and research with real-time web access + +Node type: `PERPLEXITY`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Ask Question | `ASK` | Ask a question with real-time web search | +| Research | `RESEARCH` | Multi-step research with follow-up questions | +| Fact Check | `FACT_CHECK` | Verify a claim against web sources | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| API Key | `apiKey` | Perplexity API key - set in Settings > BYOK, Settings > Environment, or paste directly Secret; enter through the secure configuration control. | +| Variable Name | `variableName` | | +| Operation | `operation` | Choices: Ask Question, Research, Fact Check | +| Model | `model` | Choices: Sonar, Sonar Small, Sonar Medium, Sonar Pro | +| Prompt | `prompt` | Conditional field. | +| System Prompt | `systemPrompt` | Conditional field. | +| Search Domain Filter | `searchDomainFilter` | Conditional field. | +| Search Recency Filter | `searchRecencyFilter` | Choices: None, Day, Week, Month, Year Conditional field. | +| Temperature | `temperature` | Conditional field. | +| Initial Question | `initialQuestion` | Conditional field. | +| Follow-Up Questions | `followUpQuestions` | Conditional field. | +| Claim | `claim` | Conditional field. | + + + +## Firecrawl + +Scrape, search, crawl, map, extract, and agent-browse the web + +Node type: `FIRECRAWL`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Scrape | `SCRAPE` | Scrape a single URL and extract content | +| Search | `SEARCH` | Search the web for relevant pages | +| Crawl | `CRAWL` | Crawl a website following links from a start URL | +| Map | `MAP` | Discover all linked pages from a URL | +| Extract | `EXTRACT` | Extract structured data from web pages using AI | +| Agent | `AGENT` | AI agent that navigates and interacts with websites | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| API Key | `apiKey` | Firecrawl API key -- set in Settings > BYOK, Settings > Environment, or paste directly Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Scrape, Search, Crawl, Map, Extract, Agent | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| URL | `url` | The URL to scrape Conditional field. | +| Output Formats | `formats` | Choose which formats to include in the output Choices: Markdown, HTML, Raw HTML, Links, Screenshot Conditional field. | +| Only Main Content | `onlyMainContent` | Extract only the main content, excluding headers, footers, and navigation Conditional field. | +| Include Tags | `includeTags` | Only include content from these HTML tags (comma-separated, e.g. article, main) Conditional field. | +| Exclude Tags | `excludeTags` | Exclude content from these HTML tags (comma-separated, e.g. nav, footer) Conditional field. | +| Wait For (ms) | `waitFor` | Wait for this many milliseconds before scraping (useful for JS-heavy pages) Conditional field. | +| Search Query | `query` | The search query to find relevant web pages Conditional field. | +| Result Limit | `limit` | Number of search results (1-20) Conditional field. | +| Language | `lang` | Language code for results (e.g. en, es, fr) Conditional field. | +| Country | `country` | Country code for results (e.g. us, gb, de) Conditional field. | +| Scrape Results | `scrapeResults` | Also scrape the full content of each search result Conditional field. | +| Start URL | `crawlUrl` | The starting URL to begin crawling from Conditional field. | +| Max Pages | `crawlLimit` | Maximum number of pages to crawl (1-1000) Conditional field. | +| Max Depth | `maxDepth` | Maximum link depth to crawl from the start URL Conditional field. | +| Allow Backward Links | `allowBackwardLinks` | Allow crawling pages that link back to already crawled pages Conditional field. | +| Allow External Links | `allowExternalLinks` | Allow crawling pages on different domains Conditional field. | +| Include Paths | `includePaths` | Only crawl URLs matching these path patterns (comma-separated, e.g. /blog/*, /docs/*) Conditional field. | +| Exclude Paths | `excludePaths` | Skip URLs matching these path patterns (comma-separated) Conditional field. | +| URL | `mapUrl` | The URL to map (discover all linked pages) Conditional field. | +| Search Filter | `mapSearch` | Filter discovered links by a search query Conditional field. | +| Link Limit | `mapLimit` | Maximum number of links to return Conditional field. | +| URLs | `extractUrls` | Enter one URL per line, or use a variable Conditional field. | +| Extraction Prompt | `extractPrompt` | Describe what data to extract from the pages Conditional field. | +| JSON Schema | `extractSchema` | Optional: Define a JSON schema for structured extraction output Conditional field. | +| Enable Web Search | `enableWebSearch` | Allow the extraction to use web search for additional context Conditional field. | +| Start URL | `agentUrl` | The starting URL for the agent to navigate Conditional field. | +| Task / Prompt | `agentPrompt` | Describe the task for the agent to perform on the website Conditional field. | + + + +## Discord + +Send messages to Discord channels via webhooks + +Node type: `DISCORD`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Webhook URL | `webhookUrl` | Get this from Discord: Channel Settings → Integrations → Webhooks Secret; enter through the secure configuration control. | +| Message Content | `content` | The message to send. Maximum 2000 characters. | +| Bot Username | `username` | Override the webhook's default username | + + + +## Slack + +Send and read messages in Slack channels + +Node type: `SLACK`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Message | `SEND_MESSAGE` | Send a message to a channel | +| Read Messages | `READ_MESSAGE` | Read recent messages from a channel | +| Create Canvas | `CREATE_CANVAS` | Listed in search, but the current Innflow implementation rejects this operation. | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Slack Account | `slackAccountId` | Select or connect a Slack workspace | +| Operation | `operation` | Choices: Send Message, Read Messages, Create Canvas | +| Channel | `channelId` | The Slack channel to interact with Choose from options loaded in the editor. | +| Message | `content` | Conditional field. | +| File Attachment | `attachmentUrl` | Attach a file to the message Conditional field. | + + + +## Google Docs + +Create, read, and write Google Docs documents + +Node type: `GOOGLE_DOCS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Document | `CREATE_DOCUMENT` | Create a new Google Docs document | +| Read Document | `READ_DOCUMENT` | Read content from a Google Docs document | +| Write to Document | `WRITE_TO_DOCUMENT` | Write content to an existing Google Docs document | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Account | `googleAccountId` | Select or connect a Google account | +| Operation | `operation` | Choices: Create Document, Read Document, Write to Document | +| Document Title | `title` | Conditional field. | +| Document ID | `documentId` | The ID from the document URL Conditional field. | +| Content | `content` | Conditional field. | + + + +## Google Sheets + +Read, write, and manage Google Sheets spreadsheets + +Node type: `GOOGLE_SHEETS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Read Rows | `READ_ROWS` | Read rows from a spreadsheet | +| Append Rows | `APPEND_ROWS` | Append rows to a spreadsheet | +| Update Rows | `UPDATE_ROWS` | Update existing rows in a spreadsheet | +| Create Spreadsheet | `CREATE_SPREADSHEET` | Create a new Google Sheets spreadsheet | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Account | `googleAccountId` | Select or connect a Google account | +| Operation | `operation` | Choices: Read Rows, Append Rows, Update Rows, Create Spreadsheet | +| Spreadsheet | `spreadsheetId` | Choose a spreadsheet from the selected Google account Choose from options loaded in the editor. Conditional field. | +| Sheet | `sheetName` | Choose a sheet tab from the selected spreadsheet Choose from options loaded in the editor. Conditional field. | +| Range | `range` | Cell range (e.g. A1:D10 or A:Z) Conditional field. | +| Map Columns | `useColumnMapping` | Load every header from the selected sheet and map values individually. Conditional field. | +| Columns | `columnMappings` | Conditional field. | +| Values | `values` | Advanced JSON array fallback or {{variable}} Conditional field. | +| Spreadsheet Title | `title` | Conditional field. | + + + +## Google Calendar + +Manage calendars, events, and scheduling via Google Calendar + +Node type: `GOOGLE_CALENDAR`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Calendars | `LIST_CALENDARS` | List all calendars for the authenticated user | +| List Events | `LIST_EVENTS` | List events from a calendar with optional search | +| Create Event | `CREATE_EVENT` | Create a new calendar event | +| Read Event | `READ_EVENT` | Get details of a specific event | +| Update Event | `UPDATE_EVENT` | Update an existing calendar event | +| Delete Event | `DELETE_EVENT` | Delete a calendar event | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Calendar Account | `connectionId` | Select or connect a Google Calendar account | +| Operation | `operation` | Choices: List Calendars, List Events, Create Event, Read Event, Update Event, Delete Event | +| Calendar ID | `calendarId` | Conditional field. | +| Event ID | `eventId` | Conditional field. | +| Summary | `summary` | Event title Conditional field. | +| Description | `description` | Conditional field. | +| Location | `location` | Conditional field. | +| Start Date/Time | `startDateTime` | Conditional field. | +| End Date/Time | `endDateTime` | Conditional field. | +| Time Zone | `timeZone` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | +| Search Query | `query` | Conditional field. | +| Send Notifications | `sendNotifications` | Conditional field. | + + + +## Google Forms + +Retrieve responses from Google Forms + +Node type: `GOOGLE_FORMS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Get Responses | `GET_RESPONSES` | Retrieve responses from a Google Form | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Forms Account | `connectionId` | Select or connect a Google account | +| Form ID | `formId` | Form ID from the Google Form URL | +| Page Size | `pageSize` | | + + + +## Google Groups + +Manage Google Groups, members, and memberships + +Node type: `GOOGLE_GROUPS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Groups | `LIST_GROUPS` | List all groups | +| Get Group | `GET_GROUP` | Get group details | +| Create Group | `CREATE_GROUP` | Create a new group | +| Update Group | `UPDATE_GROUP` | Update group settings | +| Delete Group | `DELETE_GROUP` | Delete a group | +| List Members | `LIST_MEMBERS` | List group members | +| Get Member | `GET_MEMBER` | Get member details | +| Add Member | `ADD_MEMBER` | Add a member to a group | +| Update Member Role | `UPDATE_MEMBER_ROLE` | Change a member's role | +| Remove Member | `REMOVE_MEMBER` | Remove a member from a group | +| Check Membership | `CHECK_MEMBERSHIP` | Check if a user is a member of a group | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Groups Account | `connectionId` | Select or connect a Google account | +| Operation | `operation` | Choices: List Groups, Get Group, Create Group, Update Group, Delete Group, List Members, Get Member, Add Member, Update Member Role, Remove Member, Check Membership | +| Group Key | `groupKey` | Group email or ID Conditional field. | +| Member Key | `memberKey` | Conditional field. | +| Member Email | `memberEmail` | Conditional field. | +| Member Role | `memberRole` | Choices: Owner, Manager, Member Conditional field. | +| Group Email | `email` | Conditional field. | +| Group Name | `name` | Conditional field. | +| Description | `description` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | + + + +## Google Drive + +List, download, and upload files in Google Drive + +Node type: `GOOGLE_DRIVE`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Files | `LIST_FILES` | List files in Google Drive | +| Download File | `DOWNLOAD_FILE` | Download a file from Google Drive | +| Upload File | `UPLOAD_FILE` | Upload a file to Google Drive | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Drive Account | `googleAccountId` | Select or connect a Google account | +| Operation | `operation` | Choices: List Files, Download File, Upload File | +| Search Query | `query` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | +| File ID | `fileId` | Conditional field. | +| File Name | `uploadFileName` | Conditional field. | +| File Content | `uploadContent` | Conditional field. | +| MIME Type | `uploadMimeType` | Choices: text/plain, application/json, text/csv, text/html, text/markdown Conditional field. | +| Folder ID | `uploadFolderId` | Parent folder ID Conditional field. | + + + +## Google Slides + +Create and read Google Slides presentations + +Node type: `GOOGLE_SLIDES`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Presentation | `CREATE_PRESENTATION` | Create a new Google Slides presentation | +| Read Presentation | `READ_PRESENTATION` | Read an existing Google Slides presentation | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Google Slides Account | `googleAccountId` | Select or connect a Google account | +| Operation | `operation` | Choices: Create Presentation, Read Presentation | +| Presentation Title | `title` | Conditional field. | +| Presentation ID | `presentationId` | Conditional field. | + + + +## Airtable + +Read, create, update, and delete Airtable records + +Node type: `AIRTABLE`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Records | `LIST_RECORDS` | List records from a table | +| Read Record | `READ_RECORD` | Read a single record by ID | +| Create Record | `CREATE_RECORD` | Create a new record in a table | +| Update Record | `UPDATE_RECORD` | Update an existing record | +| Delete Record | `DELETE_RECORD` | Delete a record by ID | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Airtable Account | `connectionId` | Select or connect an Airtable account | +| Operation | `operation` | Choices: List Records, Read Record, Create Record, Update Record, Delete Record | +| Base ID | `baseId` | Airtable Base ID | +| Table Name | `tableName` | Table name or ID | +| Record ID | `recordId` | Airtable Record ID Conditional field. | +| Record Data | `recordData` | JSON object with field values Conditional field. | +| Filter Formula | `filterFormula` | Airtable filter formula Conditional field. | +| Max Records | `maxRecords` | Conditional field. | + + + +## Gmail + +Send, read, search, and manage emails via Gmail + +Node type: `GMAIL`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Email | `SEND_EMAIL` | Send an email from your Gmail account | +| Read Emails | `READ_EMAILS` | Read emails from a label/folder | +| Draft Email | `DRAFT_EMAIL` | Create a draft email | +| Search Emails | `SEARCH_EMAILS` | Search emails using Gmail query syntax | +| Move Email | `MOVE_EMAIL` | Move an email by adding/removing labels | +| Mark as Read | `MARK_AS_READ` | Mark a message as read | +| Mark as Unread | `MARK_AS_UNREAD` | Mark a message as unread | +| Archive Email | `ARCHIVE_EMAIL` | Archive an email (remove from inbox) | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Gmail Account | `gmailConnectionId` | Select or connect a Gmail account | +| Operation | `operation` | Choices: Send Email, Read Emails, Draft Email, Search Emails, Move Email, Mark as Read, Mark as Unread, Archive Email | +| To | `to` | Conditional field. | +| Subject | `subject` | Conditional field. | +| Body | `body` | Conditional field. | +| Send as HTML | `isHtml` | Conditional field. | +| CC | `cc` | Conditional field. | +| BCC | `bcc` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | +| Label | `labelId` | Conditional field. | +| Search Query | `query` | Conditional field. | +| Message ID | `messageId` | Conditional field. | +| Add Label | `addLabelId` | Conditional field. | +| Remove Label | `removeLabelId` | Conditional field. | + + + +## Microsoft Teams + +Send messages, read channels, and manage teams in Microsoft Teams + +Node type: `MICROSOFT_TEAMS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Message | `SEND_MESSAGE` | Send a message to a Teams channel | +| Read Messages | `READ_MESSAGES` | Read recent messages from a channel | +| List Channels | `LIST_CHANNELS` | List channels in a team | +| List Teams | `LIST_TEAMS` | List all teams you belong to | +| Create Channel | `CREATE_CHANNEL` | Create a new channel in a team | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Teams Account | `connectionId` | Select or connect a Microsoft Teams account | +| Operation | `operation` | Choices: Send Message, Read Messages, List Channels, List Teams, Create Channel | +| Team ID | `teamId` | Conditional field. | +| Channel ID | `channelId` | Conditional field. | +| Message | `message` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | +| Channel Name | `channelNameNew` | Conditional field. | +| Channel Description | `channelDescription` | Conditional field. | + + + +## Microsoft Outlook + +Send, read, draft, and search emails via Microsoft Outlook + +Node type: `MICROSOFT_OUTLOOK`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Email | `SEND_EMAIL` | Send an email from your Outlook account | +| Read Emails | `READ_EMAILS` | Read emails from a folder | +| Read Email | `READ_EMAIL` | Read a single email by ID | +| Create Draft | `CREATE_DRAFT` | Create a draft email | +| Search Emails | `SEARCH_EMAILS` | Search emails using a query | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Outlook Account | `connectionId` | Select or connect a Microsoft Outlook account | +| Operation | `operation` | Choices: Send Email, Read Emails, Read Email, Create Draft, Search Emails | +| To | `to` | Conditional field. | +| Subject | `subject` | Conditional field. | +| Body | `body` | Conditional field. | +| Send as HTML | `isHtml` | Conditional field. | +| CC | `cc` | Conditional field. | +| BCC | `bcc` | Conditional field. | +| Folder ID | `folderId` | Conditional field. | +| Message ID | `messageId` | Conditional field. | +| Search Query | `searchQuery` | Conditional field. | +| Max Results | `maxResults` | Conditional field. | + + + +## Microsoft Word + +Create, read, and update Microsoft Word documents + +Node type: `MICROSOFT_WORD`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Document | `CREATE_DOCUMENT` | Create a new Microsoft Word document | +| Read Document | `READ_DOCUMENT` | Read content from a Microsoft Word document | +| Update Document | `UPDATE_DOCUMENT` | Update content in an existing Microsoft Word document | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Microsoft Account | `connectionId` | Select or connect a Microsoft account | +| Operation | `operation` | Choices: Create Document, Read Document, Update Document | +| File Name | `fileName` | Conditional field. | +| Folder Path | `folderPath` | OneDrive folder path for the new document Conditional field. | +| Initial Content | `initialContent` | Conditional field. | +| File ID | `fileId` | The file ID from Microsoft Graph Conditional field. | +| Content | `content` | Conditional field. | + + + +## Microsoft Excel + +Create, read, and write Microsoft Excel spreadsheets + +Node type: `MICROSOFT_EXCEL`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Spreadsheet | `CREATE_SPREADSHEET` | Create a new Microsoft Excel spreadsheet | +| Read Rows | `READ_ROWS` | Read rows from an Excel spreadsheet | +| Write Rows | `WRITE_ROWS` | Write rows to an Excel spreadsheet | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Microsoft Account | `connectionId` | Select or connect a Microsoft account | +| Operation | `operation` | Choices: Create Spreadsheet, Read Rows, Write Rows | +| File Name | `fileName` | Conditional field. | +| Folder Path | `folderPath` | OneDrive folder path for the new spreadsheet Conditional field. | +| File ID | `fileId` | The file ID from Microsoft Graph Conditional field. | +| Worksheet Name | `worksheetName` | Name of the worksheet tab Conditional field. | +| Range | `range` | Cell range (e.g. A1:Z100) Conditional field. | +| Values | `values` | JSON array of row data Conditional field. | + + + +## Microsoft OneDrive + +List, get, create folders, and delete files in OneDrive + +Node type: `MICROSOFT_ONEDRIVE`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Files | `LIST_FILES` | List files in a OneDrive folder | +| Get File | `GET_FILE` | Get a file from OneDrive | +| Create Folder | `CREATE_FOLDER` | Create a new folder in OneDrive | +| Delete File | `DELETE_FILE` | Delete a file from OneDrive | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| OneDrive Account | `connectionId` | Select or connect a Microsoft account | +| Operation | `operation` | Choices: List Files, Get File, Create Folder, Delete File | +| Folder ID | `folderId` | Parent folder ID (root if empty) Conditional field. | +| File ID | `fileId` | Conditional field. | +| Folder Name | `folderName` | Conditional field. | + + + +## Microsoft SharePoint + +Browse sites, lists, and manage list items in SharePoint Online + +Node type: `MICROSOFT_SHAREPOINT`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Sites | `LIST_SITES` | Search or list SharePoint sites | +| List Lists | `LIST_LISTS` | List all lists in a SharePoint site | +| Get List Items | `GET_LIST_ITEMS` | Get items from a SharePoint list | +| Create List Item | `CREATE_LIST_ITEM` | Create a new item in a SharePoint list | +| Update List Item | `UPDATE_LIST_ITEM` | Update an existing item in a SharePoint list | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| SharePoint Account | `connectionId` | Select or connect a Microsoft account | +| Operation | `operation` | Choices: List Sites, List Lists, Get List Items, Create List Item, Update List Item | +| Search Query | `searchQuery` | Conditional field. | +| Site ID | `siteId` | Conditional field. | +| List ID | `listId` | Conditional field. | +| Item ID | `itemId` | Conditional field. | +| Fields | `fields` | JSON object with field values Conditional field. | +| Filter | `filter` | OData filter expression Conditional field. | +| Max Results | `top` | Conditional field. | + + + +## Microsoft Planner + +Manage plans and tasks in Microsoft Planner + +Node type: `MICROSOFT_PLANNER`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Plans | `LIST_PLANS` | List all plans in the group | +| List Tasks | `LIST_TASKS` | List tasks in a plan | +| Create Task | `CREATE_TASK` | Create a new task in a plan | +| Update Task | `UPDATE_TASK` | Update an existing task | +| Delete Task | `DELETE_TASK` | Delete a task | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Microsoft Planner Account | `connectionId` | Select or connect a Microsoft Planner account | +| Operation | `operation` | Choices: List Plans, List Tasks, Create Task, Update Task, Delete Task | +| Plan ID | `planId` | Planner Plan ID Conditional field. | +| Task ID | `taskId` | Planner Task ID Conditional field. | +| Task Title | `title` | Conditional field. | +| Bucket ID | `bucketId` | Planner bucket ID Conditional field. | +| Due Date | `dueDate` | Conditional field. | +| Priority | `priority` | Choices: Urgent, Important, Medium, Low Conditional field. | +| Percent Complete | `percentComplete` | Conditional field. | + + + +## Knowledge Base + +Search your knowledge base for relevant information + +Node type: `KNOWLEDGE_BASE`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Search | `SEARCH` | Search knowledge base for relevant information | +| Upload | `UPLOAD` | Upload a document to the knowledge base | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Knowledge Base | `knowledgeBaseId` | The knowledge base to query or upload to Choose from options loaded in the editor. | +| Operation | `operation` | Choose whether to search or upload to the knowledge base Choices: Search, Upload | +| Search Query | `query` | The query to search for in the knowledge base Conditional field. | +| Number of Results | `topK` | Maximum number of results to return (1-50) Conditional field. | +| Score Threshold | `scoreThreshold` | Minimum similarity score (0-1). Leave empty for no threshold. Conditional field. | +| File URL | `fileUrl` | URL of the file to upload Conditional field. | +| File Name | `fileName` | Name to save the file as Conditional field. | +| File Type | `fileType` | Type of the file being uploaded Choices: PDF, Text, Markdown Conditional field. | + + + +## Attio + +Manage Attio CRM records, notes, tasks, and object metadata + +Node type: `ATTIO`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Records | `LIST_RECORDS` | | +| Get Record | `GET_RECORD` | | +| Update Record | `UPDATE_RECORD` | | +| Delete Record | `DELETE_RECORD` | | +| Search Records | `SEARCH_RECORDS` | | +| Assert Record | `ASSERT_RECORD` | | +| List Notes | `LIST_NOTES` | | +| Get Note | `GET_NOTE` | | +| Create Note | `CREATE_NOTE` | | +| Delete Note | `DELETE_NOTE` | | +| List Tasks | `LIST_TASKS` | | +| Create Task | `CREATE_TASK` | | +| Get Object | `GET_OBJECT` | | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Attio Account | `connectionId` | Select or connect an Attio workspace | +| Operation | `operation` | Choices: List Records, Get Record, Update Record, Delete Record, Search Records, Assert Record, List Notes, Get Note, Create Note, Delete Note, List Tasks, Create Task, Get Object | +| Object | `object` | Attio object slug or ID Conditional field. | +| Record ID | `recordId` | Conditional field. | +| Note ID | `noteId` | Conditional field. | +| Matching Attribute | `matchingAttribute` | Unique attribute slug or ID used by Attio to match a record Conditional field. | +| Values | `values` | JSON object for Attio attribute values Conditional field. | +| Filter | `filter` | Optional Attio filter object Conditional field. | +| Sorts | `sorts` | Optional Attio sorts array Conditional field. | +| Search Query | `query` | Conditional field. | +| Title | `title` | Conditional field. | +| Content | `content` | Conditional field. | +| Deadline | `deadlineAt` | Conditional field. | +| Linked Records | `linkedRecords` | Optional JSON array of Attio record identifiers Conditional field. | +| Limit | `limit` | Conditional field. | +| Offset | `offset` | Conditional field. | + + + +## HubSpot + +Manage HubSpot contacts, companies, and deals + +Node type: `HUBSPOT`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Record | `CREATE_RECORD` | Create a new CRM record | +| Read Record | `READ_RECORD` | Read a single record by ID | +| Update Record | `UPDATE_RECORD` | Update an existing record | +| Delete Record | `DELETE_RECORD` | Delete a record by ID | +| List Records | `LIST_RECORDS` | List records with optional limit | +| Search Records | `SEARCH_RECORDS` | Search records with query or filters | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| HubSpot Account | `connectionId` | Select or connect a HubSpot account | +| Object Type | `objectType` | Choices: Contacts, Companies, Deals | +| Operation | `operation` | Choices: Create Record, Read Record, Update Record, Delete Record, List Records, Search Records | +| Record ID | `recordId` | HubSpot Record ID Conditional field. | +| Properties | `properties` | JSON object with property values Conditional field. | +| Search Query | `searchQuery` | Free-text search query Conditional field. | +| Filter Groups | `filterGroups` | Advanced filter JSON Conditional field. | +| Limit | `limit` | Conditional field. | + + + +## ClickUp + +Manage ClickUp tasks, lists, comments, and custom fields + +Node type: `CLICKUP`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Task | `CREATE_TASK` | Create a new task in a list | +| Get Task | `GET_TASK` | Fetch a task by ID | +| Update Task | `UPDATE_TASK` | Partially update an existing task | +| Delete Task | `DELETE_TASK` | Permanently delete a task | +| List Tasks | `LIST_TASKS` | List tasks in a list with optional filters | +| Search Tasks | `SEARCH_TASKS` | Search tasks across an entire workspace | +| Add Comment | `ADD_COMMENT` | Post a comment on a task | +| Set Custom Field | `SET_CUSTOM_FIELD` | Set a single custom field value on a task | +| Get Lists | `GET_LISTS` | Fetch lists in a space or folder | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| ClickUp Account | `connectionId` | Select or connect a ClickUp workspace | +| Operation | `operation` | Choices: Create Task, Get Task, Update Task, Delete Task, List Tasks, Search Tasks, Add Comment, Set Custom Field, Get Lists | +| Space | `spaceId` | Pick a Space (or paste a Space ID / variable) Conditional field. | +| Folder | `folderId` | Optional — leave blank for folderless lists Conditional field. | +| List | `listId` | Conditional field. | +| Workspace ID | `teamId` | ClickUp Workspace (team) ID Conditional field. | +| Task ID | `taskId` | Conditional field. | +| Task Name | `taskName` | Conditional field. | +| Description | `description` | Conditional field. | +| Priority | `priority` | Choices: Urgent, High, Normal, Low Conditional field. | +| Due Date | `dueDate` | Conditional field. | +| Assignees | `assignees` | Conditional field. | +| Tags | `tags` | Conditional field. | +| Custom Fields | `customFields` | JSON object: { fieldId: value }. Get fieldIds from List > Custom Fields. Conditional field. | +| Field ID | `fieldId` | Conditional field. | +| Field Value | `fieldValue` | Plain text for text fields; numbers for number fields; JSON for arrays/objects Conditional field. | +| Comment | `commentText` | Conditional field. | +| Assignee (optional) | `commentAssignee` | Conditional field. | +| Statuses | `statuses` | Conditional field. | +| Limit | `limit` | Conditional field. | + + + +## Dub + +Create short links and read analytics with Dub.co + +Node type: `DUB`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Short Link | `CREATE_SHORT_LINK` | Shorten a URL into a Dub link | +| Get Link Analytics | `GET_LINK_ANALYTICS` | Fetch click analytics for a link over a time range | +| List Links | `LIST_LINKS` | List links in the connected workspace | +| Update Link | `UPDATE_LINK` | Update destination URL or metadata | +| Delete Link | `DELETE_LINK` | Permanently delete a short link | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Dub Account | `connectionId` | Select or connect a Dub workspace | +| Operation | `operation` | Choices: Create Short Link, Get Link Analytics, List Links, Update Link, Delete Link | +| Destination URL | `url` | Conditional field. | +| Domain | `domain` | Custom short domain — leave blank to use Dub's default Conditional field. | +| Custom Slug | `key` | Conditional field. | +| Title | `title` | Conditional field. | +| Description | `description` | Conditional field. | +| Expires At | `expiresAt` | Conditional field. | +| Link ID | `linkId` | Conditional field. | +| Interval | `interval` | Choices: Last 24 hours, Last 7 days, Last 30 days, Last 90 days, Last year, All time Conditional field. | +| Search | `search` | Conditional field. | +| Limit | `limit` | Conditional field. | + + + +## Notion + +Read, create, and query Notion pages and databases + +Node type: `NOTION`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Read Page | `READ_PAGE` | Read a Notion page | +| Read Database | `READ_DATABASE` | Read a Notion database | +| Create Page | `CREATE_PAGE` | Create a new page | +| Create Database | `CREATE_DATABASE` | Create a new database | +| Add Database Row | `ADD_DATABASE_ROW` | Add a row to a database | +| Append Content | `APPEND_CONTENT` | Append content to a page | +| Query Database | `QUERY_DATABASE` | Query a database with filters | +| Search Workspace | `SEARCH_WORKSPACE` | Search across the workspace | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Notion Account | `connectionId` | Select or connect a Notion workspace | +| Operation | `operation` | Choices: Read Page, Read Database, Create Page, Create Database, Add Database Row, Append Content, Query Database, Search Workspace | +| Page ID | `pageId` | Conditional field. | +| Database ID | `databaseId` | Conditional field. | +| Parent ID | `parentId` | Parent page or database ID Conditional field. | +| Title | `title` | Conditional field. | +| Properties | `properties` | Properties JSON Conditional field. | +| Content | `content` | Conditional field. | +| Search Query | `query` | Conditional field. | +| Filter | `filter` | Filter JSON Conditional field. | +| Sorts | `sorts` | Sort criteria JSON Conditional field. | + + + +## Resend + +Send emails using the Resend email API + +Node type: `RESEND`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Email | `SEND_EMAIL` | | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Resend API Key | `resendApiKey` | Secret; enter through the secure configuration control. | +| From Address | `fromAddress` | | +| To | `to` | | +| Subject | `subject` | | +| Body | `body` | | +| Content Type | `contentType` | Choices: Plain Text, HTML | +| CC | `cc` | | +| BCC | `bcc` | | +| Reply To | `replyTo` | | + + + +## Telegram + +Send messages, photos, videos, and documents via Telegram + +Node type: `TELEGRAM`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Message | `SEND_MESSAGE` | | +| Send Photo | `SEND_PHOTO` | | +| Send Video | `SEND_VIDEO` | | +| Send Audio | `SEND_AUDIO` | | +| Send Animation | `SEND_ANIMATION` | | +| Send Document | `SEND_DOCUMENT` | | +| Delete Message | `DELETE_MESSAGE` | | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Operation | `operation` | Choices: Send Message, Send Photo, Send Video, Send Audio, Send Animation, Send Document, Delete Message | +| Bot Token | `botToken` | Getting Bot Token: 1. Message "/newbot" to @BotFather 2. Choose a name for your bot 3. Copy the token and paste it here Secret; enter through the secure configuration control. | +| Chat ID | `chatId` | Getting Chat ID: 1. Add your bot to the desired channel 2. Send any message to the channel 3. Visit https://api.telegram.org/bot<TOKEN>/getUpdates 4. Find the chat ID in the JSON response | +| Message | `text` | Conditional field. | +| Photo | `photo` | Conditional field. | +| Video | `video` | Conditional field. | +| Audio | `audio` | Conditional field. | +| Animation | `animation` | Conditional field. | +| Document | `document` | Conditional field. | +| Caption | `caption` | Conditional field. | +| Message ID | `messageId` | Conditional field. | + + + +## LinkedIn + +Share posts and retrieve profile data from LinkedIn + +Node type: `LINKEDIN`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Share Post | `SHARE_POST` | Share a post on LinkedIn | +| Get Profile | `GET_PROFILE` | Retrieve LinkedIn profile information | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| LinkedIn Account | `linkedInAccountId` | Select or connect a LinkedIn account Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Share Post, Get Profile | +| Post Text | `text` | Max 3000 characters Conditional field. | +| Image URL | `imageUrl` | Optional image to attach to the post Conditional field. | +| Article URL | `articleUrl` | Optional article link to share with the post Conditional field. | +| Visibility | `visibility` | Choices: Public, Connections Only Conditional field. | + + + +## Facebook + +Publish posts and Stories to Facebook Pages + +Node type: `FACEBOOK`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Publish Page Post | `PUBLISH_PAGE_POST` | Publish a feed post or Story to a Facebook Page | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the published post | +| Facebook Account | `facebookAccountId` | Select a connected Facebook account Secret; enter through the secure configuration control. | +| Facebook Page | `pageId` | Page that will publish the post | +| Post Type | `postType` | Choices: Text, Link, Single image, Multiple images, Image Story, Video Story | +| Message | `message` | | +| Link URL | `linkUrl` | Conditional field. | +| Image URL | `imageUrl` | Public HTTPS image URL that Facebook can fetch Conditional field. | + + + +## Instagram + +Publish feed images and Stories to an Instagram professional account + +Node type: `INSTAGRAM`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Publish Media | `PUBLISH_MEDIA` | Publish a feed image or Story to Instagram | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the published post | +| Instagram Connection | `instagramAccountId` | Select a separately connected Instagram account Secret; enter through the secure configuration control. | +| Linked Facebook Page | `pageId` | Stored automatically when an Instagram account is selected | +| Instagram Professional Account | `instagramUserId` | Stored automatically when an Instagram account is selected | +| Publish Type | `publishType` | Choices: Feed image, Image Story, Video Story | +| Image URL | `imageUrl` | Public HTTPS URL that Meta can fetch during publishing | +| Caption | `caption` | | + + + +## Typeform + +Create, manage, and collect responses from Typeform forms + +Node type: `TYPEFORM`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Forms | `LIST_FORMS` | List all forms in your Typeform account | +| Get Form | `GET_FORM` | Get the full definition of a specific form | +| Create Form | `CREATE_FORM` | Create a new Typeform form with fields and settings | +| Update Form | `UPDATE_FORM` | Update an existing form with a new definition | +| Delete Form | `DELETE_FORM` | Permanently delete a form | +| Get Responses | `GET_RESPONSES` | Retrieve form responses with optional date range filtering | +| Get Form Insights | `GET_FORM_INSIGHTS` | Get analytics and insights for a form | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Name used to reference this node's output in other nodes | +| API Key | `apiKey` | Enter your Typeform API key or use an environment variable like {{TYPEFORM_API_KEY}} Secret; enter through the secure configuration control. | +| Operation | `operation` | Choose which Typeform operation to perform Choices: List Forms, Get Form, Create Form, Update Form, Delete Form, Get Responses, Get Form Insights | +| Form ID | `formId` | The unique identifier of the Typeform form Conditional field. | +| Page | `page` | Page number (starts at 1) Conditional field. | +| Page Size | `pageSize` | Number of forms per page (max 200) Conditional field. | +| Title | `title` | Title for the new form Conditional field. | +| Fields | `fields` | JSON array of form field definitions Conditional field. | +| Settings | `settings` | Form settings as JSON object Conditional field. | +| Workspace | `workspace` | Workspace ID or URL to create the form in Conditional field. | +| Form Definition | `formDefinition` | Full form definition JSON to update Conditional field. | +| Response Page Size | `responsePageSize` | Number of responses per page (max 1000) Conditional field. | +| Since | `since` | Only return responses submitted after this date (ISO 8601) Conditional field. | +| Until | `until` | Only return responses submitted before this date (ISO 8601) Conditional field. | + + + +## Trello + +Manage Trello boards, lists, cards, and comments + +Node type: `TRELLO`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Get Lists | `GET_LISTS` | Get all lists on a board | +| List Cards | `LIST_CARDS` | List cards in a list | +| Create Card | `CREATE_CARD` | Create a new card | +| Update Card | `UPDATE_CARD` | Update an existing card | +| Get Actions | `GET_ACTIONS` | Get activity on a card | +| Add Comment | `ADD_COMMENT` | Add a comment to a card | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Trello Account | `connectionId` | Select or connect a Trello account | +| Operation | `operation` | Choices: Get Lists, List Cards, Create Card, Update Card, Get Actions, Add Comment | +| Board ID | `boardId` | Trello Board ID | +| List ID | `listId` | Trello List ID Conditional field. | +| Card ID | `cardId` | Trello Card ID Conditional field. | +| Card Name | `name` | Conditional field. | +| Card Description | `desc` | Conditional field. | +| Target List ID | `idList` | Move card to this list Conditional field. | +| Comment Text | `text` | Conditional field. | + + + +## Ahrefs + +SEO analytics — domain ratings, backlinks, keywords, and more + +Node type: `AHREFS`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Domain Rating | `DOMAIN_RATING` | Get the Domain Rating score and rank | +| Backlinks Stats | `BACKLINKS_STATS` | Get backlink and referring domain counts | +| Organic Keywords | `ORGANIC_KEYWORDS` | Get organic keyword rankings | +| Top Pages | `TOP_PAGES` | Get top pages by organic traffic | +| Referring Domains | `REFERRING_DOMAINS` | Get referring domains list | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| API Key | `apiKey` | Ahrefs API key - set in Settings > Secrets or paste directly Secret; enter through the secure configuration control. | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Operation | `operation` | Choices: Domain Rating, Backlinks Stats, Organic Keywords, Top Pages, Referring Domains | +| Target Domain | `target` | The domain to analyze | +| Date | `date` | Historical date for the data snapshot. Leave empty for the latest available data. Conditional field. | +| Country | `country` | Two-letter country code (e.g. us, gb, de) Conditional field. | +| Result Limit | `limit` | Maximum number of results to return (1–1000) Conditional field. | +| Mode | `mode` | Target matching mode — subdomains includes all subdomains, exact matches only the target, prefix matches URLs starting with the target Choices: Subdomains, Exact, Prefix Conditional field. | + + + +## Apollo + +Search, enrich, and manage contacts and organizations via Apollo.io + +Node type: `APOLLO`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Search People | `SEARCH_PEOPLE` | Search for people by title, location, seniority, and company | +| Enrich Person | `ENRICH_PERSON` | Get detailed info about a person by email, name, or LinkedIn | +| Bulk Enrich People | `BULK_ENRICH_PEOPLE` | Enrich multiple people at once from a JSON array | +| Search Organizations | `SEARCH_ORGANIZATIONS` | Search for companies by location, size, and keywords | +| Enrich Organization | `ENRICH_ORGANIZATION` | Get detailed info about a company by domain | +| Bulk Enrich Organizations | `BULK_ENRICH_ORGANIZATIONS` | Enrich multiple organizations by domain | +| Create Contact | `CREATE_CONTACT` | Create a new contact in Apollo CRM | +| Update Contact | `UPDATE_CONTACT` | Update an existing contact by ID | +| Search Contacts | `SEARCH_CONTACTS` | Search contacts in your Apollo CRM | +| Bulk Create Contacts | `BULK_CREATE_CONTACTS` | Create multiple contacts from a JSON array | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| API Key | `apiKey` | Enter your Apollo.io API key or use an environment variable like {{APOLLO_API_KEY}} Secret; enter through the secure configuration control. | +| Operation | `operation` | Choose which Apollo.io operation to perform Choices: Search People, Enrich Person, Bulk Enrich People, Search Organizations, Enrich Organization, Bulk Enrich Organizations, Create Contact, Update Contact, Search Contacts, Bulk Create Contacts | +| Variable Name | `variableName` | Name used to reference this node's output in other nodes | +| Job Titles | `personTitles` | Comma-separated titles Conditional field. | +| Locations | `personLocations` | Comma-separated locations (e.g., San Francisco, New York) Conditional field. | +| Seniorities | `personSeniorities` | Comma-separated seniority levels Conditional field. | +| Organization Domains | `organizationDomains` | Comma-separated company domains to filter by Conditional field. | +| Email | `email` | Email address Conditional field. | +| First Name | `firstName` | First name Conditional field. | +| Last Name | `lastName` | Last name Conditional field. | +| Organization Name | `organizationName` | Company name Conditional field. | +| Domain | `domain` | Company domain for matching Conditional field. | +| LinkedIn URL | `linkedinUrl` | LinkedIn profile URL Conditional field. | +| Details (JSON) | `bulkEnrichDetails` | JSON array of objects with email, first_name, last_name, domain, linkedin_url Conditional field. | +| Locations | `organizationLocations` | Comma-separated organization locations Conditional field. | +| Employee Count Ranges | `numEmployeesRanges` | Ranges: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ Conditional field. | +| Keyword Tags | `keywordTags` | Comma-separated industry/keyword tags Conditional field. | +| Domain | `enrichDomain` | Company domain to enrich Conditional field. | +| Domains | `bulkEnrichDomains` | Comma-separated domain names Conditional field. | +| Title | `title` | Job title Conditional field. | +| Account ID | `accountId` | Apollo account ID to associate with Conditional field. | +| Contact ID | `contactId` | ID of the contact to update Conditional field. | +| Keywords | `keywords` | Search keywords for contacts Conditional field. | +| Sort By | `sortByField` | Field to sort results by Choices: Updated At, Created At, First Name, Last Name, Email Conditional field. | +| Contacts (JSON) | `bulkCreateContacts` | JSON array of contact objects with first_name, last_name, email, title, organization_name Conditional field. | +| Page | `page` | Page number (starts at 1) Conditional field. | +| Per Page | `perPage` | Results per page (max 100) Conditional field. | + + + +## Calendly + +Manage events, invitees, and scheduling via Calendly + +Node type: `CALENDLY`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Get Current User | `GET_CURRENT_USER` | Retrieve the authenticated user's profile information | +| List Event Types | `LIST_EVENT_TYPES` | List all event types for a user | +| Get Event Type | `GET_EVENT_TYPE` | Get details of a specific event type | +| List Scheduled Events | `LIST_SCHEDULED_EVENTS` | List scheduled events for a user with optional filters | +| Get Scheduled Event | `GET_SCHEDULED_EVENT` | Get details of a specific scheduled event | +| List Event Invitees | `LIST_EVENT_INVITEES` | List invitees for a scheduled event | +| Cancel Event | `CANCEL_EVENT` | Cancel a scheduled event with an optional reason | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Name used to reference this node's output in other nodes | +| API Key | `apiKey` | Enter your Calendly API key or use an environment variable like {{CALENDLY_API_KEY}} Secret; enter through the secure configuration control. | +| Operation | `operation` | Choose which Calendly operation to perform Choices: Get Current User, List Event Types, Get Event Type, List Scheduled Events, Get Scheduled Event, List Event Invitees, Cancel Event | +| User URI | `userUri` | Calendly user URI (returned from Get Current User) Conditional field. | +| Event Type URI | `eventTypeUri` | Full URI of the event type to retrieve Conditional field. | +| Event URI | `eventUri` | Full URI of the scheduled event Conditional field. | +| Count | `count` | Number of events to return (1-100) Conditional field. | +| Status | `status` | Filter events by status Choices: Active, Canceled Conditional field. | +| Cancellation Reason | `reason` | Optional reason for canceling the event Conditional field. | + + + +## Cal.com + +Manage Cal.com event types and bookings + +Node type: `CAL_COM`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| List Event Types | `LIST_EVENT_TYPES` | Retrieve all configured event types | +| List Bookings | `LIST_BOOKINGS` | Retrieve bookings with optional status filter | +| Create Booking | `CREATE_BOOKING` | Create a new booking for an event type | +| Cancel Booking | `CANCEL_BOOKING` | Cancel an existing booking | +| Reschedule Booking | `RESCHEDULE_BOOKING` | Reschedule an existing booking to a new time | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Cal.com Account | `connectionId` | Select or connect a Cal.com account Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: List Event Types, List Bookings, Create Booking, Cancel Booking, Reschedule Booking | +| Status Filter | `statusFilter` | Choices: Upcoming, Past, Cancelled, All Conditional field. | +| Event Type ID | `eventTypeId` | The ID of the event type to book Conditional field. | +| Start Time | `startTime` | Booking start time in ISO 8601 format Conditional field. | +| Attendee Name | `attendeeName` | Conditional field. | +| Attendee Email | `attendeeEmail` | Conditional field. | +| Attendee Timezone | `attendeeTimezone` | IANA timezone identifier for the attendee Conditional field. | +| Booking UID | `bookingUid` | The unique identifier of the booking Conditional field. | +| Cancellation Reason | `cancellationReason` | Conditional field. | +| New Start Time | `rescheduleStartTime` | New start time for the rescheduled booking Conditional field. | + + + +## Reddit + +Create, draft, or schedule Reddit posts + +Node type: `REDDIT`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Create, draft, or schedule Reddit posts | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Reddit Account | `zernioAccountId` | Select or connect a Reddit account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Subreddit | `subreddit` | | +| Post Title | `title` | | +| Link URL | `linkUrl` | | +| Flair ID | `flairId` | | +| Native Video | `nativeVideo` | | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## Bluesky + +Create, draft, or schedule Bluesky posts + +Node type: `BLUESKY`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Create, draft, or schedule Bluesky posts | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Bluesky Account | `zernioAccountId` | Select or connect a Bluesky account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## Threads + +Create, draft, or schedule Threads posts + +Node type: `THREADS`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Create, draft, or schedule Threads posts | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Threads Account | `zernioAccountId` | Select or connect a Threads account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## Telegram + +Send, draft, or schedule Telegram channel posts + +Node type: `TELEGRAM_POST`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Send, draft, or schedule Telegram channel posts | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Telegram Account | `zernioAccountId` | Select or connect a Telegram account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Parse Mode | `parseMode` | Choices: HTML, Markdown, MarkdownV2 | +| Disable Link Preview | `disableWebPagePreview` | | +| Silent Message | `disableNotification` | | +| Protect Content | `protectContent` | | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## Pinterest + +Create, draft, or schedule Pinterest pins + +Node type: `PINTEREST`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Create, draft, or schedule Pinterest pins | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Pinterest Account | `zernioAccountId` | Select or connect a Pinterest account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Board ID | `boardId` | Pinterest usually requires a board ID | +| Pin Title | `title` | | +| Destination Link | `linkUrl` | | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## X/Twitter + +Create, draft, or schedule X/Twitter posts + +Node type: `X`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Post | `CREATE_POST` | Create, draft, or schedule X/Twitter posts | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| X/Twitter Account | `zernioAccountId` | Select or connect a X/Twitter account Secret; enter through the secure configuration control. | +| Publish Mode | `publishMode` | Choices: Publish Now, Schedule, Draft | +| Scheduled For | `scheduledFor` | Conditional field. | +| Timezone | `timezone` | Conditional field. | +| Content | `content` | | +| Media URLs | `mediaUrls` | Optional public image/video URLs, separated by commas or new lines | +| Reply To Tweet ID | `replyToTweetId` | | +| Quote Tweet ID | `quoteTweetId` | | +| Made With AI | `madeWithAi` | | +| Advanced Platform Settings JSON | `platformSpecificJson` | Optional platform-specific settings. Values here override matching fields above. | + + + +## WhatsApp + +Send WhatsApp template messages + +Node type: `WHATSAPP`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Send Template Message | `SEND_TEMPLATE` | Send an approved WhatsApp template | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | | +| WhatsApp Account | `zernioAccountId` | Secret; enter through the secure configuration control. | +| Recipient Phone | `participantId` | Digits only, including country code | +| Template Name | `templateName` | | +| Template Language | `templateLanguage` | | +| Template Params JSON | `templateParamsJson` | JSON array of template parameters | + + + +## GitHub + +Manage GitHub issues, pull requests, and comments + +Node type: `GITHUB`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Issue | `CREATE_ISSUE` | Create a new issue | +| List Issues | `LIST_ISSUES` | List repository issues | +| Update Issue | `UPDATE_ISSUE` | Update an existing issue | +| Create Pull Request | `CREATE_PR` | Create a new pull request | +| List Pull Requests | `LIST_PRS` | List repository pull requests | +| Merge Pull Request | `MERGE_PR` | Merge a pull request | +| Create Comment | `CREATE_COMMENT` | Add a comment to an issue or PR | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| GitHub Account | `connectionId` | Select or connect a GitHub account Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Create Issue, List Issues, Update Issue, Create Pull Request, List Pull Requests, Merge Pull Request, Create Comment | +| Owner | `owner` | Repository owner | +| Repository | `repo` | Repository name | +| Title | `title` | Conditional field. | +| Body | `body` | Conditional field. | +| Labels | `labels` | Comma-separated labels Conditional field. | +| Assignees | `assignees` | Comma-separated GitHub usernames Conditional field. | +| Issue Number | `issueNumber` | Conditional field. | +| State | `state` | Choices: Open, Closed, All Conditional field. | +| Source Branch | `head` | Source branch Conditional field. | +| Target Branch | `base` | Target branch Conditional field. | +| PR Number | `prNumber` | Conditional field. | +| Merge Method | `mergeMethod` | Choices: Merge, Squash, Rebase Conditional field. | + + + +## Polymarket + +Prediction market data — prices, order books, and analytics + +Node type: `POLYMARKET`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Search Markets | `SEARCH_MARKETS` | Search prediction markets by keyword | +| Get Market | `GET_MARKET` | Retrieve a single market by ID or slug | +| Get Event | `GET_EVENT` | Retrieve a single event by ID | +| List Markets | `LIST_MARKETS` | List markets with filters and sorting | +| List Events | `LIST_EVENTS` | List events with filters and sorting | +| Get Price | `GET_PRICE` | Get current buy/sell price for a token | +| Get Order Book | `GET_ORDER_BOOK` | Get top bids and asks for a token | +| Get Price History | `GET_PRICE_HISTORY` | Get historical price data | +| Get Midpoint | `GET_MIDPOINT` | Get midpoint price for a token | +| Get Spread | `GET_SPREAD` | Get bid-ask spread for a token | +| Get Last Trade Price | `GET_LAST_TRADE_PRICE` | Get last traded price | +| Get Tags | `GET_TAGS` | List all available market tags | +| Get Leaderboard | `GET_LEADERBOARD` | Get top traders and stats | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| API Key | `apiKey` | Optional — most endpoints are public. Add a key for higher rate limits. Use {{VAR_NAME}} for environment variables. Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Search Markets, Get Market, Get Event, List Markets, List Events, Get Price, Get Order Book, Get Price History, Get Midpoint, Get Spread, Get Last Trade Price, Get Tags, Get Leaderboard | +| Search Query | `query` | Conditional field. | +| Market ID | `marketId` | The condition ID or slug of the market to retrieve Conditional field. | +| Event ID | `eventId` | The ID of the event to retrieve Conditional field. | +| Limit | `listLimit` | Number of markets to return (1-100) Conditional field. | +| Order By | `listOrder` | Sort markets by this field Choices: Default, Liquidity, Volume, Created At Conditional field. | +| Status | `listClosed` | Filter by open/closed status Choices: All, Closed Only, Open Only Conditional field. | +| Tag ID | `listTagId` | Filter by tag (from Get Tags) Conditional field. | +| Min Liquidity | `liquidityMin` | Minimum liquidity filter Conditional field. | +| Min Volume | `volumeMin` | Minimum volume filter Conditional field. | +| Limit | `eventsLimit` | Number of events to return (1-100) Conditional field. | +| Order By | `eventsOrder` | Sort events by this field Choices: Default, Liquidity, Volume, Created At Conditional field. | +| Status | `eventsClosed` | Filter by open/closed status Choices: All, Closed Only, Open Only Conditional field. | +| Tag ID | `eventsTagId` | Filter by tag Conditional field. | +| Token ID | `tokenId` | Use a clobTokenId from a market search result Conditional field. | +| Side | `side` | Whether to get buy or sell price Choices: Buy, Sell Conditional field. | +| Interval | `interval` | Time interval for price history data points Choices: 1 Minute, 5 Minutes, 1 Hour, 1 Day, 1 Week, Max Conditional field. | +| Fidelity | `fidelity` | Number of data points to return Conditional field. | + + + +## Dropbox + +Upload, download, and manage files in Dropbox + +Node type: `DROPBOX`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Upload File | `UPLOAD_FILE` | Upload a file to Dropbox | +| Download File | `DOWNLOAD_FILE` | Download a file from Dropbox | +| List Folder | `LIST_FOLDER` | List contents of a folder | +| Create Folder | `CREATE_FOLDER` | Create a new folder | +| Delete | `DELETE` | Delete a file or folder | +| Copy | `COPY` | Copy a file or folder | +| Move | `MOVE` | Move a file or folder | +| Get Metadata | `GET_METADATA` | Get file or folder metadata | +| Create Shared Link | `CREATE_SHARED_LINK` | Create a shared link for a file | +| Search Files | `SEARCH_FILES` | Search for files in Dropbox | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Operation | `operation` | Choices: Upload File, Download File, List Folder, Create Folder, Delete, Copy, Move, Get Metadata, Create Shared Link, Search Files | +| Dropbox Account | `connectionId` | Select or connect a Dropbox account Secret; enter through the secure configuration control. | +| File Path | `filePath` | Dropbox path (e.g. /folder/file.txt) Conditional field. | +| File Content | `fileContent` | Content to upload Conditional field. | +| Folder Path | `folderPath` | Leave empty for root folder Conditional field. | +| Source Path | `fromPath` | Conditional field. | +| Destination Path | `toPath` | Conditional field. | +| Visibility | `visibility` | Who can access the shared link Choices: Public, Team Only Conditional field. | +| Search Query | `query` | What to search for Conditional field. | +| Folder Path | `searchFolderPath` | Optionally scope search to a folder Conditional field. | +| Max Results | `maxResults` | Maximum number of results Conditional field. | +| Limit | `limit` | Maximum number of entries to return Conditional field. | + + + +## ElevenLabs + +Convert text to speech using ElevenLabs AI voices + +Node type: `ELEVENLABS`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Text to Speech | `TEXT_TO_SPEECH` | Convert text to speech using AI voices | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| API Key | `apiKey` | Enter your ElevenLabs API key or use an environment variable Secret; enter through the secure configuration control. | +| Text | `text` | The text to convert to speech. Supports template variables. | +| Voice ID | `voiceId` | Find Voice IDs in your ElevenLabs dashboard under Voices | +| Model | `modelId` | The ElevenLabs model to use for speech synthesis Choices: Monolingual v1, Multilingual v1, Multilingual v2, Turbo v2, Turbo v2.5 | + + + +## Shopify + +Manage products, orders, customers, inventory, and more + +Node type: `SHOPIFY`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Create Product | `CREATE_PRODUCT` | Create a new product | +| Get Product | `GET_PRODUCT` | Get a product by ID | +| List Products | `LIST_PRODUCTS` | List all products | +| Update Product | `UPDATE_PRODUCT` | Update an existing product | +| Delete Product | `DELETE_PRODUCT` | Delete a product | +| Get Order | `GET_ORDER` | Get an order by ID | +| List Orders | `LIST_ORDERS` | List all orders | +| Update Order | `UPDATE_ORDER` | Update an existing order | +| Cancel Order | `CANCEL_ORDER` | Cancel an order | +| Create Customer | `CREATE_CUSTOMER` | Create a new customer | +| Get Customer | `GET_CUSTOMER` | Get a customer by ID | +| List Customers | `LIST_CUSTOMERS` | List all customers | +| Update Customer | `UPDATE_CUSTOMER` | Update an existing customer | +| Delete Customer | `DELETE_CUSTOMER` | Delete a customer | +| List Inventory Items | `LIST_INVENTORY_ITEMS` | List inventory items | +| Get Inventory Level | `GET_INVENTORY_LEVEL` | Get inventory levels by location and item | +| Adjust Inventory | `ADJUST_INVENTORY` | Adjust inventory quantity | +| List Locations | `LIST_LOCATIONS` | List all locations | +| Create Fulfillment | `CREATE_FULFILLMENT` | Create a fulfillment for an order | +| List Collections | `LIST_COLLECTIONS` | List all collections | +| Get Collection | `GET_COLLECTION` | Get a collection by ID | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Shopify Store | `connectionId` | Select or connect a Shopify store Secret; enter through the secure configuration control. | +| Operation | `operation` | Choices: Create Product, Get Product, List Products, Update Product, Delete Product, Get Order, List Orders, Update Order, Cancel Order, Create Customer, Get Customer, List Customers, Update Customer, Delete Customer, List Inventory Items, Get Inventory Level, Adjust Inventory, List Locations, Create Fulfillment, List Collections, Get Collection | +| Product Title | `title` | Conditional field. | +| Product ID | `productId` | Conditional field. | +| Order ID | `orderId` | Conditional field. | +| Reason | `reason` | customer, fraud, inventory, declined, other Conditional field. | +| Status | `status` | open, closed, cancelled, any (default: any) Conditional field. | +| Financial Status | `financialStatus` | authorized, pending, paid, partially_paid, refunded, voided, partially_refunded, any Conditional field. | +| Customer ID | `customerId` | Conditional field. | +| Email | `customerEmail` | Conditional field. | +| First Name | `firstName` | Conditional field. | +| Last Name | `lastName` | Conditional field. | +| Tags | `tags` | Conditional field. | +| Search Query | `query` | Filter customers Conditional field. | +| Inventory Item ID | `inventoryItemId` | Conditional field. | +| Location ID | `locationId` | Conditional field. | +| Adjustment | `adjustment` | Positive number to add, negative to remove Conditional field. | +| Location IDs | `locationIds` | Comma-separated Conditional field. | +| Inventory Item IDs | `inventoryItemIds` | Comma-separated Conditional field. | +| Inventory Item IDs | `ids` | Comma-separated list of IDs to filter Conditional field. | +| Collection ID | `collectionId` | Conditional field. | +| Tracking Number | `trackingNumber` | Conditional field. | +| Tracking URL | `trackingUrl` | Conditional field. | +| Tracking Company | `trackingCompany` | Conditional field. | +| Properties (JSON) | `properties` | Additional fields as a JSON object Conditional field. | +| Max Records | `limit` | Maximum number of records to return (max 250) Conditional field. | + + + +## MCP + +Connect to MCP servers for agentic or direct tool execution + +Node type: `MCP`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Agentic Mode | `AGENTIC` | LLM discovers and calls MCP tools autonomously | +| Call Tool | `DIRECT` | Call a specific MCP tool with mapped inputs | +| Read Resource | `READ_RESOURCE` | Read a resource exposed by the MCP server | +| Get Prompt | `GET_PROMPT` | Render a prompt exposed by the MCP server | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Reference name.text for agentic responses; direct tool calls expose name.content and optional name.structuredContent. Resource and prompt modes expose the returned server payload. | +| Mode | `mode` | Agentic: LLM discovers and calls tools. Direct: call a specific tool with mapped inputs. Choices: Agentic, Call Tool, Read Resource, Get Prompt | +| MCP Server | `serverId` | Choose from MCP servers registered in your workspace settings. Choose from options loaded in the editor. | +| Model | `model` | Choose which AI model powers the agent. Must support tool calling. Choices: OpenAI 5.6 Sol, GPT-5.6 Luna, GPT-5.5, GPT-5.4, GPT-5.4 Mini, GPT-5.4 Nano, GPT-4.1, GPT-4.1 Mini, GPT-4o, GPT-4o Mini, o4-mini, o3, o3-mini, Claude Fable 5, Opus 5, Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5, Gemini 3.7 Flash, Gemini 3.6 Flash, Gemini 3.5 Flash, Gemini 3.5 Flash Lite, Gemini 3.1 Pro, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite, DeepSeek V4 Pro, DeepSeek V4.1 Flash, Kimi K3, Kimi K2.6 Conditional field. | +| System Prompt | `systemPrompt` | Instructions that define the agent's behavior. Supports {{variable}} syntax. Conditional field. | +| User Prompt | `userPrompt` | The task/instruction for the agent. Supports {{variable}} syntax. Conditional field. | +| Temperature | `temperature` | Controls randomness. Lower = more deterministic, Higher = more creative. Conditional field. | +| Max Steps | `maxSteps` | Maximum number of tool-calling iterations (1-20). Conditional field. | +| Allow Write Tools | `allowWriteTools` | Off by default. Enable only when the workflow owner has approved agent-initiated writes. Conditional field. | +| Tool | `selectedTool` | Choose from options loaded in the editor. Conditional field. | +| Tool Inputs | `toolInputs` | Conditional field. | +| Resource URI | `resourceUri` | Conditional field. | +| Prompt Name | `promptName` | Conditional field. | +| Prompt Arguments | `promptArguments` | Conditional field. | + + + +## PostHog + +Product analytics — events, feature flags, experiments, and more + +Node type: `POSTHOG`. + +Configure the API credential requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Capture Event | `CAPTURE_EVENT` | Capture a single analytics event | +| Batch Events | `BATCH_EVENTS` | Batch capture multiple events at once | +| List Event Definitions | `LIST_EVENT_DEFINITIONS` | List all event definitions | +| Get Event Definition | `GET_EVENT_DEFINITION` | Get a specific event definition | +| Update Event Definition | `UPDATE_EVENT_DEFINITION` | Update an event definition | +| Get Person | `GET_PERSON` | Get person details by ID | +| Delete Person | `DELETE_PERSON` | Delete a person record | +| Run Query (HogQL) | `RUN_QUERY` | Execute a HogQL analytics query | +| List Insights | `LIST_INSIGHTS` | List all saved insights | +| Get Insight | `GET_INSIGHT` | Get a specific insight and its data | +| Create Insight | `CREATE_INSIGHT` | Create a new saved insight | +| List Dashboards | `LIST_DASHBOARDS` | List all dashboards | +| Get Dashboard | `GET_DASHBOARD` | Get a dashboard with its tiles | +| List Actions | `LIST_ACTIONS` | List all defined actions | +| Get Cohort | `GET_COHORT` | Get a specific cohort | +| Create Cohort | `CREATE_COHORT` | Create a new cohort | +| List Annotations | `LIST_ANNOTATIONS` | List all annotations | +| Create Annotation | `CREATE_ANNOTATION` | Create a timeline annotation | +| List Feature Flags | `LIST_FEATURE_FLAGS` | List all feature flags | +| Get Feature Flag | `GET_FEATURE_FLAG` | Get a specific feature flag | +| Create Feature Flag | `CREATE_FEATURE_FLAG` | Create a new feature flag | +| Update Feature Flag | `UPDATE_FEATURE_FLAG` | Update an existing feature flag | +| Delete Feature Flag | `DELETE_FEATURE_FLAG` | Delete a feature flag | +| Get Experiment | `GET_EXPERIMENT` | Get experiment details | +| Create Experiment | `CREATE_EXPERIMENT` | Create a new A/B experiment | +| List Surveys | `LIST_SURVEYS` | List all surveys | +| Get Survey | `GET_SURVEY` | Get a specific survey | +| Create Survey | `CREATE_SURVEY` | Create a new survey | +| Update Survey | `UPDATE_SURVEY` | Update an existing survey | +| List Session Recordings | `LIST_SESSION_RECORDINGS` | List session recordings | +| Get Session Recording | `GET_SESSION_RECORDING` | Get a specific session recording | +| List Recording Playlists | `LIST_RECORDING_PLAYLISTS` | List recording playlists | +| List Property Definitions | `LIST_PROPERTY_DEFINITIONS` | List all property definitions | +| Get Property Definition | `GET_PROPERTY_DEFINITION` | Get a specific property definition | +| Update Property Definition | `UPDATE_PROPERTY_DEFINITION` | Update a property definition | +| List Projects | `LIST_PROJECTS` | List all projects in the organization | +| Get Project | `GET_PROJECT` | Get current project details | +| List Organizations | `LIST_ORGANIZATIONS` | List all organizations | +| Get Organization | `GET_ORGANIZATION` | Get organization details | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| API Key | `apiKey` | Your PostHog personal API key. Use an environment variable like {{POSTHOG_API_KEY}} Secret; enter through the secure configuration control. | +| Project ID | `projectId` | Your PostHog project ID (required for most operations) | +| Region | `region` | Select the PostHog cloud region where your project is hosted Choices: US Cloud (us.posthog.com), EU Cloud (eu.posthog.com) | +| Operation | `operation` | Choose which PostHog operation to perform Choices: Capture Event, Batch Events, List Event Definitions, Get Event Definition, Update Event Definition, Get Person, Delete Person, Run Query (HogQL), List Insights, Get Insight, Create Insight, List Dashboards, Get Dashboard, List Actions, Get Cohort, Create Cohort, List Annotations, Create Annotation, List Feature Flags, Get Feature Flag, Create Feature Flag, Update Feature Flag, Delete Feature Flag, Get Experiment, Create Experiment, List Surveys, Get Survey, Create Survey, Update Survey, List Session Recordings, Get Session Recording, List Recording Playlists, List Property Definitions, Get Property Definition, Update Property Definition, List Projects, Get Project, List Organizations, Get Organization | +| Variable Name | `variableName` | Name used to reference this node's output in other nodes. Access results as {{posthog.result}} | +| Distinct ID | `distinctId` | User's distinct ID Conditional field. | +| Event Name | `eventName` | Name of the event to capture Conditional field. | +| Properties | `eventProperties` | Event properties as JSON Conditional field. | +| Events | `batchEvents` | JSON array of events to batch capture Conditional field. | +| Person ID | `personId` | PostHog person ID Conditional field. | +| HogQL Query | `hogqlQuery` | HogQL query to execute Conditional field. | +| Insight ID | `insightId` | PostHog insight ID Conditional field. | +| Insight Data | `insightData` | JSON object defining the insight Conditional field. | +| Dashboard ID | `dashboardId` | PostHog dashboard ID Conditional field. | +| Cohort ID | `cohortId` | PostHog cohort ID Conditional field. | +| Cohort Data | `cohortData` | JSON object defining the cohort Conditional field. | +| Content | `annotationContent` | Annotation text content Conditional field. | +| Scope | `annotationScope` | Scope of the annotation Choices: Project, Organization Conditional field. | +| Date Marker | `annotationDateMarker` | ISO date for the annotation marker Conditional field. | +| Feature Flag ID | `featureFlagId` | PostHog feature flag ID Conditional field. | +| Flag Key | `featureFlagKey` | Unique key for the feature flag Conditional field. | +| Flag Data | `featureFlagData` | JSON object with flag configuration Conditional field. | +| Experiment ID | `experimentId` | PostHog experiment ID Conditional field. | +| Experiment Data | `experimentData` | JSON object defining the experiment Conditional field. | +| Survey ID | `surveyId` | PostHog survey ID Conditional field. | +| Survey Data | `surveyData` | JSON object defining or updating the survey Conditional field. | +| Recording ID | `recordingId` | Session recording ID Conditional field. | +| Definition ID | `definitionId` | Definition UUID Conditional field. | +| Definition Data | `definitionData` | JSON object with updated fields Conditional field. | +| Limit | `limit` | Maximum number of results to return Conditional field. | +| Offset | `offset` | Number of results to skip Conditional field. | + + + +## Integration + +Run a versioned action through a connected external app + +Node type: `INTEGRATION`. + +No account connection declared. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| QuickBooks: Query customers | `quickbooks.query_customers` | Query customers from the connected QuickBooks company. | +| QuickBooks: Query invoices | `quickbooks.query_invoices` | Query invoices from the connected QuickBooks company. | +| QuickBooks: Get aged receivables | `quickbooks.aged_receivables` | Read the aged receivables report. | +| QuickBooks: Get profit and loss | `quickbooks.profit_and_loss` | Read the profit and loss report. | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | | +| App | `integrationId` | Choices: QuickBooks | +| Connection | `externalConnectionId` | Choose from options loaded in the editor. | +| Operation | `operation` | Choose from options loaded in the editor. | +| Arguments | `arguments` | JSON arguments for the selected operation. | + + + +## Innflow + +Run another deployed workflow and continue with its result + +Node type: `INNFLOW`. + +No account connection declared. + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Action | `operation` | Choices: Run Workflow | +| Workflow | `targetWorkflowId` | | +| Trigger | `targetTriggerNodeId` | | +| Timeout | `timeout` | | + + + +## Microsoft + +Unified entry point for Microsoft 365 services + +Node type: `MICROSOFT`. + +Connect the account requested by the node. + +### Operations + +| Operation | Configuration value | Description | +| --- | --- | --- | +| Outlook | `outlook` | Microsoft Outlook operations | +| OneDrive | `onedrive` | Microsoft OneDrive operations | +| Teams | `teams` | Microsoft Teams operations | + +### Configuration + +Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected. + +| Field | Configuration key | Details | +| --- | --- | --- | +| Variable Name | `variableName` | Use this name to reference the output in other nodes | +| Microsoft Account | `connectionId` | Microsoft 365 account | +| Service | `service` | Choices: Outlook, OneDrive, Teams | +| Operation | `operation` | Operation for the selected service | + diff --git a/content/docs/tools/search-data.mdx b/content/docs/tools/search-data.mdx index 3409e9a..9f1eed3 100644 --- a/content/docs/tools/search-data.mdx +++ b/content/docs/tools/search-data.mdx @@ -7,6 +7,10 @@ description: "Search the web, retrieve cited answers, scrape pages, and pull mar AI powered web search that returns clean, relevant content. Great for research and fact checking in your workflows. +**Operations:** + +- **Search** (`SEARCH`) + **Configuration:** | Field | Description | @@ -15,7 +19,9 @@ AI powered web search that returns clean, relevant content. Great for research a | **Query** | The search query (supports template variables) | | **Max results** | Maximum number of results to return | -**Accessing output:** `{{variableName.output.results}}` +**Accessing output:** `{{variableName.results}}` + +[All operations and configuration fields](/tools/reference#tavily-search). --- @@ -24,9 +30,10 @@ AI powered web search that returns clean, relevant content. Great for research a Semantic web search powered by AI. Find content by meaning rather than just keywords. **Operations:** -- **Search** — Semantic search across the web -- **Find Similar** — Find pages similar to a given URL -- **Get Contents** — Extract content from specific URLs + +- **Search** (`SEARCH`) — Search the web with neural/keyword search +- **Find Similar** (`FIND_SIMILAR`) — Find pages similar to a URL +- **Get Contents** (`GET_CONTENTS`) — Retrieve full page content **Configuration:** @@ -36,6 +43,8 @@ Semantic web search powered by AI. Find content by meaning rather than just keyw | **Operation** | Search, Find Similar, or Get Contents | | **Query** | Search query or URL | +[All operations and configuration fields](/tools/reference#exa). + --- ## Perplexity @@ -43,9 +52,10 @@ Semantic web search powered by AI. Find content by meaning rather than just keyw Ask research questions and receive cited answers. Use Perplexity when the workflow needs a concise answer with source context instead of raw search results. **Operations:** -- **Ask** — Answer a question with citations -- **Research** — Gather a deeper research response -- **Fact Check** — Check a claim against current sources + +- **Ask Question** (`ASK`) — Ask a question with real-time web search +- **Research** (`RESEARCH`) — Multi-step research with follow-up questions +- **Fact Check** (`FACT_CHECK`) — Verify a claim against web sources **Configuration:** @@ -55,13 +65,24 @@ Ask research questions and receive cited answers. Use Perplexity when the workfl | **Operation** | Ask, Research, or Fact Check | | **Query** | Question, topic, or claim to research | +[All operations and configuration fields](/tools/reference#perplexity). + --- ## Firecrawl Use Firecrawl for web scraping, search, crawling, site mapping, structured extraction, and agent-assisted browsing. -**Operations:** Scrape, Search, Crawl, Map, Extract, and Agent +**Operations:** + +- **Scrape** (`SCRAPE`) — Scrape a single URL and extract content +- **Search** (`SEARCH`) — Search the web for relevant pages +- **Crawl** (`CRAWL`) — Crawl a website following links from a start URL +- **Map** (`MAP`) — Discover all linked pages from a URL +- **Extract** (`EXTRACT`) — Extract structured data from web pages using AI +- **Agent** (`AGENT`) — AI agent that navigates and interacts with websites + +[All operations and configuration fields](/tools/reference#firecrawl). --- @@ -71,19 +92,51 @@ The Web Scraper node provides a focused read-only path for retrieving clean publ **Operations:** -- **Scrape URL** — Extract content from one public page -- **Search + Scrape** — Search the web and retrieve content from matching pages +- **Scrape URL** (`SCRAPE_URL`) — Scrape a single public page +- **Search + Scrape** (`SEARCH_AND_SCRAPE`) — Search the web and scrape the top results Use [Browser Agent](/tools/browser-automation) instead when the task needs clicks, navigation across several pages, or other interactive browser behavior. +[All operations and configuration fields](/tools/reference#web-scraper). + --- ## Ahrefs Read domain ratings, backlink statistics, organic keywords, top pages, and referring domains from Ahrefs. +**Operations:** + +- **Domain Rating** (`DOMAIN_RATING`) — Get the Domain Rating score and rank +- **Backlinks Stats** (`BACKLINKS_STATS`) — Get backlink and referring domain counts +- **Organic Keywords** (`ORGANIC_KEYWORDS`) — Get organic keyword rankings +- **Top Pages** (`TOP_PAGES`) — Get top pages by organic traffic +- **Referring Domains** (`REFERRING_DOMAINS`) — Get referring domains list + +[All operations and configuration fields](/tools/reference#ahrefs). + --- ## Polymarket Search and list markets or events, then retrieve market details, prices, order books, price history, midpoint, spread, recent trades, tags, and leaderboard data. + +**Operations:** + +- **Search Markets** (`SEARCH_MARKETS`) — Search prediction markets by keyword +- **Get Market** (`GET_MARKET`) — Retrieve a single market by ID or slug +- **Get Event** (`GET_EVENT`) — Retrieve a single event by ID +- **List Markets** (`LIST_MARKETS`) — List markets with filters and sorting +- **List Events** (`LIST_EVENTS`) — List events with filters and sorting +- **Get Price** (`GET_PRICE`) — Get current buy/sell price for a token +- **Get Order Book** (`GET_ORDER_BOOK`) — Get top bids and asks for a token +- **Get Price History** (`GET_PRICE_HISTORY`) — Get historical price data +- **Get Midpoint** (`GET_MIDPOINT`) — Get midpoint price for a token +- **Get Spread** (`GET_SPREAD`) — Get bid-ask spread for a token +- **Get Last Trade Price** (`GET_LAST_TRADE_PRICE`) — Get last traded price +- **Get Tags** (`GET_TAGS`) — List all available market tags +- **Get Leaderboard** (`GET_LEADERBOARD`) — Get top traders and stats + +[All operations and configuration fields](/tools/reference#polymarket). + +--- diff --git a/content/docs/tools/social-publishing.mdx b/content/docs/tools/social-publishing.mdx index 008684a..fdee575 100644 --- a/content/docs/tools/social-publishing.mdx +++ b/content/docs/tools/social-publishing.mdx @@ -10,7 +10,7 @@ Innflow includes publishing nodes for social networks and messaging channels. Co | Node | Capability | Connection | | --- | --- | --- | | **LinkedIn** | Share a post or retrieve profile data | LinkedIn OAuth | -| **Meta** | Publish a Facebook Page post or Instagram image post | Meta connection | +| **Facebook / Instagram** | Publish a Facebook Page post or Instagram image post | Meta connection | | **X/Twitter** | Create, draft, or schedule a post | X OAuth | | **Reddit** | Create, draft, or schedule a post | Connected publishing account | | **Bluesky** | Create, draft, or schedule a post | Connected publishing account | diff --git a/content/docs/tools/storage-commerce.mdx b/content/docs/tools/storage-commerce.mdx index 092824e..54bfd81 100644 --- a/content/docs/tools/storage-commerce.mdx +++ b/content/docs/tools/storage-commerce.mdx @@ -15,6 +15,21 @@ Upload, download, list, and share files through Dropbox. Use Dropbox when a work **Requires:** Dropbox OAuth connection +**Operations:** + +- **Upload File** (`UPLOAD_FILE`) — Upload a file to Dropbox +- **Download File** (`DOWNLOAD_FILE`) — Download a file from Dropbox +- **List Folder** (`LIST_FOLDER`) — List contents of a folder +- **Create Folder** (`CREATE_FOLDER`) — Create a new folder +- **Delete** (`DELETE`) — Delete a file or folder +- **Copy** (`COPY`) — Copy a file or folder +- **Move** (`MOVE`) — Move a file or folder +- **Get Metadata** (`GET_METADATA`) — Get file or folder metadata +- **Create Shared Link** (`CREATE_SHARED_LINK`) — Create a shared link for a file +- **Search Files** (`SEARCH_FILES`) — Search for files in Dropbox + +[All operations and configuration fields](/tools/reference#dropbox). + --- ## Shopify @@ -29,6 +44,32 @@ Work with Shopify store data including products, orders, customers, and inventor **Requires:** Shopify connection +**Operations:** + +- **Create Product** (`CREATE_PRODUCT`) — Create a new product +- **Get Product** (`GET_PRODUCT`) — Get a product by ID +- **List Products** (`LIST_PRODUCTS`) — List all products +- **Update Product** (`UPDATE_PRODUCT`) — Update an existing product +- **Delete Product** (`DELETE_PRODUCT`) — Delete a product +- **Get Order** (`GET_ORDER`) — Get an order by ID +- **List Orders** (`LIST_ORDERS`) — List all orders +- **Update Order** (`UPDATE_ORDER`) — Update an existing order +- **Cancel Order** (`CANCEL_ORDER`) — Cancel an order +- **Create Customer** (`CREATE_CUSTOMER`) — Create a new customer +- **Get Customer** (`GET_CUSTOMER`) — Get a customer by ID +- **List Customers** (`LIST_CUSTOMERS`) — List all customers +- **Update Customer** (`UPDATE_CUSTOMER`) — Update an existing customer +- **Delete Customer** (`DELETE_CUSTOMER`) — Delete a customer +- **List Inventory Items** (`LIST_INVENTORY_ITEMS`) — List inventory items +- **Get Inventory Level** (`GET_INVENTORY_LEVEL`) — Get inventory levels by location and item +- **Adjust Inventory** (`ADJUST_INVENTORY`) — Adjust inventory quantity +- **List Locations** (`LIST_LOCATIONS`) — List all locations +- **Create Fulfillment** (`CREATE_FULFILLMENT`) — Create a fulfillment for an order +- **List Collections** (`LIST_COLLECTIONS`) — List all collections +- **Get Collection** (`GET_COLLECTION`) — Get a collection by ID + +[All operations and configuration fields](/tools/reference#shopify). + --- ## LinkedIn @@ -44,6 +85,13 @@ Publish LinkedIn posts and retrieve profile data. See [Social Publishing](/tools/social-publishing) for every supported publishing channel. +**Operations:** + +- **Share Post** (`SHARE_POST`) — Share a post on LinkedIn +- **Get Profile** (`GET_PROFILE`) — Retrieve LinkedIn profile information + +[All operations and configuration fields](/tools/reference#linkedin). + --- ## PostHog @@ -58,6 +106,50 @@ Capture events and work with PostHog analytics resources including event definit **Requires:** PostHog API credentials +**Operations:** + +- **Capture Event** (`CAPTURE_EVENT`) — Capture a single analytics event +- **Batch Events** (`BATCH_EVENTS`) — Batch capture multiple events at once +- **List Event Definitions** (`LIST_EVENT_DEFINITIONS`) — List all event definitions +- **Get Event Definition** (`GET_EVENT_DEFINITION`) — Get a specific event definition +- **Update Event Definition** (`UPDATE_EVENT_DEFINITION`) — Update an event definition +- **Get Person** (`GET_PERSON`) — Get person details by ID +- **Delete Person** (`DELETE_PERSON`) — Delete a person record +- **Run Query (HogQL)** (`RUN_QUERY`) — Execute a HogQL analytics query +- **List Insights** (`LIST_INSIGHTS`) — List all saved insights +- **Get Insight** (`GET_INSIGHT`) — Get a specific insight and its data +- **Create Insight** (`CREATE_INSIGHT`) — Create a new saved insight +- **List Dashboards** (`LIST_DASHBOARDS`) — List all dashboards +- **Get Dashboard** (`GET_DASHBOARD`) — Get a dashboard with its tiles +- **List Actions** (`LIST_ACTIONS`) — List all defined actions +- **Get Cohort** (`GET_COHORT`) — Get a specific cohort +- **Create Cohort** (`CREATE_COHORT`) — Create a new cohort +- **List Annotations** (`LIST_ANNOTATIONS`) — List all annotations +- **Create Annotation** (`CREATE_ANNOTATION`) — Create a timeline annotation +- **List Feature Flags** (`LIST_FEATURE_FLAGS`) — List all feature flags +- **Get Feature Flag** (`GET_FEATURE_FLAG`) — Get a specific feature flag +- **Create Feature Flag** (`CREATE_FEATURE_FLAG`) — Create a new feature flag +- **Update Feature Flag** (`UPDATE_FEATURE_FLAG`) — Update an existing feature flag +- **Delete Feature Flag** (`DELETE_FEATURE_FLAG`) — Delete a feature flag +- **Get Experiment** (`GET_EXPERIMENT`) — Get experiment details +- **Create Experiment** (`CREATE_EXPERIMENT`) — Create a new A/B experiment +- **List Surveys** (`LIST_SURVEYS`) — List all surveys +- **Get Survey** (`GET_SURVEY`) — Get a specific survey +- **Create Survey** (`CREATE_SURVEY`) — Create a new survey +- **Update Survey** (`UPDATE_SURVEY`) — Update an existing survey +- **List Session Recordings** (`LIST_SESSION_RECORDINGS`) — List session recordings +- **Get Session Recording** (`GET_SESSION_RECORDING`) — Get a specific session recording +- **List Recording Playlists** (`LIST_RECORDING_PLAYLISTS`) — List recording playlists +- **List Property Definitions** (`LIST_PROPERTY_DEFINITIONS`) — List all property definitions +- **Get Property Definition** (`GET_PROPERTY_DEFINITION`) — Get a specific property definition +- **Update Property Definition** (`UPDATE_PROPERTY_DEFINITION`) — Update a property definition +- **List Projects** (`LIST_PROJECTS`) — List all projects in the organization +- **Get Project** (`GET_PROJECT`) — Get current project details +- **List Organizations** (`LIST_ORGANIZATIONS`) — List all organizations +- **Get Organization** (`GET_ORGANIZATION`) — Get organization details + +[All operations and configuration fields](/tools/reference#posthog). + --- ## Dub @@ -71,6 +163,16 @@ Create and manage short links with Dub.co. **Requires:** Dub credentials +**Operations:** + +- **Create Short Link** (`CREATE_SHORT_LINK`) — Shorten a URL into a Dub link +- **Get Link Analytics** (`GET_LINK_ANALYTICS`) — Fetch click analytics for a link over a time range +- **List Links** (`LIST_LINKS`) — List links in the connected workspace +- **Update Link** (`UPDATE_LINK`) — Update destination URL or metadata +- **Delete Link** (`DELETE_LINK`) — Permanently delete a short link + +[All operations and configuration fields](/tools/reference#dub). + --- ## ElevenLabs @@ -83,3 +185,11 @@ Convert text into speech with ElevenLabs. - Turn workflow output into audio files for distribution **Requires:** ElevenLabs API credentials + +**Operations:** + +- **Text to Speech** (`TEXT_TO_SPEECH`) — Convert text to speech using AI voices + +[All operations and configuration fields](/tools/reference#elevenlabs). + +--- diff --git a/content/docs/triggers.mdx b/content/docs/triggers.mdx index d2e34dd..258d97c 100644 --- a/content/docs/triggers.mdx +++ b/content/docs/triggers.mdx @@ -3,27 +3,15 @@ title: "Triggers" description: "Every workflow starts with a trigger. Choose the right one for your use case." --- -Triggers are the entry point of every workflow. When a trigger fires, the workflow begins executing from that node. Legacy workflows must enable independent triggers before adding another entry point. Multiple-trigger authoring must also be enabled in the environment. +Triggers start a workflow run from a specific entry point. New workflows support multiple triggers automatically, including multiple triggers of the same type. ## Adding another trigger -If adding a second trigger shows this message: +Add the next trigger from the node picker, universal search, or the canvas context menu. You can also duplicate an existing trigger. No independent-trigger setting is required. Saving a second trigger upgrades an existing draft automatically while preserving its existing node IDs. -> Enable independent triggers from the Triggers menu before adding another entry point. +Undeploy a workflow before changing its entry points, and wait for pending or running executions to finish. Configure and test each entry point before deploying again. Copies are paused and receive new variable names; configure their connections before enabling them. -Open **Triggers → Enable independent triggers**, when available. Before converting a legacy workflow: - -1. Undeploy the workflow and let active runs finish. -2. Review its entry points in the conversion dialog. -3. Update callers that could match more than one trigger to identify the intended entry point. Replace workflow-only Stripe and Google Forms callback URLs with the node-specific URLs shown in their settings. -4. Acknowledge the review and complete the conversion, then add the additional trigger. -5. Test each entry point before deploying again. Each event starts its selected trigger path rather than all root nodes. - -### The Triggers menu is missing or the action is disabled - -The same message also appears when multiple-trigger authoring is disabled for the environment. In that case, the menu may be hidden for a legacy workflow, or its conversion action may be unavailable. Contact your workspace administrator or support; repeatedly adding the node will not enable the capability. Editing restrictions can also disable the conversion action. - -For self-hosted operators, the editor checks `NEXT_PUBLIC_MULTI_TRIGGER_ENABLED=true` as well as the workflow's independent-trigger execution version. Changing only the workflow or only the environment does not satisfy both checks. Coordinate rollout with the compatible backend and worker configuration. +Each event starts only its selected trigger path. When **Run** has more than one eligible trigger, choose the trigger to test. API and workflow callers must identify the intended trigger if more than one matches. Existing workflow-only Stripe and Google Forms callback URLs may need to be replaced with the node-specific URLs from the trigger settings. ## Manual Trigger @@ -35,7 +23,7 @@ The simplest trigger type. No configuration required. Click **Run** in the edito This node appears as **Trigger manually** in the node picker. -**Variable name:** Not applicable (no input data) +Manual triggers can have an output variable. Use the variable picker or the active trigger context (`{{$trigger}}`) rather than assuming a manual run has no trigger metadata. --- @@ -67,6 +55,16 @@ Create a form with custom fields that must be filled out before the workflow run --- +## Innflow Trigger + +Use **Innflow Trigger** when another Innflow workflow should call this workflow. Define the typed input fields the caller must supply, then select this entry point in the calling workflow’s **Innflow** node. + +Required inputs are checked before a run starts. Use distinct names for multiple Innflow entry points so the caller can select the intended one. Reference the actual trigger variable shown in the editor, and use `{{$trigger.nodeId}}` to identify the active root. + +See the [Innflow Trigger fields](/tools/reference#innflow-trigger) and [Innflow action](/tools/reference#innflow). + +--- + ## Form Trigger diff --git a/package.json b/package.json index 0e7b597..069ba2a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "start": "next start", "types:check": "next typegen && tsc --noEmit", "check": "npm run types:check", - "verify": "node scripts/verify-build.mjs" + "verify": "node scripts/verify-build.mjs", + "docs:sync": "node scripts/sync-tool-reference.mjs", + "docs:check": "node scripts/check-tool-docs.mjs" }, "dependencies": { "cn": "^0.3.0", diff --git a/scripts/check-tool-docs.mjs b/scripts/check-tool-docs.mjs new file mode 100644 index 0000000..43210b2 --- /dev/null +++ b/scripts/check-tool-docs.mjs @@ -0,0 +1,35 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { execFileSync } from 'node:child_process'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +const root=resolve(dirname(fileURLToPath(import.meta.url)),'..'); +execFileSync(process.execPath,[resolve(root,'scripts/sync-tool-reference.mjs'),'--check'],{cwd:root,stdio:'inherit'}); +const catalog=JSON.parse(readFileSync(resolve(root,'scripts/tool-catalog.snapshot.json'),'utf8')); +const mapping=JSON.parse(readFileSync(resolve(root,'scripts/tool-guide-map.json'),'utf8')); +const byType=new Map(catalog.nodes.map(node=>[node.nodeType,node])); +const section=(text,heading)=>{ + const start=text.indexOf(`## ${heading}\n`); + assert.ok(start>=0,`Missing section ${heading}`); + const next=text.indexOf('\n## ',start+3); + return text.slice(start,next<0?text.length:next); +}; +for(const item of mapping){ + const text=readFileSync(resolve(root,item.file),'utf8'); + const body=section(text,item.heading); + const listed=[...body.matchAll(/^- \*\*[^\n]+?\*\* \(`([^`]+)`\)/gm)].map(match=>match[1]).sort(); + const expected=byType.get(item.nodeType).operations.map(op=>op.value).sort(); + assert.deepEqual(listed,expected,`${item.file} ${item.heading}: operation list differs from universal search`); +} +const checks=[ + ['content/docs/triggers.mdx',['## Innflow Trigger','No independent-trigger setting is required'],['NEXT_PUBLIC_MULTI_TRIGGER_ENABLED','Enable independent triggers']], + ['content/docs/essentials/variables.mdx',['{{api.httpResponse.data}}','{{code.result}}','{{kb.results}}'],['{{http_response.output.data}}']], + ['content/docs/features/copilot.mdx',['configured model automatically'],['- Model selection','choose a chat model']], + ['content/docs/features/assistant.mdx',['not separate active chat runtimes'],['Exclusive → Assistant']], +]; +for(const [file,required,forbidden] of checks){ + const text=readFileSync(resolve(root,file),'utf8'); + for(const value of required)assert.ok(text.includes(value),`${file}: missing ${value}`); + for(const value of forbidden)assert.ok(!text.includes(value),`${file}: obsolete ${value}`); +} +console.log(`Checked ${mapping.length} guide operation lists and regression claims.`); diff --git a/scripts/sync-tool-reference.mjs b/scripts/sync-tool-reference.mjs new file mode 100644 index 0000000..8e57ec3 --- /dev/null +++ b/scripts/sync-tool-reference.mjs @@ -0,0 +1,52 @@ +import { execFileSync } from 'node:child_process'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { resolve, dirname } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +const docsRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..'); +const appRoot = resolve(process.env.INNFLOW_SOURCE ?? resolve(docsRoot, '../innflow')); +const moduleUrl = path => JSON.stringify(pathToFileURL(resolve(appRoot, path)).href); +const program = ` +import {buildUniversalSearchItems} from ${moduleUrl('src/components/universal-search-items.ts')}; +import {getAuthoringContract} from ${moduleUrl('src/features/editor/lib/authoring/contracts.ts')}; +import {NODE_REGISTRY} from ${moduleUrl('src/config/node-registry.ts')}; +const items=buildUniversalSearchItems().map(({icon,...item})=>item); +const nodes=items.filter(i=>i.category!=="operations").map(item=>({ + ...item, contract:getAuthoringContract(item.nodeType), + operations:items.filter(i=>i.category==="operations"&&i.nodeType===item.nodeType).map(i=>({label:i.label,value:i.operationValue,description:i.description})), +})); +console.log(JSON.stringify({nodes,searchItemCount:items.length,operationCount:items.filter(i=>i.category==="operations").length, + hiddenTypes:Object.entries(NODE_REGISTRY).filter(([,value])=>value.pickerVisible===false).map(([type])=>type).sort()}));`; +const catalog = JSON.parse(execFileSync(resolve(appRoot, 'node_modules/.bin/tsx'), ['--tsconfig='+resolve(appRoot, 'tsconfig.json'), '--eval', program], {cwd:appRoot, encoding:'utf8', maxBuffer:20*1024*1024, env:{...process.env, NEXT_PUBLIC_JEV_NODE_ENABLED:'false'}})); +// A searchable operation can still be an unimplemented application path. +// This exception is based on Innflow source, not a claim about Slack's public API. +const canvasSource=readFileSync(resolve(appRoot,'src/tools/slack/actions/create-canvas.ts'),'utf8'); +if(!canvasSource.includes('throw new NonRetriableError(')) throw new Error('Re-review Slack Canvas availability: implementation changed.'); +const operationDescription=(node,op)=>node.nodeType==='SLACK' && op.value==='CREATE_CANVAS' + ? 'Listed in search, but the current Innflow implementation rejects this operation.' : op.description; +const escape = value => String(value ?? '').replaceAll('&','&').replaceAll('<','<').replaceAll('>','>').replaceAll('{','{').replaceAll('}','}').replaceAll('|','|').replaceAll('\n',' '); +const auth = {oauth:'Connect the account requested by the node.',api_key:'Configure the API credential requested by the node.',platform:'Uses a platform-managed connection.',none:'No account connection declared.',connection:'Select the connection requested by the node.'}; +const lines = ['---','title: "Tool and operation reference"','description: "Every standard node and operation available in universal search, with configuration fields from the application."','---','','This reference lists the standard universal-search catalog. Availability can also depend on your plan and workspace. [AI Decision](/tools/ai-decision) is separately controlled and is not included in the standard catalog.','','Search includes **'+catalog.nodes.length+' node entries** and **'+catalog.operationCount+' operations**. The category guides explain common workflows; use this reference for the complete operation list.','','Configuration fields may appear only after selecting an operation, account, or mode. Required fields depend on that selection. Account selectors load live choices; do not invent their IDs. Output fields can also depend on configuration and the response from a service—inspect an execution before referencing a value.','']; +for (const node of catalog.nodes) { + lines.push(``, '', `## ${escape(node.label)}`, '', escape(node.description), '', `Node type: \`${node.nodeType}\`.`, '', auth[node.contract.authMode] ?? 'Follow the connection controls shown in the editor.', ''); + if (node.operations.length) { + lines.push('### Operations','','| Operation | Configuration value | Description |','| --- | --- | --- |'); + for (const op of node.operations) lines.push(`| ${escape(op.label)} | \`${op.value}\` | ${escape(operationDescription(node,op))} |`); + lines.push(''); + } + if (node.contract.fields.length) { + lines.push('### Configuration','','Fields are listed across available modes. Conditional fields are only applicable when the matching operation or mode is selected.','','| Field | Configuration key | Details |','| --- | --- | --- |'); + for (const field of node.contract.fields) { + const description = node.nodeType === "CODE" && field.name === "code" ? "Read upstream data through context. For Python scripts, print JSON as the last output for a structured result. Use return only inside a function. Captured expression results are used when the runner provides them." : node.nodeType === "MCP" && field.name === "variableName" ? "Reference name.text for agentic responses; direct tool calls expose name.content and optional name.structuredContent. Resource and prompt modes expose the returned server payload." : field.description; + const details = [description,field.readOnly?'Read only.':null,field.secret?'Secret; enter through the secure configuration control.':null,field.dynamicOptions?'Choose from options loaded in the editor.':null,field.options?.length?'Choices: '+field.options.map(o=>o.label).join(', '):field.enum?.length?'Choices: '+field.enum.join(', '):null,field.condition!==undefined?'Conditional field.':null].filter(Boolean).join(' '); + lines.push(`| ${escape(field.label ?? field.name)} | \`${field.name}\` | ${escape(details)} |`); + } + lines.push(''); + } else lines.push('Open this node in the editor for its setup controls. No editable field list is declared in the shared configuration catalog.',''); +} +const rendered=lines.join('\n')+'\n'; +const outputs = [[resolve(docsRoot,'content/docs/tools/reference.mdx'),rendered],[resolve(docsRoot,'scripts/tool-catalog.snapshot.json'),JSON.stringify(catalog,null,2)+'\n']]; +if(process.argv.includes('--check')) { + const stale=outputs.filter(([file,value])=>readFileSync(file,'utf8')!==value).map(([file])=>file); + if(stale.length) throw new Error('Tool reference differs from application source: '+stale.join(', ')); +} else for(const [file,value] of outputs) writeFileSync(file,value); +console.log(`Verified ${catalog.nodes.length} node entries and ${catalog.operationCount} exact operation IDs against universal search.`); diff --git a/scripts/tool-catalog.snapshot.json b/scripts/tool-catalog.snapshot.json new file mode 100644 index 0000000..eb06388 --- /dev/null +++ b/scripts/tool-catalog.snapshot.json @@ -0,0 +1,21642 @@ +{ + "nodes": [ + { + "id": "trigger-MANUAL_TRIGGER", + "category": "triggers", + "nodeType": "MANUAL_TRIGGER", + "label": "Trigger manually", + "description": "Runs the flow on clicking a button. Good for getting started quickly", + "contract": { + "contractVersion": 1, + "type": "MANUAL_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "trigger-INPUT_TRIGGER", + "category": "triggers", + "nodeType": "INPUT_TRIGGER", + "label": "Input Trigger", + "description": "Define input fields to fill when running. Great for workflows with parameters", + "contract": { + "contractVersion": 1, + "type": "INPUT_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "fields", + "type": "array", + "description": "Input fields. Each item uses {name, type, defaultValue?}; supported types are string, number, boolean, object, array, and files. IDs are generated when omitted.", + "secret": false + } + ], + "outputs": { + "data": { + "type": "object", + "properties": {} + }, + "triggeredAt": { + "type": "string", + "description": "Time the input trigger ran" + }, + "_fields": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "trigger-INNFLOW_TRIGGER", + "category": "triggers", + "nodeType": "INNFLOW_TRIGGER", + "label": "Innflow Trigger", + "description": "Receive typed input when another Innflow workflow calls this workflow", + "contract": { + "contractVersion": 1, + "type": "INNFLOW_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "fields", + "type": "array", + "description": "Innflow input fields. Each item uses {name, type, required?, defaultValue?}; names must be unique and IDs are generated when omitted.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "trigger-FORM_TRIGGER", + "category": "triggers", + "nodeType": "FORM_TRIGGER", + "label": "Form", + "description": "Host a public form and run the flow when someone submits it", + "contract": { + "contractVersion": 1, + "type": "FORM_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "title", + "type": "string", + "description": "Published form title.", + "secret": false + }, + { + "name": "description", + "type": "string", + "description": "Published form description.", + "secret": false + }, + { + "name": "fields", + "type": "array", + "description": "Published fields using {name, label, type, required?, placeholder?, defaultValue?, options?}. Types: short_text, long_text, email, number, checkbox, select, date, file_upload. IDs are generated when omitted.", + "secret": false + }, + { + "name": "submitLabel", + "type": "string", + "description": "Submit button label.", + "secret": false + }, + { + "name": "redirectUrl", + "type": "string", + "description": "Optional HTTP or HTTPS URL to open after successful submission. Empty string disables redirect.", + "secret": false + }, + { + "name": "successMessage", + "type": "string", + "description": "Message shown after a successful submission.", + "secret": false + }, + { + "name": "appearance", + "type": "object", + "description": "Appearance settings: accentColor, background, backgroundColor, and density.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "outputContract": { + "root": "formTrigger", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:nodeId", + "path": "nodeId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:triggerId", + "path": "triggerId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:_fields", + "path": "_fields", + "type": "array", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:data", + "path": "data", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:submittedAt", + "path": "submittedAt", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:submissionId", + "path": "submissionId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:metadata", + "path": "metadata", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-WEBHOOK_TRIGGER", + "category": "triggers", + "nodeType": "WEBHOOK_TRIGGER", + "label": "Webhook", + "description": "Runs the flow when an HTTP request is received", + "contract": { + "contractVersion": 1, + "type": "WEBHOOK_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "name", + "type": "string", + "description": "Webhook name.", + "secret": false + }, + { + "name": "description", + "type": "string", + "description": "Webhook description.", + "secret": false + }, + { + "name": "requireAuth", + "type": "boolean", + "description": "Require a request authentication header.", + "secret": false + }, + { + "name": "authHeaderName", + "type": "string", + "description": "Authentication header name.", + "secret": false + }, + { + "name": "authTokenEnvVar", + "type": "string", + "description": "Existing encrypted environment-variable name. Raw tokens are rejected.", + "secret": true + }, + { + "name": "inputSchema", + "type": "array", + "description": "Expected request fields using {name, type, required?}.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "outputContract": { + "root": "webhookTrigger", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:nodeId", + "path": "nodeId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:triggerCount", + "path": "triggerCount", + "type": "number", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:body", + "path": "body", + "type": "unknown", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:headers", + "path": "headers", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:query", + "path": "query", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:method", + "path": "method", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:triggerId", + "path": "triggerId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:triggeredAt", + "path": "triggeredAt", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-GOOGLE_FORM_TRIGGER", + "category": "triggers", + "nodeType": "GOOGLE_FORM_TRIGGER", + "label": "Google Form", + "description": "Runs the flow when a Google Form is submitted", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_FORM_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "connectionId", + "type": "string", + "required": true, + "description": "ID of a connected Google Forms account.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth", + "outputContract": { + "root": "googleForm", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:formId", + "path": "formId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:formTitle", + "path": "formTitle", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:responseId", + "path": "responseId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:timestamp", + "path": "timestamp", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:respondentEmail", + "path": "respondentEmail", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:responses", + "path": "responses", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:raw", + "path": "raw", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-STRIPE_TRIGGER", + "category": "triggers", + "nodeType": "STRIPE_TRIGGER", + "label": "Stripe Event", + "description": "Runs the flow when a Stripe Event is captured", + "contract": { + "contractVersion": 1, + "type": "STRIPE_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth", + "outputContract": { + "root": "stripe", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:eventId", + "path": "eventId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:eventType", + "path": "eventType", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:timestamp", + "path": "timestamp", + "type": "number", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:livemode", + "path": "livemode", + "type": "boolean", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:raw", + "path": "raw", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-TYPEFORM_TRIGGER", + "category": "triggers", + "nodeType": "TYPEFORM_TRIGGER", + "label": "Typeform", + "description": "Runs the flow when a Typeform response is submitted", + "contract": { + "contractVersion": 1, + "type": "TYPEFORM_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "formId", + "type": "string", + "required": true, + "description": "Typeform form ID.", + "secret": false + }, + { + "name": "accessTokenEnvVar", + "type": "string", + "description": "Existing encrypted environment-variable name containing a Typeform personal access token. Required only when creating the registration.", + "secret": true + }, + { + "name": "webhookSecretEnvVar", + "type": "string", + "description": "Optional encrypted environment-variable name containing the Typeform webhook secret.", + "secret": true + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "outputContract": { + "root": "typeform", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:nodeId", + "path": "nodeId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:formId", + "path": "formId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:responseId", + "path": "responseId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:submittedAt", + "path": "submittedAt", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:answers", + "path": "answers", + "type": "array", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:variables", + "path": "variables", + "type": "unknown", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:hidden", + "path": "hidden", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:raw", + "path": "raw", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-SCHEDULER_TRIGGER", + "category": "triggers", + "nodeType": "SCHEDULER_TRIGGER", + "label": "Schedule", + "description": "Runs the flow on a schedule using cron expressions", + "contract": { + "contractVersion": 1, + "type": "SCHEDULER_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "schedule", + "type": "string", + "required": true, + "description": "Five-field cron expression.", + "secret": false + }, + { + "name": "timezone", + "type": "string", + "description": "IANA timezone, for example America/Toronto.", + "secret": false + }, + { + "name": "frequency", + "type": "string", + "description": "Optional display frequency.", + "secret": false + }, + { + "name": "payload", + "type": "object", + "description": "Optional input payload for scheduled runs.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "trigger-NOTION_TRIGGER", + "category": "triggers", + "nodeType": "NOTION_TRIGGER", + "label": "Notion Event", + "description": "Runs the flow when a Notion page or database event is received", + "contract": { + "contractVersion": 1, + "type": "NOTION_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "connectionId", + "type": "string", + "required": true, + "description": "ID of a connected Notion workspace.", + "secret": false + }, + { + "name": "entityId", + "type": "string", + "required": true, + "description": "Notion page or database ID.", + "secret": false + }, + { + "name": "entityType", + "type": "string", + "required": true, + "enum": [ + "page", + "database" + ], + "description": "Notion entity type.", + "secret": false + }, + { + "name": "eventTypes", + "type": "array", + "required": true, + "description": "Notion webhook event types to accept.", + "enum": [ + "page.content_updated", + "page.properties_updated", + "page.created", + "page.deleted", + "database.row_created", + "database.row_updated", + "database.row_deleted", + "comment.created", + "comment.updated", + "comment.deleted" + ], + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "outputContract": { + "root": "notion", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:eventId", + "path": "eventId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:eventType", + "path": "eventType", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:entityId", + "path": "entityId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:entityType", + "path": "entityType", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:timestamp", + "path": "timestamp", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:authors", + "path": "authors", + "type": "array", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:workspaceId", + "path": "workspaceId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:raw", + "path": "raw", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-TELEGRAM_TRIGGER", + "category": "triggers", + "nodeType": "TELEGRAM_TRIGGER", + "label": "Telegram", + "description": "Runs the flow when a message is sent to your Telegram bot", + "contract": { + "contractVersion": 1, + "type": "TELEGRAM_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + }, + { + "name": "botTokenEnvVar", + "type": "string", + "description": "Existing encrypted environment-variable name containing the Telegram bot token. Required only when creating the registration.", + "secret": true + } + ], + "outputs": {}, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "outputContract": { + "root": "telegram", + "version": 1, + "revision": 0, + "fields": [ + { + "id": "provider:nodeId", + "path": "nodeId", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:messageId", + "path": "messageId", + "type": "number", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:text", + "path": "text", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:chatId", + "path": "chatId", + "type": "number", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:chatType", + "path": "chatType", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:fromId", + "path": "fromId", + "type": "number", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:fromUsername", + "path": "fromUsername", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:fromFirstName", + "path": "fromFirstName", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:date", + "path": "date", + "type": "string", + "required": false, + "nullable": true, + "provenance": "provider" + }, + { + "id": "provider:raw", + "path": "raw", + "type": "object", + "required": false, + "nullable": true, + "provenance": "provider" + } + ] + } + }, + "operations": [] + }, + { + "id": "trigger-CHAT_TRIGGER", + "category": "triggers", + "nodeType": "CHAT_TRIGGER", + "label": "Chat", + "description": "Trigger workflow with chat messages from a conversational interface", + "contract": { + "contractVersion": 1, + "type": "CHAT_TRIGGER", + "operations": [], + "fields": [ + { + "name": "customName", + "type": "string", + "description": "Optional user-facing name. Do not change variableName.", + "secret": false + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-AI_AGENT", + "category": "utility", + "nodeType": "AI_AGENT", + "label": "AI Agent", + "description": "Autonomous AI agent with tool calling. Select tools inline.", + "contract": { + "contractVersion": 1, + "type": "AI_AGENT", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "model", + "type": "dropdown", + "label": "Model", + "description": "Choose which AI model powers the agent. The model must support tool calling.", + "required": false, + "visible": true, + "options": [ + { + "id": "gpt-5.6-sol", + "label": "OpenAI 5.6 Sol" + }, + { + "id": "gpt-5.6-luna", + "label": "GPT-5.6 Luna" + }, + { + "id": "gpt-5.5", + "label": "GPT-5.5" + }, + { + "id": "gpt-5.4", + "label": "GPT-5.4" + }, + { + "id": "gpt-5.4-mini", + "label": "GPT-5.4 Mini" + }, + { + "id": "gpt-5.4-nano", + "label": "GPT-5.4 Nano" + }, + { + "id": "gpt-4.1", + "label": "GPT-4.1" + }, + { + "id": "gpt-4.1-mini", + "label": "GPT-4.1 Mini" + }, + { + "id": "gpt-4o", + "label": "GPT-4o" + }, + { + "id": "gpt-4o-mini", + "label": "GPT-4o Mini" + }, + { + "id": "o4-mini", + "label": "o4-mini" + }, + { + "id": "o3", + "label": "o3" + }, + { + "id": "o3-mini", + "label": "o3-mini" + }, + { + "id": "claude-fable-5", + "label": "Claude Fable 5" + }, + { + "id": "claude-opus-5", + "label": "Opus 5" + }, + { + "id": "claude-sonnet-5", + "label": "Claude Sonnet 5" + }, + { + "id": "claude-opus-4-8", + "label": "Claude Opus 4.8" + }, + { + "id": "claude-haiku-4-5-20251001", + "label": "Claude Haiku 4.5" + }, + { + "id": "gemini-3.7-flash", + "label": "Gemini 3.7 Flash" + }, + { + "id": "gemini-3.6-flash", + "label": "Gemini 3.6 Flash" + }, + { + "id": "gemini-3.5-flash", + "label": "Gemini 3.5 Flash" + }, + { + "id": "gemini-3.5-flash-lite", + "label": "Gemini 3.5 Flash Lite" + }, + { + "id": "gemini-3.1-pro-preview", + "label": "Gemini 3.1 Pro" + }, + { + "id": "gemini-2.5-pro", + "label": "Gemini 2.5 Pro" + }, + { + "id": "gemini-2.5-flash", + "label": "Gemini 2.5 Flash" + }, + { + "id": "gemini-2.5-flash-lite", + "label": "Gemini 2.5 Flash Lite" + }, + { + "id": "deepseek-v4-pro", + "label": "DeepSeek V4 Pro" + }, + { + "id": "deepseek-flash", + "label": "DeepSeek V4.1 Flash" + }, + { + "id": "kimi-k3", + "label": "Kimi K3" + }, + { + "id": "kimi-k2.6", + "label": "Kimi K2.6" + } + ], + "defaultValue": "gemini-3.7-flash", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "systemPrompt", + "type": "long-input", + "label": "System Prompt", + "description": "Instructions that define the agent's behavior. Supports {{variable}} syntax.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "userPrompt", + "type": "long-input", + "label": "User Prompt", + "description": "The task/instruction for the agent. Supports {{variable}} syntax.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "temperature", + "type": "slider", + "label": "Temperature", + "description": "Controls randomness. Lower = more deterministic, Higher = more creative.", + "required": false, + "visible": true, + "condition": { + "field": "model", + "value": "kimi-k3", + "not": true + }, + "defaultValue": 0.7, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0, + "max": 1 + }, + { + "name": "maxSteps", + "type": "slider", + "label": "Max Steps", + "description": "Maximum tool-calling rounds (1-20). A final synthesis is added when tools are used.", + "required": false, + "visible": true, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 20 + }, + { + "name": "skills", + "type": "skill-picker", + "label": "Skills", + "description": "Select instruction skills the agent should follow.", + "required": false, + "visible": true, + "defaultValue": [], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "sandboxEnabled", + "type": "switch", + "label": "Ubuntu Sandbox", + "description": "Explicitly allow isolated shell and filesystem commands. Connected-app credentials are never placed in the sandbox.", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tools", + "type": "tool-picker", + "label": "Tools", + "description": "Select tools the agent can use during execution.", + "required": false, + "visible": true, + "defaultValue": [], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "version": { + "type": "number", + "description": "Agent result contract version" + }, + "status": { + "type": "string", + "description": "Agent completion status: completed or partial" + }, + "text": { + "type": "string", + "description": "Agent's final text response" + }, + "usage": { + "type": "json", + "description": "Token usage metadata" + }, + "toolCalls": { + "type": "array", + "description": "List of tool calls made by the agent" + }, + "toolResults": { + "type": "array", + "description": "Results from tool calls" + }, + "stepsCompleted": { + "type": "number", + "description": "Number of agentic loop iterations completed" + }, + "model": { + "type": "string", + "description": "Model ID used for execution" + }, + "taskRunId": { + "type": "string", + "description": "Durable task run ID" + }, + "artifacts": { + "type": "array", + "description": "Externalized task artifacts" + }, + "completionReason": { + "type": "string", + "description": "Why the durable task stopped" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-BROWSER_AGENT", + "category": "utility", + "nodeType": "BROWSER_AGENT", + "label": "Browser Agent", + "description": "Run an interactive browser task with Stagehand and Browserbase", + "contract": { + "contractVersion": 1, + "type": "BROWSER_AGENT", + "operations": [ + { + "value": "RUN_TASK", + "label": "Run Browser Task", + "description": "Complete one multi-step task in a fresh browser session" + }, + { + "value": "RUN_SEQUENCE", + "label": "Run Browser Sequence", + "description": "Run deterministic browser actions in one shared session" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the browser result downstream", + "required": true, + "visible": true, + "defaultValue": "browserResult", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "RUN_TASK", + "label": "Agent task" + }, + { + "id": "RUN_SEQUENCE", + "label": "Action sequence" + } + ], + "defaultValue": "RUN_TASK", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "startUrl", + "type": "short-input", + "label": "Starting URL", + "description": "The public HTTP or HTTPS page where the browser task starts", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "RUN_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "instruction", + "type": "long-input", + "label": "Task", + "description": "A clear browser task. Supports {{variable}} syntax.", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "RUN_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxSteps", + "type": "number-input", + "label": "Max Steps", + "description": "Maximum browser-agent actions before the task stops (1-20)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RUN_TASK" + }, + "defaultValue": 20, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 20 + }, + { + "name": "steps", + "type": "json-editor", + "label": "Actions", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RUN_SEQUENCE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "success": { + "type": "boolean", + "description": "Whether the task succeeded" + }, + "completed": { + "type": "boolean", + "description": "Whether the agent completed its instruction" + }, + "message": { + "type": "string", + "description": "Agent result message" + }, + "actionsTaken": { + "type": "number", + "description": "Number of browser actions taken" + }, + "finalUrl": { + "type": "string", + "description": "URL open when the task ended" + }, + "sessionId": { + "type": "string", + "description": "Browserbase session ID" + }, + "sessionUrl": { + "type": "string", + "description": "Complete Browserbase session and replay URL" + }, + "providers": { + "type": "json", + "description": "Browserbase, Stagehand, and model attribution" + }, + "usage": { + "type": "json", + "description": "Browser session duration and Stagehand token usage" + }, + "mode": { + "type": "string", + "description": "Agent or sequence execution mode" + }, + "steps": { + "type": "json", + "description": "Per-action results" + }, + "lastOutput": { + "type": "json", + "description": "Output from the last completed action" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Run Browser Task", + "value": "RUN_TASK", + "description": "Complete one multi-step task in a fresh browser session" + }, + { + "label": "Run Browser Sequence", + "value": "RUN_SEQUENCE", + "description": "Run deterministic browser actions in one shared session" + } + ] + }, + { + "id": "utility-A2A_AGENT", + "category": "utility", + "nodeType": "A2A_AGENT", + "label": "A2A Agent", + "description": "Delegate tasks to external A2A-compatible agents over HTTP", + "contract": { + "contractVersion": 1, + "type": "A2A_AGENT", + "operations": [ + { + "value": "POLLING", + "label": "Polling Mode", + "description": "Send task and poll for result" + }, + { + "value": "STREAMING", + "label": "Streaming Mode", + "description": "Receive real-time SSE updates from the agent" + } + ], + "fields": [], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "setupRequired": "Inspect this node in the editor; no editable field contract is available. Do not guess fields." + }, + "operations": [ + { + "label": "Polling Mode", + "value": "POLLING", + "description": "Send task and poll for result" + }, + { + "label": "Streaming Mode", + "value": "STREAMING", + "description": "Receive real-time SSE updates from the agent" + } + ] + }, + { + "id": "utility-GENERATE_IMAGE", + "category": "utility", + "nodeType": "GENERATE_IMAGE", + "label": "Image Generation", + "description": "Generate images with Kie.ai image models", + "contract": { + "contractVersion": 1, + "type": "GENERATE_IMAGE", + "operations": [ + { + "value": "GENERATE", + "label": "Image Generation", + "description": "Generate image URLs using Kie.ai" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference generated images downstream", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "model", + "type": "dropdown", + "label": "Model", + "description": "Kie.ai Market image model to run", + "required": true, + "visible": true, + "options": [ + { + "id": "nano-banana-2", + "label": "Nano Banana 2" + }, + { + "id": "gpt-image-2-text-to-image", + "label": "OpenAI Image Gen 2" + }, + { + "id": "wan/2-7-image", + "label": "Wan 2.7 Image" + }, + { + "id": "qwen2/text-to-image", + "label": "Qwen 2" + } + ], + "defaultValue": "nano-banana-2", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "prompt", + "type": "long-input", + "label": "Prompt", + "description": "Prompt sent to Kie.ai. Supports workflow variables.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "aspectRatio", + "type": "dropdown", + "label": "Aspect Ratio", + "description": "Aspect ratio for the generated image", + "required": false, + "visible": true, + "options": [ + { + "id": "auto", + "label": "Auto" + }, + { + "id": "1:1", + "label": "1:1" + }, + { + "id": "1:4", + "label": "1:4" + }, + { + "id": "1:8", + "label": "1:8" + }, + { + "id": "2:3", + "label": "2:3" + }, + { + "id": "3:2", + "label": "3:2" + }, + { + "id": "3:4", + "label": "3:4" + }, + { + "id": "4:1", + "label": "4:1" + }, + { + "id": "4:3", + "label": "4:3" + }, + { + "id": "4:5", + "label": "4:5" + }, + { + "id": "5:4", + "label": "5:4" + }, + { + "id": "8:1", + "label": "8:1" + }, + { + "id": "16:9", + "label": "16:9" + }, + { + "id": "9:16", + "label": "9:16" + }, + { + "id": "21:9", + "label": "21:9" + } + ], + "defaultValue": "auto", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "inputUrls", + "type": "long-input", + "label": "Input Image URLs", + "description": "Optional reference image URLs, one per line or comma-separated.", + "required": false, + "visible": false, + "condition": { + "field": "model", + "value": [ + "nano-banana-2", + "wan/2-7-image" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "resolution", + "type": "dropdown", + "label": "Resolution", + "required": false, + "visible": false, + "condition": { + "field": "model", + "value": [ + "nano-banana-2", + "wan/2-7-image" + ] + }, + "options": [ + { + "id": "1K", + "label": "1K" + }, + { + "id": "2K", + "label": "2K" + }, + { + "id": "4K", + "label": "4K" + } + ], + "defaultValue": "1K", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "seed", + "type": "number-input", + "label": "Seed", + "description": "Optional generation seed for repeatable supported outputs", + "required": false, + "visible": false, + "condition": { + "field": "model", + "value": [ + "wan/2-7-image", + "qwen2/text-to-image" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxWaitSeconds", + "type": "slider", + "label": "Max Wait", + "description": "Maximum time to wait for Kie.ai to finish the image task", + "required": false, + "visible": true, + "defaultValue": 600, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 60, + "max": 900 + } + ], + "outputs": { + "taskId": { + "type": "string", + "description": "Kie.ai task ID" + }, + "state": { + "type": "string", + "description": "Final Kie.ai task state" + }, + "imageUrls": { + "type": "array", + "description": "Generated image URLs" + }, + "firstImageUrl": { + "type": "string", + "description": "First generated image URL" + }, + "result": { + "type": "object", + "description": "Raw Kie.ai task detail data" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Image Generation", + "value": "GENERATE", + "description": "Generate image URLs using Kie.ai" + } + ] + }, + { + "id": "utility-WEB_SCRAPER", + "category": "utility", + "nodeType": "WEB_SCRAPER", + "label": "Web Scraper", + "description": "Scrape pages or search the web and extract clean page content", + "contract": { + "contractVersion": 1, + "type": "WEB_SCRAPER", + "operations": [ + { + "value": "SCRAPE_URL", + "label": "Scrape URL", + "description": "Scrape a single public page" + }, + { + "value": "SEARCH_AND_SCRAPE", + "label": "Search + Scrape", + "description": "Search the web and scrape the top results" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference scraped content downstream", + "required": true, + "visible": true, + "defaultValue": "webScrape", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose whether to scrape a known page or search first", + "required": true, + "visible": true, + "options": [ + { + "id": "SCRAPE_URL", + "label": "Scrape URL" + }, + { + "id": "SEARCH_AND_SCRAPE", + "label": "Search + Scrape" + } + ], + "defaultValue": "SCRAPE_URL", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "url", + "type": "short-input", + "label": "URL", + "description": "The public HTTP or HTTPS page to scrape", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE_URL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "description": "The web search query to run before scraping results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_AND_SCRAPE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "description": "Number of search results to scrape, capped at 10", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_AND_SCRAPE" + }, + "defaultValue": 5, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 10 + }, + { + "name": "outputFormat", + "type": "dropdown", + "label": "Output Format", + "description": "Choose whether to include HTML in addition to markdown", + "required": false, + "visible": true, + "options": [ + { + "id": "markdown", + "label": "Markdown" + }, + { + "id": "markdown_html", + "label": "Markdown + HTML" + } + ], + "defaultValue": "markdown", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeMetadata", + "type": "switch", + "label": "Include Metadata", + "description": "Include title, description, Open Graph, and page metadata", + "required": false, + "visible": true, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeLinks", + "type": "switch", + "label": "Include Links", + "description": "Include links discovered on scraped pages", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "operation": { + "type": "string", + "description": "Executed scraper operation" + }, + "provider": { + "type": "string", + "description": "Backend scraper provider" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Scrape URL", + "value": "SCRAPE_URL", + "description": "Scrape a single public page" + }, + { + "label": "Search + Scrape", + "value": "SEARCH_AND_SCRAPE", + "description": "Search the web and scrape the top results" + } + ] + }, + { + "id": "utility-TABLES", + "category": "utility", + "nodeType": "TABLES", + "label": "Tables", + "description": "Read, query, and modify rows in internal tables", + "contract": { + "contractVersion": 1, + "type": "TABLES", + "operations": [ + { + "value": "READ_TABLE", + "label": "Read Table", + "description": "Read all rows" + }, + { + "value": "QUERY_ROWS", + "label": "Query Rows", + "description": "Filter rows by column value" + }, + { + "value": "ADD_ROW", + "label": "Add Row", + "description": "Insert new row(s)" + }, + { + "value": "UPDATE_ROW", + "label": "Update Row", + "description": "Update an existing row" + }, + { + "value": "DELETE_ROW", + "label": "Delete Row", + "description": "Remove a row by ID" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output (e.g. {{tables.rows}}, {{tables.totalRows}})", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tableId", + "type": "table-selector", + "label": "Table", + "description": "The table to operate on", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "READ_TABLE", + "label": "Read Table" + }, + { + "id": "QUERY_ROWS", + "label": "Query Rows" + }, + { + "id": "ADD_ROW", + "label": "Add Row" + }, + { + "id": "UPDATE_ROW", + "label": "Update Row" + }, + { + "id": "DELETE_ROW", + "label": "Delete Row" + } + ], + "defaultValue": "READ_TABLE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Row Limit", + "description": "Maximum number of rows to return. Leave empty for all.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_TABLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 10000 + }, + { + "name": "filterColumn", + "type": "table-column-selector", + "label": "Filter Column", + "description": "The column to filter on", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "QUERY_ROWS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "tableId" + ] + }, + { + "name": "filterOperator", + "type": "table-filter-operator", + "label": "Operator", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "QUERY_ROWS" + }, + "defaultValue": "equals", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "tableId", + "filterColumn" + ] + }, + { + "name": "filterValue", + "type": "table-filter-value", + "label": "Filter Value", + "description": "The value to filter by. Supports {{variable}} syntax.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "QUERY_ROWS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "tableId", + "filterColumn" + ] + }, + { + "name": "columnMappings", + "type": "table-column-mapper", + "label": "Map Columns", + "description": "Map values from earlier nodes or enter a fixed value for each table column.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ADD_ROW", + "UPDATE_ROW" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "tableId" + ] + }, + { + "name": "rowData", + "type": "code", + "label": "Row Data (JSON)", + "description": "JSON object mapping column names to values. Supports {{variable}} in string values. Use an array for bulk insert: [{\"col\": \"val\"}, ...]", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADD_ROW" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "rowId", + "type": "short-input", + "label": "Row ID", + "description": "The ID of the row to modify. Supports {{variable}} syntax.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_ROW", + "DELETE_ROW" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "updateData", + "type": "code", + "label": "Update Data (JSON)", + "description": "Advanced fallback: a JSON object with column values to update.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_ROW" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Read Table", + "value": "READ_TABLE", + "description": "Read all rows" + }, + { + "label": "Query Rows", + "value": "QUERY_ROWS", + "description": "Filter rows by column value" + }, + { + "label": "Add Row", + "value": "ADD_ROW", + "description": "Insert new row(s)" + }, + { + "label": "Update Row", + "value": "UPDATE_ROW", + "description": "Update an existing row" + }, + { + "label": "Delete Row", + "value": "DELETE_ROW", + "description": "Remove a row by ID" + } + ] + }, + { + "id": "utility-HTTP_REQUEST", + "category": "utility", + "nodeType": "HTTP_REQUEST", + "label": "API", + "description": "Send a request to any public HTTP API", + "contract": { + "contractVersion": 1, + "type": "HTTP_REQUEST", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the response in later nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "method", + "type": "dropdown", + "label": "Method", + "required": true, + "visible": true, + "options": [ + { + "id": "GET", + "label": "GET" + }, + { + "id": "POST", + "label": "POST" + }, + { + "id": "PUT", + "label": "PUT" + }, + { + "id": "PATCH", + "label": "PATCH" + }, + { + "id": "DELETE", + "label": "DELETE" + }, + { + "id": "HEAD", + "label": "HEAD" + }, + { + "id": "OPTIONS", + "label": "OPTIONS" + } + ], + "defaultValue": "GET", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "endpoint", + "type": "short-input", + "label": "URL", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "queryParams", + "type": "key-value", + "label": "Query parameters", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "authType", + "type": "dropdown", + "label": "Authorization", + "required": false, + "visible": true, + "options": [ + { + "id": "none", + "label": "None" + }, + { + "id": "bearer", + "label": "Bearer token" + }, + { + "id": "api-key", + "label": "API key" + }, + { + "id": "basic", + "label": "Basic auth" + } + ], + "defaultValue": "none", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bearerToken", + "type": "short-input", + "label": "Bearer token", + "description": "Select an encrypted Secret or a workflow variable.", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "bearer" + }, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "apiKeyName", + "type": "short-input", + "label": "API key name", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "api-key" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKeyValue", + "type": "short-input", + "label": "API key value", + "description": "Select an encrypted Secret or a workflow variable.", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "api-key" + }, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "apiKeyLocation", + "type": "dropdown", + "label": "Send API key in", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "api-key" + }, + "options": [ + { + "id": "header", + "label": "Header" + }, + { + "id": "query", + "label": "Query parameter" + } + ], + "defaultValue": "header", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "basicUsername", + "type": "short-input", + "label": "Username", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "basic" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "basicPassword", + "type": "short-input", + "label": "Password", + "description": "Select an encrypted Secret or a workflow variable.", + "required": false, + "visible": false, + "condition": { + "field": "authType", + "value": "basic" + }, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "headers", + "type": "key-value", + "label": "Headers", + "description": "Sensitive header values must use encrypted Secrets. Legacy JSON header objects remain supported.", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "bodyType", + "type": "dropdown", + "label": "Body", + "required": false, + "visible": false, + "condition": { + "field": "method", + "value": [ + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS" + ] + }, + "options": [ + { + "id": "none", + "label": "None" + }, + { + "id": "json", + "label": "JSON" + }, + { + "id": "text", + "label": "Text" + }, + { + "id": "form-urlencoded", + "label": "Form URL encoded" + } + ], + "defaultValue": "none", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Request body", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "formFields", + "type": "key-value", + "label": "Form fields", + "required": false, + "visible": false, + "condition": { + "field": "bodyType", + "value": "form-urlencoded" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timeoutMs", + "type": "number-input", + "label": "Timeout (milliseconds)", + "description": "Between 1 and 60 seconds", + "required": false, + "visible": true, + "defaultValue": 30000, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1000, + "max": 60000 + } + ], + "outputs": { + "httpResponse": { + "type": "object", + "description": "Structured HTTP response, including non-2xx responses", + "properties": { + "status": { + "type": "number", + "description": "HTTP status code" + }, + "statusText": { + "type": "string", + "description": "HTTP status text" + }, + "ok": { + "type": "boolean", + "description": "Whether the status is 2xx" + }, + "data": { + "type": "json", + "description": "Parsed JSON or text response body" + }, + "headers": { + "type": "json", + "description": "Response headers with secrets redacted" + }, + "url": { + "type": "string", + "description": "Final response URL" + }, + "contentType": { + "type": "string", + "description": "Response content type" + }, + "durationMs": { + "type": "number", + "description": "Request duration in milliseconds" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-WEBHOOK_ACTION", + "category": "utility", + "nodeType": "WEBHOOK_ACTION", + "label": "Webhook", + "description": "Send webhook events to external services", + "contract": { + "contractVersion": 1, + "type": "WEBHOOK_ACTION", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mode", + "type": "dropdown", + "label": "Mode", + "description": "Direct HTTP sends requests directly; Svix provides managed delivery with retries and logging", + "required": true, + "visible": true, + "options": [ + { + "id": "direct", + "label": "Direct HTTP" + }, + { + "id": "svix", + "label": "Svix (Managed)" + } + ], + "defaultValue": "direct", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "url", + "type": "short-input", + "label": "URL", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "direct" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "method", + "type": "dropdown", + "label": "Method", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "direct" + }, + "options": [ + { + "id": "GET", + "label": "GET" + }, + { + "id": "POST", + "label": "POST" + }, + { + "id": "PUT", + "label": "PUT" + }, + { + "id": "PATCH", + "label": "PATCH" + }, + { + "id": "DELETE", + "label": "DELETE" + } + ], + "defaultValue": "POST", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "headers", + "type": "long-input", + "label": "Headers", + "description": "JSON object with header key-value pairs", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "direct" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "svixAppId", + "type": "short-input", + "label": "Svix App ID", + "description": "Your Svix application ID", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "svix" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventType", + "type": "dropdown", + "label": "Event Type", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "svix" + }, + "options": [ + { + "id": "workflow.completed", + "label": "Workflow Completed" + }, + { + "id": "workflow.failed", + "label": "Workflow Failed" + }, + { + "id": "workflow.step.completed", + "label": "Step Completed" + }, + { + "id": "custom", + "label": "Custom" + } + ], + "defaultValue": "workflow.completed", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Body / Payload", + "description": "JSON payload to send with the webhook", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "status": { + "type": "number", + "description": "HTTP status code" + }, + "data": { + "type": "json", + "description": "Response body" + }, + "success": { + "type": "boolean", + "description": "Whether the request succeeded" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-SLEEP", + "category": "utility", + "nodeType": "SLEEP", + "label": "Wait", + "description": "Pause for a duration or until a specific time", + "contract": { + "contractVersion": 1, + "type": "SLEEP", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mode", + "type": "dropdown", + "label": "Wait Until", + "required": true, + "visible": true, + "options": [ + { + "id": "duration", + "label": "A duration" + }, + { + "id": "until", + "label": "A date and time" + } + ], + "defaultValue": "duration", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "duration", + "type": "time-input", + "label": "Duration", + "description": "Supported units: seconds, minutes, hours, days, weeks", + "required": true, + "visible": false, + "condition": { + "field": "mode", + "value": "duration" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "untilAt", + "type": "datetime-input", + "label": "Date and Time", + "description": "Uses your browser's local timezone and stores the instant in the workflow", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "until" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "duration": { + "type": "string", + "description": "The configured duration" + }, + "startedAt": { + "type": "string", + "description": "ISO timestamp when sleep started" + }, + "completedAt": { + "type": "string", + "description": "ISO timestamp when sleep completed" + }, + "actualDurationMs": { + "type": "number", + "description": "Actual duration in milliseconds" + }, + "targetAt": { + "type": "string", + "description": "Resolved target timestamp" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-HUMAN_APPROVAL", + "category": "utility", + "nodeType": "HUMAN_APPROVAL", + "label": "Human Approval", + "description": "Pause until a selected workspace member approves or rejects", + "contract": { + "contractVersion": 1, + "type": "HUMAN_APPROVAL", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Approval Title", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "instructions", + "type": "long-input", + "label": "Instructions", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reviewerUserIds", + "type": "member-selector", + "label": "Reviewers", + "description": "The first selected reviewer to respond resolves the request", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false + }, + { + "name": "timeout", + "type": "time-input", + "label": "Timeout", + "required": true, + "visible": true, + "defaultValue": "7 days", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "deliveryChannels", + "type": "checkbox-list", + "label": "Additional Notifications", + "description": "Inbox notifications are always created", + "required": false, + "visible": true, + "options": [ + { + "id": "EMAIL", + "label": "Email reviewers" + }, + { + "id": "SLACK", + "label": "Slack channel" + }, + { + "id": "TEAMS", + "label": "Microsoft Teams channel" + } + ], + "defaultValue": [], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "slackAccountId", + "type": "oauth-input", + "label": "Slack Account", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "slack" + }, + { + "name": "slackChannelId", + "type": "slack-channel-selector", + "label": "Slack Channel", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "slackAccountId" + ] + }, + { + "name": "teamsConnectionId", + "type": "oauth-input", + "label": "Teams Account", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_teams" + }, + { + "name": "teamsTeamId", + "type": "short-input", + "label": "Teams Team ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "teamsChannelId", + "type": "short-input", + "label": "Teams Channel ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "status": { + "type": "string" + }, + "requestId": { + "type": "string" + }, + "respondedAt": { + "type": "string" + }, + "respondedByUserId": { + "type": "string" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "approved", + "rejected", + "timed-out" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-WAIT_FOR_EVENT", + "category": "utility", + "nodeType": "WAIT_FOR_EVENT", + "label": "Wait for Event", + "description": "Pause until a unique callback URL receives an event", + "contract": { + "contractVersion": 1, + "type": "WAIT_FOR_EVENT", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Event Name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timeout", + "type": "time-input", + "label": "Timeout", + "required": true, + "visible": true, + "defaultValue": "7 days", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recipientUserIds", + "type": "member-selector", + "label": "Additional Inbox Recipients", + "description": "The workflow owner always receives the callback URL", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false + }, + { + "name": "deliveryChannels", + "type": "checkbox-list", + "label": "Additional Notifications", + "required": false, + "visible": true, + "options": [ + { + "id": "EMAIL", + "label": "Email recipients" + }, + { + "id": "SLACK", + "label": "Slack channel" + }, + { + "id": "TEAMS", + "label": "Microsoft Teams channel" + } + ], + "defaultValue": [], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "slackAccountId", + "type": "oauth-input", + "label": "Slack Account", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "slack" + }, + { + "name": "slackChannelId", + "type": "slack-channel-selector", + "label": "Slack Channel", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "slackAccountId" + ] + }, + { + "name": "teamsConnectionId", + "type": "oauth-input", + "label": "Teams Account", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_teams" + }, + { + "name": "teamsTeamId", + "type": "short-input", + "label": "Teams Team ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "teamsChannelId", + "type": "short-input", + "label": "Teams Channel ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "status": { + "type": "string" + }, + "requestId": { + "type": "string" + }, + "receivedAt": { + "type": "string" + }, + "payload": { + "type": "json" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "received", + "timed-out" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-CONDITION", + "category": "utility", + "nodeType": "CONDITION", + "label": "Condition", + "description": "Branch workflow based on a condition (If/Else)", + "contract": { + "contractVersion": 1, + "type": "CONDITION", + "operations": [], + "fields": [ + { + "name": "branches", + "type": "array", + "required": true, + "defaultValue": [ + { + "id": "if", + "type": "if", + "name": "If matched" + }, + { + "id": "else", + "type": "else", + "name": "Otherwise" + } + ], + "readOnly": true + }, + { + "name": "schemaVersion", + "type": "number", + "required": true, + "defaultValue": 2 + }, + { + "name": "conditionType", + "type": "string", + "required": true, + "defaultValue": "rule" + }, + { + "name": "combinator", + "type": "string", + "required": true, + "options": [ + { + "id": "and", + "label": "All rules" + }, + { + "id": "or", + "label": "Any rule" + } + ] + }, + { + "name": "predicates", + "type": "array", + "required": true, + "description": "Use configureCondition for typed comparison rules." + } + ], + "outputs": { + "result": { + "type": "boolean", + "description": "Whether the matched branch evaluated to true" + }, + "matched": { + "type": "boolean", + "description": "Whether a non-fallback branch matched" + }, + "isFallback": { + "type": "boolean", + "description": "Whether the Else branch was selected" + }, + "branch": { + "type": "string", + "description": "The ID of the matched branch" + }, + "branchType": { + "type": "string", + "description": "if, else-if, or else" + }, + "reasoning": { + "type": "string", + "description": "LLM reasoning for the chosen branch (LLM mode only)" + }, + "evaluatedAt": { + "type": "string", + "description": "ISO timestamp" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "if", + "else" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-ROUTER", + "category": "utility", + "nodeType": "ROUTER", + "label": "Router", + "description": "AI-powered routing with multiple dynamic branches", + "contract": { + "contractVersion": 1, + "type": "ROUTER", + "operations": [], + "fields": [ + { + "name": "context", + "type": "long-input", + "label": "Context", + "description": "The context to analyze for routing decision", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "routes", + "type": "condition-input", + "label": "routes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "model", + "type": "dropdown", + "label": "Model", + "description": "AI model to use for routing decision", + "required": true, + "visible": true, + "options": [ + { + "id": "default", + "label": "Default" + }, + { + "id": "fastest", + "label": "Fastest" + }, + { + "id": "balanced", + "label": "Balanced" + }, + { + "id": "smartest", + "label": "Smartest" + }, + { + "id": "gpt-5.6-sol", + "label": "OpenAI 5.6 Sol" + }, + { + "id": "gpt-5.5", + "label": "GPT-5.5" + }, + { + "id": "gpt-5.4", + "label": "GPT-5.4" + }, + { + "id": "gpt-5.4-mini", + "label": "GPT-5.4 Mini" + }, + { + "id": "gpt-5.4-nano", + "label": "GPT-5.4 Nano" + }, + { + "id": "gpt-4.1", + "label": "GPT-4.1" + }, + { + "id": "gpt-4.1-mini", + "label": "GPT-4.1 Mini" + }, + { + "id": "gpt-4o", + "label": "GPT-4o" + }, + { + "id": "gpt-4o-mini", + "label": "GPT-4o Mini" + }, + { + "id": "claude-fable-5", + "label": "Claude Fable 5" + }, + { + "id": "claude-opus-5", + "label": "Opus 5" + }, + { + "id": "claude-sonnet-5", + "label": "Claude Sonnet 5" + }, + { + "id": "claude-opus-4-8", + "label": "Claude Opus 4.8" + }, + { + "id": "claude-haiku-4-5-20251001", + "label": "Claude Haiku 4.5" + }, + { + "id": "gemini-3.7-flash", + "label": "Gemini 3.7 Flash" + }, + { + "id": "gemini-3.6-flash", + "label": "Gemini 3.6 Flash" + }, + { + "id": "gemini-3.5-flash", + "label": "Gemini 3.5 Flash" + }, + { + "id": "gemini-3.5-flash-lite", + "label": "Gemini 3.5 Flash Lite" + }, + { + "id": "gemini-3.1-pro-preview", + "label": "Gemini 3.1 Pro" + }, + { + "id": "gemini-2.5-flash", + "label": "Gemini 2.5 Flash" + }, + { + "id": "gemini-2.5-pro", + "label": "Gemini 2.5 Pro" + }, + { + "id": "deepseek-v4-pro", + "label": "DeepSeek V4 Pro" + }, + { + "id": "deepseek-flash", + "label": "DeepSeek V4.1 Flash" + } + ], + "defaultValue": "default", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "selectedRoute": { + "type": "string", + "description": "The chosen route ID" + }, + "parsedContext": { + "type": "string", + "description": "Resolved context" + }, + "model": { + "type": "string", + "description": "Model used" + }, + "routedAt": { + "type": "string", + "description": "ISO timestamp" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-LABEL_FIELDS", + "category": "utility", + "nodeType": "LABEL_FIELDS", + "label": "Label Fields", + "description": "AI-powered extraction of structured data from unstructured input", + "contract": { + "contractVersion": 1, + "type": "LABEL_FIELDS", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "inputSource", + "type": "long-input", + "label": "Input Source", + "description": "The data to extract fields from. Use {{variable}} to reference upstream data.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fields", + "type": "code", + "label": "Fields to Extract", + "description": "Define fields as JSON array. Types: string, number, boolean, array, json.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "model", + "type": "dropdown", + "label": "AI Model", + "description": "Select the AI model for extraction", + "required": false, + "visible": true, + "options": [ + { + "id": "default", + "label": "Default (GPT-5.4 Mini)" + }, + { + "id": "gpt-5.6-sol", + "label": "OpenAI 5.6 Sol" + }, + { + "id": "gpt-5.5", + "label": "GPT-5.5" + }, + { + "id": "gpt-5.4", + "label": "GPT-5.4" + }, + { + "id": "gpt-5.4-mini", + "label": "GPT-5.4 Mini" + }, + { + "id": "gpt-5.4-nano", + "label": "GPT-5.4 Nano" + }, + { + "id": "gpt-4o", + "label": "GPT-4o" + }, + { + "id": "gpt-4o-mini", + "label": "GPT-4o mini" + }, + { + "id": "claude-fable-5", + "label": "Claude Fable 5" + }, + { + "id": "claude-opus-5", + "label": "Opus 5" + }, + { + "id": "claude-sonnet-5", + "label": "Claude Sonnet 5" + }, + { + "id": "claude-opus-4-8", + "label": "Claude Opus 4.8" + }, + { + "id": "claude-haiku-4-5-20251001", + "label": "Claude Haiku 4.5" + }, + { + "id": "gemini-3.7-flash", + "label": "Gemini 3.7 Flash" + }, + { + "id": "gemini-3.6-flash", + "label": "Gemini 3.6 Flash" + }, + { + "id": "gemini-3.5-flash", + "label": "Gemini 3.5 Flash" + }, + { + "id": "gemini-3.5-flash-lite", + "label": "Gemini 3.5 Flash Lite" + }, + { + "id": "gemini-3.1-pro-preview", + "label": "Gemini 3.1 Pro" + }, + { + "id": "gemini-2.5-pro", + "label": "Gemini 2.5 Pro" + }, + { + "id": "gemini-2.5-flash", + "label": "Gemini 2.5 Flash" + }, + { + "id": "deepseek-v4-pro", + "label": "DeepSeek V4 Pro" + }, + { + "id": "deepseek-flash", + "label": "DeepSeek V4.1 Flash" + } + ], + "defaultValue": "default", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "instructions", + "type": "long-input", + "label": "Additional Instructions", + "description": "Optional guidance for the AI on how to extract fields", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "extractedData": { + "type": "object", + "description": "Extracted field values as an object", + "properties": {} + }, + "usage": { + "type": "object", + "description": "Token usage metadata from the AI model", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-TRANSFORM_ARRAY", + "category": "utility", + "nodeType": "TRANSFORM_ARRAY", + "label": "Transform Array", + "description": "Map, filter, or reduce arrays for data transformation", + "contract": { + "contractVersion": 1, + "type": "TRANSFORM_ARRAY", + "operations": [ + { + "value": "MAP", + "label": "Map", + "description": "Transform each item into a new shape" + }, + { + "value": "FILTER", + "label": "Filter", + "description": "Keep only items matching a condition" + }, + { + "value": "REDUCE", + "label": "Reduce", + "description": "Aggregate items into a single value" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "inputArray", + "type": "long-input", + "label": "Input Array", + "description": "The array to transform. Use {{variable}} to reference upstream data.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose how to transform the array", + "required": true, + "visible": true, + "options": [ + { + "id": "map", + "label": "Map — Transform each item" + }, + { + "id": "filter", + "label": "Filter — Keep matching items" + }, + { + "id": "reduce", + "label": "Reduce — Aggregate into single value" + } + ], + "defaultValue": "map", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mapExpression", + "type": "long-input", + "label": "Transform Expression", + "description": "Use {{item}} for current item, {{index}} for position", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "map" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filterField", + "type": "short-input", + "label": "Filter Field", + "description": "Field path to filter on", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "filter" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filterOperator", + "type": "dropdown", + "label": "Operator", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "filter" + }, + "options": [ + { + "id": "equals", + "label": "Equals" + }, + { + "id": "not_equals", + "label": "Not Equals" + }, + { + "id": "contains", + "label": "Contains" + }, + { + "id": "not_contains", + "label": "Not Contains" + }, + { + "id": "gt", + "label": "Greater Than" + }, + { + "id": "gte", + "label": "Greater Than or Equal" + }, + { + "id": "lt", + "label": "Less Than" + }, + { + "id": "lte", + "label": "Less Than or Equal" + }, + { + "id": "exists", + "label": "Exists (not null/undefined)" + }, + { + "id": "not_exists", + "label": "Does Not Exist" + } + ], + "defaultValue": "equals", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filterValue", + "type": "short-input", + "label": "Value", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reduceType", + "type": "dropdown", + "label": "Reduce Type", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "reduce" + }, + "options": [ + { + "id": "sum", + "label": "Sum — Add up numeric values" + }, + { + "id": "count", + "label": "Count — Count number of items" + }, + { + "id": "concat", + "label": "Concatenate — Join values together" + }, + { + "id": "first", + "label": "First — Get first item" + }, + { + "id": "last", + "label": "Last — Get last item" + }, + { + "id": "min", + "label": "Minimum — Get smallest value" + }, + { + "id": "max", + "label": "Maximum — Get largest value" + }, + { + "id": "custom", + "label": "Custom — Write custom expression" + } + ], + "defaultValue": "count", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reduceField", + "type": "short-input", + "label": "Field to Aggregate", + "description": "The field from each item to aggregate", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reduceInitial", + "type": "short-input", + "label": "Initial Value", + "description": "Starting value for the accumulator (JSON or string)", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reduceExpression", + "type": "long-input", + "label": "Reduce Expression", + "description": "Use {{accumulator}} for running value, {{item}} for current item", + "required": true, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "errorHandling", + "type": "dropdown", + "label": "Error Handling", + "description": "How to handle errors during transformation", + "required": false, + "visible": true, + "options": [ + { + "id": "continue", + "label": "Continue — Collect partial results" + }, + { + "id": "fail", + "label": "Fail — Stop on first error" + } + ], + "defaultValue": "continue", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Transformed array or aggregated value" + }, + "processedCount": { + "type": "number", + "description": "Number of items processed" + }, + "errorCount": { + "type": "number", + "description": "Number of errors encountered" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Map", + "value": "MAP", + "description": "Transform each item into a new shape" + }, + { + "label": "Filter", + "value": "FILTER", + "description": "Keep only items matching a condition" + }, + { + "label": "Reduce", + "value": "REDUCE", + "description": "Aggregate items into a single value" + } + ] + }, + { + "id": "utility-LOOP", + "category": "utility", + "nodeType": "LOOP", + "label": "Loop", + "description": "Run connected nodes once for each item in an array", + "contract": { + "contractVersion": 1, + "type": "LOOP", + "operations": [], + "fields": [ + { + "name": "inputArray", + "type": "long-input", + "label": "Items", + "description": "The array whose items should run through the loop body.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "resultExpression", + "type": "long-input", + "label": "Result", + "description": "Evaluated after each body run. When empty, the current item is collected.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "errorHandling", + "type": "dropdown", + "label": "If an item fails", + "required": true, + "visible": true, + "options": [ + { + "id": "continue", + "label": "Continue and collect the error" + }, + { + "id": "stop", + "label": "Stop the loop and fail the workflow" + } + ], + "defaultValue": "continue", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxIterations", + "type": "number-input", + "label": "Maximum iterations", + "description": "Must be between 1 and 1,000.", + "required": true, + "visible": true, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 1000 + } + ], + "outputs": { + "current": { + "type": "json", + "description": "Current iteration metadata; null after completion", + "properties": { + "item": { + "type": "json", + "description": "Current array item" + }, + "index": { + "type": "number", + "description": "Zero-based item index" + }, + "number": { + "type": "number", + "description": "One-based iteration number" + }, + "total": { + "type": "number", + "description": "Total number of items" + }, + "isFirst": { + "type": "boolean", + "description": "Whether this is the first item" + }, + "isLast": { + "type": "boolean", + "description": "Whether this is the final item" + } + } + }, + "results": { + "type": "array", + "description": "Per-item success values and errors", + "items": { + "type": "json", + "description": "Loop result entry" + } + }, + "summary": { + "type": "json", + "description": "Loop processing counts", + "properties": { + "total": { + "type": "number", + "description": "Input item count" + }, + "processed": { + "type": "number", + "description": "Processed item count" + }, + "succeeded": { + "type": "number", + "description": "Successful item count" + }, + "failed": { + "type": "number", + "description": "Failed item count" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "body", + "done" + ], + "targets": [ + "target-1", + "continue" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-CSV_EXPORT", + "category": "utility", + "nodeType": "CSV_EXPORT", + "label": "CSV Export", + "description": "Convert arrays of data into CSV format", + "contract": { + "contractVersion": 1, + "type": "CSV_EXPORT", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "dataSource", + "type": "long-input", + "label": "Data Source", + "description": "The array of objects to convert to CSV. Use {{variable}} to reference upstream data.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeHeaders", + "type": "switch", + "label": "Include Headers", + "description": "Include column headers as the first row of the CSV", + "required": false, + "visible": true, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "delimiter", + "type": "dropdown", + "label": "Delimiter", + "description": "Character used to separate values in each row", + "required": false, + "visible": true, + "options": [ + { + "id": ",", + "label": "Comma (,)" + }, + { + "id": ";", + "label": "Semicolon (;)" + }, + { + "id": "\t", + "label": "Tab" + } + ], + "defaultValue": ",", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileName", + "type": "short-input", + "label": "File Name", + "description": "Informational label for the exported file (without .csv extension)", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "csv": { + "type": "string", + "description": "CSV string output" + }, + "rowCount": { + "type": "number", + "description": "Number of rows" + }, + "fileName": { + "type": "string", + "description": "File name with .csv extension" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "utility-CODE", + "category": "utility", + "nodeType": "CODE", + "label": "Code", + "description": "Execute JavaScript, Python, or Java code in a secure sandbox", + "contract": { + "contractVersion": 1, + "type": "CODE", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output in downstream nodes (e.g. {{code.result}})", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "language", + "type": "dropdown", + "label": "Language", + "description": "Select the programming language for your code. Python is the default and recommended option.", + "required": true, + "visible": true, + "options": [ + { + "id": "python", + "label": "Python" + }, + { + "id": "javascript", + "label": "JavaScript" + }, + { + "id": "java", + "label": "Java" + } + ], + "defaultValue": "python", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "code", + "type": "code", + "label": "Code", + "description": "Write your code here. Use the 'context' variable to access upstream workflow data. The last expression value is captured as the result. Python runs as a script: use return only inside functions. For structured output, import json and end with print(json.dumps(result)).", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timeout", + "type": "number-input", + "label": "Timeout (seconds)", + "description": "Maximum execution time in seconds (1-300). Default: 30s", + "required": false, + "visible": true, + "defaultValue": 30, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 300 + }, + { + "name": "outputFields", + "type": "code", + "label": "Output Fields", + "description": "Optional declarations used to expose object fields downstream before execution.", + "required": false, + "visible": true, + "defaultValue": "[]", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "object", + "description": "Return value of the last expression", + "properties": {} + }, + "stdout": { + "type": "string", + "description": "Standard output" + }, + "stderr": { + "type": "string", + "description": "Standard error" + }, + "language": { + "type": "string", + "description": "Execution language" + }, + "executedAt": { + "type": "string", + "description": "Execution timestamp" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-AI_MODEL", + "category": "tools", + "nodeType": "AI_MODEL", + "label": "OpenRouter", + "description": "Access 200+ AI models via OpenRouter (GPT, Claude, Llama, Gemini & more)", + "contract": { + "contractVersion": 1, + "type": "AI_MODEL", + "operations": [ + { + "value": "GENERATE_TEXT", + "label": "Generate Text", + "description": "Generate text using any of 200+ AI models via OpenRouter" + } + ], + "fields": [ + { + "name": "variableName", + "type": "string", + "required": true, + "description": "Variable name to store output" + }, + { + "name": "model", + "type": "string", + "required": true, + "description": "OpenRouter model ID (e.g. openai/gpt-4o, anthropic/claude-sonnet-5)" + }, + { + "name": "messages", + "type": "array", + "required": true, + "description": "Chat messages (system, user, assistant)" + }, + { + "name": "apiKey", + "type": "string", + "description": "OpenRouter API key (optional — platform key used as fallback)" + }, + { + "name": "temperature", + "type": "number", + "description": "Temperature 0-2 (default 0.7)" + }, + { + "name": "maxTokens", + "type": "number", + "description": "Maximum output tokens (default 4096)" + }, + { + "name": "jsonMode", + "type": "boolean", + "description": "Enable JSON output mode" + }, + { + "name": "systemPrompt", + "type": "string", + "description": "Custom system prompt" + } + ], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + }, + "model": { + "type": "string" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Generate Text", + "value": "GENERATE_TEXT", + "description": "Generate text using any of 200+ AI models via OpenRouter" + } + ] + }, + { + "id": "tool-OPENAI", + "category": "tools", + "nodeType": "OPENAI", + "label": "OpenAI", + "description": "Uses OpenAI to generate text", + "contract": { + "contractVersion": 1, + "type": "OPENAI", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "string", + "required": true, + "description": "Variable name to store output", + "aiSettable": true + }, + { + "name": "messages", + "type": "array", + "required": true, + "description": "Chat messages (system, user, assistant)", + "aiSettable": true + }, + { + "name": "model", + "type": "string", + "enum": [ + "gpt-5.6-sol", + "gpt-5.5", + "gpt-5.4-mini", + "gpt-5.4", + "gpt-4o", + "gpt-4o-mini" + ], + "description": "Model to use", + "aiSettable": true + } + ], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-GEMINI", + "category": "tools", + "nodeType": "GEMINI", + "label": "Gemini", + "description": "Uses Google Gemini to generate text", + "contract": { + "contractVersion": 1, + "type": "GEMINI", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "string", + "required": true, + "description": "Variable name to store output" + }, + { + "name": "messages", + "type": "array", + "required": true, + "description": "Chat messages" + }, + { + "name": "model", + "type": "string", + "enum": [ + "gemini-3.7-flash", + "gemini-3.6-flash", + "gemini-3.5-flash", + "gemini-3.5-flash-lite", + "gemini-3.1-pro-preview", + "gemini-2.5-flash", + "gemini-2.5-pro" + ], + "description": "Model to use" + } + ], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-ANTHROPIC", + "category": "tools", + "nodeType": "ANTHROPIC", + "label": "Anthropic", + "description": "Uses Anthropic to generate text", + "contract": { + "contractVersion": 1, + "type": "ANTHROPIC", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "string", + "required": true, + "description": "Variable name to store output" + }, + { + "name": "messages", + "type": "array", + "required": true, + "description": "Chat messages" + }, + { + "name": "model", + "type": "string", + "enum": [ + "claude-fable-5", + "claude-opus-5", + "claude-sonnet-5", + "claude-opus-4-8", + "claude-haiku-4-5-20251001" + ], + "description": "Model to use" + } + ], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-DEEPSEEK", + "category": "tools", + "nodeType": "DEEPSEEK", + "label": "DeepSeek", + "description": "Uses DeepSeek to generate text", + "contract": { + "contractVersion": 1, + "type": "DEEPSEEK", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "string", + "required": true, + "description": "Variable name to store output" + }, + { + "name": "messages", + "type": "array", + "required": true, + "description": "Chat messages" + }, + { + "name": "model", + "type": "string", + "enum": [ + "deepseek-v4-pro", + "deepseek-flash" + ], + "description": "Model to use" + } + ], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-KIMI", + "category": "tools", + "nodeType": "KIMI", + "label": "Kimi", + "description": "Uses Kimi (Moonshot AI) to generate text", + "contract": { + "contractVersion": 1, + "type": "KIMI", + "operations": [], + "fields": [], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "setupRequired": "Inspect this node in the editor; no editable field contract is available. Do not guess fields." + }, + "operations": [] + }, + { + "id": "tool-GROK", + "category": "tools", + "nodeType": "GROK", + "label": "Grok", + "description": "Uses Grok (xAI) to generate text", + "contract": { + "contractVersion": 1, + "type": "GROK", + "operations": [], + "fields": [], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "setupRequired": "Inspect this node in the editor; no editable field contract is available. Do not guess fields." + }, + "operations": [] + }, + { + "id": "tool-QWEN", + "category": "tools", + "nodeType": "QWEN", + "label": "Qwen", + "description": "Uses Qwen (Alibaba Cloud) to generate text", + "contract": { + "contractVersion": 1, + "type": "QWEN", + "operations": [], + "fields": [], + "outputs": { + "text": { + "type": "string", + "description": "Generated response text" + }, + "usage": { + "type": "object", + "properties": { + "inputTokens": { + "type": "number" + }, + "outputTokens": { + "type": "number" + }, + "totalTokens": { + "type": "number" + } + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none", + "setupRequired": "Inspect this node in the editor; no editable field contract is available. Do not guess fields." + }, + "operations": [] + }, + { + "id": "tool-TAVILY_SEARCH", + "category": "tools", + "nodeType": "TAVILY_SEARCH", + "label": "Tavily", + "description": "Search the web for real-time information", + "contract": { + "contractVersion": 1, + "type": "TAVILY_SEARCH", + "operations": [ + { + "value": "SEARCH", + "label": "Search" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Tavily API key - set in Settings > BYOK, Settings > Environment, or paste directly", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "search_depth", + "type": "dropdown", + "label": "Search Depth", + "required": false, + "visible": true, + "options": [ + { + "id": "basic", + "label": "Basic" + }, + { + "id": "advanced", + "label": "Advanced" + } + ], + "defaultValue": "basic", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "max_results", + "type": "short-input", + "label": "Max Results", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "topic", + "type": "dropdown", + "label": "Topic", + "required": false, + "visible": true, + "options": [ + { + "id": "general", + "label": "General" + }, + { + "id": "news", + "label": "News" + }, + { + "id": "finance", + "label": "Finance" + } + ], + "defaultValue": "general", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "include_answer", + "type": "dropdown", + "label": "Include Answer", + "required": false, + "visible": true, + "options": [ + { + "id": "", + "label": "None" + }, + { + "id": "basic", + "label": "Basic" + }, + { + "id": "advanced", + "label": "Advanced" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "include_images", + "type": "switch", + "label": "Include Images", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "time_range", + "type": "dropdown", + "label": "Time Range", + "required": false, + "visible": true, + "options": [ + { + "id": "", + "label": "All Time" + }, + { + "id": "d", + "label": "Day" + }, + { + "id": "w", + "label": "Week" + }, + { + "id": "m", + "label": "Month" + }, + { + "id": "y", + "label": "Year" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "include_domains", + "type": "long-input", + "label": "Include Domains", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "exclude_domains", + "type": "long-input", + "label": "Exclude Domains", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "query": { + "type": "string", + "description": "Search query used" + }, + "results": { + "type": "json", + "description": "Search results data" + }, + "answer": { + "type": "string", + "description": "LLM-generated answer" + }, + "images": { + "type": "array", + "description": "Image URLs" + }, + "response_time": { + "type": "number", + "description": "Request duration in seconds" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Search", + "value": "SEARCH", + "description": "" + } + ] + }, + { + "id": "tool-EXA", + "category": "tools", + "nodeType": "EXA", + "label": "Exa", + "description": "AI-powered web search with neural, keyword, and similarity modes", + "contract": { + "contractVersion": 1, + "type": "EXA", + "operations": [ + { + "value": "SEARCH", + "label": "Search", + "description": "Search the web with neural/keyword search" + }, + { + "value": "FIND_SIMILAR", + "label": "Find Similar", + "description": "Find pages similar to a URL" + }, + { + "value": "GET_CONTENTS", + "label": "Get Contents", + "description": "Retrieve full page content" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Exa API key - set in Settings > BYOK, Settings > Environment, or paste directly", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEARCH", + "label": "Search" + }, + { + "id": "FIND_SIMILAR", + "label": "Find Similar" + }, + { + "id": "GET_CONTENTS", + "label": "Get Contents" + } + ], + "defaultValue": "SEARCH", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchType", + "type": "dropdown", + "label": "Search Type", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "options": [ + { + "id": "auto", + "label": "Auto" + }, + { + "id": "neural", + "label": "Neural" + }, + { + "id": "keyword", + "label": "Keyword" + } + ], + "defaultValue": "auto", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "category", + "type": "dropdown", + "label": "Category Filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "options": [ + { + "id": "all", + "label": "All" + }, + { + "id": "company", + "label": "Company" + }, + { + "id": "research paper", + "label": "Research Paper" + }, + { + "id": "news", + "label": "News" + }, + { + "id": "pdf", + "label": "PDF" + }, + { + "id": "github", + "label": "GitHub" + }, + { + "id": "tweet", + "label": "Tweet" + }, + { + "id": "personal site", + "label": "Personal Site" + }, + { + "id": "linkedin profile", + "label": "LinkedIn Profile" + } + ], + "defaultValue": "all", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "useAutoprompt", + "type": "switch", + "label": "Use Autoprompt", + "description": "Let Exa optimize your query for better results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "url", + "type": "short-input", + "label": "Source URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "FIND_SIMILAR" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "excludeSourceDomain", + "type": "switch", + "label": "Exclude Source Domain", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "FIND_SIMILAR" + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "urls", + "type": "long-input", + "label": "URLs", + "description": "Comma or newline separated URLs (max 100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_CONTENTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "summaryQuery", + "type": "short-input", + "label": "Summary Focus", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "numResults", + "type": "number-input", + "label": "Number of Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH", + "FIND_SIMILAR" + ] + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + }, + { + "name": "includeDomains", + "type": "short-input", + "label": "Include Domains", + "description": "Comma-separated list of domains to limit results to", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH", + "FIND_SIMILAR" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "excludeDomains", + "type": "short-input", + "label": "Exclude Domains", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH", + "FIND_SIMILAR" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "startPublishedDate", + "type": "date-picker", + "label": "Published After", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "endPublishedDate", + "type": "date-picker", + "label": "Published Before", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeHighlights", + "type": "switch", + "label": "Include Highlights", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH", + "FIND_SIMILAR", + "GET_CONTENTS" + ] + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeText", + "type": "switch", + "label": "Include Full Text", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeSummary", + "type": "switch", + "label": "Include AI Summary", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH", + "GET_CONTENTS" + ] + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "results": { + "type": "array", + "description": "Search/content results" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Search", + "value": "SEARCH", + "description": "Search the web with neural/keyword search" + }, + { + "label": "Find Similar", + "value": "FIND_SIMILAR", + "description": "Find pages similar to a URL" + }, + { + "label": "Get Contents", + "value": "GET_CONTENTS", + "description": "Retrieve full page content" + } + ] + }, + { + "id": "tool-PERPLEXITY", + "category": "tools", + "nodeType": "PERPLEXITY", + "label": "Perplexity", + "description": "AI-powered search and research with real-time web access", + "contract": { + "contractVersion": 1, + "type": "PERPLEXITY", + "operations": [ + { + "value": "ASK", + "label": "Ask Question", + "description": "Ask a question with real-time web search" + }, + { + "value": "RESEARCH", + "label": "Research", + "description": "Multi-step research with follow-up questions" + }, + { + "value": "FACT_CHECK", + "label": "Fact Check", + "description": "Verify a claim against web sources" + } + ], + "fields": [ + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Perplexity API key - set in Settings > BYOK, Settings > Environment, or paste directly", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "ASK", + "label": "Ask Question" + }, + { + "id": "RESEARCH", + "label": "Research" + }, + { + "id": "FACT_CHECK", + "label": "Fact Check" + } + ], + "defaultValue": "ASK", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "model", + "type": "dropdown", + "label": "Model", + "required": false, + "visible": true, + "options": [ + { + "id": "sonar", + "label": "Sonar" + }, + { + "id": "sonar-small", + "label": "Sonar Small" + }, + { + "id": "sonar-medium", + "label": "Sonar Medium" + }, + { + "id": "sonar-pro", + "label": "Sonar Pro" + } + ], + "defaultValue": "sonar", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "prompt", + "type": "long-input", + "label": "Prompt", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "systemPrompt", + "type": "long-input", + "label": "System Prompt", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchDomainFilter", + "type": "short-input", + "label": "Search Domain Filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchRecencyFilter", + "type": "dropdown", + "label": "Search Recency Filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASK" + }, + "options": [ + { + "id": "none", + "label": "None" + }, + { + "id": "day", + "label": "Day" + }, + { + "id": "week", + "label": "Week" + }, + { + "id": "month", + "label": "Month" + }, + { + "id": "year", + "label": "Year" + } + ], + "defaultValue": "none", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "temperature", + "type": "number-input", + "label": "Temperature", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASK" + }, + "defaultValue": 0.2, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0, + "max": 2 + }, + { + "name": "initialQuestion", + "type": "long-input", + "label": "Initial Question", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RESEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "followUpQuestions", + "type": "long-input", + "label": "Follow-Up Questions", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RESEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "claim", + "type": "long-input", + "label": "Claim", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "FACT_CHECK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "response": { + "type": "string", + "description": "Perplexity response text" + }, + "citations": { + "type": "array", + "description": "Source citations" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Ask Question", + "value": "ASK", + "description": "Ask a question with real-time web search" + }, + { + "label": "Research", + "value": "RESEARCH", + "description": "Multi-step research with follow-up questions" + }, + { + "label": "Fact Check", + "value": "FACT_CHECK", + "description": "Verify a claim against web sources" + } + ] + }, + { + "id": "tool-FIRECRAWL", + "category": "tools", + "nodeType": "FIRECRAWL", + "label": "Firecrawl", + "description": "Scrape, search, crawl, map, extract, and agent-browse the web", + "contract": { + "contractVersion": 1, + "type": "FIRECRAWL", + "operations": [ + { + "value": "SCRAPE", + "label": "Scrape", + "description": "Scrape a single URL and extract content" + }, + { + "value": "SEARCH", + "label": "Search", + "description": "Search the web for relevant pages" + }, + { + "value": "CRAWL", + "label": "Crawl", + "description": "Crawl a website following links from a start URL" + }, + { + "value": "MAP", + "label": "Map", + "description": "Discover all linked pages from a URL" + }, + { + "value": "EXTRACT", + "label": "Extract", + "description": "Extract structured data from web pages using AI" + }, + { + "value": "AGENT", + "label": "Agent", + "description": "AI agent that navigates and interacts with websites" + } + ], + "fields": [ + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Firecrawl API key -- set in Settings > BYOK, Settings > Environment, or paste directly", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SCRAPE", + "label": "Scrape" + }, + { + "id": "SEARCH", + "label": "Search" + }, + { + "id": "CRAWL", + "label": "Crawl" + }, + { + "id": "MAP", + "label": "Map" + }, + { + "id": "EXTRACT", + "label": "Extract" + }, + { + "id": "AGENT", + "label": "Agent" + } + ], + "defaultValue": "SCRAPE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "url", + "type": "short-input", + "label": "URL", + "description": "The URL to scrape", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "formats", + "type": "checkbox-list", + "label": "Output Formats", + "description": "Choose which formats to include in the output", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "options": [ + { + "id": "markdown", + "label": "Markdown" + }, + { + "id": "html", + "label": "HTML" + }, + { + "id": "rawHtml", + "label": "Raw HTML" + }, + { + "id": "links", + "label": "Links" + }, + { + "id": "screenshot", + "label": "Screenshot" + } + ], + "defaultValue": [ + "markdown" + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "onlyMainContent", + "type": "switch", + "label": "Only Main Content", + "description": "Extract only the main content, excluding headers, footers, and navigation", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includeTags", + "type": "short-input", + "label": "Include Tags", + "description": "Only include content from these HTML tags (comma-separated, e.g. article, main)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "excludeTags", + "type": "short-input", + "label": "Exclude Tags", + "description": "Exclude content from these HTML tags (comma-separated, e.g. nav, footer)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "waitFor", + "type": "number-input", + "label": "Wait For (ms)", + "description": "Wait for this many milliseconds before scraping (useful for JS-heavy pages)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SCRAPE" + }, + "defaultValue": 0, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0 + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "description": "The search query to find relevant web pages", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Result Limit", + "description": "Number of search results (1-20)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "defaultValue": 5, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 20 + }, + { + "name": "lang", + "type": "short-input", + "label": "Language", + "description": "Language code for results (e.g. en, es, fr)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "country", + "type": "short-input", + "label": "Country", + "description": "Country code for results (e.g. us, gb, de)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scrapeResults", + "type": "switch", + "label": "Scrape Results", + "description": "Also scrape the full content of each search result", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "crawlUrl", + "type": "short-input", + "label": "Start URL", + "description": "The starting URL to begin crawling from", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "crawlLimit", + "type": "number-input", + "label": "Max Pages", + "description": "Maximum number of pages to crawl (1-1000)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 1000 + }, + { + "name": "maxDepth", + "type": "number-input", + "label": "Max Depth", + "description": "Maximum link depth to crawl from the start URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "defaultValue": 2, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "allowBackwardLinks", + "type": "switch", + "label": "Allow Backward Links", + "description": "Allow crawling pages that link back to already crawled pages", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "allowExternalLinks", + "type": "switch", + "label": "Allow External Links", + "description": "Allow crawling pages on different domains", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "includePaths", + "type": "short-input", + "label": "Include Paths", + "description": "Only crawl URLs matching these path patterns (comma-separated, e.g. /blog/*, /docs/*)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "excludePaths", + "type": "short-input", + "label": "Exclude Paths", + "description": "Skip URLs matching these path patterns (comma-separated)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CRAWL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mapUrl", + "type": "short-input", + "label": "URL", + "description": "The URL to map (discover all linked pages)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MAP" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mapSearch", + "type": "short-input", + "label": "Search Filter", + "description": "Filter discovered links by a search query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MAP" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mapLimit", + "type": "number-input", + "label": "Link Limit", + "description": "Maximum number of links to return", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MAP" + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "extractUrls", + "type": "long-input", + "label": "URLs", + "description": "Enter one URL per line, or use a variable", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "EXTRACT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "extractPrompt", + "type": "long-input", + "label": "Extraction Prompt", + "description": "Describe what data to extract from the pages", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "EXTRACT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "extractSchema", + "type": "code", + "label": "JSON Schema", + "description": "Optional: Define a JSON schema for structured extraction output", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "EXTRACT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "enableWebSearch", + "type": "switch", + "label": "Enable Web Search", + "description": "Allow the extraction to use web search for additional context", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "EXTRACT" + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "agentUrl", + "type": "short-input", + "label": "Start URL", + "description": "The starting URL for the agent to navigate", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "AGENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "agentPrompt", + "type": "long-input", + "label": "Task / Prompt", + "description": "Describe the task for the agent to perform on the website", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "AGENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Scrape", + "value": "SCRAPE", + "description": "Scrape a single URL and extract content" + }, + { + "label": "Search", + "value": "SEARCH", + "description": "Search the web for relevant pages" + }, + { + "label": "Crawl", + "value": "CRAWL", + "description": "Crawl a website following links from a start URL" + }, + { + "label": "Map", + "value": "MAP", + "description": "Discover all linked pages from a URL" + }, + { + "label": "Extract", + "value": "EXTRACT", + "description": "Extract structured data from web pages using AI" + }, + { + "label": "Agent", + "value": "AGENT", + "description": "AI agent that navigates and interacts with websites" + } + ] + }, + { + "id": "tool-DISCORD", + "category": "tools", + "nodeType": "DISCORD", + "label": "Discord", + "description": "Send messages to Discord channels via webhooks", + "contract": { + "contractVersion": 1, + "type": "DISCORD", + "operations": [], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "webhookUrl", + "type": "short-input", + "label": "Webhook URL", + "description": "Get this from Discord: Channel Settings → Integrations → Webhooks", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "content", + "type": "long-input", + "label": "Message Content", + "description": "The message to send. Maximum 2000 characters.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "username", + "type": "short-input", + "label": "Bot Username", + "description": "Override the webhook's default username", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "messageContent": { + "type": "string", + "description": "Sent message confirmation" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-SLACK", + "category": "tools", + "nodeType": "SLACK", + "label": "Slack", + "description": "Send and read messages in Slack channels", + "contract": { + "contractVersion": 1, + "type": "SLACK", + "operations": [ + { + "value": "SEND_MESSAGE", + "label": "Send Message", + "description": "Send a message to a channel" + }, + { + "value": "READ_MESSAGE", + "label": "Read Messages", + "description": "Read recent messages from a channel" + }, + { + "value": "CREATE_CANVAS", + "label": "Create Canvas", + "description": "Create a Slack Canvas (API not yet available)" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "slackAccountId", + "type": "oauth-input", + "label": "Slack Account", + "description": "Select or connect a Slack workspace", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "slack" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEND_MESSAGE", + "label": "Send Message" + }, + { + "id": "READ_MESSAGE", + "label": "Read Messages" + }, + { + "id": "CREATE_CANVAS", + "label": "Create Canvas" + } + ], + "defaultValue": "SEND_MESSAGE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "channelId", + "type": "slack-channel-selector", + "label": "Channel", + "description": "The Slack channel to interact with", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "slackAccountId" + ] + }, + { + "name": "content", + "type": "long-input", + "label": "Message", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEND_MESSAGE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "attachmentUrl", + "type": "file-upload", + "label": "File Attachment", + "description": "Attach a file to the message", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEND_MESSAGE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Send Message", + "value": "SEND_MESSAGE", + "description": "Send a message to a channel" + }, + { + "label": "Read Messages", + "value": "READ_MESSAGE", + "description": "Read recent messages from a channel" + }, + { + "label": "Create Canvas", + "value": "CREATE_CANVAS", + "description": "Create a Slack Canvas (API not yet available)" + } + ] + }, + { + "id": "tool-GOOGLE_DOCS", + "category": "tools", + "nodeType": "GOOGLE_DOCS", + "label": "Google Docs", + "description": "Create, read, and write Google Docs documents", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_DOCS", + "operations": [ + { + "value": "CREATE_DOCUMENT", + "label": "Create Document", + "description": "Create a new Google Docs document" + }, + { + "value": "READ_DOCUMENT", + "label": "Read Document", + "description": "Read content from a Google Docs document" + }, + { + "value": "WRITE_TO_DOCUMENT", + "label": "Write to Document", + "description": "Write content to an existing Google Docs document" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "googleAccountId", + "type": "oauth-input", + "label": "Google Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_docs" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_DOCUMENT", + "label": "Create Document" + }, + { + "id": "READ_DOCUMENT", + "label": "Read Document" + }, + { + "id": "WRITE_TO_DOCUMENT", + "label": "Write to Document" + } + ], + "defaultValue": "CREATE_DOCUMENT", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Document Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_DOCUMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "documentId", + "type": "short-input", + "label": "Document ID", + "description": "The ID from the document URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_DOCUMENT", + "WRITE_TO_DOCUMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_DOCUMENT", + "WRITE_TO_DOCUMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Document", + "value": "CREATE_DOCUMENT", + "description": "Create a new Google Docs document" + }, + { + "label": "Read Document", + "value": "READ_DOCUMENT", + "description": "Read content from a Google Docs document" + }, + { + "label": "Write to Document", + "value": "WRITE_TO_DOCUMENT", + "description": "Write content to an existing Google Docs document" + } + ] + }, + { + "id": "tool-GOOGLE_SHEETS", + "category": "tools", + "nodeType": "GOOGLE_SHEETS", + "label": "Google Sheets", + "description": "Read, write, and manage Google Sheets spreadsheets", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_SHEETS", + "operations": [ + { + "value": "READ_ROWS", + "label": "Read Rows", + "description": "Read rows from a spreadsheet" + }, + { + "value": "APPEND_ROWS", + "label": "Append Rows", + "description": "Append rows to a spreadsheet" + }, + { + "value": "UPDATE_ROWS", + "label": "Update Rows", + "description": "Update existing rows in a spreadsheet" + }, + { + "value": "CREATE_SPREADSHEET", + "label": "Create Spreadsheet", + "description": "Create a new Google Sheets spreadsheet" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "googleAccountId", + "type": "oauth-input", + "label": "Google Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_sheets" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "READ_ROWS", + "label": "Read Rows" + }, + { + "id": "APPEND_ROWS", + "label": "Append Rows" + }, + { + "id": "UPDATE_ROWS", + "label": "Update Rows" + }, + { + "id": "CREATE_SPREADSHEET", + "label": "Create Spreadsheet" + } + ], + "defaultValue": "READ_ROWS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "spreadsheetId", + "type": "google-sheets-resource-selector", + "label": "Spreadsheet", + "description": "Choose a spreadsheet from the selected Google account", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "APPEND_ROWS", + "UPDATE_ROWS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "googleAccountId" + ] + }, + { + "name": "sheetName", + "type": "google-sheets-resource-selector", + "label": "Sheet", + "description": "Choose a sheet tab from the selected spreadsheet", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "APPEND_ROWS", + "UPDATE_ROWS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "googleAccountId", + "spreadsheetId" + ] + }, + { + "name": "range", + "type": "short-input", + "label": "Range", + "description": "Cell range (e.g. A1:D10 or A:Z)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "APPEND_ROWS", + "UPDATE_ROWS" + ] + }, + "defaultValue": "A:Z", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "useColumnMapping", + "type": "switch", + "label": "Map Columns", + "description": "Load every header from the selected sheet and map values individually.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "APPEND_ROWS", + "UPDATE_ROWS" + ] + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "columnMappings", + "type": "google-sheets-column-mapper", + "label": "Columns", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "googleAccountId", + "spreadsheetId", + "sheetName" + ] + }, + { + "name": "values", + "type": "long-input", + "label": "Values", + "description": "Advanced JSON array fallback or {{variable}}", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Spreadsheet Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SPREADSHEET" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Read Rows", + "value": "READ_ROWS", + "description": "Read rows from a spreadsheet" + }, + { + "label": "Append Rows", + "value": "APPEND_ROWS", + "description": "Append rows to a spreadsheet" + }, + { + "label": "Update Rows", + "value": "UPDATE_ROWS", + "description": "Update existing rows in a spreadsheet" + }, + { + "label": "Create Spreadsheet", + "value": "CREATE_SPREADSHEET", + "description": "Create a new Google Sheets spreadsheet" + } + ] + }, + { + "id": "tool-GOOGLE_CALENDAR", + "category": "tools", + "nodeType": "GOOGLE_CALENDAR", + "label": "Google Calendar", + "description": "Manage calendars, events, and scheduling via Google Calendar", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_CALENDAR", + "operations": [ + { + "value": "LIST_CALENDARS", + "label": "List Calendars", + "description": "List all calendars for the authenticated user" + }, + { + "value": "LIST_EVENTS", + "label": "List Events", + "description": "List events from a calendar with optional search" + }, + { + "value": "CREATE_EVENT", + "label": "Create Event", + "description": "Create a new calendar event" + }, + { + "value": "READ_EVENT", + "label": "Read Event", + "description": "Get details of a specific event" + }, + { + "value": "UPDATE_EVENT", + "label": "Update Event", + "description": "Update an existing calendar event" + }, + { + "value": "DELETE_EVENT", + "label": "Delete Event", + "description": "Delete a calendar event" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Google Calendar Account", + "description": "Select or connect a Google Calendar account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_calendar" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_CALENDARS", + "label": "List Calendars" + }, + { + "id": "LIST_EVENTS", + "label": "List Events" + }, + { + "id": "CREATE_EVENT", + "label": "Create Event" + }, + { + "id": "READ_EVENT", + "label": "Read Event" + }, + { + "id": "UPDATE_EVENT", + "label": "Update Event" + }, + { + "id": "DELETE_EVENT", + "label": "Delete Event" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "calendarId", + "type": "short-input", + "label": "Calendar ID", + "required": false, + "visible": true, + "condition": { + "field": "operation", + "value": "LIST_CALENDARS", + "not": true + }, + "defaultValue": "primary", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventId", + "type": "short-input", + "label": "Event ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_EVENT", + "UPDATE_EVENT", + "DELETE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "summary", + "type": "short-input", + "label": "Summary", + "description": "Event title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "description", + "type": "long-input", + "label": "Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "location", + "type": "short-input", + "label": "Location", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "startDateTime", + "type": "short-input", + "label": "Start Date/Time", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "endDateTime", + "type": "short-input", + "label": "End Date/Time", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timeZone", + "type": "short-input", + "label": "Time Zone", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_EVENT", + "UPDATE_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "defaultValue": 50, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 250 + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "sendNotifications", + "type": "switch", + "label": "Send Notifications", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "DELETE_EVENT" + }, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Calendars", + "value": "LIST_CALENDARS", + "description": "List all calendars for the authenticated user" + }, + { + "label": "List Events", + "value": "LIST_EVENTS", + "description": "List events from a calendar with optional search" + }, + { + "label": "Create Event", + "value": "CREATE_EVENT", + "description": "Create a new calendar event" + }, + { + "label": "Read Event", + "value": "READ_EVENT", + "description": "Get details of a specific event" + }, + { + "label": "Update Event", + "value": "UPDATE_EVENT", + "description": "Update an existing calendar event" + }, + { + "label": "Delete Event", + "value": "DELETE_EVENT", + "description": "Delete a calendar event" + } + ] + }, + { + "id": "tool-GOOGLE_FORMS", + "category": "tools", + "nodeType": "GOOGLE_FORMS", + "label": "Google Forms", + "description": "Retrieve responses from Google Forms", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_FORMS", + "operations": [ + { + "value": "GET_RESPONSES", + "label": "Get Responses", + "description": "Retrieve responses from a Google Form" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Google Forms Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_forms" + }, + { + "name": "formId", + "type": "short-input", + "label": "Form ID", + "description": "Form ID from the Google Form URL", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "pageSize", + "type": "number-input", + "label": "Page Size", + "required": false, + "visible": true, + "defaultValue": 50, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 5000 + } + ], + "outputs": { + "responses": { + "type": "array", + "description": "Form responses" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Get Responses", + "value": "GET_RESPONSES", + "description": "Retrieve responses from a Google Form" + } + ] + }, + { + "id": "tool-GOOGLE_GROUPS", + "category": "tools", + "nodeType": "GOOGLE_GROUPS", + "label": "Google Groups", + "description": "Manage Google Groups, members, and memberships", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_GROUPS", + "operations": [ + { + "value": "LIST_GROUPS", + "label": "List Groups", + "description": "List all groups" + }, + { + "value": "GET_GROUP", + "label": "Get Group", + "description": "Get group details" + }, + { + "value": "CREATE_GROUP", + "label": "Create Group", + "description": "Create a new group" + }, + { + "value": "UPDATE_GROUP", + "label": "Update Group", + "description": "Update group settings" + }, + { + "value": "DELETE_GROUP", + "label": "Delete Group", + "description": "Delete a group" + }, + { + "value": "LIST_MEMBERS", + "label": "List Members", + "description": "List group members" + }, + { + "value": "GET_MEMBER", + "label": "Get Member", + "description": "Get member details" + }, + { + "value": "ADD_MEMBER", + "label": "Add Member", + "description": "Add a member to a group" + }, + { + "value": "UPDATE_MEMBER_ROLE", + "label": "Update Member Role", + "description": "Change a member's role" + }, + { + "value": "REMOVE_MEMBER", + "label": "Remove Member", + "description": "Remove a member from a group" + }, + { + "value": "CHECK_MEMBERSHIP", + "label": "Check Membership", + "description": "Check if a user is a member of a group" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Google Groups Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_groups" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_GROUPS", + "label": "List Groups" + }, + { + "id": "GET_GROUP", + "label": "Get Group" + }, + { + "id": "CREATE_GROUP", + "label": "Create Group" + }, + { + "id": "UPDATE_GROUP", + "label": "Update Group" + }, + { + "id": "DELETE_GROUP", + "label": "Delete Group" + }, + { + "id": "LIST_MEMBERS", + "label": "List Members" + }, + { + "id": "GET_MEMBER", + "label": "Get Member" + }, + { + "id": "ADD_MEMBER", + "label": "Add Member" + }, + { + "id": "UPDATE_MEMBER_ROLE", + "label": "Update Member Role" + }, + { + "id": "REMOVE_MEMBER", + "label": "Remove Member" + }, + { + "id": "CHECK_MEMBERSHIP", + "label": "Check Membership" + } + ], + "defaultValue": "LIST_GROUPS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "groupKey", + "type": "short-input", + "label": "Group Key", + "description": "Group email or ID", + "required": false, + "visible": true, + "condition": { + "field": "operation", + "value": "LIST_GROUPS", + "not": true + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "memberKey", + "type": "short-input", + "label": "Member Key", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_MEMBER", + "UPDATE_MEMBER_ROLE", + "REMOVE_MEMBER", + "CHECK_MEMBERSHIP" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "memberEmail", + "type": "short-input", + "label": "Member Email", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADD_MEMBER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "memberRole", + "type": "dropdown", + "label": "Member Role", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ADD_MEMBER", + "UPDATE_MEMBER_ROLE" + ] + }, + "options": [ + { + "id": "OWNER", + "label": "Owner" + }, + { + "id": "MANAGER", + "label": "Manager" + }, + { + "id": "MEMBER", + "label": "Member" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "email", + "type": "short-input", + "label": "Group Email", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_GROUP", + "UPDATE_GROUP" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "name", + "type": "short-input", + "label": "Group Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_GROUP", + "UPDATE_GROUP" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "description", + "type": "long-input", + "label": "Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_GROUP", + "UPDATE_GROUP" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_GROUPS", + "LIST_MEMBERS" + ] + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 200 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Groups", + "value": "LIST_GROUPS", + "description": "List all groups" + }, + { + "label": "Get Group", + "value": "GET_GROUP", + "description": "Get group details" + }, + { + "label": "Create Group", + "value": "CREATE_GROUP", + "description": "Create a new group" + }, + { + "label": "Update Group", + "value": "UPDATE_GROUP", + "description": "Update group settings" + }, + { + "label": "Delete Group", + "value": "DELETE_GROUP", + "description": "Delete a group" + }, + { + "label": "List Members", + "value": "LIST_MEMBERS", + "description": "List group members" + }, + { + "label": "Get Member", + "value": "GET_MEMBER", + "description": "Get member details" + }, + { + "label": "Add Member", + "value": "ADD_MEMBER", + "description": "Add a member to a group" + }, + { + "label": "Update Member Role", + "value": "UPDATE_MEMBER_ROLE", + "description": "Change a member's role" + }, + { + "label": "Remove Member", + "value": "REMOVE_MEMBER", + "description": "Remove a member from a group" + }, + { + "label": "Check Membership", + "value": "CHECK_MEMBERSHIP", + "description": "Check if a user is a member of a group" + } + ] + }, + { + "id": "tool-GOOGLE_DRIVE", + "category": "tools", + "nodeType": "GOOGLE_DRIVE", + "label": "Google Drive", + "description": "List, download, and upload files in Google Drive", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_DRIVE", + "operations": [ + { + "value": "LIST_FILES", + "label": "List Files", + "description": "List files in Google Drive" + }, + { + "value": "DOWNLOAD_FILE", + "label": "Download File", + "description": "Download a file from Google Drive" + }, + { + "value": "UPLOAD_FILE", + "label": "Upload File", + "description": "Upload a file to Google Drive" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "googleAccountId", + "type": "oauth-input", + "label": "Google Drive Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_drive" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_FILES", + "label": "List Files" + }, + { + "id": "DOWNLOAD_FILE", + "label": "Download File" + }, + { + "id": "UPLOAD_FILE", + "label": "Upload File" + } + ], + "defaultValue": "LIST_FILES", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_FILES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_FILES" + }, + "defaultValue": 20, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "fileId", + "type": "short-input", + "label": "File ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "DOWNLOAD_FILE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "uploadFileName", + "type": "short-input", + "label": "File Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD_FILE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "uploadContent", + "type": "long-input", + "label": "File Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD_FILE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "uploadMimeType", + "type": "dropdown", + "label": "MIME Type", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD_FILE" + }, + "options": [ + { + "id": "text/plain", + "label": "text/plain" + }, + { + "id": "application/json", + "label": "application/json" + }, + { + "id": "text/csv", + "label": "text/csv" + }, + { + "id": "text/html", + "label": "text/html" + }, + { + "id": "text/markdown", + "label": "text/markdown" + } + ], + "defaultValue": "text/plain", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "uploadFolderId", + "type": "short-input", + "label": "Folder ID", + "description": "Parent folder ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD_FILE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Files", + "value": "LIST_FILES", + "description": "List files in Google Drive" + }, + { + "label": "Download File", + "value": "DOWNLOAD_FILE", + "description": "Download a file from Google Drive" + }, + { + "label": "Upload File", + "value": "UPLOAD_FILE", + "description": "Upload a file to Google Drive" + } + ] + }, + { + "id": "tool-GOOGLE_SLIDES", + "category": "tools", + "nodeType": "GOOGLE_SLIDES", + "label": "Google Slides", + "description": "Create and read Google Slides presentations", + "contract": { + "contractVersion": 1, + "type": "GOOGLE_SLIDES", + "operations": [ + { + "value": "CREATE_PRESENTATION", + "label": "Create Presentation", + "description": "Create a new Google Slides presentation" + }, + { + "value": "READ_PRESENTATION", + "label": "Read Presentation", + "description": "Read an existing Google Slides presentation" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "googleAccountId", + "type": "oauth-input", + "label": "Google Slides Account", + "description": "Select or connect a Google account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "google_drive" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_PRESENTATION", + "label": "Create Presentation" + }, + { + "id": "READ_PRESENTATION", + "label": "Read Presentation" + } + ], + "defaultValue": "CREATE_PRESENTATION", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Presentation Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_PRESENTATION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "presentationId", + "type": "short-input", + "label": "Presentation ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_PRESENTATION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Presentation", + "value": "CREATE_PRESENTATION", + "description": "Create a new Google Slides presentation" + }, + { + "label": "Read Presentation", + "value": "READ_PRESENTATION", + "description": "Read an existing Google Slides presentation" + } + ] + }, + { + "id": "tool-AIRTABLE", + "category": "tools", + "nodeType": "AIRTABLE", + "label": "Airtable", + "description": "Read, create, update, and delete Airtable records", + "contract": { + "contractVersion": 1, + "type": "AIRTABLE", + "operations": [ + { + "value": "LIST_RECORDS", + "label": "List Records", + "description": "List records from a table" + }, + { + "value": "READ_RECORD", + "label": "Read Record", + "description": "Read a single record by ID" + }, + { + "value": "CREATE_RECORD", + "label": "Create Record", + "description": "Create a new record in a table" + }, + { + "value": "UPDATE_RECORD", + "label": "Update Record", + "description": "Update an existing record" + }, + { + "value": "DELETE_RECORD", + "label": "Delete Record", + "description": "Delete a record by ID" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Airtable Account", + "description": "Select or connect an Airtable account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "airtable" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_RECORDS", + "label": "List Records" + }, + { + "id": "READ_RECORD", + "label": "Read Record" + }, + { + "id": "CREATE_RECORD", + "label": "Create Record" + }, + { + "id": "UPDATE_RECORD", + "label": "Update Record" + }, + { + "id": "DELETE_RECORD", + "label": "Delete Record" + } + ], + "defaultValue": "LIST_RECORDS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "baseId", + "type": "short-input", + "label": "Base ID", + "description": "Airtable Base ID", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tableName", + "type": "short-input", + "label": "Table Name", + "description": "Table name or ID", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recordId", + "type": "short-input", + "label": "Record ID", + "description": "Airtable Record ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_RECORD", + "UPDATE_RECORD", + "DELETE_RECORD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recordData", + "type": "code", + "label": "Record Data", + "description": "JSON object with field values", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_RECORD", + "UPDATE_RECORD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filterFormula", + "type": "short-input", + "label": "Filter Formula", + "description": "Airtable filter formula", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxRecords", + "type": "number-input", + "label": "Max Records", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_RECORDS" + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Records", + "value": "LIST_RECORDS", + "description": "List records from a table" + }, + { + "label": "Read Record", + "value": "READ_RECORD", + "description": "Read a single record by ID" + }, + { + "label": "Create Record", + "value": "CREATE_RECORD", + "description": "Create a new record in a table" + }, + { + "label": "Update Record", + "value": "UPDATE_RECORD", + "description": "Update an existing record" + }, + { + "label": "Delete Record", + "value": "DELETE_RECORD", + "description": "Delete a record by ID" + } + ] + }, + { + "id": "tool-GMAIL", + "category": "tools", + "nodeType": "GMAIL", + "label": "Gmail", + "description": "Send, read, search, and manage emails via Gmail", + "contract": { + "contractVersion": 1, + "type": "GMAIL", + "operations": [ + { + "value": "SEND_EMAIL", + "label": "Send Email", + "description": "Send an email from your Gmail account" + }, + { + "value": "READ_EMAILS", + "label": "Read Emails", + "description": "Read emails from a label/folder" + }, + { + "value": "DRAFT_EMAIL", + "label": "Draft Email", + "description": "Create a draft email" + }, + { + "value": "SEARCH_EMAILS", + "label": "Search Emails", + "description": "Search emails using Gmail query syntax" + }, + { + "value": "MOVE_EMAIL", + "label": "Move Email", + "description": "Move an email by adding/removing labels" + }, + { + "value": "MARK_AS_READ", + "label": "Mark as Read", + "description": "Mark a message as read" + }, + { + "value": "MARK_AS_UNREAD", + "label": "Mark as Unread", + "description": "Mark a message as unread" + }, + { + "value": "ARCHIVE_EMAIL", + "label": "Archive Email", + "description": "Archive an email (remove from inbox)" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "gmailConnectionId", + "type": "oauth-input", + "label": "Gmail Account", + "description": "Select or connect a Gmail account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "gmail" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEND_EMAIL", + "label": "Send Email" + }, + { + "id": "READ_EMAILS", + "label": "Read Emails" + }, + { + "id": "DRAFT_EMAIL", + "label": "Draft Email" + }, + { + "id": "SEARCH_EMAILS", + "label": "Search Emails" + }, + { + "id": "MOVE_EMAIL", + "label": "Move Email" + }, + { + "id": "MARK_AS_READ", + "label": "Mark as Read" + }, + { + "id": "MARK_AS_UNREAD", + "label": "Mark as Unread" + }, + { + "id": "ARCHIVE_EMAIL", + "label": "Archive Email" + } + ], + "defaultValue": "SEND_EMAIL", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "to", + "type": "short-input", + "label": "To", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "subject", + "type": "short-input", + "label": "Subject", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Body", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "isHtml", + "type": "switch", + "label": "Send as HTML", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cc", + "type": "short-input", + "label": "CC", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bcc", + "type": "short-input", + "label": "BCC", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "DRAFT_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_EMAILS", + "SEARCH_EMAILS" + ] + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 500 + }, + { + "name": "labelId", + "type": "short-input", + "label": "Label", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_EMAILS" + }, + "defaultValue": "INBOX", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_EMAILS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "messageId", + "type": "short-input", + "label": "Message ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "MOVE_EMAIL", + "MARK_AS_READ", + "MARK_AS_UNREAD", + "ARCHIVE_EMAIL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "addLabelId", + "type": "short-input", + "label": "Add Label", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MOVE_EMAIL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "removeLabelId", + "type": "short-input", + "label": "Remove Label", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MOVE_EMAIL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Send Email", + "value": "SEND_EMAIL", + "description": "Send an email from your Gmail account" + }, + { + "label": "Read Emails", + "value": "READ_EMAILS", + "description": "Read emails from a label/folder" + }, + { + "label": "Draft Email", + "value": "DRAFT_EMAIL", + "description": "Create a draft email" + }, + { + "label": "Search Emails", + "value": "SEARCH_EMAILS", + "description": "Search emails using Gmail query syntax" + }, + { + "label": "Move Email", + "value": "MOVE_EMAIL", + "description": "Move an email by adding/removing labels" + }, + { + "label": "Mark as Read", + "value": "MARK_AS_READ", + "description": "Mark a message as read" + }, + { + "label": "Mark as Unread", + "value": "MARK_AS_UNREAD", + "description": "Mark a message as unread" + }, + { + "label": "Archive Email", + "value": "ARCHIVE_EMAIL", + "description": "Archive an email (remove from inbox)" + } + ] + }, + { + "id": "tool-MICROSOFT_TEAMS", + "category": "tools", + "nodeType": "MICROSOFT_TEAMS", + "label": "Microsoft Teams", + "description": "Send messages, read channels, and manage teams in Microsoft Teams", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_TEAMS", + "operations": [ + { + "value": "SEND_MESSAGE", + "label": "Send Message", + "description": "Send a message to a Teams channel" + }, + { + "value": "READ_MESSAGES", + "label": "Read Messages", + "description": "Read recent messages from a channel" + }, + { + "value": "LIST_CHANNELS", + "label": "List Channels", + "description": "List channels in a team" + }, + { + "value": "LIST_TEAMS", + "label": "List Teams", + "description": "List all teams you belong to" + }, + { + "value": "CREATE_CHANNEL", + "label": "Create Channel", + "description": "Create a new channel in a team" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Teams Account", + "description": "Select or connect a Microsoft Teams account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_teams" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEND_MESSAGE", + "label": "Send Message" + }, + { + "id": "READ_MESSAGES", + "label": "Read Messages" + }, + { + "id": "LIST_CHANNELS", + "label": "List Channels" + }, + { + "id": "LIST_TEAMS", + "label": "List Teams" + }, + { + "id": "CREATE_CHANNEL", + "label": "Create Channel" + } + ], + "defaultValue": "SEND_MESSAGE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "teamId", + "type": "short-input", + "label": "Team ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_MESSAGE", + "READ_MESSAGES", + "LIST_CHANNELS", + "CREATE_CHANNEL" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "channelId", + "type": "short-input", + "label": "Channel ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_MESSAGE", + "READ_MESSAGES" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "message", + "type": "long-input", + "label": "Message", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEND_MESSAGE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_MESSAGES" + }, + "defaultValue": 20, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "channelNameNew", + "type": "short-input", + "label": "Channel Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CHANNEL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "channelDescription", + "type": "long-input", + "label": "Channel Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CHANNEL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Send Message", + "value": "SEND_MESSAGE", + "description": "Send a message to a Teams channel" + }, + { + "label": "Read Messages", + "value": "READ_MESSAGES", + "description": "Read recent messages from a channel" + }, + { + "label": "List Channels", + "value": "LIST_CHANNELS", + "description": "List channels in a team" + }, + { + "label": "List Teams", + "value": "LIST_TEAMS", + "description": "List all teams you belong to" + }, + { + "label": "Create Channel", + "value": "CREATE_CHANNEL", + "description": "Create a new channel in a team" + } + ] + }, + { + "id": "tool-MICROSOFT_OUTLOOK", + "category": "tools", + "nodeType": "MICROSOFT_OUTLOOK", + "label": "Microsoft Outlook", + "description": "Send, read, draft, and search emails via Microsoft Outlook", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_OUTLOOK", + "operations": [ + { + "value": "SEND_EMAIL", + "label": "Send Email", + "description": "Send an email from your Outlook account" + }, + { + "value": "READ_EMAILS", + "label": "Read Emails", + "description": "Read emails from a folder" + }, + { + "value": "READ_EMAIL", + "label": "Read Email", + "description": "Read a single email by ID" + }, + { + "value": "CREATE_DRAFT", + "label": "Create Draft", + "description": "Create a draft email" + }, + { + "value": "SEARCH_EMAILS", + "label": "Search Emails", + "description": "Search emails using a query" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Outlook Account", + "description": "Select or connect a Microsoft Outlook account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_outlook" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEND_EMAIL", + "label": "Send Email" + }, + { + "id": "READ_EMAILS", + "label": "Read Emails" + }, + { + "id": "READ_EMAIL", + "label": "Read Email" + }, + { + "id": "CREATE_DRAFT", + "label": "Create Draft" + }, + { + "id": "SEARCH_EMAILS", + "label": "Search Emails" + } + ], + "defaultValue": "SEND_EMAIL", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "to", + "type": "short-input", + "label": "To", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "subject", + "type": "short-input", + "label": "Subject", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Body", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "isHtml", + "type": "switch", + "label": "Send as HTML", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cc", + "type": "short-input", + "label": "CC", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bcc", + "type": "short-input", + "label": "BCC", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEND_EMAIL", + "CREATE_DRAFT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderId", + "type": "short-input", + "label": "Folder ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_EMAILS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "messageId", + "type": "short-input", + "label": "Message ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "READ_EMAIL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchQuery", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_EMAILS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_EMAILS", + "SEARCH_EMAILS" + ] + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Send Email", + "value": "SEND_EMAIL", + "description": "Send an email from your Outlook account" + }, + { + "label": "Read Emails", + "value": "READ_EMAILS", + "description": "Read emails from a folder" + }, + { + "label": "Read Email", + "value": "READ_EMAIL", + "description": "Read a single email by ID" + }, + { + "label": "Create Draft", + "value": "CREATE_DRAFT", + "description": "Create a draft email" + }, + { + "label": "Search Emails", + "value": "SEARCH_EMAILS", + "description": "Search emails using a query" + } + ] + }, + { + "id": "tool-MICROSOFT_WORD", + "category": "tools", + "nodeType": "MICROSOFT_WORD", + "label": "Microsoft Word", + "description": "Create, read, and update Microsoft Word documents", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_WORD", + "operations": [ + { + "value": "CREATE_DOCUMENT", + "label": "Create Document", + "description": "Create a new Microsoft Word document" + }, + { + "value": "READ_DOCUMENT", + "label": "Read Document", + "description": "Read content from a Microsoft Word document" + }, + { + "value": "UPDATE_DOCUMENT", + "label": "Update Document", + "description": "Update content in an existing Microsoft Word document" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Microsoft Account", + "description": "Select or connect a Microsoft account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_word" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_DOCUMENT", + "label": "Create Document" + }, + { + "id": "READ_DOCUMENT", + "label": "Read Document" + }, + { + "id": "UPDATE_DOCUMENT", + "label": "Update Document" + } + ], + "defaultValue": "CREATE_DOCUMENT", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileName", + "type": "short-input", + "label": "File Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_DOCUMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderPath", + "type": "short-input", + "label": "Folder Path", + "description": "OneDrive folder path for the new document", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_DOCUMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "initialContent", + "type": "long-input", + "label": "Initial Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_DOCUMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileId", + "type": "short-input", + "label": "File ID", + "description": "The file ID from Microsoft Graph", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_DOCUMENT", + "UPDATE_DOCUMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_DOCUMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Document", + "value": "CREATE_DOCUMENT", + "description": "Create a new Microsoft Word document" + }, + { + "label": "Read Document", + "value": "READ_DOCUMENT", + "description": "Read content from a Microsoft Word document" + }, + { + "label": "Update Document", + "value": "UPDATE_DOCUMENT", + "description": "Update content in an existing Microsoft Word document" + } + ] + }, + { + "id": "tool-MICROSOFT_EXCEL", + "category": "tools", + "nodeType": "MICROSOFT_EXCEL", + "label": "Microsoft Excel", + "description": "Create, read, and write Microsoft Excel spreadsheets", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_EXCEL", + "operations": [ + { + "value": "CREATE_SPREADSHEET", + "label": "Create Spreadsheet", + "description": "Create a new Microsoft Excel spreadsheet" + }, + { + "value": "READ_ROWS", + "label": "Read Rows", + "description": "Read rows from an Excel spreadsheet" + }, + { + "value": "WRITE_ROWS", + "label": "Write Rows", + "description": "Write rows to an Excel spreadsheet" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Microsoft Account", + "description": "Select or connect a Microsoft account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_excel" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_SPREADSHEET", + "label": "Create Spreadsheet" + }, + { + "id": "READ_ROWS", + "label": "Read Rows" + }, + { + "id": "WRITE_ROWS", + "label": "Write Rows" + } + ], + "defaultValue": "CREATE_SPREADSHEET", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileName", + "type": "short-input", + "label": "File Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SPREADSHEET" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderPath", + "type": "short-input", + "label": "Folder Path", + "description": "OneDrive folder path for the new spreadsheet", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SPREADSHEET" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileId", + "type": "short-input", + "label": "File ID", + "description": "The file ID from Microsoft Graph", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "WRITE_ROWS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "worksheetName", + "type": "short-input", + "label": "Worksheet Name", + "description": "Name of the worksheet tab", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "WRITE_ROWS" + ] + }, + "defaultValue": "Sheet1", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "range", + "type": "short-input", + "label": "Range", + "description": "Cell range (e.g. A1:Z100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_ROWS", + "WRITE_ROWS" + ] + }, + "defaultValue": "A1:Z100", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "values", + "type": "long-input", + "label": "Values", + "description": "JSON array of row data", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "WRITE_ROWS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Spreadsheet", + "value": "CREATE_SPREADSHEET", + "description": "Create a new Microsoft Excel spreadsheet" + }, + { + "label": "Read Rows", + "value": "READ_ROWS", + "description": "Read rows from an Excel spreadsheet" + }, + { + "label": "Write Rows", + "value": "WRITE_ROWS", + "description": "Write rows to an Excel spreadsheet" + } + ] + }, + { + "id": "tool-MICROSOFT_ONEDRIVE", + "category": "tools", + "nodeType": "MICROSOFT_ONEDRIVE", + "label": "Microsoft OneDrive", + "description": "List, get, create folders, and delete files in OneDrive", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_ONEDRIVE", + "operations": [ + { + "value": "LIST_FILES", + "label": "List Files", + "description": "List files in a OneDrive folder" + }, + { + "value": "GET_FILE", + "label": "Get File", + "description": "Get a file from OneDrive" + }, + { + "value": "CREATE_FOLDER", + "label": "Create Folder", + "description": "Create a new folder in OneDrive" + }, + { + "value": "DELETE_FILE", + "label": "Delete File", + "description": "Delete a file from OneDrive" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "OneDrive Account", + "description": "Select or connect a Microsoft account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_onedrive" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_FILES", + "label": "List Files" + }, + { + "id": "GET_FILE", + "label": "Get File" + }, + { + "id": "CREATE_FOLDER", + "label": "Create Folder" + }, + { + "id": "DELETE_FILE", + "label": "Delete File" + } + ], + "defaultValue": "LIST_FILES", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderId", + "type": "short-input", + "label": "Folder ID", + "description": "Parent folder ID (root if empty)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_FILES", + "CREATE_FOLDER" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileId", + "type": "short-input", + "label": "File ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_FILE", + "DELETE_FILE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderName", + "type": "short-input", + "label": "Folder Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FOLDER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Files", + "value": "LIST_FILES", + "description": "List files in a OneDrive folder" + }, + { + "label": "Get File", + "value": "GET_FILE", + "description": "Get a file from OneDrive" + }, + { + "label": "Create Folder", + "value": "CREATE_FOLDER", + "description": "Create a new folder in OneDrive" + }, + { + "label": "Delete File", + "value": "DELETE_FILE", + "description": "Delete a file from OneDrive" + } + ] + }, + { + "id": "tool-MICROSOFT_SHAREPOINT", + "category": "tools", + "nodeType": "MICROSOFT_SHAREPOINT", + "label": "Microsoft SharePoint", + "description": "Browse sites, lists, and manage list items in SharePoint Online", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_SHAREPOINT", + "operations": [ + { + "value": "LIST_SITES", + "label": "List Sites", + "description": "Search or list SharePoint sites" + }, + { + "value": "LIST_LISTS", + "label": "List Lists", + "description": "List all lists in a SharePoint site" + }, + { + "value": "GET_LIST_ITEMS", + "label": "Get List Items", + "description": "Get items from a SharePoint list" + }, + { + "value": "CREATE_LIST_ITEM", + "label": "Create List Item", + "description": "Create a new item in a SharePoint list" + }, + { + "value": "UPDATE_LIST_ITEM", + "label": "Update List Item", + "description": "Update an existing item in a SharePoint list" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "SharePoint Account", + "description": "Select or connect a Microsoft account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_sharepoint" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_SITES", + "label": "List Sites" + }, + { + "id": "LIST_LISTS", + "label": "List Lists" + }, + { + "id": "GET_LIST_ITEMS", + "label": "Get List Items" + }, + { + "id": "CREATE_LIST_ITEM", + "label": "Create List Item" + }, + { + "id": "UPDATE_LIST_ITEM", + "label": "Update List Item" + } + ], + "defaultValue": "LIST_SITES", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchQuery", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_SITES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "siteId", + "type": "short-input", + "label": "Site ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_LISTS", + "GET_LIST_ITEMS", + "CREATE_LIST_ITEM", + "UPDATE_LIST_ITEM" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listId", + "type": "short-input", + "label": "List ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_LIST_ITEMS", + "CREATE_LIST_ITEM", + "UPDATE_LIST_ITEM" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "itemId", + "type": "short-input", + "label": "Item ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_LIST_ITEM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fields", + "type": "code", + "label": "Fields", + "description": "JSON object with field values", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_LIST_ITEM", + "UPDATE_LIST_ITEM" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filter", + "type": "short-input", + "label": "Filter", + "description": "OData filter expression", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_LIST_ITEMS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "top", + "type": "number-input", + "label": "Max Results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_LIST_ITEMS" + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 500 + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Sites", + "value": "LIST_SITES", + "description": "Search or list SharePoint sites" + }, + { + "label": "List Lists", + "value": "LIST_LISTS", + "description": "List all lists in a SharePoint site" + }, + { + "label": "Get List Items", + "value": "GET_LIST_ITEMS", + "description": "Get items from a SharePoint list" + }, + { + "label": "Create List Item", + "value": "CREATE_LIST_ITEM", + "description": "Create a new item in a SharePoint list" + }, + { + "label": "Update List Item", + "value": "UPDATE_LIST_ITEM", + "description": "Update an existing item in a SharePoint list" + } + ] + }, + { + "id": "tool-MICROSOFT_PLANNER", + "category": "tools", + "nodeType": "MICROSOFT_PLANNER", + "label": "Microsoft Planner", + "description": "Manage plans and tasks in Microsoft Planner", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT_PLANNER", + "operations": [ + { + "value": "LIST_PLANS", + "label": "List Plans", + "description": "List all plans in the group" + }, + { + "value": "LIST_TASKS", + "label": "List Tasks", + "description": "List tasks in a plan" + }, + { + "value": "CREATE_TASK", + "label": "Create Task", + "description": "Create a new task in a plan" + }, + { + "value": "UPDATE_TASK", + "label": "Update Task", + "description": "Update an existing task" + }, + { + "value": "DELETE_TASK", + "label": "Delete Task", + "description": "Delete a task" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Microsoft Planner Account", + "description": "Select or connect a Microsoft Planner account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_planner" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_PLANS", + "label": "List Plans" + }, + { + "id": "LIST_TASKS", + "label": "List Tasks" + }, + { + "id": "CREATE_TASK", + "label": "Create Task" + }, + { + "id": "UPDATE_TASK", + "label": "Update Task" + }, + { + "id": "DELETE_TASK", + "label": "Delete Task" + } + ], + "defaultValue": "LIST_PLANS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "planId", + "type": "short-input", + "label": "Plan ID", + "description": "Planner Plan ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_TASKS", + "CREATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "taskId", + "type": "short-input", + "label": "Task ID", + "description": "Planner Task ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_TASK", + "DELETE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Task Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bucketId", + "type": "short-input", + "label": "Bucket ID", + "description": "Planner bucket ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "dueDate", + "type": "short-input", + "label": "Due Date", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "priority", + "type": "dropdown", + "label": "Priority", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "options": [ + { + "id": "1", + "label": "Urgent" + }, + { + "id": "2", + "label": "Important" + }, + { + "id": "3", + "label": "Medium" + }, + { + "id": "4", + "label": "Low" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "percentComplete", + "type": "number-input", + "label": "Percent Complete", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Plans", + "value": "LIST_PLANS", + "description": "List all plans in the group" + }, + { + "label": "List Tasks", + "value": "LIST_TASKS", + "description": "List tasks in a plan" + }, + { + "label": "Create Task", + "value": "CREATE_TASK", + "description": "Create a new task in a plan" + }, + { + "label": "Update Task", + "value": "UPDATE_TASK", + "description": "Update an existing task" + }, + { + "label": "Delete Task", + "value": "DELETE_TASK", + "description": "Delete a task" + } + ] + }, + { + "id": "tool-KNOWLEDGE_BASE", + "category": "tools", + "nodeType": "KNOWLEDGE_BASE", + "label": "Knowledge Base", + "description": "Search your knowledge base for relevant information", + "contract": { + "contractVersion": 1, + "type": "KNOWLEDGE_BASE", + "operations": [ + { + "value": "SEARCH", + "label": "Search", + "description": "Search knowledge base for relevant information" + }, + { + "value": "UPLOAD", + "label": "Upload", + "description": "Upload a document to the knowledge base" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "knowledgeBaseId", + "type": "kb-selector", + "label": "Knowledge Base", + "description": "The knowledge base to query or upload to", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose whether to search or upload to the knowledge base", + "required": true, + "visible": true, + "options": [ + { + "id": "SEARCH", + "label": "Search" + }, + { + "id": "UPLOAD", + "label": "Upload" + } + ], + "defaultValue": "SEARCH", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "description": "The query to search for in the knowledge base", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "topK", + "type": "number-input", + "label": "Number of Results", + "description": "Maximum number of results to return (1-50)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "defaultValue": 5, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 50 + }, + { + "name": "scoreThreshold", + "type": "number-input", + "label": "Score Threshold", + "description": "Minimum similarity score (0-1). Leave empty for no threshold.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0, + "max": 1 + }, + { + "name": "fileUrl", + "type": "short-input", + "label": "File URL", + "description": "URL of the file to upload", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileName", + "type": "short-input", + "label": "File Name", + "description": "Name to save the file as", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileType", + "type": "dropdown", + "label": "File Type", + "description": "Type of the file being uploaded", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD" + }, + "options": [ + { + "id": "pdf", + "label": "PDF" + }, + { + "id": "txt", + "label": "Text" + }, + { + "id": "md", + "label": "Markdown" + } + ], + "defaultValue": "txt", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Search", + "value": "SEARCH", + "description": "Search knowledge base for relevant information" + }, + { + "label": "Upload", + "value": "UPLOAD", + "description": "Upload a document to the knowledge base" + } + ] + }, + { + "id": "tool-ATTIO", + "category": "tools", + "nodeType": "ATTIO", + "label": "Attio", + "description": "Manage Attio CRM records, notes, tasks, and object metadata", + "contract": { + "contractVersion": 1, + "type": "ATTIO", + "operations": [ + { + "value": "LIST_RECORDS", + "label": "List Records" + }, + { + "value": "GET_RECORD", + "label": "Get Record" + }, + { + "value": "UPDATE_RECORD", + "label": "Update Record" + }, + { + "value": "DELETE_RECORD", + "label": "Delete Record" + }, + { + "value": "SEARCH_RECORDS", + "label": "Search Records" + }, + { + "value": "ASSERT_RECORD", + "label": "Assert Record" + }, + { + "value": "LIST_NOTES", + "label": "List Notes" + }, + { + "value": "GET_NOTE", + "label": "Get Note" + }, + { + "value": "CREATE_NOTE", + "label": "Create Note" + }, + { + "value": "DELETE_NOTE", + "label": "Delete Note" + }, + { + "value": "LIST_TASKS", + "label": "List Tasks" + }, + { + "value": "CREATE_TASK", + "label": "Create Task" + }, + { + "value": "GET_OBJECT", + "label": "Get Object" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Attio Account", + "description": "Select or connect an Attio workspace", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "attio" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_RECORDS", + "label": "List Records" + }, + { + "id": "GET_RECORD", + "label": "Get Record" + }, + { + "id": "UPDATE_RECORD", + "label": "Update Record" + }, + { + "id": "DELETE_RECORD", + "label": "Delete Record" + }, + { + "id": "SEARCH_RECORDS", + "label": "Search Records" + }, + { + "id": "ASSERT_RECORD", + "label": "Assert Record" + }, + { + "id": "LIST_NOTES", + "label": "List Notes" + }, + { + "id": "GET_NOTE", + "label": "Get Note" + }, + { + "id": "CREATE_NOTE", + "label": "Create Note" + }, + { + "id": "DELETE_NOTE", + "label": "Delete Note" + }, + { + "id": "LIST_TASKS", + "label": "List Tasks" + }, + { + "id": "CREATE_TASK", + "label": "Create Task" + }, + { + "id": "GET_OBJECT", + "label": "Get Object" + } + ], + "defaultValue": "LIST_RECORDS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "object", + "type": "short-input", + "label": "Object", + "description": "Attio object slug or ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_RECORDS", + "GET_RECORD", + "UPDATE_RECORD", + "DELETE_RECORD", + "SEARCH_RECORDS", + "ASSERT_RECORD", + "GET_OBJECT", + "LIST_NOTES", + "CREATE_NOTE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recordId", + "type": "short-input", + "label": "Record ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_RECORD", + "UPDATE_RECORD", + "DELETE_RECORD", + "LIST_NOTES", + "CREATE_NOTE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "noteId", + "type": "short-input", + "label": "Note ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_NOTE", + "DELETE_NOTE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "matchingAttribute", + "type": "short-input", + "label": "Matching Attribute", + "description": "Unique attribute slug or ID used by Attio to match a record", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ASSERT_RECORD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "values", + "type": "code", + "label": "Values", + "description": "JSON object for Attio attribute values", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_RECORD", + "ASSERT_RECORD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filter", + "type": "code", + "label": "Filter", + "description": "Optional Attio filter object", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "sorts", + "type": "code", + "label": "Sorts", + "description": "Optional Attio sorts array", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_NOTE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_NOTE", + "CREATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "deadlineAt", + "type": "short-input", + "label": "Deadline", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkedRecords", + "type": "code", + "label": "Linked Records", + "description": "Optional JSON array of Attio record identifiers", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_RECORDS", + "SEARCH_RECORDS", + "LIST_NOTES", + "LIST_TASKS" + ] + }, + "defaultValue": 25, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 500 + }, + { + "name": "offset", + "type": "number-input", + "label": "Offset", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_RECORDS", + "LIST_NOTES", + "LIST_TASKS" + ] + }, + "defaultValue": 0, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0 + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Records", + "value": "LIST_RECORDS", + "description": "" + }, + { + "label": "Get Record", + "value": "GET_RECORD", + "description": "" + }, + { + "label": "Update Record", + "value": "UPDATE_RECORD", + "description": "" + }, + { + "label": "Delete Record", + "value": "DELETE_RECORD", + "description": "" + }, + { + "label": "Search Records", + "value": "SEARCH_RECORDS", + "description": "" + }, + { + "label": "Assert Record", + "value": "ASSERT_RECORD", + "description": "" + }, + { + "label": "List Notes", + "value": "LIST_NOTES", + "description": "" + }, + { + "label": "Get Note", + "value": "GET_NOTE", + "description": "" + }, + { + "label": "Create Note", + "value": "CREATE_NOTE", + "description": "" + }, + { + "label": "Delete Note", + "value": "DELETE_NOTE", + "description": "" + }, + { + "label": "List Tasks", + "value": "LIST_TASKS", + "description": "" + }, + { + "label": "Create Task", + "value": "CREATE_TASK", + "description": "" + }, + { + "label": "Get Object", + "value": "GET_OBJECT", + "description": "" + } + ] + }, + { + "id": "tool-HUBSPOT", + "category": "tools", + "nodeType": "HUBSPOT", + "label": "HubSpot", + "description": "Manage HubSpot contacts, companies, and deals", + "contract": { + "contractVersion": 1, + "type": "HUBSPOT", + "operations": [ + { + "value": "CREATE_RECORD", + "label": "Create Record", + "description": "Create a new CRM record" + }, + { + "value": "READ_RECORD", + "label": "Read Record", + "description": "Read a single record by ID" + }, + { + "value": "UPDATE_RECORD", + "label": "Update Record", + "description": "Update an existing record" + }, + { + "value": "DELETE_RECORD", + "label": "Delete Record", + "description": "Delete a record by ID" + }, + { + "value": "LIST_RECORDS", + "label": "List Records", + "description": "List records with optional limit" + }, + { + "value": "SEARCH_RECORDS", + "label": "Search Records", + "description": "Search records with query or filters" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "HubSpot Account", + "description": "Select or connect a HubSpot account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "hubspot" + }, + { + "name": "objectType", + "type": "dropdown", + "label": "Object Type", + "required": true, + "visible": true, + "options": [ + { + "id": "contacts", + "label": "Contacts" + }, + { + "id": "companies", + "label": "Companies" + }, + { + "id": "deals", + "label": "Deals" + } + ], + "defaultValue": "contacts", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_RECORD", + "label": "Create Record" + }, + { + "id": "READ_RECORD", + "label": "Read Record" + }, + { + "id": "UPDATE_RECORD", + "label": "Update Record" + }, + { + "id": "DELETE_RECORD", + "label": "Delete Record" + }, + { + "id": "LIST_RECORDS", + "label": "List Records" + }, + { + "id": "SEARCH_RECORDS", + "label": "Search Records" + } + ], + "defaultValue": "LIST_RECORDS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recordId", + "type": "short-input", + "label": "Record ID", + "description": "HubSpot Record ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_RECORD", + "UPDATE_RECORD", + "DELETE_RECORD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "properties", + "type": "code", + "label": "Properties", + "description": "JSON object with property values", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_RECORD", + "UPDATE_RECORD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchQuery", + "type": "short-input", + "label": "Search Query", + "description": "Free-text search query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filterGroups", + "type": "code", + "label": "Filter Groups", + "description": "Advanced filter JSON", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_RECORDS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_RECORDS", + "SEARCH_RECORDS" + ] + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Record", + "value": "CREATE_RECORD", + "description": "Create a new CRM record" + }, + { + "label": "Read Record", + "value": "READ_RECORD", + "description": "Read a single record by ID" + }, + { + "label": "Update Record", + "value": "UPDATE_RECORD", + "description": "Update an existing record" + }, + { + "label": "Delete Record", + "value": "DELETE_RECORD", + "description": "Delete a record by ID" + }, + { + "label": "List Records", + "value": "LIST_RECORDS", + "description": "List records with optional limit" + }, + { + "label": "Search Records", + "value": "SEARCH_RECORDS", + "description": "Search records with query or filters" + } + ] + }, + { + "id": "tool-CLICKUP", + "category": "tools", + "nodeType": "CLICKUP", + "label": "ClickUp", + "description": "Manage ClickUp tasks, lists, comments, and custom fields", + "contract": { + "contractVersion": 1, + "type": "CLICKUP", + "operations": [ + { + "value": "CREATE_TASK", + "label": "Create Task", + "description": "Create a new task in a list" + }, + { + "value": "GET_TASK", + "label": "Get Task", + "description": "Fetch a task by ID" + }, + { + "value": "UPDATE_TASK", + "label": "Update Task", + "description": "Partially update an existing task" + }, + { + "value": "DELETE_TASK", + "label": "Delete Task", + "description": "Permanently delete a task" + }, + { + "value": "LIST_TASKS", + "label": "List Tasks", + "description": "List tasks in a list with optional filters" + }, + { + "value": "SEARCH_TASKS", + "label": "Search Tasks", + "description": "Search tasks across an entire workspace" + }, + { + "value": "ADD_COMMENT", + "label": "Add Comment", + "description": "Post a comment on a task" + }, + { + "value": "SET_CUSTOM_FIELD", + "label": "Set Custom Field", + "description": "Set a single custom field value on a task" + }, + { + "value": "GET_LISTS", + "label": "Get Lists", + "description": "Fetch lists in a space or folder" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "ClickUp Account", + "description": "Select or connect a ClickUp workspace", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "clickup" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_TASK", + "label": "Create Task" + }, + { + "id": "GET_TASK", + "label": "Get Task" + }, + { + "id": "UPDATE_TASK", + "label": "Update Task" + }, + { + "id": "DELETE_TASK", + "label": "Delete Task" + }, + { + "id": "LIST_TASKS", + "label": "List Tasks" + }, + { + "id": "SEARCH_TASKS", + "label": "Search Tasks" + }, + { + "id": "ADD_COMMENT", + "label": "Add Comment" + }, + { + "id": "SET_CUSTOM_FIELD", + "label": "Set Custom Field" + }, + { + "id": "GET_LISTS", + "label": "Get Lists" + } + ], + "defaultValue": "CREATE_TASK", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "spaceId", + "type": "short-input", + "label": "Space", + "description": "Pick a Space (or paste a Space ID / variable)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "LIST_TASKS", + "GET_LISTS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderId", + "type": "short-input", + "label": "Folder", + "description": "Optional — leave blank for folderless lists", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "LIST_TASKS", + "GET_LISTS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listId", + "type": "short-input", + "label": "List", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "LIST_TASKS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "teamId", + "type": "short-input", + "label": "Workspace ID", + "description": "ClickUp Workspace (team) ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_TASKS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "taskId", + "type": "short-input", + "label": "Task ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_TASK", + "UPDATE_TASK", + "DELETE_TASK", + "ADD_COMMENT", + "SET_CUSTOM_FIELD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "taskName", + "type": "short-input", + "label": "Task Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "description", + "type": "long-input", + "label": "Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "priority", + "type": "dropdown", + "label": "Priority", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "options": [ + { + "id": "1", + "label": "Urgent" + }, + { + "id": "2", + "label": "High" + }, + { + "id": "3", + "label": "Normal" + }, + { + "id": "4", + "label": "Low" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "dueDate", + "type": "short-input", + "label": "Due Date", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "assignees", + "type": "short-input", + "label": "Assignees", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tags", + "type": "short-input", + "label": "Tags", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_TASK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "customFields", + "type": "code", + "label": "Custom Fields", + "description": "JSON object: { fieldId: value }. Get fieldIds from List > Custom Fields.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_TASK", + "UPDATE_TASK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fieldId", + "type": "short-input", + "label": "Field ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SET_CUSTOM_FIELD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fieldValue", + "type": "short-input", + "label": "Field Value", + "description": "Plain text for text fields; numbers for number fields; JSON for arrays/objects", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SET_CUSTOM_FIELD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "commentText", + "type": "long-input", + "label": "Comment", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADD_COMMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "commentAssignee", + "type": "short-input", + "label": "Assignee (optional)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADD_COMMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "statuses", + "type": "short-input", + "label": "Statuses", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_TASKS", + "SEARCH_TASKS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_TASKS", + "SEARCH_TASKS" + ] + }, + "defaultValue": 50, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Task", + "value": "CREATE_TASK", + "description": "Create a new task in a list" + }, + { + "label": "Get Task", + "value": "GET_TASK", + "description": "Fetch a task by ID" + }, + { + "label": "Update Task", + "value": "UPDATE_TASK", + "description": "Partially update an existing task" + }, + { + "label": "Delete Task", + "value": "DELETE_TASK", + "description": "Permanently delete a task" + }, + { + "label": "List Tasks", + "value": "LIST_TASKS", + "description": "List tasks in a list with optional filters" + }, + { + "label": "Search Tasks", + "value": "SEARCH_TASKS", + "description": "Search tasks across an entire workspace" + }, + { + "label": "Add Comment", + "value": "ADD_COMMENT", + "description": "Post a comment on a task" + }, + { + "label": "Set Custom Field", + "value": "SET_CUSTOM_FIELD", + "description": "Set a single custom field value on a task" + }, + { + "label": "Get Lists", + "value": "GET_LISTS", + "description": "Fetch lists in a space or folder" + } + ] + }, + { + "id": "tool-DUB", + "category": "tools", + "nodeType": "DUB", + "label": "Dub", + "description": "Create short links and read analytics with Dub.co", + "contract": { + "contractVersion": 1, + "type": "DUB", + "operations": [ + { + "value": "CREATE_SHORT_LINK", + "label": "Create Short Link", + "description": "Shorten a URL into a Dub link" + }, + { + "value": "GET_LINK_ANALYTICS", + "label": "Get Link Analytics", + "description": "Fetch click analytics for a link over a time range" + }, + { + "value": "LIST_LINKS", + "label": "List Links", + "description": "List links in the connected workspace" + }, + { + "value": "UPDATE_LINK", + "label": "Update Link", + "description": "Update destination URL or metadata" + }, + { + "value": "DELETE_LINK", + "label": "Delete Link", + "description": "Permanently delete a short link" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Dub Account", + "description": "Select or connect a Dub workspace", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "dub" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_SHORT_LINK", + "label": "Create Short Link" + }, + { + "id": "GET_LINK_ANALYTICS", + "label": "Get Link Analytics" + }, + { + "id": "LIST_LINKS", + "label": "List Links" + }, + { + "id": "UPDATE_LINK", + "label": "Update Link" + }, + { + "id": "DELETE_LINK", + "label": "Delete Link" + } + ], + "defaultValue": "CREATE_SHORT_LINK", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "url", + "type": "short-input", + "label": "Destination URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_SHORT_LINK", + "UPDATE_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "domain", + "type": "short-input", + "label": "Domain", + "description": "Custom short domain — leave blank to use Dub's default", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SHORT_LINK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "key", + "type": "short-input", + "label": "Custom Slug", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SHORT_LINK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_SHORT_LINK", + "UPDATE_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "description", + "type": "long-input", + "label": "Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_SHORT_LINK", + "UPDATE_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "expiresAt", + "type": "short-input", + "label": "Expires At", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_SHORT_LINK", + "UPDATE_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkId", + "type": "short-input", + "label": "Link ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_LINK_ANALYTICS", + "UPDATE_LINK", + "DELETE_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "interval", + "type": "dropdown", + "label": "Interval", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_LINK_ANALYTICS" + }, + "options": [ + { + "id": "24h", + "label": "Last 24 hours" + }, + { + "id": "7d", + "label": "Last 7 days" + }, + { + "id": "30d", + "label": "Last 30 days" + }, + { + "id": "90d", + "label": "Last 90 days" + }, + { + "id": "1y", + "label": "Last year" + }, + { + "id": "all", + "label": "All time" + } + ], + "defaultValue": "30d", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "search", + "type": "short-input", + "label": "Search", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_LINKS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_LINKS" + }, + "defaultValue": 50, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Short Link", + "value": "CREATE_SHORT_LINK", + "description": "Shorten a URL into a Dub link" + }, + { + "label": "Get Link Analytics", + "value": "GET_LINK_ANALYTICS", + "description": "Fetch click analytics for a link over a time range" + }, + { + "label": "List Links", + "value": "LIST_LINKS", + "description": "List links in the connected workspace" + }, + { + "label": "Update Link", + "value": "UPDATE_LINK", + "description": "Update destination URL or metadata" + }, + { + "label": "Delete Link", + "value": "DELETE_LINK", + "description": "Permanently delete a short link" + } + ] + }, + { + "id": "tool-NOTION", + "category": "tools", + "nodeType": "NOTION", + "label": "Notion", + "description": "Read, create, and query Notion pages and databases", + "contract": { + "contractVersion": 1, + "type": "NOTION", + "operations": [ + { + "value": "READ_PAGE", + "label": "Read Page", + "description": "Read a Notion page" + }, + { + "value": "READ_DATABASE", + "label": "Read Database", + "description": "Read a Notion database" + }, + { + "value": "CREATE_PAGE", + "label": "Create Page", + "description": "Create a new page" + }, + { + "value": "CREATE_DATABASE", + "label": "Create Database", + "description": "Create a new database" + }, + { + "value": "ADD_DATABASE_ROW", + "label": "Add Database Row", + "description": "Add a row to a database" + }, + { + "value": "APPEND_CONTENT", + "label": "Append Content", + "description": "Append content to a page" + }, + { + "value": "QUERY_DATABASE", + "label": "Query Database", + "description": "Query a database with filters" + }, + { + "value": "SEARCH_WORKSPACE", + "label": "Search Workspace", + "description": "Search across the workspace" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Notion Account", + "description": "Select or connect a Notion workspace", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "notion" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "READ_PAGE", + "label": "Read Page" + }, + { + "id": "READ_DATABASE", + "label": "Read Database" + }, + { + "id": "CREATE_PAGE", + "label": "Create Page" + }, + { + "id": "CREATE_DATABASE", + "label": "Create Database" + }, + { + "id": "ADD_DATABASE_ROW", + "label": "Add Database Row" + }, + { + "id": "APPEND_CONTENT", + "label": "Append Content" + }, + { + "id": "QUERY_DATABASE", + "label": "Query Database" + }, + { + "id": "SEARCH_WORKSPACE", + "label": "Search Workspace" + } + ], + "defaultValue": "READ_PAGE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "pageId", + "type": "short-input", + "label": "Page ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_PAGE", + "APPEND_CONTENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "databaseId", + "type": "short-input", + "label": "Database ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "READ_DATABASE", + "ADD_DATABASE_ROW", + "QUERY_DATABASE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "parentId", + "type": "short-input", + "label": "Parent ID", + "description": "Parent page or database ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_PAGE", + "CREATE_DATABASE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_PAGE", + "CREATE_DATABASE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "properties", + "type": "code", + "label": "Properties", + "description": "Properties JSON", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_PAGE", + "ADD_DATABASE_ROW", + "CREATE_DATABASE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_PAGE", + "APPEND_CONTENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_WORKSPACE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "filter", + "type": "code", + "label": "Filter", + "description": "Filter JSON", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "QUERY_DATABASE", + "SEARCH_WORKSPACE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "sorts", + "type": "code", + "label": "Sorts", + "description": "Sort criteria JSON", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "QUERY_DATABASE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Read Page", + "value": "READ_PAGE", + "description": "Read a Notion page" + }, + { + "label": "Read Database", + "value": "READ_DATABASE", + "description": "Read a Notion database" + }, + { + "label": "Create Page", + "value": "CREATE_PAGE", + "description": "Create a new page" + }, + { + "label": "Create Database", + "value": "CREATE_DATABASE", + "description": "Create a new database" + }, + { + "label": "Add Database Row", + "value": "ADD_DATABASE_ROW", + "description": "Add a row to a database" + }, + { + "label": "Append Content", + "value": "APPEND_CONTENT", + "description": "Append content to a page" + }, + { + "label": "Query Database", + "value": "QUERY_DATABASE", + "description": "Query a database with filters" + }, + { + "label": "Search Workspace", + "value": "SEARCH_WORKSPACE", + "description": "Search across the workspace" + } + ] + }, + { + "id": "tool-RESEND", + "category": "tools", + "nodeType": "RESEND", + "label": "Resend", + "description": "Send emails using the Resend email API", + "contract": { + "contractVersion": 1, + "type": "RESEND", + "operations": [ + { + "value": "SEND_EMAIL", + "label": "Send Email" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "resendApiKey", + "type": "short-input", + "label": "Resend API Key", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "fromAddress", + "type": "short-input", + "label": "From Address", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "to", + "type": "short-input", + "label": "To", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "subject", + "type": "short-input", + "label": "Subject", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Body", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "contentType", + "type": "dropdown", + "label": "Content Type", + "required": false, + "visible": true, + "options": [ + { + "id": "text", + "label": "Plain Text" + }, + { + "id": "html", + "label": "HTML" + } + ], + "defaultValue": "text", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cc", + "type": "short-input", + "label": "CC", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bcc", + "type": "short-input", + "label": "BCC", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "replyTo", + "type": "short-input", + "label": "Reply To", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "id": { + "type": "string", + "description": "Email ID returned by Resend" + }, + "from": { + "type": "string", + "description": "Sender email address" + }, + "to": { + "type": "string", + "description": "Recipient email address" + }, + "subject": { + "type": "string", + "description": "Email subject" + }, + "success": { + "type": "boolean", + "description": "Whether the email was sent" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Send Email", + "value": "SEND_EMAIL", + "description": "" + } + ] + }, + { + "id": "tool-TELEGRAM", + "category": "tools", + "nodeType": "TELEGRAM", + "label": "Telegram", + "description": "Send messages, photos, videos, and documents via Telegram", + "contract": { + "contractVersion": 1, + "type": "TELEGRAM", + "operations": [ + { + "value": "SEND_MESSAGE", + "label": "Send Message" + }, + { + "value": "SEND_PHOTO", + "label": "Send Photo" + }, + { + "value": "SEND_VIDEO", + "label": "Send Video" + }, + { + "value": "SEND_AUDIO", + "label": "Send Audio" + }, + { + "value": "SEND_ANIMATION", + "label": "Send Animation" + }, + { + "value": "SEND_DOCUMENT", + "label": "Send Document" + }, + { + "value": "DELETE_MESSAGE", + "label": "Delete Message" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": false, + "visible": true, + "options": [ + { + "id": "send_message", + "label": "Send Message" + }, + { + "id": "send_photo", + "label": "Send Photo" + }, + { + "id": "send_video", + "label": "Send Video" + }, + { + "id": "send_audio", + "label": "Send Audio" + }, + { + "id": "send_animation", + "label": "Send Animation" + }, + { + "id": "send_document", + "label": "Send Document" + }, + { + "id": "delete_message", + "label": "Delete Message" + } + ], + "defaultValue": "send_message", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "botToken", + "type": "short-input", + "label": "Bot Token", + "description": "Getting Bot Token:\n1. Message \"/newbot\" to @BotFather\n2. Choose a name for your bot\n3. Copy the token and paste it here", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "chatId", + "type": "short-input", + "label": "Chat ID", + "description": "Getting Chat ID:\n1. Add your bot to the desired channel\n2. Send any message to the channel\n3. Visit https://api.telegram.org/bot/getUpdates\n4. Find the chat ID in the JSON response", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "text", + "type": "long-input", + "label": "Message", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_message" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "photo", + "type": "short-input", + "label": "Photo", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_photo" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "video", + "type": "short-input", + "label": "Video", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_video" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "audio", + "type": "short-input", + "label": "Audio", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_audio" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "animation", + "type": "short-input", + "label": "Animation", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_animation" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "document", + "type": "short-input", + "label": "Document", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "send_document" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "caption", + "type": "long-input", + "label": "Caption", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "send_photo", + "send_video", + "send_audio", + "send_animation", + "send_document" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "messageId", + "type": "short-input", + "label": "Message ID", + "required": true, + "visible": false, + "condition": { + "field": "operation", + "value": "delete_message" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "message": { + "type": "string", + "description": "Success or error message" + }, + "data": { + "type": "json", + "description": "Telegram API response data" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Send Message", + "value": "SEND_MESSAGE", + "description": "" + }, + { + "label": "Send Photo", + "value": "SEND_PHOTO", + "description": "" + }, + { + "label": "Send Video", + "value": "SEND_VIDEO", + "description": "" + }, + { + "label": "Send Audio", + "value": "SEND_AUDIO", + "description": "" + }, + { + "label": "Send Animation", + "value": "SEND_ANIMATION", + "description": "" + }, + { + "label": "Send Document", + "value": "SEND_DOCUMENT", + "description": "" + }, + { + "label": "Delete Message", + "value": "DELETE_MESSAGE", + "description": "" + } + ] + }, + { + "id": "tool-LINKEDIN", + "category": "tools", + "nodeType": "LINKEDIN", + "label": "LinkedIn", + "description": "Share posts and retrieve profile data from LinkedIn", + "contract": { + "contractVersion": 1, + "type": "LINKEDIN", + "operations": [ + { + "value": "SHARE_POST", + "label": "Share Post", + "description": "Share a post on LinkedIn" + }, + { + "value": "GET_PROFILE", + "label": "Get Profile", + "description": "Retrieve LinkedIn profile information" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkedInAccountId", + "type": "oauth-input", + "label": "LinkedIn Account", + "description": "Select or connect a LinkedIn account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "linkedin" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SHARE_POST", + "label": "Share Post" + }, + { + "id": "GET_PROFILE", + "label": "Get Profile" + } + ], + "defaultValue": "SHARE_POST", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "text", + "type": "long-input", + "label": "Post Text", + "description": "Max 3000 characters", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SHARE_POST" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "imageUrl", + "type": "short-input", + "label": "Image URL", + "description": "Optional image to attach to the post", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SHARE_POST" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "articleUrl", + "type": "short-input", + "label": "Article URL", + "description": "Optional article link to share with the post", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SHARE_POST" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "visibility", + "type": "dropdown", + "label": "Visibility", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SHARE_POST" + }, + "options": [ + { + "id": "PUBLIC", + "label": "Public" + }, + { + "id": "CONNECTIONS", + "label": "Connections Only" + } + ], + "defaultValue": "PUBLIC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Share Post", + "value": "SHARE_POST", + "description": "Share a post on LinkedIn" + }, + { + "label": "Get Profile", + "value": "GET_PROFILE", + "description": "Retrieve LinkedIn profile information" + } + ] + }, + { + "id": "tool-FACEBOOK", + "category": "tools", + "nodeType": "FACEBOOK", + "label": "Facebook", + "description": "Publish posts and Stories to Facebook Pages", + "contract": { + "contractVersion": 1, + "type": "FACEBOOK", + "operations": [ + { + "value": "PUBLISH_PAGE_POST", + "label": "Publish Page Post", + "description": "Publish a feed post or Story to a Facebook Page" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the published post", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "facebookAccountId", + "type": "oauth-input", + "label": "Facebook Account", + "description": "Select a connected Facebook account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "facebook" + }, + { + "name": "pageId", + "type": "dropdown", + "label": "Facebook Page", + "description": "Page that will publish the post", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "facebookAccountId" + ] + }, + { + "name": "postType", + "type": "dropdown", + "label": "Post Type", + "required": true, + "visible": true, + "options": [ + { + "id": "TEXT", + "label": "Text" + }, + { + "id": "LINK", + "label": "Link" + }, + { + "id": "IMAGE", + "label": "Single image" + }, + { + "id": "MULTI_IMAGE", + "label": "Multiple images" + }, + { + "id": "IMAGE_STORY", + "label": "Image Story" + }, + { + "id": "VIDEO_STORY", + "label": "Video Story" + } + ], + "defaultValue": "TEXT", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "message", + "type": "long-input", + "label": "Message", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkUrl", + "type": "short-input", + "label": "Link URL", + "required": false, + "visible": false, + "condition": { + "field": "postType", + "value": "LINK" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "imageUrl", + "type": "short-input", + "label": "Image URL", + "description": "Public HTTPS image URL that Facebook can fetch", + "required": false, + "visible": false, + "condition": { + "field": "postType", + "value": "IMAGE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Published Facebook Page post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Publish Page Post", + "value": "PUBLISH_PAGE_POST", + "description": "Publish a feed post or Story to a Facebook Page" + } + ] + }, + { + "id": "tool-INSTAGRAM", + "category": "tools", + "nodeType": "INSTAGRAM", + "label": "Instagram", + "description": "Publish feed images and Stories to an Instagram professional account", + "contract": { + "contractVersion": 1, + "type": "INSTAGRAM", + "operations": [ + { + "value": "PUBLISH_MEDIA", + "label": "Publish Media", + "description": "Publish a feed image or Story to Instagram" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the published post", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "instagramAccountId", + "type": "oauth-input", + "label": "Instagram Connection", + "description": "Select a separately connected Instagram account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "instagram" + }, + { + "name": "pageId", + "type": "short-input", + "label": "Linked Facebook Page", + "description": "Stored automatically when an Instagram account is selected", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "instagramUserId", + "type": "short-input", + "label": "Instagram Professional Account", + "description": "Stored automatically when an Instagram account is selected", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "publishType", + "type": "dropdown", + "label": "Publish Type", + "required": true, + "visible": true, + "options": [ + { + "id": "FEED_IMAGE", + "label": "Feed image" + }, + { + "id": "IMAGE_STORY", + "label": "Image Story" + }, + { + "id": "VIDEO_STORY", + "label": "Video Story" + } + ], + "defaultValue": "FEED_IMAGE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "imageUrl", + "type": "short-input", + "label": "Image URL", + "description": "Public HTTPS URL that Meta can fetch during publishing", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "caption", + "type": "long-input", + "label": "Caption", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Published Instagram post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Publish Media", + "value": "PUBLISH_MEDIA", + "description": "Publish a feed image or Story to Instagram" + } + ] + }, + { + "id": "tool-TYPEFORM", + "category": "tools", + "nodeType": "TYPEFORM", + "label": "Typeform", + "description": "Create, manage, and collect responses from Typeform forms", + "contract": { + "contractVersion": 1, + "type": "TYPEFORM", + "operations": [ + { + "value": "LIST_FORMS", + "label": "List Forms", + "description": "List all forms in your Typeform account" + }, + { + "value": "GET_FORM", + "label": "Get Form", + "description": "Get the full definition of a specific form" + }, + { + "value": "CREATE_FORM", + "label": "Create Form", + "description": "Create a new Typeform form with fields and settings" + }, + { + "value": "UPDATE_FORM", + "label": "Update Form", + "description": "Update an existing form with a new definition" + }, + { + "value": "DELETE_FORM", + "label": "Delete Form", + "description": "Permanently delete a form" + }, + { + "value": "GET_RESPONSES", + "label": "Get Responses", + "description": "Retrieve form responses with optional date range filtering" + }, + { + "value": "GET_FORM_INSIGHTS", + "label": "Get Form Insights", + "description": "Get analytics and insights for a form" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Enter your Typeform API key or use an environment variable like {{TYPEFORM_API_KEY}}", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose which Typeform operation to perform", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_FORMS", + "label": "List Forms" + }, + { + "id": "GET_FORM", + "label": "Get Form" + }, + { + "id": "CREATE_FORM", + "label": "Create Form" + }, + { + "id": "UPDATE_FORM", + "label": "Update Form" + }, + { + "id": "DELETE_FORM", + "label": "Delete Form" + }, + { + "id": "GET_RESPONSES", + "label": "Get Responses" + }, + { + "id": "GET_FORM_INSIGHTS", + "label": "Get Form Insights" + } + ], + "defaultValue": "LIST_FORMS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "formId", + "type": "short-input", + "label": "Form ID", + "description": "The unique identifier of the Typeform form", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_FORM", + "UPDATE_FORM", + "DELETE_FORM", + "GET_RESPONSES", + "GET_FORM_INSIGHTS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "page", + "type": "number-input", + "label": "Page", + "description": "Page number (starts at 1)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_FORMS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "pageSize", + "type": "number-input", + "label": "Page Size", + "description": "Number of forms per page (max 200)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_FORMS" + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 200 + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "description": "Title for the new form", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FORM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fields", + "type": "code", + "label": "Fields", + "description": "JSON array of form field definitions", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FORM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "settings", + "type": "code", + "label": "Settings", + "description": "Form settings as JSON object", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FORM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "workspace", + "type": "short-input", + "label": "Workspace", + "description": "Workspace ID or URL to create the form in", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FORM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "formDefinition", + "type": "code", + "label": "Form Definition", + "description": "Full form definition JSON to update", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_FORM" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "responsePageSize", + "type": "number-input", + "label": "Response Page Size", + "description": "Number of responses per page (max 1000)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_RESPONSES" + }, + "defaultValue": 25, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 1000 + }, + { + "name": "since", + "type": "short-input", + "label": "Since", + "description": "Only return responses submitted after this date (ISO 8601)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_RESPONSES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "until", + "type": "short-input", + "label": "Until", + "description": "Only return responses submitted before this date (ISO 8601)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_RESPONSES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "List Forms", + "value": "LIST_FORMS", + "description": "List all forms in your Typeform account" + }, + { + "label": "Get Form", + "value": "GET_FORM", + "description": "Get the full definition of a specific form" + }, + { + "label": "Create Form", + "value": "CREATE_FORM", + "description": "Create a new Typeform form with fields and settings" + }, + { + "label": "Update Form", + "value": "UPDATE_FORM", + "description": "Update an existing form with a new definition" + }, + { + "label": "Delete Form", + "value": "DELETE_FORM", + "description": "Permanently delete a form" + }, + { + "label": "Get Responses", + "value": "GET_RESPONSES", + "description": "Retrieve form responses with optional date range filtering" + }, + { + "label": "Get Form Insights", + "value": "GET_FORM_INSIGHTS", + "description": "Get analytics and insights for a form" + } + ] + }, + { + "id": "tool-TRELLO", + "category": "tools", + "nodeType": "TRELLO", + "label": "Trello", + "description": "Manage Trello boards, lists, cards, and comments", + "contract": { + "contractVersion": 1, + "type": "TRELLO", + "operations": [ + { + "value": "GET_LISTS", + "label": "Get Lists", + "description": "Get all lists on a board" + }, + { + "value": "LIST_CARDS", + "label": "List Cards", + "description": "List cards in a list" + }, + { + "value": "CREATE_CARD", + "label": "Create Card", + "description": "Create a new card" + }, + { + "value": "UPDATE_CARD", + "label": "Update Card", + "description": "Update an existing card" + }, + { + "value": "GET_ACTIONS", + "label": "Get Actions", + "description": "Get activity on a card" + }, + { + "value": "ADD_COMMENT", + "label": "Add Comment", + "description": "Add a comment to a card" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Trello Account", + "description": "Select or connect a Trello account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "trello" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "GET_LISTS", + "label": "Get Lists" + }, + { + "id": "LIST_CARDS", + "label": "List Cards" + }, + { + "id": "CREATE_CARD", + "label": "Create Card" + }, + { + "id": "UPDATE_CARD", + "label": "Update Card" + }, + { + "id": "GET_ACTIONS", + "label": "Get Actions" + }, + { + "id": "ADD_COMMENT", + "label": "Add Comment" + } + ], + "defaultValue": "GET_LISTS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "boardId", + "type": "short-input", + "label": "Board ID", + "description": "Trello Board ID", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listId", + "type": "short-input", + "label": "List ID", + "description": "Trello List ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_CARDS", + "CREATE_CARD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cardId", + "type": "short-input", + "label": "Card ID", + "description": "Trello Card ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_CARD", + "GET_ACTIONS", + "ADD_COMMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "name", + "type": "short-input", + "label": "Card Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_CARD", + "UPDATE_CARD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "desc", + "type": "long-input", + "label": "Card Description", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_CARD", + "UPDATE_CARD" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "idList", + "type": "short-input", + "label": "Target List ID", + "description": "Move card to this list", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_CARD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "text", + "type": "long-input", + "label": "Comment Text", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADD_COMMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Get Lists", + "value": "GET_LISTS", + "description": "Get all lists on a board" + }, + { + "label": "List Cards", + "value": "LIST_CARDS", + "description": "List cards in a list" + }, + { + "label": "Create Card", + "value": "CREATE_CARD", + "description": "Create a new card" + }, + { + "label": "Update Card", + "value": "UPDATE_CARD", + "description": "Update an existing card" + }, + { + "label": "Get Actions", + "value": "GET_ACTIONS", + "description": "Get activity on a card" + }, + { + "label": "Add Comment", + "value": "ADD_COMMENT", + "description": "Add a comment to a card" + } + ] + }, + { + "id": "tool-AHREFS", + "category": "tools", + "nodeType": "AHREFS", + "label": "Ahrefs", + "description": "SEO analytics — domain ratings, backlinks, keywords, and more", + "contract": { + "contractVersion": 1, + "type": "AHREFS", + "operations": [ + { + "value": "DOMAIN_RATING", + "label": "Domain Rating", + "description": "Get the Domain Rating score and rank" + }, + { + "value": "BACKLINKS_STATS", + "label": "Backlinks Stats", + "description": "Get backlink and referring domain counts" + }, + { + "value": "ORGANIC_KEYWORDS", + "label": "Organic Keywords", + "description": "Get organic keyword rankings" + }, + { + "value": "TOP_PAGES", + "label": "Top Pages", + "description": "Get top pages by organic traffic" + }, + { + "value": "REFERRING_DOMAINS", + "label": "Referring Domains", + "description": "Get referring domains list" + } + ], + "fields": [ + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Ahrefs API key - set in Settings > Secrets or paste directly", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "DOMAIN_RATING", + "label": "Domain Rating" + }, + { + "id": "BACKLINKS_STATS", + "label": "Backlinks Stats" + }, + { + "id": "ORGANIC_KEYWORDS", + "label": "Organic Keywords" + }, + { + "id": "TOP_PAGES", + "label": "Top Pages" + }, + { + "id": "REFERRING_DOMAINS", + "label": "Referring Domains" + } + ], + "defaultValue": "DOMAIN_RATING", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "target", + "type": "short-input", + "label": "Target Domain", + "description": "The domain to analyze", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "date", + "type": "date-picker", + "label": "Date", + "description": "Historical date for the data snapshot. Leave empty for the latest available data.", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "DOMAIN_RATING", + "BACKLINKS_STATS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "country", + "type": "short-input", + "label": "Country", + "description": "Two-letter country code (e.g. us, gb, de)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ORGANIC_KEYWORDS", + "TOP_PAGES" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Result Limit", + "description": "Maximum number of results to return (1–1000)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ORGANIC_KEYWORDS", + "TOP_PAGES", + "REFERRING_DOMAINS" + ] + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 1000 + }, + { + "name": "mode", + "type": "dropdown", + "label": "Mode", + "description": "Target matching mode — subdomains includes all subdomains, exact matches only the target, prefix matches URLs starting with the target", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "BACKLINKS_STATS", + "REFERRING_DOMAINS" + ] + }, + "options": [ + { + "id": "subdomains", + "label": "Subdomains" + }, + { + "id": "exact", + "label": "Exact" + }, + { + "id": "prefix", + "label": "Prefix" + } + ], + "defaultValue": "subdomains", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "target": { + "type": "string", + "description": "The analyzed domain" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Domain Rating", + "value": "DOMAIN_RATING", + "description": "Get the Domain Rating score and rank" + }, + { + "label": "Backlinks Stats", + "value": "BACKLINKS_STATS", + "description": "Get backlink and referring domain counts" + }, + { + "label": "Organic Keywords", + "value": "ORGANIC_KEYWORDS", + "description": "Get organic keyword rankings" + }, + { + "label": "Top Pages", + "value": "TOP_PAGES", + "description": "Get top pages by organic traffic" + }, + { + "label": "Referring Domains", + "value": "REFERRING_DOMAINS", + "description": "Get referring domains list" + } + ] + }, + { + "id": "tool-APOLLO", + "category": "tools", + "nodeType": "APOLLO", + "label": "Apollo", + "description": "Search, enrich, and manage contacts and organizations via Apollo.io", + "contract": { + "contractVersion": 1, + "type": "APOLLO", + "operations": [ + { + "value": "SEARCH_PEOPLE", + "label": "Search People", + "description": "Search for people by title, location, seniority, and company" + }, + { + "value": "ENRICH_PERSON", + "label": "Enrich Person", + "description": "Get detailed info about a person by email, name, or LinkedIn" + }, + { + "value": "BULK_ENRICH_PEOPLE", + "label": "Bulk Enrich People", + "description": "Enrich multiple people at once from a JSON array" + }, + { + "value": "SEARCH_ORGANIZATIONS", + "label": "Search Organizations", + "description": "Search for companies by location, size, and keywords" + }, + { + "value": "ENRICH_ORGANIZATION", + "label": "Enrich Organization", + "description": "Get detailed info about a company by domain" + }, + { + "value": "BULK_ENRICH_ORGANIZATIONS", + "label": "Bulk Enrich Organizations", + "description": "Enrich multiple organizations by domain" + }, + { + "value": "CREATE_CONTACT", + "label": "Create Contact", + "description": "Create a new contact in Apollo CRM" + }, + { + "value": "UPDATE_CONTACT", + "label": "Update Contact", + "description": "Update an existing contact by ID" + }, + { + "value": "SEARCH_CONTACTS", + "label": "Search Contacts", + "description": "Search contacts in your Apollo CRM" + }, + { + "value": "BULK_CREATE_CONTACTS", + "label": "Bulk Create Contacts", + "description": "Create multiple contacts from a JSON array" + } + ], + "fields": [ + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Enter your Apollo.io API key or use an environment variable like {{APOLLO_API_KEY}}", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose which Apollo.io operation to perform", + "required": true, + "visible": true, + "options": [ + { + "id": "SEARCH_PEOPLE", + "label": "Search People" + }, + { + "id": "ENRICH_PERSON", + "label": "Enrich Person" + }, + { + "id": "BULK_ENRICH_PEOPLE", + "label": "Bulk Enrich People" + }, + { + "id": "SEARCH_ORGANIZATIONS", + "label": "Search Organizations" + }, + { + "id": "ENRICH_ORGANIZATION", + "label": "Enrich Organization" + }, + { + "id": "BULK_ENRICH_ORGANIZATIONS", + "label": "Bulk Enrich Organizations" + }, + { + "id": "CREATE_CONTACT", + "label": "Create Contact" + }, + { + "id": "UPDATE_CONTACT", + "label": "Update Contact" + }, + { + "id": "SEARCH_CONTACTS", + "label": "Search Contacts" + }, + { + "id": "BULK_CREATE_CONTACTS", + "label": "Bulk Create Contacts" + } + ], + "defaultValue": "SEARCH_PEOPLE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "personTitles", + "type": "short-input", + "label": "Job Titles", + "description": "Comma-separated titles", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_PEOPLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "personLocations", + "type": "short-input", + "label": "Locations", + "description": "Comma-separated locations (e.g., San Francisco, New York)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_PEOPLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "personSeniorities", + "type": "short-input", + "label": "Seniorities", + "description": "Comma-separated seniority levels", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_PEOPLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "organizationDomains", + "type": "short-input", + "label": "Organization Domains", + "description": "Comma-separated company domains to filter by", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_PEOPLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "email", + "type": "short-input", + "label": "Email", + "description": "Email address", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ENRICH_PERSON", + "CREATE_CONTACT", + "UPDATE_CONTACT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "firstName", + "type": "short-input", + "label": "First Name", + "description": "First name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ENRICH_PERSON", + "CREATE_CONTACT", + "UPDATE_CONTACT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "lastName", + "type": "short-input", + "label": "Last Name", + "description": "Last name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ENRICH_PERSON", + "CREATE_CONTACT", + "UPDATE_CONTACT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "organizationName", + "type": "short-input", + "label": "Organization Name", + "description": "Company name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "ENRICH_PERSON", + "CREATE_CONTACT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "domain", + "type": "short-input", + "label": "Domain", + "description": "Company domain for matching", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ENRICH_PERSON" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkedinUrl", + "type": "short-input", + "label": "LinkedIn URL", + "description": "LinkedIn profile URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ENRICH_PERSON" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bulkEnrichDetails", + "type": "long-input", + "label": "Details (JSON)", + "description": "JSON array of objects with email, first_name, last_name, domain, linkedin_url", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "BULK_ENRICH_PEOPLE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "organizationLocations", + "type": "short-input", + "label": "Locations", + "description": "Comma-separated organization locations", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_ORGANIZATIONS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "numEmployeesRanges", + "type": "short-input", + "label": "Employee Count Ranges", + "description": "Ranges: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_ORGANIZATIONS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "keywordTags", + "type": "short-input", + "label": "Keyword Tags", + "description": "Comma-separated industry/keyword tags", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_ORGANIZATIONS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "enrichDomain", + "type": "short-input", + "label": "Domain", + "description": "Company domain to enrich", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ENRICH_ORGANIZATION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bulkEnrichDomains", + "type": "long-input", + "label": "Domains", + "description": "Comma-separated domain names", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "BULK_ENRICH_ORGANIZATIONS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "description": "Job title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_CONTACT", + "UPDATE_CONTACT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "accountId", + "type": "short-input", + "label": "Account ID", + "description": "Apollo account ID to associate with", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CONTACT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "contactId", + "type": "short-input", + "label": "Contact ID", + "description": "ID of the contact to update", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPDATE_CONTACT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "keywords", + "type": "short-input", + "label": "Keywords", + "description": "Search keywords for contacts", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_CONTACTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "sortByField", + "type": "dropdown", + "label": "Sort By", + "description": "Field to sort results by", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_CONTACTS" + }, + "options": [ + { + "id": "contact_updated_at", + "label": "Updated At" + }, + { + "id": "contact_created_at", + "label": "Created At" + }, + { + "id": "first_name", + "label": "First Name" + }, + { + "id": "last_name", + "label": "Last Name" + }, + { + "id": "email", + "label": "Email" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bulkCreateContacts", + "type": "long-input", + "label": "Contacts (JSON)", + "description": "JSON array of contact objects with first_name, last_name, email, title, organization_name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "BULK_CREATE_CONTACTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "page", + "type": "number-input", + "label": "Page", + "description": "Page number (starts at 1)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH_PEOPLE", + "SEARCH_ORGANIZATIONS", + "SEARCH_CONTACTS" + ] + }, + "defaultValue": 1, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + }, + { + "name": "perPage", + "type": "number-input", + "label": "Per Page", + "description": "Results per page (max 100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "SEARCH_PEOPLE", + "SEARCH_ORGANIZATIONS", + "SEARCH_CONTACTS" + ] + }, + "defaultValue": 25, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Search People", + "value": "SEARCH_PEOPLE", + "description": "Search for people by title, location, seniority, and company" + }, + { + "label": "Enrich Person", + "value": "ENRICH_PERSON", + "description": "Get detailed info about a person by email, name, or LinkedIn" + }, + { + "label": "Bulk Enrich People", + "value": "BULK_ENRICH_PEOPLE", + "description": "Enrich multiple people at once from a JSON array" + }, + { + "label": "Search Organizations", + "value": "SEARCH_ORGANIZATIONS", + "description": "Search for companies by location, size, and keywords" + }, + { + "label": "Enrich Organization", + "value": "ENRICH_ORGANIZATION", + "description": "Get detailed info about a company by domain" + }, + { + "label": "Bulk Enrich Organizations", + "value": "BULK_ENRICH_ORGANIZATIONS", + "description": "Enrich multiple organizations by domain" + }, + { + "label": "Create Contact", + "value": "CREATE_CONTACT", + "description": "Create a new contact in Apollo CRM" + }, + { + "label": "Update Contact", + "value": "UPDATE_CONTACT", + "description": "Update an existing contact by ID" + }, + { + "label": "Search Contacts", + "value": "SEARCH_CONTACTS", + "description": "Search contacts in your Apollo CRM" + }, + { + "label": "Bulk Create Contacts", + "value": "BULK_CREATE_CONTACTS", + "description": "Create multiple contacts from a JSON array" + } + ] + }, + { + "id": "tool-CALENDLY", + "category": "tools", + "nodeType": "CALENDLY", + "label": "Calendly", + "description": "Manage events, invitees, and scheduling via Calendly", + "contract": { + "contractVersion": 1, + "type": "CALENDLY", + "operations": [ + { + "value": "GET_CURRENT_USER", + "label": "Get Current User", + "description": "Retrieve the authenticated user's profile information" + }, + { + "value": "LIST_EVENT_TYPES", + "label": "List Event Types", + "description": "List all event types for a user" + }, + { + "value": "GET_EVENT_TYPE", + "label": "Get Event Type", + "description": "Get details of a specific event type" + }, + { + "value": "LIST_SCHEDULED_EVENTS", + "label": "List Scheduled Events", + "description": "List scheduled events for a user with optional filters" + }, + { + "value": "GET_SCHEDULED_EVENT", + "label": "Get Scheduled Event", + "description": "Get details of a specific scheduled event" + }, + { + "value": "LIST_EVENT_INVITEES", + "label": "List Event Invitees", + "description": "List invitees for a scheduled event" + }, + { + "value": "CANCEL_EVENT", + "label": "Cancel Event", + "description": "Cancel a scheduled event with an optional reason" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Enter your Calendly API key or use an environment variable like {{CALENDLY_API_KEY}}", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose which Calendly operation to perform", + "required": true, + "visible": true, + "options": [ + { + "id": "GET_CURRENT_USER", + "label": "Get Current User" + }, + { + "id": "LIST_EVENT_TYPES", + "label": "List Event Types" + }, + { + "id": "GET_EVENT_TYPE", + "label": "Get Event Type" + }, + { + "id": "LIST_SCHEDULED_EVENTS", + "label": "List Scheduled Events" + }, + { + "id": "GET_SCHEDULED_EVENT", + "label": "Get Scheduled Event" + }, + { + "id": "LIST_EVENT_INVITEES", + "label": "List Event Invitees" + }, + { + "id": "CANCEL_EVENT", + "label": "Cancel Event" + } + ], + "defaultValue": "GET_CURRENT_USER", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "userUri", + "type": "short-input", + "label": "User URI", + "description": "Calendly user URI (returned from Get Current User)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_EVENT_TYPES", + "LIST_SCHEDULED_EVENTS" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventTypeUri", + "type": "short-input", + "label": "Event Type URI", + "description": "Full URI of the event type to retrieve", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_EVENT_TYPE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventUri", + "type": "short-input", + "label": "Event URI", + "description": "Full URI of the scheduled event", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_SCHEDULED_EVENT", + "LIST_EVENT_INVITEES", + "CANCEL_EVENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "count", + "type": "number-input", + "label": "Count", + "description": "Number of events to return (1-100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_SCHEDULED_EVENTS" + }, + "defaultValue": 20, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + }, + { + "name": "status", + "type": "dropdown", + "label": "Status", + "description": "Filter events by status", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_SCHEDULED_EVENTS" + }, + "options": [ + { + "id": "active", + "label": "Active" + }, + { + "id": "canceled", + "label": "Canceled" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reason", + "type": "long-input", + "label": "Cancellation Reason", + "description": "Optional reason for canceling the event", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CANCEL_EVENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Get Current User", + "value": "GET_CURRENT_USER", + "description": "Retrieve the authenticated user's profile information" + }, + { + "label": "List Event Types", + "value": "LIST_EVENT_TYPES", + "description": "List all event types for a user" + }, + { + "label": "Get Event Type", + "value": "GET_EVENT_TYPE", + "description": "Get details of a specific event type" + }, + { + "label": "List Scheduled Events", + "value": "LIST_SCHEDULED_EVENTS", + "description": "List scheduled events for a user with optional filters" + }, + { + "label": "Get Scheduled Event", + "value": "GET_SCHEDULED_EVENT", + "description": "Get details of a specific scheduled event" + }, + { + "label": "List Event Invitees", + "value": "LIST_EVENT_INVITEES", + "description": "List invitees for a scheduled event" + }, + { + "label": "Cancel Event", + "value": "CANCEL_EVENT", + "description": "Cancel a scheduled event with an optional reason" + } + ] + }, + { + "id": "tool-CAL_COM", + "category": "tools", + "nodeType": "CAL_COM", + "label": "Cal.com", + "description": "Manage Cal.com event types and bookings", + "contract": { + "contractVersion": 1, + "type": "CAL_COM", + "operations": [ + { + "value": "LIST_EVENT_TYPES", + "label": "List Event Types", + "description": "Retrieve all configured event types" + }, + { + "value": "LIST_BOOKINGS", + "label": "List Bookings", + "description": "Retrieve bookings with optional status filter" + }, + { + "value": "CREATE_BOOKING", + "label": "Create Booking", + "description": "Create a new booking for an event type" + }, + { + "value": "CANCEL_BOOKING", + "label": "Cancel Booking", + "description": "Cancel an existing booking" + }, + { + "value": "RESCHEDULE_BOOKING", + "label": "Reschedule Booking", + "description": "Reschedule an existing booking to a new time" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Cal.com Account", + "description": "Select or connect a Cal.com account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "cal_com" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "LIST_EVENT_TYPES", + "label": "List Event Types" + }, + { + "id": "LIST_BOOKINGS", + "label": "List Bookings" + }, + { + "id": "CREATE_BOOKING", + "label": "Create Booking" + }, + { + "id": "CANCEL_BOOKING", + "label": "Cancel Booking" + }, + { + "id": "RESCHEDULE_BOOKING", + "label": "Reschedule Booking" + } + ], + "defaultValue": "LIST_EVENT_TYPES", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "statusFilter", + "type": "dropdown", + "label": "Status Filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_BOOKINGS" + }, + "options": [ + { + "id": "upcoming", + "label": "Upcoming" + }, + { + "id": "past", + "label": "Past" + }, + { + "id": "cancelled", + "label": "Cancelled" + }, + { + "id": "all", + "label": "All" + } + ], + "defaultValue": "upcoming", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventTypeId", + "type": "short-input", + "label": "Event Type ID", + "description": "The ID of the event type to book", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "startTime", + "type": "short-input", + "label": "Start Time", + "description": "Booking start time in ISO 8601 format", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "attendeeName", + "type": "short-input", + "label": "Attendee Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "attendeeEmail", + "type": "short-input", + "label": "Attendee Email", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "attendeeTimezone", + "type": "short-input", + "label": "Attendee Timezone", + "description": "IANA timezone identifier for the attendee", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "bookingUid", + "type": "short-input", + "label": "Booking UID", + "description": "The unique identifier of the booking", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CANCEL_BOOKING", + "RESCHEDULE_BOOKING" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cancellationReason", + "type": "long-input", + "label": "Cancellation Reason", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CANCEL_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "rescheduleStartTime", + "type": "short-input", + "label": "New Start Time", + "description": "New start time for the rescheduled booking", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RESCHEDULE_BOOKING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "List Event Types", + "value": "LIST_EVENT_TYPES", + "description": "Retrieve all configured event types" + }, + { + "label": "List Bookings", + "value": "LIST_BOOKINGS", + "description": "Retrieve bookings with optional status filter" + }, + { + "label": "Create Booking", + "value": "CREATE_BOOKING", + "description": "Create a new booking for an event type" + }, + { + "label": "Cancel Booking", + "value": "CANCEL_BOOKING", + "description": "Cancel an existing booking" + }, + { + "label": "Reschedule Booking", + "value": "RESCHEDULE_BOOKING", + "description": "Reschedule an existing booking to a new time" + } + ] + }, + { + "id": "tool-REDDIT", + "category": "tools", + "nodeType": "REDDIT", + "label": "Reddit", + "description": "Create, draft, or schedule Reddit posts", + "contract": { + "contractVersion": 1, + "type": "REDDIT", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Create, draft, or schedule Reddit posts" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "Reddit Account", + "description": "Select or connect a Reddit account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "reddit" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "subreddit", + "type": "short-input", + "label": "Subreddit", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Post Title", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkUrl", + "type": "short-input", + "label": "Link URL", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "flairId", + "type": "short-input", + "label": "Flair ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "nativeVideo", + "type": "switch", + "label": "Native Video", + "required": false, + "visible": true, + "defaultValue": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Reddit post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Create, draft, or schedule Reddit posts" + } + ] + }, + { + "id": "tool-BLUESKY", + "category": "tools", + "nodeType": "BLUESKY", + "label": "Bluesky", + "description": "Create, draft, or schedule Bluesky posts", + "contract": { + "contractVersion": 1, + "type": "BLUESKY", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Create, draft, or schedule Bluesky posts" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "Bluesky Account", + "description": "Select or connect a Bluesky account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "bluesky" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Bluesky post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Create, draft, or schedule Bluesky posts" + } + ] + }, + { + "id": "tool-THREADS", + "category": "tools", + "nodeType": "THREADS", + "label": "Threads", + "description": "Create, draft, or schedule Threads posts", + "contract": { + "contractVersion": 1, + "type": "THREADS", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Create, draft, or schedule Threads posts" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "Threads Account", + "description": "Select or connect a Threads account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "threads" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Threads post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Create, draft, or schedule Threads posts" + } + ] + }, + { + "id": "tool-TELEGRAM_POST", + "category": "tools", + "nodeType": "TELEGRAM_POST", + "label": "Telegram", + "description": "Send, draft, or schedule Telegram channel posts", + "contract": { + "contractVersion": 1, + "type": "TELEGRAM_POST", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Send, draft, or schedule Telegram channel posts" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "Telegram Account", + "description": "Select or connect a Telegram account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "telegram" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "parseMode", + "type": "dropdown", + "label": "Parse Mode", + "required": false, + "visible": true, + "options": [ + { + "id": "HTML", + "label": "HTML" + }, + { + "id": "Markdown", + "label": "Markdown" + }, + { + "id": "MarkdownV2", + "label": "MarkdownV2" + } + ], + "defaultValue": "HTML", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "disableWebPagePreview", + "type": "switch", + "label": "Disable Link Preview", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "disableNotification", + "type": "switch", + "label": "Silent Message", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "protectContent", + "type": "switch", + "label": "Protect Content", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Telegram post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Send, draft, or schedule Telegram channel posts" + } + ] + }, + { + "id": "tool-PINTEREST", + "category": "tools", + "nodeType": "PINTEREST", + "label": "Pinterest", + "description": "Create, draft, or schedule Pinterest pins", + "contract": { + "contractVersion": 1, + "type": "PINTEREST", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Create, draft, or schedule Pinterest pins" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "Pinterest Account", + "description": "Select or connect a Pinterest account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "pinterest" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "boardId", + "type": "short-input", + "label": "Board ID", + "description": "Pinterest usually requires a board ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Pin Title", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "linkUrl", + "type": "short-input", + "label": "Destination Link", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "Pinterest post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Create, draft, or schedule Pinterest pins" + } + ] + }, + { + "id": "tool-X", + "category": "tools", + "nodeType": "X", + "label": "X/Twitter", + "description": "Create, draft, or schedule X/Twitter posts", + "contract": { + "contractVersion": 1, + "type": "X", + "operations": [ + { + "value": "CREATE_POST", + "label": "Create Post", + "description": "Create, draft, or schedule X/Twitter posts" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "X/Twitter Account", + "description": "Select or connect a X/Twitter account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "x_native" + }, + { + "name": "publishMode", + "type": "dropdown", + "label": "Publish Mode", + "required": true, + "visible": true, + "options": [ + { + "id": "publish_now", + "label": "Publish Now" + }, + { + "id": "schedule", + "label": "Schedule" + }, + { + "id": "draft", + "label": "Draft" + } + ], + "defaultValue": "publish_now", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "scheduledFor", + "type": "short-input", + "label": "Scheduled For", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timezone", + "type": "short-input", + "label": "Timezone", + "required": false, + "visible": false, + "condition": { + "field": "publishMode", + "value": "schedule" + }, + "defaultValue": "UTC", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "content", + "type": "long-input", + "label": "Content", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mediaUrls", + "type": "long-input", + "label": "Media URLs", + "description": "Optional public image/video URLs, separated by commas or new lines", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "replyToTweetId", + "type": "short-input", + "label": "Reply To Tweet ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "quoteTweetId", + "type": "short-input", + "label": "Quote Tweet ID", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "madeWithAi", + "type": "switch", + "label": "Made With AI", + "required": false, + "visible": true, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "platformSpecificJson", + "type": "code", + "label": "Advanced Platform Settings JSON", + "description": "Optional platform-specific settings. Values here override matching fields above.", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "post": { + "type": "json", + "description": "X/Twitter post result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Post", + "value": "CREATE_POST", + "description": "Create, draft, or schedule X/Twitter posts" + } + ] + }, + { + "id": "tool-WHATSAPP", + "category": "tools", + "nodeType": "WHATSAPP", + "label": "WhatsApp", + "description": "Send WhatsApp template messages", + "contract": { + "contractVersion": 1, + "type": "WHATSAPP", + "operations": [ + { + "value": "SEND_TEMPLATE", + "label": "Send Template Message", + "description": "Send an approved WhatsApp template" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "zernioAccountId", + "type": "oauth-input", + "label": "WhatsApp Account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "whatsapp" + }, + { + "name": "participantId", + "type": "short-input", + "label": "Recipient Phone", + "description": "Digits only, including country code", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "templateName", + "type": "short-input", + "label": "Template Name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "templateLanguage", + "type": "short-input", + "label": "Template Language", + "required": true, + "visible": true, + "defaultValue": "en", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "templateParamsJson", + "type": "code", + "label": "Template Params JSON", + "description": "JSON array of template parameters", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "message": { + "type": "json", + "description": "WhatsApp message result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Send Template Message", + "value": "SEND_TEMPLATE", + "description": "Send an approved WhatsApp template" + } + ] + }, + { + "id": "tool-GITHUB", + "category": "tools", + "nodeType": "GITHUB", + "label": "GitHub", + "description": "Manage GitHub issues, pull requests, and comments", + "contract": { + "contractVersion": 1, + "type": "GITHUB", + "operations": [ + { + "value": "CREATE_ISSUE", + "label": "Create Issue", + "description": "Create a new issue" + }, + { + "value": "LIST_ISSUES", + "label": "List Issues", + "description": "List repository issues" + }, + { + "value": "UPDATE_ISSUE", + "label": "Update Issue", + "description": "Update an existing issue" + }, + { + "value": "CREATE_PR", + "label": "Create Pull Request", + "description": "Create a new pull request" + }, + { + "value": "LIST_PRS", + "label": "List Pull Requests", + "description": "List repository pull requests" + }, + { + "value": "MERGE_PR", + "label": "Merge Pull Request", + "description": "Merge a pull request" + }, + { + "value": "CREATE_COMMENT", + "label": "Create Comment", + "description": "Add a comment to an issue or PR" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "GitHub Account", + "description": "Select or connect a GitHub account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "github" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_ISSUE", + "label": "Create Issue" + }, + { + "id": "LIST_ISSUES", + "label": "List Issues" + }, + { + "id": "UPDATE_ISSUE", + "label": "Update Issue" + }, + { + "id": "CREATE_PR", + "label": "Create Pull Request" + }, + { + "id": "LIST_PRS", + "label": "List Pull Requests" + }, + { + "id": "MERGE_PR", + "label": "Merge Pull Request" + }, + { + "id": "CREATE_COMMENT", + "label": "Create Comment" + } + ], + "defaultValue": "CREATE_ISSUE", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "owner", + "type": "short-input", + "label": "Owner", + "description": "Repository owner", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "repo", + "type": "short-input", + "label": "Repository", + "description": "Repository name", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_ISSUE", + "UPDATE_ISSUE", + "CREATE_PR" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "body", + "type": "long-input", + "label": "Body", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_ISSUE", + "UPDATE_ISSUE", + "CREATE_PR", + "CREATE_COMMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "labels", + "type": "short-input", + "label": "Labels", + "description": "Comma-separated labels", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_ISSUE", + "UPDATE_ISSUE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "assignees", + "type": "short-input", + "label": "Assignees", + "description": "Comma-separated GitHub usernames", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_ISSUE", + "UPDATE_ISSUE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "issueNumber", + "type": "short-input", + "label": "Issue Number", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_ISSUE", + "CREATE_COMMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "state", + "type": "dropdown", + "label": "State", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_ISSUES", + "LIST_PRS" + ] + }, + "options": [ + { + "id": "open", + "label": "Open" + }, + { + "id": "closed", + "label": "Closed" + }, + { + "id": "all", + "label": "All" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "head", + "type": "short-input", + "label": "Source Branch", + "description": "Source branch", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_PR" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "base", + "type": "short-input", + "label": "Target Branch", + "description": "Target branch", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_PR" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "prNumber", + "type": "short-input", + "label": "PR Number", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MERGE_PR" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mergeMethod", + "type": "dropdown", + "label": "Merge Method", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "MERGE_PR" + }, + "options": [ + { + "id": "merge", + "label": "Merge" + }, + { + "id": "squash", + "label": "Squash" + }, + { + "id": "rebase", + "label": "Rebase" + } + ], + "defaultValue": "merge", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Issue", + "value": "CREATE_ISSUE", + "description": "Create a new issue" + }, + { + "label": "List Issues", + "value": "LIST_ISSUES", + "description": "List repository issues" + }, + { + "label": "Update Issue", + "value": "UPDATE_ISSUE", + "description": "Update an existing issue" + }, + { + "label": "Create Pull Request", + "value": "CREATE_PR", + "description": "Create a new pull request" + }, + { + "label": "List Pull Requests", + "value": "LIST_PRS", + "description": "List repository pull requests" + }, + { + "label": "Merge Pull Request", + "value": "MERGE_PR", + "description": "Merge a pull request" + }, + { + "label": "Create Comment", + "value": "CREATE_COMMENT", + "description": "Add a comment to an issue or PR" + } + ] + }, + { + "id": "tool-POLYMARKET", + "category": "tools", + "nodeType": "POLYMARKET", + "label": "Polymarket", + "description": "Prediction market data — prices, order books, and analytics", + "contract": { + "contractVersion": 1, + "type": "POLYMARKET", + "operations": [ + { + "value": "SEARCH_MARKETS", + "label": "Search Markets", + "description": "Search prediction markets by keyword" + }, + { + "value": "GET_MARKET", + "label": "Get Market", + "description": "Retrieve a single market by ID or slug" + }, + { + "value": "GET_EVENT", + "label": "Get Event", + "description": "Retrieve a single event by ID" + }, + { + "value": "LIST_MARKETS", + "label": "List Markets", + "description": "List markets with filters and sorting" + }, + { + "value": "LIST_EVENTS", + "label": "List Events", + "description": "List events with filters and sorting" + }, + { + "value": "GET_PRICE", + "label": "Get Price", + "description": "Get current buy/sell price for a token" + }, + { + "value": "GET_ORDER_BOOK", + "label": "Get Order Book", + "description": "Get top bids and asks for a token" + }, + { + "value": "GET_PRICE_HISTORY", + "label": "Get Price History", + "description": "Get historical price data" + }, + { + "value": "GET_MIDPOINT", + "label": "Get Midpoint", + "description": "Get midpoint price for a token" + }, + { + "value": "GET_SPREAD", + "label": "Get Spread", + "description": "Get bid-ask spread for a token" + }, + { + "value": "GET_LAST_TRADE_PRICE", + "label": "Get Last Trade Price", + "description": "Get last traded price" + }, + { + "value": "GET_TAGS", + "label": "Get Tags", + "description": "List all available market tags" + }, + { + "value": "GET_LEADERBOARD", + "label": "Get Leaderboard", + "description": "Get top traders and stats" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Optional — most endpoints are public. Add a key for higher rate limits. Use {{VAR_NAME}} for environment variables.", + "required": false, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "SEARCH_MARKETS", + "label": "Search Markets" + }, + { + "id": "GET_MARKET", + "label": "Get Market" + }, + { + "id": "GET_EVENT", + "label": "Get Event" + }, + { + "id": "LIST_MARKETS", + "label": "List Markets" + }, + { + "id": "LIST_EVENTS", + "label": "List Events" + }, + { + "id": "GET_PRICE", + "label": "Get Price" + }, + { + "id": "GET_ORDER_BOOK", + "label": "Get Order Book" + }, + { + "id": "GET_PRICE_HISTORY", + "label": "Get Price History" + }, + { + "id": "GET_MIDPOINT", + "label": "Get Midpoint" + }, + { + "id": "GET_SPREAD", + "label": "Get Spread" + }, + { + "id": "GET_LAST_TRADE_PRICE", + "label": "Get Last Trade Price" + }, + { + "id": "GET_TAGS", + "label": "Get Tags" + }, + { + "id": "GET_LEADERBOARD", + "label": "Get Leaderboard" + } + ], + "defaultValue": "SEARCH_MARKETS", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "long-input", + "label": "Search Query", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_MARKETS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "marketId", + "type": "short-input", + "label": "Market ID", + "description": "The condition ID or slug of the market to retrieve", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_MARKET" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventId", + "type": "short-input", + "label": "Event ID", + "description": "The ID of the event to retrieve", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_EVENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listLimit", + "type": "number-input", + "label": "Limit", + "description": "Number of markets to return (1-100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + }, + { + "name": "listOrder", + "type": "dropdown", + "label": "Order By", + "description": "Sort markets by this field", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "options": [ + { + "id": "", + "label": "Default" + }, + { + "id": "liquidity", + "label": "Liquidity" + }, + { + "id": "volume", + "label": "Volume" + }, + { + "id": "created_at", + "label": "Created At" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listClosed", + "type": "dropdown", + "label": "Status", + "description": "Filter by open/closed status", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "options": [ + { + "id": "", + "label": "All" + }, + { + "id": "true", + "label": "Closed Only" + }, + { + "id": "false", + "label": "Open Only" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "listTagId", + "type": "short-input", + "label": "Tag ID", + "description": "Filter by tag (from Get Tags)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "liquidityMin", + "type": "number-input", + "label": "Min Liquidity", + "description": "Minimum liquidity filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0 + }, + { + "name": "volumeMin", + "type": "number-input", + "label": "Min Volume", + "description": "Minimum volume filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_MARKETS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0 + }, + { + "name": "eventsLimit", + "type": "number-input", + "label": "Limit", + "description": "Number of events to return (1-100)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 100 + }, + { + "name": "eventsOrder", + "type": "dropdown", + "label": "Order By", + "description": "Sort events by this field", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "options": [ + { + "id": "", + "label": "Default" + }, + { + "id": "liquidity", + "label": "Liquidity" + }, + { + "id": "volume", + "label": "Volume" + }, + { + "id": "created_at", + "label": "Created At" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventsClosed", + "type": "dropdown", + "label": "Status", + "description": "Filter by open/closed status", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "options": [ + { + "id": "", + "label": "All" + }, + { + "id": "true", + "label": "Closed Only" + }, + { + "id": "false", + "label": "Open Only" + } + ], + "defaultValue": "", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventsTagId", + "type": "short-input", + "label": "Tag ID", + "description": "Filter by tag", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_EVENTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tokenId", + "type": "short-input", + "label": "Token ID", + "description": "Use a clobTokenId from a market search result", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_PRICE", + "GET_ORDER_BOOK", + "GET_MIDPOINT", + "GET_SPREAD", + "GET_LAST_TRADE_PRICE", + "GET_PRICE_HISTORY" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "side", + "type": "dropdown", + "label": "Side", + "description": "Whether to get buy or sell price", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_PRICE" + }, + "options": [ + { + "id": "buy", + "label": "Buy" + }, + { + "id": "sell", + "label": "Sell" + } + ], + "defaultValue": "buy", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "interval", + "type": "dropdown", + "label": "Interval", + "description": "Time interval for price history data points", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_PRICE_HISTORY" + }, + "options": [ + { + "id": "1m", + "label": "1 Minute" + }, + { + "id": "5m", + "label": "5 Minutes" + }, + { + "id": "1h", + "label": "1 Hour" + }, + { + "id": "1d", + "label": "1 Day" + }, + { + "id": "1w", + "label": "1 Week" + }, + { + "id": "max", + "label": "Max" + } + ], + "defaultValue": "1d", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fidelity", + "type": "number-input", + "label": "Fidelity", + "description": "Number of data points to return", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_PRICE_HISTORY" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1 + } + ], + "outputs": {}, + "outputDiscovery": "requires_output_contract", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Search Markets", + "value": "SEARCH_MARKETS", + "description": "Search prediction markets by keyword" + }, + { + "label": "Get Market", + "value": "GET_MARKET", + "description": "Retrieve a single market by ID or slug" + }, + { + "label": "Get Event", + "value": "GET_EVENT", + "description": "Retrieve a single event by ID" + }, + { + "label": "List Markets", + "value": "LIST_MARKETS", + "description": "List markets with filters and sorting" + }, + { + "label": "List Events", + "value": "LIST_EVENTS", + "description": "List events with filters and sorting" + }, + { + "label": "Get Price", + "value": "GET_PRICE", + "description": "Get current buy/sell price for a token" + }, + { + "label": "Get Order Book", + "value": "GET_ORDER_BOOK", + "description": "Get top bids and asks for a token" + }, + { + "label": "Get Price History", + "value": "GET_PRICE_HISTORY", + "description": "Get historical price data" + }, + { + "label": "Get Midpoint", + "value": "GET_MIDPOINT", + "description": "Get midpoint price for a token" + }, + { + "label": "Get Spread", + "value": "GET_SPREAD", + "description": "Get bid-ask spread for a token" + }, + { + "label": "Get Last Trade Price", + "value": "GET_LAST_TRADE_PRICE", + "description": "Get last traded price" + }, + { + "label": "Get Tags", + "value": "GET_TAGS", + "description": "List all available market tags" + }, + { + "label": "Get Leaderboard", + "value": "GET_LEADERBOARD", + "description": "Get top traders and stats" + } + ] + }, + { + "id": "tool-DROPBOX", + "category": "tools", + "nodeType": "DROPBOX", + "label": "Dropbox", + "description": "Upload, download, and manage files in Dropbox", + "contract": { + "contractVersion": 1, + "type": "DROPBOX", + "operations": [ + { + "value": "UPLOAD_FILE", + "label": "Upload File", + "description": "Upload a file to Dropbox" + }, + { + "value": "DOWNLOAD_FILE", + "label": "Download File", + "description": "Download a file from Dropbox" + }, + { + "value": "LIST_FOLDER", + "label": "List Folder", + "description": "List contents of a folder" + }, + { + "value": "CREATE_FOLDER", + "label": "Create Folder", + "description": "Create a new folder" + }, + { + "value": "DELETE", + "label": "Delete", + "description": "Delete a file or folder" + }, + { + "value": "COPY", + "label": "Copy", + "description": "Copy a file or folder" + }, + { + "value": "MOVE", + "label": "Move", + "description": "Move a file or folder" + }, + { + "value": "GET_METADATA", + "label": "Get Metadata", + "description": "Get file or folder metadata" + }, + { + "value": "CREATE_SHARED_LINK", + "label": "Create Shared Link", + "description": "Create a shared link for a file" + }, + { + "value": "SEARCH_FILES", + "label": "Search Files", + "description": "Search for files in Dropbox" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "UPLOAD_FILE", + "label": "Upload File" + }, + { + "id": "DOWNLOAD_FILE", + "label": "Download File" + }, + { + "id": "LIST_FOLDER", + "label": "List Folder" + }, + { + "id": "CREATE_FOLDER", + "label": "Create Folder" + }, + { + "id": "DELETE", + "label": "Delete" + }, + { + "id": "COPY", + "label": "Copy" + }, + { + "id": "MOVE", + "label": "Move" + }, + { + "id": "GET_METADATA", + "label": "Get Metadata" + }, + { + "id": "CREATE_SHARED_LINK", + "label": "Create Shared Link" + }, + { + "id": "SEARCH_FILES", + "label": "Search Files" + } + ], + "defaultValue": "LIST_FOLDER", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Dropbox Account", + "description": "Select or connect a Dropbox account", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "dropbox" + }, + { + "name": "filePath", + "type": "short-input", + "label": "File Path", + "description": "Dropbox path (e.g. /folder/file.txt)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPLOAD_FILE", + "DOWNLOAD_FILE", + "DELETE", + "GET_METADATA", + "CREATE_SHARED_LINK" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fileContent", + "type": "long-input", + "label": "File Content", + "description": "Content to upload", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "UPLOAD_FILE" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "folderPath", + "type": "short-input", + "label": "Folder Path", + "description": "Leave empty for root folder", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_FOLDER", + "CREATE_FOLDER" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "fromPath", + "type": "short-input", + "label": "Source Path", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "COPY", + "MOVE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "toPath", + "type": "short-input", + "label": "Destination Path", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "COPY", + "MOVE" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "visibility", + "type": "dropdown", + "label": "Visibility", + "description": "Who can access the shared link", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_SHARED_LINK" + }, + "options": [ + { + "id": "public", + "label": "Public" + }, + { + "id": "team_only", + "label": "Team Only" + } + ], + "defaultValue": "public", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "description": "What to search for", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_FILES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "searchFolderPath", + "type": "short-input", + "label": "Folder Path", + "description": "Optionally scope search to a folder", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_FILES" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "maxResults", + "type": "number-input", + "label": "Max Results", + "description": "Maximum number of results", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "SEARCH_FILES" + }, + "defaultValue": 20, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "description": "Maximum number of entries to return", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_FOLDER" + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Upload File", + "value": "UPLOAD_FILE", + "description": "Upload a file to Dropbox" + }, + { + "label": "Download File", + "value": "DOWNLOAD_FILE", + "description": "Download a file from Dropbox" + }, + { + "label": "List Folder", + "value": "LIST_FOLDER", + "description": "List contents of a folder" + }, + { + "label": "Create Folder", + "value": "CREATE_FOLDER", + "description": "Create a new folder" + }, + { + "label": "Delete", + "value": "DELETE", + "description": "Delete a file or folder" + }, + { + "label": "Copy", + "value": "COPY", + "description": "Copy a file or folder" + }, + { + "label": "Move", + "value": "MOVE", + "description": "Move a file or folder" + }, + { + "label": "Get Metadata", + "value": "GET_METADATA", + "description": "Get file or folder metadata" + }, + { + "label": "Create Shared Link", + "value": "CREATE_SHARED_LINK", + "description": "Create a shared link for a file" + }, + { + "label": "Search Files", + "value": "SEARCH_FILES", + "description": "Search for files in Dropbox" + } + ] + }, + { + "id": "tool-ELEVENLABS", + "category": "tools", + "nodeType": "ELEVENLABS", + "label": "ElevenLabs", + "description": "Convert text to speech using ElevenLabs AI voices", + "contract": { + "contractVersion": 1, + "type": "ELEVENLABS", + "operations": [ + { + "value": "TEXT_TO_SPEECH", + "label": "Text to Speech", + "description": "Convert text to speech using AI voices" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Enter your ElevenLabs API key or use an environment variable", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "text", + "type": "long-input", + "label": "Text", + "description": "The text to convert to speech. Supports template variables.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "voiceId", + "type": "short-input", + "label": "Voice ID", + "description": "Find Voice IDs in your ElevenLabs dashboard under Voices", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "modelId", + "type": "dropdown", + "label": "Model", + "description": "The ElevenLabs model to use for speech synthesis", + "required": false, + "visible": true, + "options": [ + { + "id": "eleven_monolingual_v1", + "label": "Monolingual v1" + }, + { + "id": "eleven_multilingual_v1", + "label": "Multilingual v1" + }, + { + "id": "eleven_multilingual_v2", + "label": "Multilingual v2" + }, + { + "id": "eleven_turbo_v2", + "label": "Turbo v2" + }, + { + "id": "eleven_turbo_v2_5", + "label": "Turbo v2.5" + } + ], + "defaultValue": "eleven_monolingual_v1", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "url": { + "type": "string", + "description": "Public URL of the generated audio file" + }, + "format": { + "type": "string", + "description": "Audio format (mp3)" + }, + "sizeBytes": { + "type": "number", + "description": "Size of the audio file in bytes" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Text to Speech", + "value": "TEXT_TO_SPEECH", + "description": "Convert text to speech using AI voices" + } + ] + }, + { + "id": "tool-SHOPIFY", + "category": "tools", + "nodeType": "SHOPIFY", + "label": "Shopify", + "description": "Manage products, orders, customers, inventory, and more", + "contract": { + "contractVersion": 1, + "type": "SHOPIFY", + "operations": [ + { + "value": "CREATE_PRODUCT", + "label": "Create Product", + "description": "Create a new product" + }, + { + "value": "GET_PRODUCT", + "label": "Get Product", + "description": "Get a product by ID" + }, + { + "value": "LIST_PRODUCTS", + "label": "List Products", + "description": "List all products" + }, + { + "value": "UPDATE_PRODUCT", + "label": "Update Product", + "description": "Update an existing product" + }, + { + "value": "DELETE_PRODUCT", + "label": "Delete Product", + "description": "Delete a product" + }, + { + "value": "GET_ORDER", + "label": "Get Order", + "description": "Get an order by ID" + }, + { + "value": "LIST_ORDERS", + "label": "List Orders", + "description": "List all orders" + }, + { + "value": "UPDATE_ORDER", + "label": "Update Order", + "description": "Update an existing order" + }, + { + "value": "CANCEL_ORDER", + "label": "Cancel Order", + "description": "Cancel an order" + }, + { + "value": "CREATE_CUSTOMER", + "label": "Create Customer", + "description": "Create a new customer" + }, + { + "value": "GET_CUSTOMER", + "label": "Get Customer", + "description": "Get a customer by ID" + }, + { + "value": "LIST_CUSTOMERS", + "label": "List Customers", + "description": "List all customers" + }, + { + "value": "UPDATE_CUSTOMER", + "label": "Update Customer", + "description": "Update an existing customer" + }, + { + "value": "DELETE_CUSTOMER", + "label": "Delete Customer", + "description": "Delete a customer" + }, + { + "value": "LIST_INVENTORY_ITEMS", + "label": "List Inventory Items", + "description": "List inventory items" + }, + { + "value": "GET_INVENTORY_LEVEL", + "label": "Get Inventory Level", + "description": "Get inventory levels by location and item" + }, + { + "value": "ADJUST_INVENTORY", + "label": "Adjust Inventory", + "description": "Adjust inventory quantity" + }, + { + "value": "LIST_LOCATIONS", + "label": "List Locations", + "description": "List all locations" + }, + { + "value": "CREATE_FULFILLMENT", + "label": "Create Fulfillment", + "description": "Create a fulfillment for an order" + }, + { + "value": "LIST_COLLECTIONS", + "label": "List Collections", + "description": "List all collections" + }, + { + "value": "GET_COLLECTION", + "label": "Get Collection", + "description": "Get a collection by ID" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Shopify Store", + "description": "Select or connect a Shopify store", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "shopify" + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "required": true, + "visible": true, + "options": [ + { + "id": "CREATE_PRODUCT", + "label": "Create Product" + }, + { + "id": "GET_PRODUCT", + "label": "Get Product" + }, + { + "id": "LIST_PRODUCTS", + "label": "List Products" + }, + { + "id": "UPDATE_PRODUCT", + "label": "Update Product" + }, + { + "id": "DELETE_PRODUCT", + "label": "Delete Product" + }, + { + "id": "GET_ORDER", + "label": "Get Order" + }, + { + "id": "LIST_ORDERS", + "label": "List Orders" + }, + { + "id": "UPDATE_ORDER", + "label": "Update Order" + }, + { + "id": "CANCEL_ORDER", + "label": "Cancel Order" + }, + { + "id": "CREATE_CUSTOMER", + "label": "Create Customer" + }, + { + "id": "GET_CUSTOMER", + "label": "Get Customer" + }, + { + "id": "LIST_CUSTOMERS", + "label": "List Customers" + }, + { + "id": "UPDATE_CUSTOMER", + "label": "Update Customer" + }, + { + "id": "DELETE_CUSTOMER", + "label": "Delete Customer" + }, + { + "id": "LIST_INVENTORY_ITEMS", + "label": "List Inventory Items" + }, + { + "id": "GET_INVENTORY_LEVEL", + "label": "Get Inventory Level" + }, + { + "id": "ADJUST_INVENTORY", + "label": "Adjust Inventory" + }, + { + "id": "LIST_LOCATIONS", + "label": "List Locations" + }, + { + "id": "CREATE_FULFILLMENT", + "label": "Create Fulfillment" + }, + { + "id": "LIST_COLLECTIONS", + "label": "List Collections" + }, + { + "id": "GET_COLLECTION", + "label": "Get Collection" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "title", + "type": "short-input", + "label": "Product Title", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_PRODUCT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "productId", + "type": "short-input", + "label": "Product ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_PRODUCT", + "UPDATE_PRODUCT", + "DELETE_PRODUCT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "orderId", + "type": "short-input", + "label": "Order ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_ORDER", + "UPDATE_ORDER", + "CANCEL_ORDER", + "CREATE_FULFILLMENT" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "reason", + "type": "short-input", + "label": "Reason", + "description": "customer, fraud, inventory, declined, other", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CANCEL_ORDER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "status", + "type": "short-input", + "label": "Status", + "description": "open, closed, cancelled, any (default: any)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_ORDERS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "financialStatus", + "type": "short-input", + "label": "Financial Status", + "description": "authorized, pending, paid, partially_paid, refunded, voided, partially_refunded, any", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_ORDERS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "customerId", + "type": "short-input", + "label": "Customer ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_CUSTOMER", + "UPDATE_CUSTOMER", + "DELETE_CUSTOMER" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "customerEmail", + "type": "short-input", + "label": "Email", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CUSTOMER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "firstName", + "type": "short-input", + "label": "First Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CUSTOMER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "lastName", + "type": "short-input", + "label": "Last Name", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CUSTOMER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "tags", + "type": "short-input", + "label": "Tags", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_CUSTOMER" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "query", + "type": "short-input", + "label": "Search Query", + "description": "Filter customers", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_CUSTOMERS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "inventoryItemId", + "type": "short-input", + "label": "Inventory Item ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADJUST_INVENTORY" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "locationId", + "type": "short-input", + "label": "Location ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADJUST_INVENTORY" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "adjustment", + "type": "short-input", + "label": "Adjustment", + "description": "Positive number to add, negative to remove", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "ADJUST_INVENTORY" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "locationIds", + "type": "short-input", + "label": "Location IDs", + "description": "Comma-separated", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_INVENTORY_LEVEL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "inventoryItemIds", + "type": "short-input", + "label": "Inventory Item IDs", + "description": "Comma-separated", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_INVENTORY_LEVEL" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "ids", + "type": "short-input", + "label": "Inventory Item IDs", + "description": "Comma-separated list of IDs to filter", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "LIST_INVENTORY_ITEMS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "collectionId", + "type": "short-input", + "label": "Collection ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_COLLECTION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "trackingNumber", + "type": "short-input", + "label": "Tracking Number", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FULFILLMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "trackingUrl", + "type": "short-input", + "label": "Tracking URL", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FULFILLMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "trackingCompany", + "type": "short-input", + "label": "Tracking Company", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_FULFILLMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "properties", + "type": "long-input", + "label": "Properties (JSON)", + "description": "Additional fields as a JSON object", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_PRODUCT", + "UPDATE_ORDER", + "UPDATE_CUSTOMER", + "CREATE_CUSTOMER" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "short-input", + "label": "Max Records", + "description": "Maximum number of records to return (max 250)", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_PRODUCTS", + "LIST_ORDERS", + "LIST_CUSTOMERS", + "LIST_INVENTORY_ITEMS", + "LIST_COLLECTIONS" + ] + }, + "defaultValue": "50", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Create Product", + "value": "CREATE_PRODUCT", + "description": "Create a new product" + }, + { + "label": "Get Product", + "value": "GET_PRODUCT", + "description": "Get a product by ID" + }, + { + "label": "List Products", + "value": "LIST_PRODUCTS", + "description": "List all products" + }, + { + "label": "Update Product", + "value": "UPDATE_PRODUCT", + "description": "Update an existing product" + }, + { + "label": "Delete Product", + "value": "DELETE_PRODUCT", + "description": "Delete a product" + }, + { + "label": "Get Order", + "value": "GET_ORDER", + "description": "Get an order by ID" + }, + { + "label": "List Orders", + "value": "LIST_ORDERS", + "description": "List all orders" + }, + { + "label": "Update Order", + "value": "UPDATE_ORDER", + "description": "Update an existing order" + }, + { + "label": "Cancel Order", + "value": "CANCEL_ORDER", + "description": "Cancel an order" + }, + { + "label": "Create Customer", + "value": "CREATE_CUSTOMER", + "description": "Create a new customer" + }, + { + "label": "Get Customer", + "value": "GET_CUSTOMER", + "description": "Get a customer by ID" + }, + { + "label": "List Customers", + "value": "LIST_CUSTOMERS", + "description": "List all customers" + }, + { + "label": "Update Customer", + "value": "UPDATE_CUSTOMER", + "description": "Update an existing customer" + }, + { + "label": "Delete Customer", + "value": "DELETE_CUSTOMER", + "description": "Delete a customer" + }, + { + "label": "List Inventory Items", + "value": "LIST_INVENTORY_ITEMS", + "description": "List inventory items" + }, + { + "label": "Get Inventory Level", + "value": "GET_INVENTORY_LEVEL", + "description": "Get inventory levels by location and item" + }, + { + "label": "Adjust Inventory", + "value": "ADJUST_INVENTORY", + "description": "Adjust inventory quantity" + }, + { + "label": "List Locations", + "value": "LIST_LOCATIONS", + "description": "List all locations" + }, + { + "label": "Create Fulfillment", + "value": "CREATE_FULFILLMENT", + "description": "Create a fulfillment for an order" + }, + { + "label": "List Collections", + "value": "LIST_COLLECTIONS", + "description": "List all collections" + }, + { + "label": "Get Collection", + "value": "GET_COLLECTION", + "description": "Get a collection by ID" + } + ] + }, + { + "id": "tool-MCP", + "category": "tools", + "nodeType": "MCP", + "label": "MCP", + "description": "Connect to MCP servers for agentic or direct tool execution", + "contract": { + "contractVersion": 1, + "type": "MCP", + "operations": [ + { + "value": "AGENTIC", + "label": "Agentic Mode", + "description": "LLM discovers and calls MCP tools autonomously" + }, + { + "value": "DIRECT", + "label": "Call Tool", + "description": "Call a specific MCP tool with mapped inputs" + }, + { + "value": "READ_RESOURCE", + "label": "Read Resource", + "description": "Read a resource exposed by the MCP server" + }, + { + "value": "GET_PROMPT", + "label": "Get Prompt", + "description": "Render a prompt exposed by the MCP server" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output. Access via {{name.text}} (agentic) or {{name.result}} (direct).", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "mode", + "type": "dropdown", + "label": "Mode", + "description": "Agentic: LLM discovers and calls tools. Direct: call a specific tool with mapped inputs.", + "required": false, + "visible": true, + "options": [ + { + "id": "agentic", + "label": "Agentic" + }, + { + "id": "call_tool", + "label": "Call Tool" + }, + { + "id": "read_resource", + "label": "Read Resource" + }, + { + "id": "get_prompt", + "label": "Get Prompt" + } + ], + "defaultValue": "agentic", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "serverId", + "type": "mcp-server-selector", + "label": "MCP Server", + "description": "Choose from MCP servers registered in your workspace settings.", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false + }, + { + "name": "model", + "type": "dropdown", + "label": "Model", + "description": "Choose which AI model powers the agent. Must support tool calling.", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "agentic" + }, + "options": [ + { + "id": "gpt-5.6-sol", + "label": "OpenAI 5.6 Sol" + }, + { + "id": "gpt-5.6-luna", + "label": "GPT-5.6 Luna" + }, + { + "id": "gpt-5.5", + "label": "GPT-5.5" + }, + { + "id": "gpt-5.4", + "label": "GPT-5.4" + }, + { + "id": "gpt-5.4-mini", + "label": "GPT-5.4 Mini" + }, + { + "id": "gpt-5.4-nano", + "label": "GPT-5.4 Nano" + }, + { + "id": "gpt-4.1", + "label": "GPT-4.1" + }, + { + "id": "gpt-4.1-mini", + "label": "GPT-4.1 Mini" + }, + { + "id": "gpt-4o", + "label": "GPT-4o" + }, + { + "id": "gpt-4o-mini", + "label": "GPT-4o Mini" + }, + { + "id": "o4-mini", + "label": "o4-mini" + }, + { + "id": "o3", + "label": "o3" + }, + { + "id": "o3-mini", + "label": "o3-mini" + }, + { + "id": "claude-fable-5", + "label": "Claude Fable 5" + }, + { + "id": "claude-opus-5", + "label": "Opus 5" + }, + { + "id": "claude-sonnet-5", + "label": "Claude Sonnet 5" + }, + { + "id": "claude-opus-4-8", + "label": "Claude Opus 4.8" + }, + { + "id": "claude-haiku-4-5-20251001", + "label": "Claude Haiku 4.5" + }, + { + "id": "gemini-3.7-flash", + "label": "Gemini 3.7 Flash" + }, + { + "id": "gemini-3.6-flash", + "label": "Gemini 3.6 Flash" + }, + { + "id": "gemini-3.5-flash", + "label": "Gemini 3.5 Flash" + }, + { + "id": "gemini-3.5-flash-lite", + "label": "Gemini 3.5 Flash Lite" + }, + { + "id": "gemini-3.1-pro-preview", + "label": "Gemini 3.1 Pro" + }, + { + "id": "gemini-2.5-pro", + "label": "Gemini 2.5 Pro" + }, + { + "id": "gemini-2.5-flash", + "label": "Gemini 2.5 Flash" + }, + { + "id": "gemini-2.5-flash-lite", + "label": "Gemini 2.5 Flash Lite" + }, + { + "id": "deepseek-v4-pro", + "label": "DeepSeek V4 Pro" + }, + { + "id": "deepseek-flash", + "label": "DeepSeek V4.1 Flash" + }, + { + "id": "kimi-k3", + "label": "Kimi K3" + }, + { + "id": "kimi-k2.6", + "label": "Kimi K2.6" + } + ], + "defaultValue": "gemini-3.7-flash", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "systemPrompt", + "type": "long-input", + "label": "System Prompt", + "description": "Instructions that define the agent's behavior. Supports {{variable}} syntax.", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "agentic" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "userPrompt", + "type": "long-input", + "label": "User Prompt", + "description": "The task/instruction for the agent. Supports {{variable}} syntax.", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "agentic" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "temperature", + "type": "slider", + "label": "Temperature", + "description": "Controls randomness. Lower = more deterministic, Higher = more creative.", + "required": false, + "visible": false, + "condition": false, + "defaultValue": 0.7, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0, + "max": 1 + }, + { + "name": "maxSteps", + "type": "slider", + "label": "Max Steps", + "description": "Maximum number of tool-calling iterations (1-20).", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "agentic" + }, + "defaultValue": 10, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 20 + }, + { + "name": "allowWriteTools", + "type": "switch", + "label": "Allow Write Tools", + "description": "Off by default. Enable only when the workflow owner has approved agent-initiated writes.", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "agentic" + }, + "defaultValue": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "selectedTool", + "type": "mcp-tool-selector", + "label": "Tool", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "serverId" + ] + }, + { + "name": "toolInputs", + "type": "mcp-dynamic-args", + "label": "Tool Inputs", + "required": false, + "visible": false, + "condition": false, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "dependsOn": [ + "selectedTool" + ] + }, + { + "name": "resourceUri", + "type": "short-input", + "label": "Resource URI", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "read_resource" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "promptName", + "type": "short-input", + "label": "Prompt Name", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "get_prompt" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "promptArguments", + "type": "code", + "label": "Prompt Arguments", + "required": false, + "visible": false, + "condition": { + "field": "mode", + "value": "get_prompt" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Tool call result (direct mode)", + "condition": { + "field": "mode", + "value": "agentic", + "not": true + } + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "Agentic Mode", + "value": "AGENTIC", + "description": "LLM discovers and calls MCP tools autonomously" + }, + { + "label": "Call Tool", + "value": "DIRECT", + "description": "Call a specific MCP tool with mapped inputs" + }, + { + "label": "Read Resource", + "value": "READ_RESOURCE", + "description": "Read a resource exposed by the MCP server" + }, + { + "label": "Get Prompt", + "value": "GET_PROMPT", + "description": "Render a prompt exposed by the MCP server" + } + ] + }, + { + "id": "tool-POSTHOG", + "category": "tools", + "nodeType": "POSTHOG", + "label": "PostHog", + "description": "Product analytics — events, feature flags, experiments, and more", + "contract": { + "contractVersion": 1, + "type": "POSTHOG", + "operations": [ + { + "value": "CAPTURE_EVENT", + "label": "Capture Event", + "description": "Capture a single analytics event" + }, + { + "value": "BATCH_EVENTS", + "label": "Batch Events", + "description": "Batch capture multiple events at once" + }, + { + "value": "LIST_EVENT_DEFINITIONS", + "label": "List Event Definitions", + "description": "List all event definitions" + }, + { + "value": "GET_EVENT_DEFINITION", + "label": "Get Event Definition", + "description": "Get a specific event definition" + }, + { + "value": "UPDATE_EVENT_DEFINITION", + "label": "Update Event Definition", + "description": "Update an event definition" + }, + { + "value": "GET_PERSON", + "label": "Get Person", + "description": "Get person details by ID" + }, + { + "value": "DELETE_PERSON", + "label": "Delete Person", + "description": "Delete a person record" + }, + { + "value": "RUN_QUERY", + "label": "Run Query (HogQL)", + "description": "Execute a HogQL analytics query" + }, + { + "value": "LIST_INSIGHTS", + "label": "List Insights", + "description": "List all saved insights" + }, + { + "value": "GET_INSIGHT", + "label": "Get Insight", + "description": "Get a specific insight and its data" + }, + { + "value": "CREATE_INSIGHT", + "label": "Create Insight", + "description": "Create a new saved insight" + }, + { + "value": "LIST_DASHBOARDS", + "label": "List Dashboards", + "description": "List all dashboards" + }, + { + "value": "GET_DASHBOARD", + "label": "Get Dashboard", + "description": "Get a dashboard with its tiles" + }, + { + "value": "LIST_ACTIONS", + "label": "List Actions", + "description": "List all defined actions" + }, + { + "value": "GET_COHORT", + "label": "Get Cohort", + "description": "Get a specific cohort" + }, + { + "value": "CREATE_COHORT", + "label": "Create Cohort", + "description": "Create a new cohort" + }, + { + "value": "LIST_ANNOTATIONS", + "label": "List Annotations", + "description": "List all annotations" + }, + { + "value": "CREATE_ANNOTATION", + "label": "Create Annotation", + "description": "Create a timeline annotation" + }, + { + "value": "LIST_FEATURE_FLAGS", + "label": "List Feature Flags", + "description": "List all feature flags" + }, + { + "value": "GET_FEATURE_FLAG", + "label": "Get Feature Flag", + "description": "Get a specific feature flag" + }, + { + "value": "CREATE_FEATURE_FLAG", + "label": "Create Feature Flag", + "description": "Create a new feature flag" + }, + { + "value": "UPDATE_FEATURE_FLAG", + "label": "Update Feature Flag", + "description": "Update an existing feature flag" + }, + { + "value": "DELETE_FEATURE_FLAG", + "label": "Delete Feature Flag", + "description": "Delete a feature flag" + }, + { + "value": "GET_EXPERIMENT", + "label": "Get Experiment", + "description": "Get experiment details" + }, + { + "value": "CREATE_EXPERIMENT", + "label": "Create Experiment", + "description": "Create a new A/B experiment" + }, + { + "value": "LIST_SURVEYS", + "label": "List Surveys", + "description": "List all surveys" + }, + { + "value": "GET_SURVEY", + "label": "Get Survey", + "description": "Get a specific survey" + }, + { + "value": "CREATE_SURVEY", + "label": "Create Survey", + "description": "Create a new survey" + }, + { + "value": "UPDATE_SURVEY", + "label": "Update Survey", + "description": "Update an existing survey" + }, + { + "value": "LIST_SESSION_RECORDINGS", + "label": "List Session Recordings", + "description": "List session recordings" + }, + { + "value": "GET_SESSION_RECORDING", + "label": "Get Session Recording", + "description": "Get a specific session recording" + }, + { + "value": "LIST_RECORDING_PLAYLISTS", + "label": "List Recording Playlists", + "description": "List recording playlists" + }, + { + "value": "LIST_PROPERTY_DEFINITIONS", + "label": "List Property Definitions", + "description": "List all property definitions" + }, + { + "value": "GET_PROPERTY_DEFINITION", + "label": "Get Property Definition", + "description": "Get a specific property definition" + }, + { + "value": "UPDATE_PROPERTY_DEFINITION", + "label": "Update Property Definition", + "description": "Update a property definition" + }, + { + "value": "LIST_PROJECTS", + "label": "List Projects", + "description": "List all projects in the organization" + }, + { + "value": "GET_PROJECT", + "label": "Get Project", + "description": "Get current project details" + }, + { + "value": "LIST_ORGANIZATIONS", + "label": "List Organizations", + "description": "List all organizations" + }, + { + "value": "GET_ORGANIZATION", + "label": "Get Organization", + "description": "Get organization details" + } + ], + "fields": [ + { + "name": "apiKey", + "type": "short-input", + "label": "API Key", + "description": "Your PostHog personal API key. Use an environment variable like {{POSTHOG_API_KEY}}", + "required": true, + "visible": true, + "secret": true, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false + }, + { + "name": "projectId", + "type": "short-input", + "label": "Project ID", + "description": "Your PostHog project ID (required for most operations)", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "region", + "type": "dropdown", + "label": "Region", + "description": "Select the PostHog cloud region where your project is hosted", + "required": true, + "visible": true, + "options": [ + { + "id": "us", + "label": "US Cloud (us.posthog.com)" + }, + { + "id": "eu", + "label": "EU Cloud (eu.posthog.com)" + } + ], + "defaultValue": "us", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "dropdown", + "label": "Operation", + "description": "Choose which PostHog operation to perform", + "required": true, + "visible": true, + "options": [ + { + "id": "CAPTURE_EVENT", + "label": "Capture Event" + }, + { + "id": "BATCH_EVENTS", + "label": "Batch Events" + }, + { + "id": "LIST_EVENT_DEFINITIONS", + "label": "List Event Definitions" + }, + { + "id": "GET_EVENT_DEFINITION", + "label": "Get Event Definition" + }, + { + "id": "UPDATE_EVENT_DEFINITION", + "label": "Update Event Definition" + }, + { + "id": "GET_PERSON", + "label": "Get Person" + }, + { + "id": "DELETE_PERSON", + "label": "Delete Person" + }, + { + "id": "RUN_QUERY", + "label": "Run Query (HogQL)" + }, + { + "id": "LIST_INSIGHTS", + "label": "List Insights" + }, + { + "id": "GET_INSIGHT", + "label": "Get Insight" + }, + { + "id": "CREATE_INSIGHT", + "label": "Create Insight" + }, + { + "id": "LIST_DASHBOARDS", + "label": "List Dashboards" + }, + { + "id": "GET_DASHBOARD", + "label": "Get Dashboard" + }, + { + "id": "LIST_ACTIONS", + "label": "List Actions" + }, + { + "id": "GET_COHORT", + "label": "Get Cohort" + }, + { + "id": "CREATE_COHORT", + "label": "Create Cohort" + }, + { + "id": "LIST_ANNOTATIONS", + "label": "List Annotations" + }, + { + "id": "CREATE_ANNOTATION", + "label": "Create Annotation" + }, + { + "id": "LIST_FEATURE_FLAGS", + "label": "List Feature Flags" + }, + { + "id": "GET_FEATURE_FLAG", + "label": "Get Feature Flag" + }, + { + "id": "CREATE_FEATURE_FLAG", + "label": "Create Feature Flag" + }, + { + "id": "UPDATE_FEATURE_FLAG", + "label": "Update Feature Flag" + }, + { + "id": "DELETE_FEATURE_FLAG", + "label": "Delete Feature Flag" + }, + { + "id": "GET_EXPERIMENT", + "label": "Get Experiment" + }, + { + "id": "CREATE_EXPERIMENT", + "label": "Create Experiment" + }, + { + "id": "LIST_SURVEYS", + "label": "List Surveys" + }, + { + "id": "GET_SURVEY", + "label": "Get Survey" + }, + { + "id": "CREATE_SURVEY", + "label": "Create Survey" + }, + { + "id": "UPDATE_SURVEY", + "label": "Update Survey" + }, + { + "id": "LIST_SESSION_RECORDINGS", + "label": "List Session Recordings" + }, + { + "id": "GET_SESSION_RECORDING", + "label": "Get Session Recording" + }, + { + "id": "LIST_RECORDING_PLAYLISTS", + "label": "List Recording Playlists" + }, + { + "id": "LIST_PROPERTY_DEFINITIONS", + "label": "List Property Definitions" + }, + { + "id": "GET_PROPERTY_DEFINITION", + "label": "Get Property Definition" + }, + { + "id": "UPDATE_PROPERTY_DEFINITION", + "label": "Update Property Definition" + }, + { + "id": "LIST_PROJECTS", + "label": "List Projects" + }, + { + "id": "GET_PROJECT", + "label": "Get Project" + }, + { + "id": "LIST_ORGANIZATIONS", + "label": "List Organizations" + }, + { + "id": "GET_ORGANIZATION", + "label": "Get Organization" + } + ], + "defaultValue": "CAPTURE_EVENT", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Name used to reference this node's output in other nodes. Access results as {{posthog.result}}", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "distinctId", + "type": "short-input", + "label": "Distinct ID", + "description": "User's distinct ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CAPTURE_EVENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventName", + "type": "short-input", + "label": "Event Name", + "description": "Name of the event to capture", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CAPTURE_EVENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "eventProperties", + "type": "long-input", + "label": "Properties", + "description": "Event properties as JSON", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CAPTURE_EVENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "batchEvents", + "type": "long-input", + "label": "Events", + "description": "JSON array of events to batch capture", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "BATCH_EVENTS" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "personId", + "type": "short-input", + "label": "Person ID", + "description": "PostHog person ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_PERSON", + "DELETE_PERSON" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "hogqlQuery", + "type": "long-input", + "label": "HogQL Query", + "description": "HogQL query to execute", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "RUN_QUERY" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "insightId", + "type": "short-input", + "label": "Insight ID", + "description": "PostHog insight ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_INSIGHT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "insightData", + "type": "long-input", + "label": "Insight Data", + "description": "JSON object defining the insight", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_INSIGHT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "dashboardId", + "type": "short-input", + "label": "Dashboard ID", + "description": "PostHog dashboard ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_DASHBOARD" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cohortId", + "type": "short-input", + "label": "Cohort ID", + "description": "PostHog cohort ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_COHORT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "cohortData", + "type": "long-input", + "label": "Cohort Data", + "description": "JSON object defining the cohort", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_COHORT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "annotationContent", + "type": "long-input", + "label": "Content", + "description": "Annotation text content", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_ANNOTATION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "annotationScope", + "type": "dropdown", + "label": "Scope", + "description": "Scope of the annotation", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_ANNOTATION" + }, + "options": [ + { + "id": "project", + "label": "Project" + }, + { + "id": "organization", + "label": "Organization" + } + ], + "defaultValue": "project", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "annotationDateMarker", + "type": "short-input", + "label": "Date Marker", + "description": "ISO date for the annotation marker", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_ANNOTATION" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "featureFlagId", + "type": "short-input", + "label": "Feature Flag ID", + "description": "PostHog feature flag ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_FEATURE_FLAG", + "DELETE_FEATURE_FLAG", + "UPDATE_FEATURE_FLAG" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "featureFlagKey", + "type": "short-input", + "label": "Flag Key", + "description": "Unique key for the feature flag", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_FEATURE_FLAG", + "UPDATE_FEATURE_FLAG" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "featureFlagData", + "type": "long-input", + "label": "Flag Data", + "description": "JSON object with flag configuration", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_FEATURE_FLAG", + "UPDATE_FEATURE_FLAG" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "experimentId", + "type": "short-input", + "label": "Experiment ID", + "description": "PostHog experiment ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_EXPERIMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "experimentData", + "type": "long-input", + "label": "Experiment Data", + "description": "JSON object defining the experiment", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "CREATE_EXPERIMENT" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "surveyId", + "type": "short-input", + "label": "Survey ID", + "description": "PostHog survey ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_SURVEY", + "UPDATE_SURVEY" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "surveyData", + "type": "long-input", + "label": "Survey Data", + "description": "JSON object defining or updating the survey", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "CREATE_SURVEY", + "UPDATE_SURVEY" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "recordingId", + "type": "short-input", + "label": "Recording ID", + "description": "Session recording ID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": "GET_SESSION_RECORDING" + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "definitionId", + "type": "short-input", + "label": "Definition ID", + "description": "Definition UUID", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "GET_EVENT_DEFINITION", + "UPDATE_EVENT_DEFINITION", + "GET_PROPERTY_DEFINITION", + "UPDATE_PROPERTY_DEFINITION" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "definitionData", + "type": "long-input", + "label": "Definition Data", + "description": "JSON object with updated fields", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "UPDATE_EVENT_DEFINITION", + "UPDATE_PROPERTY_DEFINITION" + ] + }, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "limit", + "type": "number-input", + "label": "Limit", + "description": "Maximum number of results to return", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_INSIGHTS", + "LIST_DASHBOARDS", + "LIST_ACTIONS", + "LIST_ANNOTATIONS", + "LIST_FEATURE_FLAGS", + "LIST_SURVEYS", + "LIST_SESSION_RECORDINGS", + "LIST_RECORDING_PLAYLISTS", + "LIST_EVENT_DEFINITIONS", + "LIST_PROPERTY_DEFINITIONS" + ] + }, + "defaultValue": 100, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 1, + "max": 1000 + }, + { + "name": "offset", + "type": "number-input", + "label": "Offset", + "description": "Number of results to skip", + "required": false, + "visible": false, + "condition": { + "field": "operation", + "value": [ + "LIST_INSIGHTS", + "LIST_DASHBOARDS", + "LIST_ACTIONS", + "LIST_ANNOTATIONS", + "LIST_FEATURE_FLAGS", + "LIST_SURVEYS", + "LIST_SESSION_RECORDINGS", + "LIST_RECORDING_PLAYLISTS", + "LIST_EVENT_DEFINITIONS", + "LIST_PROPERTY_DEFINITIONS" + ] + }, + "defaultValue": 0, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true, + "min": 0 + } + ], + "outputs": { + "result": { + "type": "json", + "description": "API response data" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "api_key" + }, + "operations": [ + { + "label": "Capture Event", + "value": "CAPTURE_EVENT", + "description": "Capture a single analytics event" + }, + { + "label": "Batch Events", + "value": "BATCH_EVENTS", + "description": "Batch capture multiple events at once" + }, + { + "label": "List Event Definitions", + "value": "LIST_EVENT_DEFINITIONS", + "description": "List all event definitions" + }, + { + "label": "Get Event Definition", + "value": "GET_EVENT_DEFINITION", + "description": "Get a specific event definition" + }, + { + "label": "Update Event Definition", + "value": "UPDATE_EVENT_DEFINITION", + "description": "Update an event definition" + }, + { + "label": "Get Person", + "value": "GET_PERSON", + "description": "Get person details by ID" + }, + { + "label": "Delete Person", + "value": "DELETE_PERSON", + "description": "Delete a person record" + }, + { + "label": "Run Query (HogQL)", + "value": "RUN_QUERY", + "description": "Execute a HogQL analytics query" + }, + { + "label": "List Insights", + "value": "LIST_INSIGHTS", + "description": "List all saved insights" + }, + { + "label": "Get Insight", + "value": "GET_INSIGHT", + "description": "Get a specific insight and its data" + }, + { + "label": "Create Insight", + "value": "CREATE_INSIGHT", + "description": "Create a new saved insight" + }, + { + "label": "List Dashboards", + "value": "LIST_DASHBOARDS", + "description": "List all dashboards" + }, + { + "label": "Get Dashboard", + "value": "GET_DASHBOARD", + "description": "Get a dashboard with its tiles" + }, + { + "label": "List Actions", + "value": "LIST_ACTIONS", + "description": "List all defined actions" + }, + { + "label": "Get Cohort", + "value": "GET_COHORT", + "description": "Get a specific cohort" + }, + { + "label": "Create Cohort", + "value": "CREATE_COHORT", + "description": "Create a new cohort" + }, + { + "label": "List Annotations", + "value": "LIST_ANNOTATIONS", + "description": "List all annotations" + }, + { + "label": "Create Annotation", + "value": "CREATE_ANNOTATION", + "description": "Create a timeline annotation" + }, + { + "label": "List Feature Flags", + "value": "LIST_FEATURE_FLAGS", + "description": "List all feature flags" + }, + { + "label": "Get Feature Flag", + "value": "GET_FEATURE_FLAG", + "description": "Get a specific feature flag" + }, + { + "label": "Create Feature Flag", + "value": "CREATE_FEATURE_FLAG", + "description": "Create a new feature flag" + }, + { + "label": "Update Feature Flag", + "value": "UPDATE_FEATURE_FLAG", + "description": "Update an existing feature flag" + }, + { + "label": "Delete Feature Flag", + "value": "DELETE_FEATURE_FLAG", + "description": "Delete a feature flag" + }, + { + "label": "Get Experiment", + "value": "GET_EXPERIMENT", + "description": "Get experiment details" + }, + { + "label": "Create Experiment", + "value": "CREATE_EXPERIMENT", + "description": "Create a new A/B experiment" + }, + { + "label": "List Surveys", + "value": "LIST_SURVEYS", + "description": "List all surveys" + }, + { + "label": "Get Survey", + "value": "GET_SURVEY", + "description": "Get a specific survey" + }, + { + "label": "Create Survey", + "value": "CREATE_SURVEY", + "description": "Create a new survey" + }, + { + "label": "Update Survey", + "value": "UPDATE_SURVEY", + "description": "Update an existing survey" + }, + { + "label": "List Session Recordings", + "value": "LIST_SESSION_RECORDINGS", + "description": "List session recordings" + }, + { + "label": "Get Session Recording", + "value": "GET_SESSION_RECORDING", + "description": "Get a specific session recording" + }, + { + "label": "List Recording Playlists", + "value": "LIST_RECORDING_PLAYLISTS", + "description": "List recording playlists" + }, + { + "label": "List Property Definitions", + "value": "LIST_PROPERTY_DEFINITIONS", + "description": "List all property definitions" + }, + { + "label": "Get Property Definition", + "value": "GET_PROPERTY_DEFINITION", + "description": "Get a specific property definition" + }, + { + "label": "Update Property Definition", + "value": "UPDATE_PROPERTY_DEFINITION", + "description": "Update a property definition" + }, + { + "label": "List Projects", + "value": "LIST_PROJECTS", + "description": "List all projects in the organization" + }, + { + "label": "Get Project", + "value": "GET_PROJECT", + "description": "Get current project details" + }, + { + "label": "List Organizations", + "value": "LIST_ORGANIZATIONS", + "description": "List all organizations" + }, + { + "label": "Get Organization", + "value": "GET_ORGANIZATION", + "description": "Get organization details" + } + ] + }, + { + "id": "tool-INTEGRATION", + "category": "tools", + "nodeType": "INTEGRATION", + "label": "Integration", + "description": "Run a versioned action through a connected external app", + "contract": { + "contractVersion": 1, + "type": "INTEGRATION", + "operations": [ + { + "value": "quickbooks.query_customers", + "label": "QuickBooks: Query customers", + "description": "Query customers from the connected QuickBooks company." + }, + { + "value": "quickbooks.query_invoices", + "label": "QuickBooks: Query invoices", + "description": "Query invoices from the connected QuickBooks company." + }, + { + "value": "quickbooks.aged_receivables", + "label": "QuickBooks: Get aged receivables", + "description": "Read the aged receivables report." + }, + { + "value": "quickbooks.profit_and_loss", + "label": "QuickBooks: Get profit and loss", + "description": "Read the profit and loss report." + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "integrationId", + "type": "dropdown", + "label": "App", + "required": true, + "visible": true, + "options": [ + { + "id": "quickbooks", + "label": "QuickBooks" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "externalConnectionId", + "type": "external-connection-selector", + "label": "Connection", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "integrationId" + ] + }, + { + "name": "operation", + "type": "external-operation-selector", + "label": "Operation", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": true, + "aiSettable": false, + "dependsOn": [ + "integrationId" + ] + }, + { + "name": "arguments", + "type": "json-editor", + "label": "Arguments", + "description": "JSON arguments for the selected operation.", + "required": false, + "visible": true, + "defaultValue": "{}", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Normalized provider result" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [ + { + "label": "QuickBooks: Query customers", + "value": "quickbooks.query_customers", + "description": "Query customers from the connected QuickBooks company." + }, + { + "label": "QuickBooks: Query invoices", + "value": "quickbooks.query_invoices", + "description": "Query invoices from the connected QuickBooks company." + }, + { + "label": "QuickBooks: Get aged receivables", + "value": "quickbooks.aged_receivables", + "description": "Read the aged receivables report." + }, + { + "label": "QuickBooks: Get profit and loss", + "value": "quickbooks.profit_and_loss", + "description": "Read the profit and loss report." + } + ] + }, + { + "id": "tool-INNFLOW", + "category": "tools", + "nodeType": "INNFLOW", + "label": "Innflow", + "description": "Run another deployed workflow and continue with its result", + "contract": { + "contractVersion": 1, + "type": "INNFLOW", + "operations": [], + "fields": [ + { + "name": "operation", + "type": "dropdown", + "label": "Action", + "required": true, + "visible": true, + "options": [ + { + "id": "RUN_WORKFLOW", + "label": "Run Workflow" + } + ], + "defaultValue": "RUN_WORKFLOW", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "targetWorkflowId", + "type": "short-input", + "label": "Workflow", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "targetTriggerNodeId", + "type": "short-input", + "label": "Trigger", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "timeout", + "type": "time-input", + "label": "Timeout", + "required": true, + "visible": true, + "defaultValue": "7 days", + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "status": { + "type": "string" + }, + "workflowId": { + "type": "string" + }, + "workflowName": { + "type": "string" + }, + "executionId": { + "type": "string" + }, + "output": { + "type": "json" + }, + "error": { + "type": "string" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "success", + "failed" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "none" + }, + "operations": [] + }, + { + "id": "tool-MICROSOFT", + "category": "tools", + "nodeType": "MICROSOFT", + "label": "Microsoft", + "description": "Unified entry point for Microsoft 365 services", + "contract": { + "contractVersion": 1, + "type": "MICROSOFT", + "operations": [ + { + "value": "outlook", + "label": "Outlook", + "description": "Microsoft Outlook operations" + }, + { + "value": "onedrive", + "label": "OneDrive", + "description": "Microsoft OneDrive operations" + }, + { + "value": "teams", + "label": "Teams", + "description": "Microsoft Teams operations" + } + ], + "fields": [ + { + "name": "variableName", + "type": "short-input", + "label": "Variable Name", + "description": "Use this name to reference the output in other nodes", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "connectionId", + "type": "oauth-input", + "label": "Microsoft Account", + "description": "Microsoft 365 account", + "required": true, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": false, + "serviceId": "microsoft_teams" + }, + { + "name": "service", + "type": "dropdown", + "label": "Service", + "required": true, + "visible": true, + "options": [ + { + "id": "outlook", + "label": "Outlook" + }, + { + "id": "onedrive", + "label": "OneDrive" + }, + { + "id": "teams", + "label": "Teams" + } + ], + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + }, + { + "name": "operation", + "type": "short-input", + "label": "Operation", + "description": "Operation for the selected service", + "required": false, + "visible": true, + "secret": false, + "readOnly": false, + "dynamicOptions": false, + "aiSettable": true + } + ], + "outputs": { + "result": { + "type": "json", + "description": "Operation result from the selected service" + } + }, + "outputDiscovery": "declared", + "handles": { + "sources": [ + "source-1" + ], + "targets": [ + "target-1" + ] + }, + "authMode": "oauth" + }, + "operations": [ + { + "label": "Outlook", + "value": "outlook", + "description": "Microsoft Outlook operations" + }, + { + "label": "OneDrive", + "value": "onedrive", + "description": "Microsoft OneDrive operations" + }, + { + "label": "Teams", + "value": "teams", + "description": "Microsoft Teams operations" + } + ] + } + ], + "searchItemCount": 403, + "operationCount": 309, + "hiddenTypes": [ + "AI_DECISION", + "META" + ] +} diff --git a/scripts/tool-guide-map.json b/scripts/tool-guide-map.json new file mode 100644 index 0000000..fea9fa8 --- /dev/null +++ b/scripts/tool-guide-map.json @@ -0,0 +1,267 @@ +[ + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Excel", + "nodeType": "MICROSOFT_EXCEL" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Word", + "nodeType": "MICROSOFT_WORD" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft OneDrive", + "nodeType": "MICROSOFT_ONEDRIVE" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Outlook", + "nodeType": "MICROSOFT_OUTLOOK" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Teams", + "nodeType": "MICROSOFT_TEAMS" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Planner", + "nodeType": "MICROSOFT_PLANNER" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft SharePoint", + "nodeType": "MICROSOFT_SHAREPOINT" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Dropbox", + "nodeType": "DROPBOX" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Shopify", + "nodeType": "SHOPIFY" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "LinkedIn", + "nodeType": "LINKEDIN" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "PostHog", + "nodeType": "POSTHOG" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Dub", + "nodeType": "DUB" + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "ElevenLabs", + "nodeType": "ELEVENLABS" + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "MCP", + "nodeType": "MCP" + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "A2A Agent", + "nodeType": "A2A_AGENT" + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "Browser Agent", + "nodeType": "BROWSER_AGENT" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Tavily Search", + "nodeType": "TAVILY_SEARCH" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Exa", + "nodeType": "EXA" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Perplexity", + "nodeType": "PERPLEXITY" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Firecrawl", + "nodeType": "FIRECRAWL" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Web Scraper", + "nodeType": "WEB_SCRAPER" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Ahrefs", + "nodeType": "AHREFS" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Polymarket", + "nodeType": "POLYMARKET" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Sheets", + "nodeType": "GOOGLE_SHEETS" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Docs", + "nodeType": "GOOGLE_DOCS" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Calendar", + "nodeType": "GOOGLE_CALENDAR" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Drive", + "nodeType": "GOOGLE_DRIVE" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Slides", + "nodeType": "GOOGLE_SLIDES" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Forms", + "nodeType": "GOOGLE_FORMS" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Groups", + "nodeType": "GOOGLE_GROUPS" + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Transform Array", + "nodeType": "TRANSFORM_ARRAY" + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Tables Node", + "nodeType": "TABLES" + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Knowledge Base Node", + "nodeType": "KNOWLEDGE_BASE" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Notion", + "nodeType": "NOTION" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Trello", + "nodeType": "TRELLO" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "GitHub", + "nodeType": "GITHUB" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "ClickUp", + "nodeType": "CLICKUP" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Cal.com", + "nodeType": "CAL_COM" + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Calendly", + "nodeType": "CALENDLY" + }, + { + "file": "content/docs/tools/forms.mdx", + "heading": "Typeform", + "nodeType": "TYPEFORM" + }, + { + "file": "content/docs/tools/forms.mdx", + "heading": "Google Forms", + "nodeType": "GOOGLE_FORMS" + }, + { + "file": "content/docs/tools/ai.mdx", + "heading": "OpenRouter", + "nodeType": "AI_MODEL" + }, + { + "file": "content/docs/tools/ai.mdx", + "heading": "Image Generation", + "nodeType": "GENERATE_IMAGE" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Slack", + "nodeType": "SLACK" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Gmail", + "nodeType": "GMAIL" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Microsoft Outlook", + "nodeType": "MICROSOFT_OUTLOOK" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Microsoft Teams", + "nodeType": "MICROSOFT_TEAMS" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Telegram", + "nodeType": "TELEGRAM" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Resend", + "nodeType": "RESEND" + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Airtable", + "nodeType": "AIRTABLE" + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "HubSpot", + "nodeType": "HUBSPOT" + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Attio", + "nodeType": "ATTIO" + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Apollo", + "nodeType": "APOLLO" + } +] diff --git a/scripts/tool-operation-audit.json b/scripts/tool-operation-audit.json new file mode 100644 index 0000000..8ee533a --- /dev/null +++ b/scripts/tool-operation-audit.json @@ -0,0 +1,373 @@ +[ + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Excel", + "nodeType": "MICROSOFT_EXCEL", + "operationCount": 3, + "previousList": "**Operations:**\n- **Create Spreadsheet** \u2014 Create a workbook\n- **Read Range** \u2014 Fetch data from a range of cells\n- **Write Range** \u2014 Write data to a range of cells" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Word", + "nodeType": "MICROSOFT_WORD", + "operationCount": 3, + "previousList": "**Operations:**\n- **Create** \u2014 Create a new Word document\n- **Read** \u2014 Read content from an existing document" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft OneDrive", + "nodeType": "MICROSOFT_ONEDRIVE", + "operationCount": 4, + "previousList": "**Operations:**\n- **List Files** \u2014 Browse files in a folder\n- **Get File** \u2014 Retrieve a file\n- **Create Folder** \u2014 Add a folder\n- **Delete File** \u2014 Remove a file" + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Outlook", + "nodeType": "MICROSOFT_OUTLOOK", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Teams", + "nodeType": "MICROSOFT_TEAMS", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft Planner", + "nodeType": "MICROSOFT_PLANNER", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/microsoft.mdx", + "heading": "Microsoft SharePoint", + "nodeType": "MICROSOFT_SHAREPOINT", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Dropbox", + "nodeType": "DROPBOX", + "operationCount": 10, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Shopify", + "nodeType": "SHOPIFY", + "operationCount": 21, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "LinkedIn", + "nodeType": "LINKEDIN", + "operationCount": 2, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "PostHog", + "nodeType": "POSTHOG", + "operationCount": 39, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "Dub", + "nodeType": "DUB", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/storage-commerce.mdx", + "heading": "ElevenLabs", + "nodeType": "ELEVENLABS", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "MCP", + "nodeType": "MCP", + "operationCount": 4, + "previousList": null + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "A2A Agent", + "nodeType": "A2A_AGENT", + "operationCount": 2, + "previousList": null + }, + { + "file": "content/docs/tools/agents-protocols.mdx", + "heading": "Browser Agent", + "nodeType": "BROWSER_AGENT", + "operationCount": 2, + "previousList": null + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Tavily Search", + "nodeType": "TAVILY_SEARCH", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Exa", + "nodeType": "EXA", + "operationCount": 3, + "previousList": "**Operations:**\n- **Search** \u2014 Semantic search across the web\n- **Find Similar** \u2014 Find pages similar to a given URL\n- **Get Contents** \u2014 Extract content from specific URLs" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Perplexity", + "nodeType": "PERPLEXITY", + "operationCount": 3, + "previousList": "**Operations:**\n- **Ask** \u2014 Answer a question with citations\n- **Research** \u2014 Gather a deeper research response\n- **Fact Check** \u2014 Check a claim against current sources" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Firecrawl", + "nodeType": "FIRECRAWL", + "operationCount": 6, + "previousList": "**Operations:** Scrape, Search, Crawl, Map, Extract, and Agent" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Web Scraper", + "nodeType": "WEB_SCRAPER", + "operationCount": 2, + "previousList": "**Operations:**\n\n- **Scrape URL** \u2014 Extract content from one public page\n- **Search + Scrape** \u2014 Search the web and retrieve content from matching pages" + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Ahrefs", + "nodeType": "AHREFS", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/search-data.mdx", + "heading": "Polymarket", + "nodeType": "POLYMARKET", + "operationCount": 13, + "previousList": null + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Sheets", + "nodeType": "GOOGLE_SHEETS", + "operationCount": 4, + "previousList": "**Operations:**\n- **Read Rows** \u2014 Fetch data from a range of cells\n- **Append Row** \u2014 Add a new row to the end of a sheet\n- **Update Row** \u2014 Modify an existing row\n- **Create Spreadsheet** \u2014 Create a new spreadsheet" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Docs", + "nodeType": "GOOGLE_DOCS", + "operationCount": 3, + "previousList": "**Operations:**\n- **Create** \u2014 Create a new document with a title and content\n- **Read** \u2014 Retrieve the content of an existing document\n- **Write** \u2014 Add or replace document content" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Calendar", + "nodeType": "GOOGLE_CALENDAR", + "operationCount": 6, + "previousList": "**Operations:**\n- **List Events** \u2014 Fetch upcoming events from a calendar\n- **Create Event** \u2014 Add a new event\n- **Read Event** \u2014 Retrieve one event\n- **Update Event** \u2014 Change an event\n- **Delete Event** \u2014 Remove an event" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Drive", + "nodeType": "GOOGLE_DRIVE", + "operationCount": 3, + "previousList": "**Operations:**\n- **List Files** \u2014 Browse files in a folder\n- **Upload** \u2014 Upload a file to Drive\n- **Download** \u2014 Download a file by ID" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Slides", + "nodeType": "GOOGLE_SLIDES", + "operationCount": 2, + "previousList": "**Operations:**\n- **Create** \u2014 Create a new presentation\n- **Read** \u2014 Read slide content from an existing presentation" + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Forms", + "nodeType": "GOOGLE_FORMS", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/google-suite.mdx", + "heading": "Google Groups", + "nodeType": "GOOGLE_GROUPS", + "operationCount": 11, + "previousList": null + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Transform Array", + "nodeType": "TRANSFORM_ARRAY", + "operationCount": 3, + "previousList": null + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Tables Node", + "nodeType": "TABLES", + "operationCount": 5, + "previousList": "**Operations:**\n- **Read Table** \u2014 Get all rows from a table\n- **Query Rows** \u2014 Search for specific rows\n- **Add Row** \u2014 Insert a new row\n- **Update Row** \u2014 Modify an existing row\n- **Delete Row** \u2014 Remove a row" + }, + { + "file": "content/docs/tools/logic-utility.mdx", + "heading": "Knowledge Base Node", + "nodeType": "KNOWLEDGE_BASE", + "operationCount": 2, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Notion", + "nodeType": "NOTION", + "operationCount": 8, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Trello", + "nodeType": "TRELLO", + "operationCount": 6, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "GitHub", + "nodeType": "GITHUB", + "operationCount": 7, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "ClickUp", + "nodeType": "CLICKUP", + "operationCount": 9, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Cal.com", + "nodeType": "CAL_COM", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/project-management.mdx", + "heading": "Calendly", + "nodeType": "CALENDLY", + "operationCount": 7, + "previousList": null + }, + { + "file": "content/docs/tools/forms.mdx", + "heading": "Typeform", + "nodeType": "TYPEFORM", + "operationCount": 7, + "previousList": "**Operations:**\n\n- List, get, create, update, and delete forms\n- Retrieve form responses\n- Read form insights" + }, + { + "file": "content/docs/tools/forms.mdx", + "heading": "Google Forms", + "nodeType": "GOOGLE_FORMS", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/ai.mdx", + "heading": "OpenRouter", + "nodeType": "AI_MODEL", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/ai.mdx", + "heading": "Image Generation", + "nodeType": "GENERATE_IMAGE", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Slack", + "nodeType": "SLACK", + "operationCount": 3, + "previousList": "**Operations:**\n- **Send Message** \u2014 Post a message to a Slack channel\n- **Read Messages** \u2014 Fetch recent messages from a channel\n- **Create Canvas** \u2014 Create a Slack canvas for structured shared content" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Gmail", + "nodeType": "GMAIL", + "operationCount": 8, + "previousList": "**Operations:**\n- **Send Email** \u2014 Compose and send an email\n- **Read Emails** \u2014 Fetch recent emails from your inbox\n- **Draft Email** \u2014 Save a draft without sending it\n- **Search Emails** \u2014 Find matching messages\n- **Move / Mark / Archive** \u2014 Organize message state" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Microsoft Outlook", + "nodeType": "MICROSOFT_OUTLOOK", + "operationCount": 5, + "previousList": "**Operations:**\n- **Send Email** \u2014 Compose and send an email\n- **Read Emails** \u2014 Fetch recent emails\n- **Read Email** \u2014 Retrieve one message\n- **Create Draft** \u2014 Save a draft without sending\n- **Search Emails** \u2014 Find matching messages" + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Microsoft Teams", + "nodeType": "MICROSOFT_TEAMS", + "operationCount": 5, + "previousList": null + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Telegram", + "nodeType": "TELEGRAM", + "operationCount": 7, + "previousList": null + }, + { + "file": "content/docs/tools/communication.mdx", + "heading": "Resend", + "nodeType": "RESEND", + "operationCount": 1, + "previousList": null + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Airtable", + "nodeType": "AIRTABLE", + "operationCount": 5, + "previousList": "**Operations:**\n- **List Records** \u2014 Fetch records from a table\n- **Read Record** \u2014 Retrieve one record\n- **Create Record** \u2014 Add a new record\n- **Update Record** \u2014 Modify an existing record\n- **Delete Record** \u2014 Remove a record" + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "HubSpot", + "nodeType": "HUBSPOT", + "operationCount": 6, + "previousList": null + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Attio", + "nodeType": "ATTIO", + "operationCount": 13, + "previousList": null + }, + { + "file": "content/docs/tools/crm-sales.mdx", + "heading": "Apollo", + "nodeType": "APOLLO", + "operationCount": 10, + "previousList": null + } +] diff --git a/scripts/verify-build.mjs b/scripts/verify-build.mjs index b749a55..dbe739c 100644 --- a/scripts/verify-build.mjs +++ b/scripts/verify-build.mjs @@ -41,15 +41,29 @@ try { } if (!ready) throw new Error(`Server did not start: ${logs}`); const targets = new Set(['/sitemap.xml', '/robots.txt', '/llms.txt', '/index']); + const pageHtml = new Map(); + const fragmentLinks = []; for (const route of routes) { const response = await get(route); if (!response.ok) { errors.push(`${route}: HTTP ${response.status}`); continue; } const html = await response.text(); + pageHtml.set(route, html); + for (const match of html.matchAll(/href="(\/[^"?#]*)#([^"]+)"/g)) fragmentLinks.push({from:route,path:match[1],id:decodeURIComponent(match[2])}); if (!html.includes('id="nd-page"')) errors.push(`${route}: missing documentation article`); for (const match of html.matchAll(/(?:href|src)="(\/[^"#?]*)(?:[?#][^"]*)?"/g)) { if (!match[1].startsWith('//')) targets.add(match[1].replaceAll('&', '&')); } } + for (const link of fragmentLinks) { + const html = pageHtml.get(link.path); + if (html && !html.includes(`id="${link.id}"`)) errors.push(`${link.from}: missing fragment ${link.path}#${link.id}`); + } + const catalog = JSON.parse(readFileSync('scripts/tool-catalog.snapshot.json', 'utf8')); + const reference = pageHtml.get('/tools/reference') ?? ''; + for (const node of catalog.nodes) { + const id = node.nodeType.toLowerCase().replaceAll('_', '-'); + if (!reference.includes(`id="${id}"`)) errors.push(`Missing rendered tool reference: ${node.nodeType}`); + } for (const target of targets) { if (routes.has(target)) continue; const response = await get(target); @@ -57,6 +71,8 @@ try { } const search = await get('/api/search?query=Loop'); if (!search.ok || !(await search.json()).some(item => item.url?.includes('/academy/loops'))) errors.push('Search did not return the Loop lesson.'); + const triggerSearch = await get('/api/search?query=Innflow%20Trigger'); + if (!triggerSearch.ok || !(await triggerSearch.json()).some(item => item.url?.includes('/triggers') || item.url?.includes('/tools/reference'))) errors.push('Search did not return the Innflow Trigger documentation.'); if ((await get('/__verify_missing_page__')).status !== 404) errors.push('Unknown route did not return HTTP 404.'); if (errors.length) throw new Error([...new Set(errors)].join('\n')); console.log(`Verified ${pages.length} content pages, navigation, ${targets.size} local targets, search, and 404 on the standalone server.`);