Node Types
Gondo workflows use four node types: trigger, task, code, and human.
Shared node fields
Most nodes share this shape:
id: example_node
type: task
title: Example node
goal: One short sentence for people reading the graph.
integrations:
- finance_gmail
config: {}
ui:
x: 0
y: 0
integrations lists the integration reference IDs the node is allowed to use.
Trigger nodes
Triggers start workflows.
Command trigger
Use a command trigger when the workflow starts from chat, a manual run, or a command-style invocation.
type: trigger
title: Run
config:
kind: command
name: review-invoices
dataSchema:
type: object
properties:
folderId:
type: string
required: [folderId]
The config.name field above names the command trigger, not the workflow itself.
The trigger output is available downstream as ctx.data.<triggerNodeId>.
Auto trigger
Use an auto trigger when the workflow should run on a schedule.
type: trigger
title: Weekday check
config:
kind: auto
cron: '0 9 * * 1-5'
timezone: Europe/London
An auto trigger can also run code before starting workflow runs.
type: trigger
title: New Gmail messages
integrations:
- finance_gmail
config:
kind: auto
cron: '*/15 * * * *'
code: |
const gmail = getIntegration('finance_gmail')
const messages = await (await gmail.get('/messages?q=invoice')).json()
for (const message of messages.messages ?? []) {
await triggerWorkflow({ messageId: message.id })
}
dataSchema:
type: object
required: [messageId]
properties:
messageId:
type: string
Auto trigger code can use store.get, store.set, store.delete, and triggerWorkflow(data).
Task nodes
A task node is an AI reasoning step.
Use it when the workflow needs judgement, classification, drafting, document reading, messy data handling, or adaptable browser work.
type: task
title: Classify invoice
goal: Decide whether the invoice needs review.
integrations:
- finance_gmail
config:
instruction: |-
Read the invoice email identified by ctx.data.new_email.messageId.
Return whether it needs human review.
If the amount is missing, set needsReview to true and explain why.
dataSchema:
type: object
required: [needsReview, reason]
properties:
needsReview:
type: boolean
reason:
type: string
The task node returns structured data matching dataSchema.
Code nodes
A code node runs deterministic JavaScript.
Use it for API calls, structured writes, file movement in the workflow workspace, or transformations where the input shape is already clear.
type: code
title: Add row to sheet
goal: Write approved invoice data to the finance sheet.
integrations:
- finance_sheets
config:
code: |
const sheets = getIntegration('finance_sheets')
const invoice = ctx.data.classify_invoice
const response = await sheets.post('/values/A1:append', {
values: [[invoice.supplierName, invoice.amount]]
})
const result = await response.json()
return { updatedRange: result.updates?.updatedRange ?? null }
dataSchema:
type: object
required: [updatedRange]
properties:
updatedRange:
type: [string, 'null']
Code nodes can use:
ctx.datactx.runctx.varsgetIntegration('<referenceId>')log(...)
External provider calls must go through getIntegration().
Human nodes
A human node pauses the workflow.
Use it when a person should review, approve, edit, or provide information.
Human node UI is stored as a Vue single-file component in config.component. When completed, its final state becomes ctx.data.<nodeId>.
type: human
title: Approve invoice
goal: Ask finance to approve or reject the invoice.
config:
dataSchema:
type: object
required: [decision, notes]
properties:
decision:
type: string
enum: [approved, rejected]
notes:
type: string
component: |
<template>
<section>
<p>Approve this invoice?</p>
<button type="button" @click="approve">Approve</button>
</section>
</template>
<script setup>
const { submitAction } = defineProps({
submitAction: { type: Function, required: true }
})
function approve() {
submitAction('approve', { notes: '' })
}
</script>
<script backend>
export async function approve(state, inputs) {
return { ...state, decision: 'approved', notes: inputs.notes, done: true }
}
</script>
Human nodes should render both an active input state and a completed recap state.