Introduction
MirroCRM is a purpose-built operations platform for trades and service businesses. It manages the full job lifecycle — from the first customer enquiry through quoting, scheduling, and materials, all the way to final payment.
Unlike generic CRM tools, MirroCRM is designed around the real workflow of a service team: site surveys, trade quotes, Irish VAT rates, supplier orders, and job tracking. Every screen is built for the way service businesses actually work.
Full pipeline
Track every job from new lead to paid invoice across 24 statuses.
Quotes & VAT
Build professional quotes with Irish VAT rates and generate PDFs instantly.
Mobile-first
Install as a PWA on iPhone or Android — works on-site without a laptop.
Core workflow#
Every job follows the same end-to-end path. Understanding this flow makes every other feature click into place.
At each stage the system surfaces exactly what is needed: surveys become site notes, quotes flow into tasks, material orders track against the schedule. The pipeline is always visible on the Projects board.
Key concepts#
| Term | Meaning |
|---|---|
| Project | The central record for one job. Links the customer, quote, tasks, payments, materials, and files. |
| Customer | The person or household commissioning the work. One customer can have multiple projects. |
| Quote | A priced document sent to the customer. A project can have multiple quote versions. |
| Task | A single piece of work (e.g. "Lay floor tiles — bathroom"). Tasks belong to a project, or stand alone with a due date as a personal follow-up. |
| Supplier quote | A price request or order record for tiles, adhesive, sanitaryware, etc. |
| Payment stage | One instalment in a multi-stage payment plan (deposit, progress, final). |
Logging in#
Open your CRM web address in any modern browser (e.g. mirrocrm.com/kaes — older bookmarks like kaes.mirrocrm.com or kaes.httoya.org still redirect there automatically). Enter your email and password on the login screen. If this is your first time, your account was created by the team owner — check your email for the invite link.
Bookmark the app or install it to your home screen — see Install mobile app below. This gives you one-tap access with full offline support.
Forgotten password
Click Forgot password on the login screen and enter your email. You will receive a reset link valid for 60 minutes.
Dashboard#
The dashboard gives an immediate overview of the business. On every visit you see:
- ✦Active projects — Count of jobs currently in progress, split by status category.
- ✦Upcoming tasks — Tasks due today or overdue — tap to action them.
- ✦Recent activity — A live feed of changes made by the team across all projects.
- ✦Pipeline value — Combined quote value of all non-archived projects.
Install mobile app#
MirroCRM is a Progressive Web App (PWA). Installing it creates a native-like experience with push notifications, a home screen icon, and fast load times.
iPhone / iPad (Safari)
- 1Open the app in Safari.
- 2Tap the Share button (rectangle with an arrow) in the toolbar.
- 3Scroll down and tap Add to Home Screen.
- 4Confirm the name and tap Add.
Android (Chrome)
- 1Open the app in Chrome.
- 2Tap the three-dot menu in the top-right corner.
- 3Tap Add to Home screen.
- 4Confirm by tapping Install.
After installing, open the app and allow push notifications when prompted. This enables task due-date alerts even when the app is in the background.
Creating a project#
Every job starts as a new lead. Navigate to Projects and tap + New Lead. You need a customer name and job type at minimum — everything else can be filled in as the job progresses.
Required fields
| Field | Notes |
|---|---|
| Customer name | Creates a new customer record or links to an existing one. |
| Job type | One of: Full bathroom, En-suite, Tiling only, Kitchen backsplash, Shower replacement, Floor tiling, Wall tiling, Repair/snagging, Multi-room. |
| Phone / Email | At least one contact method is required to send a quote. |
| Lead source | WhatsApp, phone, email, website, referral, social media, or other. |
Optional fields
Address, Eircode, site access notes, rooms with dimensions, estimated value, and assigned sales/PM/installer. These can all be added after the lead is created.
Status pipeline#
Each project moves through a defined set of statuses that reflect where it sits in the job lifecycle. Statuses are grouped into colour-coded phases visible on the Pipeline board.
| Status code | Label | Description |
|---|---|---|
new_lead | New lead | Enquiry received, not yet contacted. |
info_needed | Info needed | Awaiting further details from the customer. |
survey_needed | Survey needed | Site visit not yet booked. |
survey_booked | Survey booked | Site visit date confirmed. |
draft_quote | Draft quote | Quote being prepared internally. |
quote_review | Quote review | Quote awaiting owner approval before sending. |
quoted | Quoted | Formal quote sent to the customer. |
follow_up | Follow-up | Quote sent; following up on decision. |
accepted | Accepted | Customer confirmed they want to proceed. |
deposit_requested | Deposit requested | Deposit invoice issued to customer. |
deposit_paid | Deposit paid | Deposit received — job is financially committed. |
merchant_quote_needed | Merchant quote needed | Tile/materials pricing required from supplier. |
materials_selected | Materials selected | Tiles and materials chosen and confirmed. |
materials_ordered | Materials ordered | Order placed with supplier. |
scheduled | Scheduled | Start date confirmed in the calendar. |
in_progress | In progress | Installation actively underway. |
on_hold | On hold | Work paused — awaiting materials, customer decision, etc. |
rework_issue | Rework issue | A problem was identified requiring remedial work. |
snagging | Snagging | Punch-list items being addressed before handover. |
complete | Complete | All work finished and handed over. |
final_payment_requested | Final payment requested | Final invoice sent to customer. |
paid | Paid | All payments received. Job closed. |
archived | Archived | Job removed from active views. Data retained. |
lost | Lost | Customer did not proceed. Quote rejected or no response. |
Risk & priority#
Priority levels
Priority affects how a project appears in list views and helps the team decide what to work on next.
Risk levels & flags
Risk flags are added manually when there is a specific concern: customer payment history, complex access, disputed scope, etc. Risk level rolls up across all active flags.
Projects with Critical risk level are highlighted in red across all views. Address the underlying issue before proceeding with further financial commitments.
Notes & activity#
Each project has a chronological notes feed visible to the whole team. Notes are permanent (not editable after saving) to create a reliable audit trail.
Below notes, the activity log shows every field change, status update, and system event on the project — with a timestamp and the team member who made it.
Building a quote#
Open any project and navigate to the Quote tab. Tap + New Quote to start the three-step wizard.
Step 1 — Basics
Choose the quote type, set a validity period (default 30 days), and write a scope summary describing the work to be done.
| Quote type | Use when |
|---|---|
Draft estimate | Internal ballpark figure, not yet for the customer. |
Formal quote | The primary priced document sent to the customer. |
Revised quote | An updated version after negotiation or scope changes. |
Variation | Additional works beyond the original contract. |
Snagging quote | Remedial or finishing works after project completion. |
Step 2 — Line items
Add sections (e.g. Labour, Floor Tiles, Wall Tiles, Materials & Fixings) and populate each section with line items. Each item has a description, quantity, unit, unit price, and VAT rate.
The system automatically categorises sections by name: sections containing Labour count towards labour spend; sections containing Tilecount towards tiles spend. This data feeds into the project's cost breakdown.
Line items & VAT#
KAES supports all three Irish VAT rates applicable to renovation work:
| Rate | Applies to |
|---|---|
| 0% | Zero-rated supplies (certain exported goods, etc.) |
| 13.5% | Construction services and certain building materials — the most common rate for renovation work. |
| 23% | Standard rate — certain goods and professional services. |
Renovation labour performed on a principal private residence typically qualifies for the 13.5% reduced rate. Always verify with your accountant for each job type. Incorrectly applying 23% to qualifying renovation works is a common error.
Totals are shown excluding and including VAT throughout. The quote PDF displays both.
Payment schedules#
Step 3 of the quote wizard lets you define how the customer will pay. Choose a preset or build custom stages.
| Preset | Stages |
|---|---|
| 30 / 30 / 40 | Deposit on acceptance · Progress on commencement · Final on completion |
| 50 / 50 | Deposit on acceptance · Final on completion |
| 30 / 40 / 30 | Deposit on acceptance · Progress payment · Final on completion |
| Custom | Define any number of stages with arbitrary percentages and trigger conditions. |
Sending & PDF#
Once a quote is saved, tap Generate PDF from the quote card. The PDF includes your logo, scope summary, full line-item breakdown, VAT summary, and payment schedule — ready to share via WhatsApp or email.
Update the quote status from Draft → Sent when you share it with the customer. When they confirm, mark it as Accepted — this automatically advances the project status.
AI pricing check#
When you reach Step 3 of the quote wizard, the system automatically checks your pricing against historical accepted quotes for the same job type and against current Dublin market rates.
The check returns one of three results:
Looks competitive
Pricing is consistent with market rates and your own history for this job type.
May be underpriced
One or more line items appear low relative to typical rates for this scope of work.
Significantly below market
The total is materially lower than comparable accepted quotes. Review before sending.
Tap Re-check after adjusting prices to run the analysis again. The check is advisory — you are free to save and send any quote regardless of the result.
Managing tasks#
Tasks are the individual units of work within a project. Navigate to the Tasks tab on any project or use the global Tasks view to see everything assigned to you.
Task statuses
Blocking dependencies
Any task can be marked as blocking another. A blocked task shows clearly that it cannot start until its blocker is resolved. This is useful for sequences like: Waterproofing → Floor tiles → Wall tiles → Grouting → Final clean.
Tasks marked as Internal only are visible to the team but are not shown on any customer-facing document.
Job-type templates#
When a project reaches the Scheduled status, you can generate a full task list from a pre-built template for the job type. Templates include standard steps for bathroom renovations, tiling-only jobs, shower replacements, and more.
Each template task includes a recommended day offset from the project start date, a default assignee role, and an order index for sequencing.
Payment stages#
Payments are managed on the Payments tab of each project. Each accepted quote generates a set of payment stage records matching the schedule you defined.
| Stage type | Typical timing |
|---|---|
Deposit | Collected on quote acceptance, before any work starts. |
Progress | Collected at commencement or a milestone during the job. |
Final | Collected on completion before the customer signs off. |
Add-on | Any additional charge agreed during or after the job. |
Recording payments#
When a customer pays, open the payment stage and tap Mark as paid. Record the payment method (cash, bank transfer, card, cheque) and the date received.
The project card immediately updates to show the outstanding balance. The accountant role can see a full payments summary across all projects from the Payments section.
Supplier quotes#
The Materials tab on each project tracks what you need to order and from whom. Create a supplier quote request by adding line items: tile reference, quantity, unit, and expected price.
Material categories cover the full scope of a bathroom renovation:
Order tracking#
Each line item on a supplier quote has two checkboxes: Ordered and Delivered. As materials arrive on site, tick them off. The project status should move to materials_ordered and then materials_selected as the team progresses.
Task due dates#
Personal, timed follow-up prompts are just tasks with a due date — there is no separate reminders feature. Add a quick one from any project's activity feed: tap the + button next to the message box and choose Add task.
A task has a title, an optional description, a due date and time, and is linked to a project (or stands alone on the Tasks screen). Tasks with a due date appear in three buckets there:
| Bucket | Meaning |
|---|---|
| Overdue | Past the due time and not yet done. |
| Today | Due today. |
| Upcoming | Due on a future date. |
Snooze options
On a task entry in the activity feed, tap the clock icon to delay its due date by 10 minutes, 1 hour, or until the next day at 9 am — without opening the full task editor.
Push notifications#
When you install the app and allow notifications, a task's due date is delivered as a push alert once, at the moment it falls due, even when the app is closed or in the background. The notification includes the task title and the linked project reference.
Tap the notification to open the project directly. Due tasks are processed every minute by the server.
Notification permission is per-device. If you use the app on both a phone and a desktop, you will need to allow notifications on each separately.
Calendar view#
The Calendar screen shows all scheduled projects across a monthly grid. Each event displays the project reference, job type, and assignee. Tap any event to open the project.
Tasks with a due date also appear on the calendar, colour-coded separately from project events.
iCal sync#
Subscribe to a personal iCal feed to see your KAES calendar inside Apple Calendar, Google Calendar, or any other calendar app that supports the .ics standard.
- 1Go to Account → Calendar settings.
- 2Tap Generate feed URL. A unique, private URL is created for your account.
- 3Copy the URL and add it as a subscribed calendar in your calendar app of choice.
- 4Events update automatically when projects are rescheduled.
The feed URL is private and tied to your account. Do not share it. If the URL is compromised, you can regenerate it from Account settings — the old URL will immediately stop working.
Uploading files#
Open the Files tab on a project and tap + Upload. Select one or more files from your device. Large images are automatically compressed before upload to save bandwidth and storage.
Files are stored securely in cloud storage with access restricted to your team. Each file has a direct download link valid for a limited time.
Photo categories#
| Category | Use for |
|---|---|
Before | Photos taken before any work starts — documents the existing condition. |
During | Progress photos taken mid-installation. |
After | Completion photos showing the finished work — critical for portfolio and disputes. |
Quote | Measurements, sketches, or reference images used when preparing the quote. |
Invoice | Scanned or photographed invoices from the customer. |
Receipt | Supplier receipts for materials purchased for this job. |
Plan | Floor plans, drawings, or layout sketches. |
Other | Anything that does not fit the above categories. |
Always take Before photos before starting any job. They protect against disputes about pre-existing damage and are invaluable if a customer raises a concern later.
User roles#
Every team member is assigned one role. Roles control what they can see and do across the system.
| Role | Access level | Typical person |
|---|---|---|
Owner | Full access. Manages users and billing. | Company owner / director. |
Sales | Full project & quote access. Cannot manage users. | Sales manager or estimator. |
Project manager | Full project access. Cannot see financial summaries. | Site manager or operations lead. |
Installer | View-only on projects & tasks. Can mark tasks done. | Tiling technician on site. |
Accountant | Read-only on projects. Full access to payments & invoicing. | Bookkeeper or finance admin. |
Read only | View everything; no editing or creating. | Client-side oversight or temporary access. |
The Payments screen is restricted to owner and accountant roles. All other roles are redirected to the dashboard if they try to access it directly.
Inviting members#
Navigate to Account → Team. Tap + Invite member, enter their email address, and select their role. They will receive an email with a sign-up link.
You can deactivate a team member at any time from the same screen. Deactivated accounts cannot log in but their historical actions remain in the activity log.
AI pricing check#
The pricing check is powered by a large language model that analyses your quote and compares it against your own accepted-quote history and general Dublin renovation market rates (updated to 2024).
The model evaluates:
- →Total quote value relative to job type
- →Labour-to-materials ratio (normally 50–65% labour)
- →Per-m² rate compared to historical jobs of the same type
- →Individual section totals for obvious anomalies
Privacy & data#
The AI check is designed with privacy as the primary constraint. No personal data is sent to the AI provider. The request contains only:
- →Job type (e.g. "full bathroom")
- →Section titles and totals in euros
- →Room floor area in m² (if available)
- →Anonymised historical averages from your own accepted quotes
Customer names, addresses, contact details, and project references are never included. The AI model is run via the Groq API using an open-weights model. Queries are not used for model training.
Public API#
Connect your own website's booking or enquiry form directly to your MirroCRM workspace. Submit a lead from your site and it appears instantly on your Leads page, ready to be picked up by your team — and by any automation flow you've set up for new website leads.
- 1Open Settings → Integrations and create a new connection.
- 2Copy the API key shown — it's only ever displayed once.
- 3From your booking form's submit handler, send the visitor's details to the endpoint below with your key in the
Authorizationheader.
Call this endpoint from your own server, never from browser JavaScript. Your API key would be visible to any site visitor (view-source, devtools) if embedded in client-side code — same exposure as committing it to a public repo. Have your form post to your own server-side route, which then forwards the request to MirroCRM with the key attached.
Authentication#
Every request must include your API key as a bearer token:
Authorization: Bearer mcrm_live_...Treat your API key like a password. It grants permission to create leads directly in your workspace. Store it in your site's server-side config or a build-time environment variable, not committed to source control. If a key is ever exposed, revoke it from the Integrations tab and create a new one.
Create a lead
POST https://www.mirrocrm.com/api/public/v1/leads
Only name and email are required — everything else is optional.
| Field | Type | Notes |
|---|---|---|
name | string | Required. |
email | string | Required. |
phone | string | |
type | string | Enquiry type, e.g. "quote". Defaults to "quote". |
message | string | |
preferred_date | string | |
preferred_time | string | |
address | string | |
apt | string | |
city | string | |
eircode | string | |
bedrooms | number | |
bathrooms | number | |
service_type | string | |
estimated_total | number | |
extras | array | List of { id, label, qty, price }. |
curl -X POST https://www.mirrocrm.com/api/public/v1/leads \
-H "Authorization: Bearer mcrm_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "+353 87 000 0000",
"message": "Looking for a quote on a full bathroom renovation."
}'From a Next.js/Node API route on your own site — your form posts here, and this route holds the key server-side and forwards to MirroCRM:
// your site's own server-side route, e.g. app/api/quote/route.ts
export async function POST(request) {
const { name, email, phone, message } = await request.json()
const res = await fetch('https://www.mirrocrm.com/api/public/v1/leads', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MIRROCRM_API_KEY}`,
},
body: JSON.stringify({ name, email, phone, message }),
})
return Response.json({ ok: res.ok })
}A successful request returns:
{ "ok": true, "leadId": "..." }Errors & rate limits#
| Status | Error | Meaning |
|---|---|---|
| 401 | missing_or_invalid_key | The Authorization header is missing or malformed. |
| 401 | invalid_or_revoked_key | The key doesn’t match an active connection. |
| 400 | invalid_payload | A required field is missing or a value is invalid — see the response’s "details" array. |
| 429 | rate_limited | Too many requests from this key. |
| 500 | internal_error | Something went wrong on our side — safe to retry. |
Each API key is limited to 30 requests per minute — generous for a booking form, enough to stop a runaway script. If you need a higher limit for a legitimate use case, contact support.
Status codes reference#
The full list of project status codes appears in the Status pipeline section above. For quick programmatic reference when building integrations via the iCal feed or API:
new_leadinfo_neededsurvey_neededsurvey_bookeddraft_quotequote_reviewquotedfollow_upaccepteddeposit_requesteddeposit_paidmerchant_quote_neededmaterials_selectedmaterials_orderedscheduledin_progresson_holdrework_issuesnaggingcompletefinal_payment_requestedpaidarchivedlostKeyboard shortcuts#
| Shortcut | Action |
|---|---|
⌘ K / Ctrl K | Open global search |
Esc | Close search, modal, or dropdown |
⌘ / | Focus search |
On mobile, tap the search icon in the header to access global search. You can search by project reference, customer name, or job type.
FAQ#
Can multiple team members use the app at the same time?
Yes. The app supports concurrent access. Changes made by one team member are visible to others after a page refresh. The activity log records who changed what and when.
What happens to data if we stop using the service?
All project data is stored in a managed PostgreSQL database. You can request a full data export at any time. Data is retained for 12 months after an account is deactivated.
Can I customise the job-type templates?
Not from the UI currently — template customisation requires a code change. Contact the team if you need a template adjusted for your specific workflow.
Why does the AI pricing check say "unavailable"?
The check requires a GROQ_API_KEY to be configured in the server environment. If you see this message, the key is missing or the service is temporarily unavailable.
Are customer bank details stored in the system?
No. KAES records payment amounts, methods, and dates — it does not store any bank account, card, or sensitive financial data. Payments are handled outside the system.
Can I add the app to multiple Apple devices?
Yes. Follow the PWA install steps on each device. Push notifications are subscribed separately per device, so you will receive alerts on all installed devices.
How is the iCal feed URL kept secure?
The URL contains a unique, cryptographically random token tied to your user account. You can regenerate it from Account settings if you suspect it has been shared. The old URL stops working immediately.
Something missing?
Contact the team if you need a section added or clarified.