Capture the schematic.
Use sch_find_free_placement() before adding new parts when you need collision-free coordinates, and pass keepout_regions if parts must stay out of reserved areas.
Use sch_get_bounding_boxes() to inspect occupied sheet regions with pin-aware symbol extents.
Assign footprints.
Export a netlist.
If the schematic needs cleanup first, run sch_auto_place_functional() to group connectors, MCU blocks, sensors, and UI parts. Set anchor_ref to keep already-reviewed symbols fixed, and tune inter-group spacing with project_set_design_intent(functional_spacing_mm=...).
Use sch_get_template_info() to inspect bundled subcircuit templates, including their declared left/right pin lists, before instantiating them.
Place footprints and route.
Use pcb_auto_place_force_directed() for a headless spring-layout pass when you want a deterministic starting point before manual polish. Stopping is convergence-based — not wall-clock — so the same inputs yield bit-for-bit identical placement on any machine; the result reports iterations_run, converged, and max_displacement_mm. The tool supports keepout_regions and grid_mm, and exposes max_seconds only as an opt-in safety valve (default 0 = disabled, deterministic) for pathologically large boards.
Review pcb_score_placement() after placement; it now reports critical-net Manhattan proxy length and thermal-hotspot proximity in addition to the existing intent-aware checks.
For external autorouting, stage DSN/SES with route_export_dsn(), route_autoroute_freerouting(), and route_import_ses(). FreeRouting runs Docker-first when available using the pinned ghcr.io/freerouting/freerouting:2.1.0 image, falls back to a configured JAR, and reports routed percentage, pass count, wall time, and stdout tail.