Skip to main content
All Docs
FeaturesmyProp (AgentOS People Portal)Updated April 4, 2026

Maintenance Request Management

Maintenance Request Management

The myProp portal provides a full maintenance request lifecycle for tenants, landlords, and property managers — from submitting a new issue through to job completion, contractor tracking, and note history.

Overview

Maintenance requests are backed by the AgentOS (letmc.com) API. The portal surfaces real-time job data and enables two-way interactions: clients can report issues, track progress, communicate via notes, and monitor contractor assignments without contacting the agency directly.

Submitting a Request

Clients can report a maintenance issue by providing:

  • Title — A short description of the problem.
  • Description — Detailed account of the issue (may be skipped for emergency categories — see Step-Skip Logic).
  • Category — Selected from the agency's configured category list.
  • Priority — Urgency level for the job.
  • Preferred date and time — Scheduling preferences (may be skipped for emergency categories).
  • Access instructions — Entry notes for the contractor.
  • Contact details — Phone and email for coordination.

Tracking Jobs

Once submitted, a maintenance job can be tracked in the portal. The following information is surfaced per job:

  • Job status (open, in progress, awaiting contractor, completed, cancelled)
  • Reported date and reported-by details
  • Assigned contractor name, ID, and contact phone number
  • Estimated and actual costs
  • Preferred scheduling details
  • Last updated timestamp
  • Full note history

Job Statuses

StatusMeaning
OpenReported, not yet actioned
In ProgressWork has started
Awaiting ContractorPending contractor assignment or attendance
CompletedWork finished
CancelledRequest withdrawn or closed

Notes

Notes can be added to any active maintenance job by authorised users. Notes are listed in chronological order and distinguish between user-authored notes and system-generated notes.

Summary Statistics

A per-property maintenance summary provides aggregate KPIs:

  • Total requests
  • Open requests
  • In-progress requests
  • Completed requests
  • Awaiting-contractor requests
  • Average completion time (days)

Step-Skip Logic

Certain high-urgency categories automatically skip non-essential form steps to speed up emergency reporting.

Skipped Steps by Category

CategorySkips DescriptionSkips Scheduling
Emergency
Urgent
Gas Leak
Flood
Fire
Break-in
No Heating
No Hot Water

Step-skip behaviour is resolved in the following order:

  1. API flags — If the AgentOS category record includes SkipDescription: true or SkipScheduling: true, those steps are skipped unconditionally.
  2. Emergency flag — If the record includes IsEmergency: true (or equivalent), both steps are skipped.
  3. Category name match — If the category name matches a known emergency name (case-insensitive), the appropriate steps are skipped.

FixFlo Integration

For agencies using FixFlo as their maintenance portal, the system resolves the correct maintenance URL using a priority chain:

  1. Company-level FixFlo URL
  2. Person-level FixFlo URL
  3. None — standard in-portal flow

The removeMaintenanceJobs flag is respected: if set, the standard job list is suppressed in favour of the FixFlo redirect.

API Endpoints

All endpoints are available under the maintenance tRPC namespace and require authentication.

maintenance.status

Check whether the maintenance service is available for the current agency.

maintenance.categories

Fetch the list of available maintenance categories, including step-skip flags for each.

Returns: Array of categories, each with:

  • categoryId
  • name
  • description
  • parentCategoryId
  • skipDescriptionStep (boolean)
  • skipSchedulingStep (boolean)
  • displayOrder

maintenance.submit

Create a new maintenance request.

Input:

{
  propertyId: string;
  tenancyId?: string;
  title: string;
  description: string;
  categoryId?: string;
  priority?: string;
  preferredDate?: string;    // ISO date string
  preferredTime?: string;
  accessInstructions?: string;
  contactPhone?: string;
  contactEmail?: string;
}

Returns: { jobId, success, message }

maintenance.list

Paginated list of maintenance jobs for a property.

Input: { propertyId, status?, offset?, count? }

Returns: Array of MaintenanceRequest objects.

maintenance.details

Fetch a single maintenance job with its full note history (parallel fetch).

Input: { jobId, shortName }

Returns: { request: MaintenanceRequest, notes: MaintenanceNote[] }

maintenance.notes

List all notes for a maintenance job.

Input: { jobId, shortName }

Returns: Array of MaintenanceNote objects.

maintenance.addNote

Add a note to an existing maintenance job.

Input: { jobId, shortName, text }

Returns: Success indicator.

maintenance.updateStatus

Update the status of a maintenance job (complete, reopen, cancel).

Input: { jobId, shortName, status: 'completed' | 'reopened' | 'cancelled' }

Returns: Success indicator.

maintenance.summary

Fetch aggregate maintenance statistics for a property.

Input: { propertyId, shortName }

Returns: MaintenanceSummary object with open/in-progress/completed counts and average completion days.

maintenance.resolveFixflo

Resolve the FixFlo maintenance URL for the current user/agency context.

Input: { shortName, personId, companyId? }

Returns: { url: string | null, removeMaintenanceJobs: boolean }

Data Model

MaintenanceRequest

{
  jobId: string;
  propertyId: string;
  propertyAddress: string | null;
  tenancyId: string | null;
  title: string;
  description: string | null;
  status: string;
  priority: string | null;
  category: string | null;
  categoryId: string | null;
  reportedDate: string | null;
  reportedBy: string | null;
  completedDate: string | null;
  estimatedCost: number | null;
  actualCost: number | null;
  contractorName: string | null;
  contractorId: string | null;
  contractorPhone: string | null;
  accessInstructions: string | null;
  preferredDate: string | null;
  preferredTime: string | null;
  lastUpdated: string | null;
  metadata: Record<string, unknown>;
}

MaintenanceNote

{
  noteId: string;
  jobId: string;
  text: string;
  createdAt: string | null;
  createdBy: string | null;
  type: string | null;
  isSystemNote: boolean;
  metadata: Record<string, unknown>;
}

MaintenanceSummary

{
  totalRequests: number;
  openRequests: number;
  inProgressRequests: number;
  completedRequests: number;
  awaitingContractorRequests: number;
  averageCompletionDays: number | null;
}

Error Handling

  • 404 responses from AgentOS return null or empty arrays — no error is thrown.
  • Non-critical errors are captured via captureError for observability without surfacing to the client.
  • Critical errors (e.g. service misconfiguration) throw LetmcNotConfiguredError.