Skip to Content
Platform
How-toStart work from your systems

Start work from your systems

Anything that can run a command or make an HTTP call can start your agent.

Your service receives the event and starts a task with a project API key.

You need: a deployed runtime (Deploy) and a project API key for the environment you target (Credentials).

1. Give your service the key

export INTROSPECTION_TOKEN=<api-key> export INTROSPECTION_PROJECT=<project-slug> export INTROSPECTION_DP_URL=<data-plane-url> # for tasks, conversations, and files commands export INTROSPECTION_API_BASE_URL=https://api.introspection.dev # for tasks create

The key’s environment picks staging or production. With a key, tasks create takes --runtime-id and that same --environment; --runtime is refused.

2. Start one task per event

Return at once. conversation_metadata makes the task findable later.

server.ts
import { IntrospectionClient } from "@introspection-sdk/introspection-node"; const client = new IntrospectionClient(); // reads INTROSPECTION_TOKEN app.post("/webhooks/events", async (req, res) => { const { id, text } = req.body; const runner = await client.runtimes("triage-agent").run(); const handle = await runner.tasks.start({ prompt: `New event ${id}:\n\n${text}`, conversation_metadata: { event_id: id }, }); res.status(202).json({ task_id: handle.run.task_id }); });

For per-customer memory, open the runner with an identity (who owns a task).

3. Find the task for an event

introspection conversations list --filter metadata=event_id:<event-id> --query "[].id" -o table

conversation_metadata can never be edited or deleted: keep personal data out of it.

4. Run a batch

Your organization runs 5 tasks at once by default; the rest wait as queued, and a task queued for over an hour is cancelled (Limits). Send waves sized to that:

batch.ts
const runner = await client.runtimes("triage-agent").run(); for (let i = 0; i < tickets.length; i += 5) { const wave = await Promise.all( tickets.slice(i, i + 5).map((t) => runner.tasks.start({ prompt: `Triage ticket ${t}`, tags: ["batch:2026-10-15"] }), ), ); await Promise.all(wave.map((h) => h.text())); // waits for each run to settle }

List the batch later with runner.tasks.list({ tag: "batch:2026-10-15" }).

5. Collect the outputs

introspection tasks stream <task-id> returns when the run settles; then list and download its outputs (Send files in and out).

Verify

introspection tasks list --limit 20 -o table

Expect your tasks as idle (turn finished) or failed.

Or ask your agent: “Write a webhook handler that starts a triage-agent task per event.”

Receive email or third-party webhooks

Introspection receives webhooks only for its own Slack connectors. Point anything else, including inbound email, at your service, then start a task with the message and attachments:

introspection tasks create --runtime-id <runtime-id> -e production \ --file @./invoice.pdf --prompt "From: billing@acme.com. Subject: Invoice 88. Process it."

Keep one task per email thread: store thread ID → task ID, or start from the SDK with conversation_metadata: { thread_id } and find it as in step 3. The agent can’t send email: give it a draft tool and let your service send the reply.

Relay another chat app

Start a task on a thread’s first message, send later ones with runner.tasks.runs.create(taskId, ...), and post handle.text() back.

Continue a task later

introspection tasks prompt <task-id> --prompt "..." adds a turn at any age; the task restarts with its history, outputs, and memory.

Limits

Not supportedDo this instead
Inbound email address, generic webhook receiverYour service receives it (above).
Sending emailYour service sends the agent’s draft.
Tag or metadata filter on tasks list in the CLIconversations list --filter metadata=... (step 3), or the SDK’s tasks.list({ tag }).
Last updated on