Common Good Industries

Circuit

Dispatch optimization and automated follow-up for field-service shops. Circuit takes a day's worth of jobs and a crew of technicians and works out who goes where, in what order — then writes the customer messages the shop keeps meaning to send.

How jobs get assigned

Urgent work first, then oldest first. Each job goes to the eligible technician it adds the least drive time to, which also builds a nearest-neighbour route for that tech's day. A tech is only eligible if:

They have the skill
the job's service type is one of theirs — no sending a roofer to an electrical call
The day still fits
travel plus service time stays inside their shift; anything that doesn't fit is reported, never silently dropped

Deterministic and keyless — same input, same routes, every time. That makes it auditable, and it means a heavier solver can slot in later without changing a single caller.

Automated follow-up

Completing a job schedules the messages that actually drive repeat revenue — a review request the next day, and a maintenance reminder on the right cadence for the trade:

pestevery 90 days
hvacevery 180 days
roofing · plumbing · electricalyearly

Circuit drafts and schedules. Sending is a channel adapter you point at your own email or SMS provider — the software never messages your customers on its own.

Try the dispatcher

/optimize is open and stateless — it routes a crew and returns the plan without storing anything.

curl -s https://circuit.forthecommongood.ai/optimize \
  -H 'content-type: application/json' -d '{
    "technicians": [
      { "tech_id": "t1", "name": "Ana",  "skills": ["hvac"], "home_lat": 39.74, "home_lon": -104.99 },
      { "tech_id": "t2", "name": "Beau", "skills": ["hvac","plumbing"], "home_lat": 39.68, "home_lon": -105.08 }
    ],
    "jobs": [
      { "job_id": "j1", "service_type": "hvac",     "lat": 39.75, "lon": -105.00, "priority": 1 },
      { "job_id": "j2", "service_type": "plumbing", "lat": 39.69, "lon": -105.07 },
      { "job_id": "j3", "service_type": "hvac",     "lat": 39.73, "lon": -104.97 }
    ]
  }'

Returns each tech's ordered stops with travel and service minutes, their day totals, and any job that couldn't be placed.

Endpoints

POST /optimizeroute a crew, stateless
GET /jobs?status=the job board
GET /techniciansthe crew
GET /followupsthe scheduled message queue
POST /jobsbook work · key
POST /dispatchroute the board + save · key
POST /jobs/{id}/completeclose out + spawn follow-ups · key