Skip to content

Starting Tasks

Once a task template is planned in the UI and services are implemented, you can start tasks programmatically.

bash npm install @requence/task
import { createTask } from '@requence/task'
const result = await createTask({
taskTemplate: 'my-template',
input: { name: 'World' },
})
console.log(result.result) // The final output of the task

createTask / Task returns a task handle with methods to access task metadata without waiting for the task to finish:

const task = createTask({ taskTemplate: 'my-template', input: {} })
const taskId = await task.getTaskId() // Resolves as soon as the task is created
const taskUrl = await task.getTaskUrl() // URL to view the task in the Requence UI
await task.abort('No longer needed') // Abort the running task
await task.protect() // Protect the task from auto cleanup
// Await the final result only when needed
const result = await task

The task handle is also an AsyncIterable — see Streaming Updates.

Awaiting Finalization / Validation (Cheap Monitoring)

Section titled “Awaiting Finalization / Validation (Cheap Monitoring)”

By default, awaiting the task handle (await task / await task.result) or using onUpdate will start active task monitoring. Active monitoring connects to the Server-Sent Events (SSE) stream to track the progress of every node, which is expensive and often unnecessary if you only want to start the task and catch initial validation errors.

If you want to ensure the task has successfully passed input schema validation and successfully started on the backend—without incurring the overhead of monitoring the entire execution—you can await task.finalized():

const task = createTask({
taskTemplate: 'my-template',
input: { /* ... */ },
})
try {
// Resolves when input validation passes and the task starts on the backend.
// Rejects immediately with a TaskError if validation fails.
const taskId = await task.finalized()
console.log(`Task ${taskId} is running in the background!`)
} catch (error) {
console.error('Validation failed:', error.message)
}
const result = await createTask({
taskTemplate: 'my-template', // Required — name of the task template
input: { /* ... */ }, // Required if the template defines an input schema
name: 'Daily Import', // Optional — human-readable task name
priority: 5, // Optional — 0 (low) to 10 (high), default: 5
requireAck: true, // Optional — see Delivery Guarantee below
})

The resolved result contains:

{
input: unknown // The input you provided
result: unknown // The final task output
taskId: string // Unique task identifier
taskUrl: string // URL to view the task in the Requence UI
getNodeData(alias) // Get output from a specific node by alias
getNodeError(alias) // Get error from a specific node by alias
}
const task = createTask({ taskTemplate: 'my-template', input: {} })
// Abort after some condition
await task.abort('No longer needed')

Or use the standalone abortTask function:

import { abortTask } from '@requence/task'
await abortTask({
taskId: 'some-task-id',
reason: 'Cancelled by user',
})

Protected tasks are excluded from automatic cleanup. This is useful for important task results you want to keep indefinitely.

const task = createTask({ taskTemplate: 'my-template', input: {} })
// Protect after the task is created
await task.protect()

Or use the standalone protectTask function:

import { protectTask } from '@requence/task'
await protectTask({
taskId: 'some-task-id',
})

By default a task transitions directly from RUNNING to SUCCESSFUL / FAILED / STOPPED when it finishes. If the process that started the task crashes or disconnects at the exact moment the terminal event is emitted, the event can be lost.

Setting requireAck: true (require_ack=True in Python) enables an explicit acknowledgement step:

  1. When the task reaches its terminal state the backend holds it in AWAITING_DELIVERY instead of immediately finalising it.
  2. The SDK receives the terminal event over the SSE stream and automatically sends an ACK back to the backend.
  3. Only after the ACK is received does the task move to its real final status (SUCCESSFUL, FAILED, or STOPPED), and the exact delivery timestamp is recorded.

Because the ACK is tied to the same access token that created the task, the backend can guarantee the correct client received the result.

// The SDK handles the ACK automatically — await the result as normal.
const result = await createTask({
taskTemplate: 'my-template',
input: { /* ... */ },
requireAck: true,
})
console.log(result.result) // Only resolves after the ACK has been confirmed

requireAck also works with watchTasks / TaskWatcher — when a task with requireAck reaches its terminal state, the watcher automatically sends the ACK on behalf of the access token that created the task.

Learn about Streaming Updates to monitor task progress in real-time.