> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dedaluslabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Lifecycle

> Sleep, wake, and delete Dedalus Machines

export const Pop = ({content, children}) => {
  const [open, setOpen] = useState(false);
  const [hoverOpen, setHoverOpen] = useState(false);
  const [isDark, setIsDark] = useState(false);
  const triggerRef = useRef(null);
  const portalRef = useRef(null);
  const closeTimer = useRef(null);
  const isOpen = open || hoverOpen;
  useEffect(() => {
    const probe = () => setIsDark(document.documentElement.classList.contains("dark"));
    probe();
    const obs = new MutationObserver(probe);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => obs.disconnect();
  }, []);
  const onEnter = () => {
    clearTimeout(closeTimer.current);
    setHoverOpen(true);
  };
  const onLeave = () => {
    closeTimer.current = setTimeout(() => setHoverOpen(false), 150);
  };
  useEffect(() => {
    if (!isOpen) return;
    const node = document.createElement("div");
    node.setAttribute("role", "dialog");
    node.textContent = content;
    document.body.appendChild(node);
    portalRef.current = node;
    const dark = document.documentElement.classList.contains("dark");
    Object.assign(node.style, {
      position: "fixed",
      zIndex: "9999",
      maxWidth: "20rem",
      width: "max-content",
      padding: "0.5rem 0.75rem",
      fontSize: "0.875rem",
      lineHeight: "1.55",
      color: dark ? "rgb(244, 244, 245)" : "rgb(39, 39, 42)",
      backgroundColor: dark ? "rgba(24, 24, 27, 0.4)" : "rgba(255, 255, 255, 0.4)",
      backdropFilter: "blur(4px) saturate(160%)",
      WebkitBackdropFilter: "blur(4px) saturate(160%)",
      border: dark ? "1px solid rgba(255, 255, 255, 0.18)" : "1px solid rgba(0, 0, 0, 0.16)",
      boxShadow: "0 8px 32px rgba(0, 0, 0, 0.12)",
      opacity: "0",
      transform: "translateY(-4px)",
      transition: "opacity 180ms cubic-bezier(0.16, 1, 0.3, 1), transform 180ms cubic-bezier(0.16, 1, 0.3, 1)"
    });
    const place = () => {
      const r = triggerRef.current?.getBoundingClientRect();
      if (!r || !portalRef.current) return;
      portalRef.current.style.left = `${r.left}px`;
      portalRef.current.style.top = `${r.bottom + 8}px`;
    };
    place();
    requestAnimationFrame(() => {
      node.style.opacity = "1";
      node.style.transform = "translateY(0)";
    });
    node.addEventListener("mouseenter", onEnter);
    node.addEventListener("mouseleave", onLeave);
    window.addEventListener("scroll", place, true);
    window.addEventListener("resize", place);
    return () => {
      window.removeEventListener("scroll", place, true);
      window.removeEventListener("resize", place);
      node.remove();
      portalRef.current = null;
    };
  }, [isOpen, content]);
  useEffect(() => {
    if (!open) return;
    const dismiss = e => {
      const inside = triggerRef.current?.contains(e.target) || portalRef.current?.contains(e.target);
      if (!inside) {
        setOpen(false);
        setHoverOpen(false);
      }
    };
    const onKey = e => e.key === "Escape" && (setOpen(false), setHoverOpen(false));
    document.addEventListener("mousedown", dismiss);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", dismiss);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);
  return <button ref={triggerRef} type="button" onClick={() => setOpen(v => !v)} onMouseEnter={onEnter} onMouseLeave={onLeave} aria-expanded={isOpen} className="cursor-pointer bg-transparent border-0 p-0 text-inherit underline decoration-dotted underline-offset-[3px] transition-colors" style={{
    textDecorationColor: isDark ? "rgb(113, 113, 122)" : "rgb(161, 161, 170)"
  }}>
			{children}
		</button>;
};

export const Callout = ({icon = "lightbulb", iconJsx, color = "default", children}) => {
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const probe = () => setIsDark(document.documentElement.classList.contains("dark"));
    probe();
    const obs = new MutationObserver(probe);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => obs.disconnect();
  }, []);
  const palette = {
    default: {
      bg: isDark ? "rgba(39, 39, 42, 0.6)" : "rgb(244, 244, 245)",
      fg: isDark ? "rgb(228, 228, 231)" : "rgb(39, 39, 42)"
    },
    brand: {
      bg: isDark ? "rgba(76, 29, 149, 0.2)" : "rgb(245, 243, 255)",
      fg: isDark ? "rgb(221, 214, 254)" : "rgb(76, 29, 149)"
    },
    info: {
      bg: isDark ? "rgba(30, 58, 138, 0.2)" : "rgb(239, 246, 255)",
      fg: isDark ? "rgb(191, 219, 254)" : "rgb(30, 58, 138)"
    },
    success: {
      bg: isDark ? "rgba(20, 83, 45, 0.2)" : "rgb(240, 253, 244)",
      fg: isDark ? "rgb(187, 247, 208)" : "rgb(20, 83, 45)"
    },
    warning: {
      bg: isDark ? "rgba(120, 53, 15, 0.2)" : "rgb(255, 251, 235)",
      fg: isDark ? "rgb(253, 230, 138)" : "rgb(120, 53, 15)"
    },
    danger: {
      bg: isDark ? "rgba(127, 29, 29, 0.2)" : "rgb(254, 242, 242)",
      fg: isDark ? "rgb(254, 202, 202)" : "rgb(127, 29, 29)"
    }
  };
  const tint = palette[color] ?? palette.default;
  const lucide = {
    "lightbulb": <>
				<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5" />
				<path d="M9 18h6" />
				<path d="M10 22h4" />
			</>,
    "info": <>
				<circle cx="12" cy="12" r="10" />
				<path d="M12 16v-4" />
				<path d="M12 8h.01" />
			</>,
    "alert-triangle": <>
				<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z" />
				<path d="M12 9v4" />
				<path d="M12 17h.01" />
			</>,
    "alert-octagon": <>
				<polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2" />
				<line x1="12" y1="8" x2="12" y2="12" />
				<line x1="12" y1="16" x2="12.01" y2="16" />
			</>,
    "check-circle": <>
				<path d="M21.801 10A10 10 0 1 1 17 3.335" />
				<path d="m9 11 3 3L22 4" />
			</>,
    "x-circle": <>
				<circle cx="12" cy="12" r="10" />
				<path d="m15 9-6 6" />
				<path d="m9 9 6 6" />
			</>,
    "sparkles": <>
				<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z" />
				<path d="M20 3v4" />
				<path d="M22 5h-4" />
				<path d="M4 17v2" />
				<path d="M5 18H3" />
			</>,
    "code": <>
				<polyline points="16 18 22 12 16 6" />
				<polyline points="8 6 2 12 8 18" />
			</>,
    "terminal": <>
				<polyline points="4 17 10 11 4 5" />
				<line x1="12" y1="19" x2="20" y2="19" />
			</>,
    "book-open": <>
				<path d="M12 7v14" />
				<path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z" />
			</>,
    "zap": <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />,
    "clock": <>
				<circle cx="12" cy="12" r="10" />
				<polyline points="12 6 12 12 16 14" />
			</>
  };
  let resolvedIcon;
  if (iconJsx !== undefined) {
    resolvedIcon = iconJsx;
  } else {
    const paths = lucide[icon];
    if (!paths) {
      throw new Error(`<Callout icon="${icon}"> is not a known Lucide name. ` + `Either add it to the lucide table in callout.jsx, or pass iconJsx={...} for custom JSX. ` + `Available: ${Object.keys(lucide).join(", ")}`);
    }
    resolvedIcon = <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
				{paths}
			</svg>;
  }
  return <div className="flex items-start gap-3 px-4 py-3 my-4" style={{
    backgroundColor: tint.bg,
    color: tint.fg
  }}>
			<span className="leading-none mt-[3px] shrink-0 select-none [&>svg]:block">{resolvedIcon}</span>
			<div className="flex-1 min-w-0 [&>*:first-child]:mt-0 [&>*:last-child]:mb-0 [&_a_code]:no-underline [&_a]:underline-offset-[3px]">
				{children}
			</div>
		</div>;
};

Machines have four <Pop content="The machine lifecycle phases: running, sleeping, starting, and destroyed.">states</Pop>: **running**, **sleeping**, **starting**, and **destroyed**. You control transitions between them.

## List machines

Returns every machine in your account, including sleeping ones.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines list
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  machines = client.machines.list()
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const machines = await client.machines.list();
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  machines, _ := client.Machines.List(ctx, dedalus.MachineListParams{})
  fmt.Println(len(machines.Items))
  ```
</CodeGroup>

## Get machine details

Point-in-time snapshot per machine. Return its configs such as full machine object: id, phase, vcpu/memory/storage, autosleep policy, IP, timestamps.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines retrieve --machine-id <machine_id>
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dm = client.machines.retrieve(machine_id="<machine_id>")
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const dm = await client.machines.retrieve({ machine_id: "<machine_id>" });
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dm, _ := client.Machines.Get(ctx, dedalus.MachineGetParams{
      MachineID: machineID,
  })
  fmt.Println(dm.Status.Phase)
  ```
</CodeGroup>

<Accordion title="Parameters">
  <ParamField path="machine_id" type="string" required>
    The machine to retrieve.
  </ParamField>
</Accordion>

## Watch

Streams the machine's current state every time it changes in the life cycle. Most commonly used to monitor for phase transitions (sleep, wake, delete). The stream closes once the machine reaches a stable phase.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines watch --machine-id <machine_id>
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import json

  with client.machines.with_streaming_response.watch(machine_id="<machine_id>") as resp:
      for line in resp.iter_lines():
          if line.startswith("data:"):
              payload = json.loads(line[5:])
              print(payload["status"]["phase"])
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const stream = await client.machines.watch({ machine_id: "<machine_id>" });
  for await (const evt of stream) {
    console.log(evt.status.phase);
  }
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  stream := client.Machines.WatchStreaming(ctx, dedalus.MachineWatchParams{
      MachineID: machineID,
  })
  for stream.Next() {
      fmt.Println(stream.Current().Status.Phase)
  }
  ```
</CodeGroup>

<Accordion title="Parameters">
  <ParamField path="machine_id" type="string" required>
    The machine whose lifecycle stream you want to watch.
  </ParamField>
</Accordion>

## Auto-sleep

Machines auto-sleep after 5 minutes of no activity by default. Set `autosleep` on create or update to change the policy for one machine. Use `never` to disable auto-sleep.

Activity is any successful execution, terminal/SSH session, or preview hit. Background processes inside the VM do not count.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines update --machine-id <machine_id> --autosleep 15m
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.machines.update(
      machine_id="<machine_id>",
      autosleep="15m",
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  await client.machines.update({
    machine_id: "<machine_id>",
    autosleep: "15m",
  });
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dm, _ := client.Machines.Update(ctx, dedalus.MachineUpdateParams{
      MachineID: machineID,
      UpdateParams: dedalus.UpdateParams{
          Autosleep: dedalus.String("15m"),
      },
  })
  fmt.Println(dm.AutosleepSeconds)
  ```
</CodeGroup>

<Accordion title="Parameters">
  <ParamField body="autosleep" type="string">
    Idle window before auto-sleep. Accepts fixed units like `30s`, `15m`, `2h`, `1w3d`, raw seconds like `"1800"`, or `never`.
  </ParamField>
</Accordion>

## Sleep

Zero compute cost. Storage persists.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines sleep --machine-id <machine_id>
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.machines.sleep(machine_id="<machine_id>")
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  await client.machines.sleep({ machine_id: "<machine_id>" });
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.Machines.Sleep(ctx, dedalus.MachineSleepParams{
      MachineID: machineID,
  })
  ```
</CodeGroup>

## Wake

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines wake --machine-id <machine_id>
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.machines.wake(machine_id="<machine_id>")
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  await client.machines.wake({ machine_id: "<machine_id>" });
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.Machines.Wake(ctx, dedalus.MachineWakeParams{
      MachineID: machineID,
  })
  ```
</CodeGroup>

<Accordion title="Parameters">
  <ParamField path="machine_id" type="string" required>
    The machine to sleep or wake.
  </ParamField>
</Accordion>

## Delete

Delete the machine and its storage.

<CodeGroup>
  ```bash CLI theme={"theme":{"light":"github-light","dark":"github-dark"}}
  dedalus machines delete --machine-id <machine_id>
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.machines.delete(machine_id="<machine_id>")
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  await client.machines.delete({ machine_id: "<machine_id>" });
  ```

  ```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
  client.Machines.Delete(ctx, dedalus.MachineDeleteParams{
      MachineID: machineID,
  })
  ```
</CodeGroup>

<Accordion title="Parameters">
  <ParamField path="machine_id" type="string" required>
    The machine to delete.
  </ParamField>
</Accordion>

<Warning>
  Deletion is permanent. All storage is wiped. There is no undo.
</Warning>
