Skip to content
Try out in chatDeveloper dashboardLogin
Using Northstar

Tasks

Reference for the Tasks API, covering endpoints, streaming events, configuration, multi-turn sessions, research tasks, and artifacts.

A task is the simplest way to use Northstar: you describe what you want done, and Northstar operates a computer until the work is done. This page is the reference: endpoints, the event stream, and every configuration option. For a hands-on walkthrough, start with Run a task.

For more control over each step, see the Responses API. For direct computer control without a model, see the Computers API.

OperationSDK callWhat it does
Start (streaming)client.agent.tasks.start_stream(...)Starts a task and returns the live SSE event stream
Start (async)client.agent.tasks.start(...)Returns {task_id, status, idempotency_key, reused} immediately
Rejoin a streamGET /agent/tasks/{id}/streamRe-subscribe to a running (or just-finished) task’s events
Statusclient.agent.tasks.retrieve_status(id){status, exit_code}: "running" or "completed"
Inject a messageclient.agent.tasks.inject_message(id, message=...)Steer, clarify, or ask a follow-up, even mid-execution
Pause / resumeclient.agent.tasks.pause(id) / .resume(id)Human take-control between steps
Stopclient.agent.tasks.pause(id), or set max_duration_seconds at startPause halts between steps; the server also ends a task at its max_duration_seconds deadline. There is no separate cancel call.
from tzafon import Lightcone
client = Lightcone()
for event in client.agent.tasks.start_stream(
instruction="Go to wikipedia.org and summarize today's featured article",
kind="browser",
):
print(event)
import Lightcone from "@tzafon/lightcone";
const client = new Lightcone();
const stream = await client.agent.tasks.startStream({
instruction: "Go to wikipedia.org and summarize today's featured article",
kind: "browser",
});
for await (const event of stream) {
console.log(event);
}

When you stream a task, you get a sequence of typed events. Each carries a type and a turn number; the common ones:

EventMeaning
startedTask began, with computer_id, kind, model, and the viewport
statusEphemeral progress narration (state + message). Never the final answer; safe to show as a caption and discard
plan / plan_step_changeThe planned checklist, and which item is currently running
screenshotA screenshot was captured (image is an HTTPS URL, plus the step)
executedA GUI action ran on the computer (action, status)
answer_deltaA chunk of the assistant’s reply, streamed token-by-token, only when stream_deltas: true
needs_inputThe agent needs a clarification answered in chat: reply with inject_message
login_requiredThe agent hit a sign-in wall. A human signs in via the live view, then the task resumes. See Logins and sessions
message_received / barge_inYour injected message was accepted (mid-execution injections arrive as barge_in)
artifactA file deliverable. See Artifacts
scratchpadLive rows accumulating toward a structured deliverable
suggestionsSuggested follow-up prompts, only when suggestions: true
computer_parkedAn idle multi-turn desktop was snapshotted; it restores automatically (typically under 2s) on your next message
completedTask finished successfully: result, model, computer_id, streamed
failedTerminal failure: the stream closes; carries status, error_code, retryable
errorA non-terminal error: the task continues and the stream stays open
max_steps / max_duration / cancelledThe step limit, wall-clock limit, or a cancellation was reached
config_errorThe request was misconfigured (e.g. an unknown model)
replay_gapOn reconnect: some buffered events were evicted and couldn’t be replayed

Research tasks also emit research_swarm_* / research_subtask_* progress events. See Research tasks.

A task doesn’t have to end at completed. Send a follow-up with inject_message and the agent continues in the same session, with full context and the same computer:

client.agent.tasks.inject_message(
task_id,
message="Great, now export that table as a CSV",
)
await client.agent.tasks.injectMessage(taskId, {
message: "Great, now export that table as a CSV",
});
  • Mid-execution, your message interrupts the agent (barge_in). Use it to redirect before it goes further.
  • Between turns, idle desktops are parked (computer_parked) to save compute and restored in about a second when your next message arrives.
  • Sessions stay open for follow-ups for 30 minutes of inactivity.

If your connection drops, re-subscribe without losing events:

Terminal window
curl -N "https://api.tzafon.ai/agent/tasks/{task_id}/stream" \
-H "Authorization: Bearer $TZAFON_API_KEY" \
-H "Last-Event-ID: 42" # or ?from=42

Events replay from that sequence number. A replay_gap event means the resume point was evicted from the buffer. Re-check status and continue from live. Streams remain available for about 10 minutes after a task finishes. Pass an idempotency_key when starting tasks so retries of the start call return the same task (reused: true) instead of double-running. See Running in production.

For research-shaped instructions, the agent can fan out parallel workers (web search plus isolated browser sessions) and merge the findings. Enable it via allowed_tools:

for event in client.agent.tasks.start_stream(
instruction="Compare pricing pages of the top 5 CRM vendors and produce a table",
kind="browser",
allowed_tools=["desktop_agent", "research_swarm", "artifact_handoff"],
):
print(event)
const stream = await client.agent.tasks.startStream({
instruction: "Compare pricing pages of the top 5 CRM vendors and produce a table",
kind: "browser",
allowed_tools: ["desktop_agent", "research_swarm", "artifact_handoff"],
});

Progress arrives as research_swarm_* and research_subtask_* events. allowed_tools also works as a restriction. Pass only ["desktop_agent"] to keep the agent on a single computer.

Tasks can deliver files, not just text. When the work produces a deliverable, an artifact event arrives with the file content base64-encoded. Supported kinds include csv, excel, table, html, chart, pdf, docx, and pptx.

import base64
for event in client.agent.tasks.start_stream(
instruction="Collect the titles of the top 10 Hacker News stories into a CSV",
kind="browser",
allowed_tools=["desktop_agent", "artifact_handoff"],
):
if getattr(event, "type", None) == "artifact":
with open(event.filename, "wb") as f:
f.write(base64.b64decode(event.data))

While the agent gathers rows you’ll see scratchpad events accumulating the data live, which is useful for progress UIs.

ParameterDefaultDescription
instruction:Plain language description of the work (required)
kind:"desktop" or "browser" (required; start_url implies browser)
modellatestWhich model to use. Pin a version in production. See Running in production
system_prompt:Extra instructions appended to the agent’s system prompt: persona, domain context, or response style
context:Prior conversation turns ([{role, content}]) to seed the session
allowed_toolsallRestrict or enable agent tools: desktop_agent, research_swarm, artifact_handoff
enable_login_handofffalseEmit login_required for human sign-in instead of attempting logins. See Logins and sessions
max_steps150Maximum number of actions Northstar can take (up to 1000)
max_duration_seconds:Wall-clock limit in seconds; the task is cancelled if it runs longer
temperature0Action-model sampling temperature. 0 is deterministic; higher is more exploratory (and less precise at clicking)
stream_deltasfalseStream the reply token-by-token as answer_delta events instead of delivering it once at the end
stream_mode"verbose""concise" trims narration events for lighter streams
screenshot_mode"url"How screenshot events deliver the image: "url" (HTTPS link: smaller events) or "base64" (inline data URL: self-contained, no second fetch)
suggestionsfalseEmit follow-up suggestions events after each turn
viewport_width / viewport_height1280 / 720Screen size (320–3840 × 240–2160)
persistentfalseSave environment state when the computer is terminated (alias: save_session)
terminate_on_completiontrueTerminate the computer when the task finishes; set false (or keep_alive: true) to keep it running
computer_id:Reuse a live computer, or restore a saved session with that id
on_missing_computer"restore"If computer_id isn’t live: "restore" from its snapshot, "create_new", or "fail"
environment_id:Restore a saved environment snapshot (prefer computer_id)
start_url:Initial URL to open before the agent starts (implies kind: "browser")
idempotency_key:Deduplicate task starts across retries
thread_id:Group multiple tasks belonging to the same conversation
metadata:Arbitrary key/values echoed back in the started event