← All work

CleanHaus

Hosts and cleaners manage rental turnovers in chat, within each person's permissions

CleanHaus coordinates short-term rental bookings, cleanings and supplies between owners, cleaner managers and cleaners. We grew its live AI assistant into role-aware agents that know when to speak in a shared property chat, and with whose permissions.

Real Estate & HospitalityTurnover operations SaaSAI added to a live product

A property channel where the assistant logs a reported issue, beside a cleaner's chat with the assistant.

The challenge

The assistant already ran inside the live product but covered only part of the job cycle. One property channel holds owners, managers and cleaners at once, so it had to know who is asking and whether to answer at all.

What we did

Working in CleanHaus's own repository and AWS accounts, we turned its APIs into a tool registry under each user's login, then grew one agent into a supervisor with a graph per channel and role.

The outcome

CleanHaus reported its app and AI agent live and credited our team. The assistant now creates bookings, jobs, invites and notes, guides onboarding and drafts contractor outreach for approval.

Status
Live in the CleanHaus product
Acts through
CleanHaus APIs, under each user's own login
Permissions
A graph and tool allowlist per channel and role
Outward actions
Contractor bids wait for the owner's approval

The starting point

CleanHaus is a live operations platform where property owners, cleaner managers and cleaners coordinate short-term rental bookings, cleaning windows, checklists, notes and inventory. It runs on a serverless AWS backend with web and mobile apps, and a first version of its AI assistant was already running in the product when we joined.

What had to change

The assistant covered only part of the job cycle, while field work changes all day. It needed to create bookings, jobs, invites and notes from live data, and in shared channels stay out of conversations that were not meant for it.

What could not break

  • The AI calls only CleanHaus's existing APIs, under the user's own Cognito login
  • Cleaners act only on their own jobs, and owners cannot assign cleaners
  • No invented tasks, no tool names or IDs in replies, no loops or duplicate replies
  • Undocumented endpoints stay out unless the client provides and approves them
  • The product stays live for every role while the assistant changes underneath it

The calls we made

We framed it as permissions first: the assistant may do only what the person asking could already do in the product, and it lives in the client's own code and accounts, not ours.

  1. 01

    Real endpoints as the only tools

    Each exposed backend API became a registry entry with a name, description, method, path and parameter schema, called under the user's own Cognito identity, so tool calls stay deterministic and every action passes the access rules the product already enforces.

    Ruled out

    New services or a second permission model, and undocumented endpoints the client had not provided.

  2. 02

    A compiled graph per channel and role

    We moved from one agent to a supervisor that routes to domain agents, then compiled a separate graph and tool allowlist for each channel and role with a static role lock, so a cleaner's session simply has no owner tools.

    Ruled out

    One agent holding every tool and trusting the prompt to hold back.

  3. 03

    Decide whether to speak at all

    In a shared property channel, a decision node checks whether a message is meant for the AI and stays out of messages addressed to another person, with recent channel messages as context.

    Ruled out

    Answering every message and flooding a channel full of people.

  4. 04

    Live status, not a snapshot

    Field work changes all day, so the assistant resolves who is asking, which property and job they mean and the current status from fresh profile and property data.

    Ruled out

    Answering from context data captured earlier in the conversation instead of a live status query.

  5. 05

    Outreach waits for the owner

    The contractor bidding agent ranks marketplace contractors by rating and reviews and drafts the bid email, but nothing goes out until the owner approves, unless the owner switches that job to auto.

    Ruled out

    Letting the agent email contractors on its own by default.

How the system fits together

messagesmessageseach messagesilent contextcritical taskreason, picktoolproperty searchrole's toolsafter approvalrepliesAgent InboxOwners andmanagersBookings, jobs,invites, approvalsCleanersTheir own jobs,notes and suppliesProperty channelsStream Chat in theweb and mobile appsBackend eventsNotification queueand critical tasksSupervisor graphDecision node,domain agents…Contractorbidding agentDrafts bids, waitsfor the ownerOpenAI GPT-5.1Decides, routes andcalls toolsQdrantDocuments of eachpropertyCleanHaus backendAPIsCalled under theuser's Cognito loginAmazon SES bidmailboxOne per owner, forcontractor replies
PeopleClient's existing systemBuilt by DaticsAI modelData storeOutside serviceThe assistant has no permissions of its own: every action goes through CleanHaus's existing APIs under the user's Cognito login, and contractor email waits for the owner.

What we built

Tools on the client's own APIs

Booking, job, checklist, note, invite, inventory and marketplace cleaner tools, each allowlisted per role, with overlap and guest check-in conflict handling in the client's timezone.

The assistant checks upcoming schedules and confirms a new booking before it creates it.
02

Briefings and quiet context

Opening a personal channel brings a role-aware briefing, deduplicated by role and timezone, backend events arrive as silent context, and an attention classifier decides which channel messages earn a push notification.

03

Onboarding guide agent

A guided flow with generative UI over the AG-UI protocol walks a new host through property import, cleaner invites and payment setup inside the product.

04

Contractor bidding agent

A critical task wakes the agent, which ranks marketplace contractors, drafts outreach for the owner to approve in an Agent Inbox with a goal card, and keeps contractor replies in the same thread.

05

Tests in tiers, traces in logs

Unit tests with a scripted fake tool-calling model run on every push, routing evals use a real model against a mocked backend, and LLM-as-judge evals score answers in LangSmith.

How it works

Ask

An owner, manager or cleaner writes in a property channel or their personal channel, in their own language.

Decide

A decision node checks whether the message is meant for the AI and stays quiet when it is addressed to another person.

Route

The supervisor hands it to the right domain agent, compiled with only that role's tools for this channel.

Act

The agent calls CleanHaus's own API under the user's login, and guards keep tool names, IDs and internal fields out of the reply.

Approve

Outward actions such as contractor bids wait in the owner's Agent Inbox until approved, unless the owner set that job to auto.

A closer look

What changed

CleanHaus reported its app and AI agent live and credited our team. The assistant now works across bookings, jobs, inventory, onboarding and contractor outreach through the same APIs and logins the product already used, and it shipped from inside the client's own repository and accounts, so nothing had to be handed over.

“CleanHaus has been moving quickly to deploy our app and Broomy AI Agent with the key assistance of the Datics team. We couldn't have reached this point without your excellent bench of developers.”
Nat ParkerNat ParkerCEO and Co-FounderCleanHaus

Under the hood

Datics role
AI added to a live product
Integrations
CleanHaus APIs on AWS API Gateway and Lambda as LLM tools, Stream Chat channels and webhooks, Amazon SES, SNS and S3 for bid email, Qdrant for property documents and a Postgres LangGraph checkpointer.
Security boundary
Cognito identity on every call, allowlists per role and channel with a static role lock, guards that block leaked IDs and actions with no tool, and a runbook that requires redacting customer data and tokens before logs are shared.
Deployment
A container service on AWS ECS Fargate with Lambda functions for the stream webhook and inference, a production environment with its own Qdrant and Cognito, and CloudWatch logs by subsystem.
Evals
Tier 1 unit tests on every push in GitHub Actions, Tier 2 routing evals with a mocked backend and Tier 3 LLM-as-judge evals in LangSmith, later used for a model bake-off.

AI and models

LangGraphOpenAI GPT-5.1

Data and retrieval

Qdrant

Cloud and infrastructure

AWS ECS FargateAmazon Cognito

Apps and APIs

PythonFastAPI

Also in the stack

LangSmith

How it shipped

  1. Scope the extension

    We studied the running assistant and wrote the scope: more backend APIs as tools, the full job cycle, retrieval per property, text and voice access, and tracing for debugging.

  2. Supervisor and domain agents

    One agent became a supervisor routing to property, cleaning, booking and user management agents, with guards against tool loops and duplicate replies and a move from GPT-4 to GPT-5.

  3. Production and tests in tiers

    Production got its own Qdrant and Cognito, then came the inventory agent and a test pipeline that runs from unit tests on every push to LLM-as-judge evals.

  4. Multi-channel rebuild

    A new package compiled a graph and tool allowlist per channel and role, with a static role lock, per-user threads and the decision node for shared channels.

  5. Proactive agents at launch

    Briefings, the onboarding guide, streaming and feedback followed, and as CleanHaus reported the product live we added the attention classifier and the contractor bidding agent.

Inside the client's code and accounts

The assistant lives in CleanHaus's own GitHub repository and ships through pull requests, on its live backend, Cognito logins and AWS accounts, with access granted by its CTO and separate development, experimental and production environments.

Next to the client's CTO

We met CleanHaus's CTO regularly, shared demo recordings as features landed, integrated the login changes he shared and had him test them, and took designs such as message visibility in property channels to him for review before building.

Bugs traced from logs

Agent runs are traced in LangSmith and logged in CloudWatch by subsystem, and our runbook says to find the failing tool call and check which tools were bound before blaming the prompt.

What this unlocked

Next are voice calls for hosts, matching chat to voice on refusing overlapping bookings, and a plan for accounts with more than 2,000 properties and users who hold several roles.

Have a product with the same kind of constraints?

Tell us what already exists and what you want it to do. We will tell you what it takes.

Book a 30-minute Product Review