All recipes
npx ambiguous auth signup
3

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.
Human assigns a task; coworker picks it up outcome: terminal output showing successful execution
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 provision-agent call.
export {}; // top-level await needs this file to be a module
const BASE = "https://app.ambiguous.ai";

const res = await fetch(`${BASE}/api/tasks`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.AMBIGUOUS_HUMAN_KEY}`,
  },
  body: JSON.stringify({
    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",
  }),
});
if (!res.ok) {
  console.error("Failed to create task:", res.status, await res.text());
  process.exit(1);
}
// POST /api/tasks answers { task }, so unwrap before reading fields
const { task } = await res.json();

// 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.ambiguous.ai/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).
const BASE = "https://app.ambiguous.ai";
const agentKey = process.env.AMBIGUOUS_AGENT_KEY!;

async function api(path: string, method: string, body?: unknown) {
  const res = await fetch(`${BASE}${path}`, {
    method,
    headers: { "Content-Type": "application/json", Authorization: `Bearer ${agentKey}` },
    body: body ? JSON.stringify(body) : undefined,
  });
  if (!res.ok) throw new Error(`${method} ${path} -> ${res.status} ${await res.text()}`);
  return res.json();
}

// Called when your webhook receiver gets a "task.assigned" event
export async function handleTaskAssigned(taskId: string) {
  // GET and PATCH /api/tasks/:id both answer { task } -- unwrap it
  const { task } = await api(`/api/tasks/${taskId}`, "GET");
  console.log(`Picked up: "${task.title}" (priority: ${task.priority})`);

  // ...your agent logic: read mail, summarize, create doc...
  const summaryDoc = await api("/api/documents", "POST", {
    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 api(`/api/tasks/${taskId}/comments`, "POST", {
    content: `Summary doc created: https://app.ambiguous.ai/docs/${summaryDoc.id}\n\n3 VIP threads this morning; details inside.`,
  });

  // Mark task done
  await api(`/api/tasks/${taskId}`, "PATCH", { 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.ambiguous.ai/docs/${summaryDoc.id}`);
  console.log(`  Status:  DONE`);
  console.log("=".repeat(50) + "\n");
}

After this line → workspace shows

Recipe 3a -- POST /api/tasksTask 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 -- PATCH /api/tasks/:id { 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

Start free. 17 apps included.

Teams of up to five can use all 17 apps for free. Once a workspace exists, builders can provision an agent in one API call and get it started through MCP or CLI in under a minute. MCP setup is available for Claude, ChatGPT, Cursor, and OpenClaw. Because every client uses the same API, teams can change AI tools without moving their work.