All recipes
npm install @ambiguous/api-client3
Human assigns a task; coworker picks it up
The human-to-agent loop. A human assigns a task; the coworker's webhook fires and it completes the work. Two contexts, one handshake.
One full collaborative loop in under 60 seconds. No human polling, no manual status updates.

recipe-3a-assign-task.ts
// recipe-3a-assign-task.ts -- HUMAN SIDE
// Run with: npx tsx recipe-3a-assign-task.ts (or: bun run recipe-3a-assign-task.ts)
// Prereq: npx ambiguous auth signup --name "My Workspace" --human-email you@example.com
// Uses AMBIGUOUS_HUMAN_KEY (your workspace API key from ~/.ambi/config.json).
// COWORKER_USER_ID is the user_id returned by Recipe 1's auth.registerAgent().
import { AmbiguousClient } from "@ambiguous/api-client";
import type { Task } from "@ambiguous/api-client";
const human = new AmbiguousClient({ apiKey: process.env.AMBIGUOUS_HUMAN_KEY! });
const task: Task = await human.tasks.create({
title: "Summarize today's inbound: priority customers only",
description: "Check mail, find the VIP threads, summarize into a doc.",
assignee_id: process.env.COWORKER_USER_ID!,
priority: "high",
}).catch((err: Error) => {
console.error("Failed to create task:", err.message);
process.exit(1);
});
// Rich summary
console.log("\n" + "=".repeat(50));
console.log(" Task assigned to coworker");
console.log("=".repeat(50));
console.log(` Task ID: ${task.id}`);
console.log(` Title: ${task.title}`);
console.log(` Assignee: ${task.assignee_id}`);
console.log(` Priority: ${task.priority}`);
console.log(` View: https://app.ambi.cc/tasks/${task.id}`);
console.log("=".repeat(50));
console.log(" The coworker's webhook fires next -- see recipe-3b\n");recipe-3b-coworker-handler.ts
// recipe-3b-coworker-handler.ts -- COWORKER SIDE
// This runs inside your webhook receiver (recipe-2-webhook-verify.ts).
// Prereq: Coworker provisioned (Recipe 1) + webhook registered (Recipe 2).
import { AmbiguousClient } from "@ambiguous/api-client";
import type { Task, Document } from "@ambiguous/api-client";
// Called when your webhook receiver gets a "task.assigned" event
export async function handleTaskAssigned(taskId: string) {
const agent = new AmbiguousClient({ apiKey: process.env.AMBIGUOUS_AGENT_KEY! });
const task: Task = await agent.tasks.get(taskId);
console.log(`Picked up: "${task.title}" (priority: ${task.priority})`);
// ...your agent logic: read mail, summarize, create doc...
const summaryDoc: Document = await agent.docs.create({
type: "doc",
title: `VIP inbound: ${new Date().toISOString().slice(0, 10)}`,
content: "# Summary\n\n- Acme Corp renewal discussion\n- Widget Inc pricing request\n- Globex onboarding check-in\n",
});
// Add a completion comment linking the output doc
await agent.tasks.createComment(taskId, {
content: `Summary doc created: https://app.ambi.cc/docs/${summaryDoc.id}\n\n3 VIP threads this morning; details inside.`,
});
// Mark task done
await agent.tasks.update(taskId, { status: "done" });
// Rich summary
console.log("\n" + "=".repeat(50));
console.log(" Task completed by coworker");
console.log("=".repeat(50));
console.log(` Task: ${task.title}`);
console.log(` Output: https://app.ambi.cc/docs/${summaryDoc.id}`);
console.log(` Status: DONE`);
console.log("=".repeat(50) + "\n");
}After this line → workspace shows
Recipe 3a -- tasks.create(...)Task row appears in /tasks assigned to Research Bot; coworker's notification bell rings
Recipe 3b -- webhook firesYour server receives a task.assigned event within ~100ms of assignment
Recipe 3b -- tasks.update(..., { status: "done" })Task flips to DONE; completion comment with output doc URL shows inline; human gets a task.completed notification
End stateHuman sees: task assigned, coworker picked it up, output doc attached, task marked done. All in under a minute
Result in your workspace
After running: the task appears completed with the coworker's output doc attached.
Try it: simulated output
Terminal: recipe-3-task-handoff
Click Run to simulate this recipe
Next steps
This recipe touches Ambiguous Assistant, Tasks, and Mail.