🏠

Property Unify

Property UnifySign in

Features

Everything Property Unify does — move-in/out inspections, tenant e-signing, repairs, and reports.

đź§ľRecords & accountability

  • Audit log: what was done on the account and by whom — leases sent, signed and declined, documents approved and rejected, renewals opened and closed, settings changed — filterable by area, by person-vs-automatic, and by period.
  • The account’s member list is written by the team screen, the contractor-login admin and every member sign-in, and none of them can write over another. Each names the version it read and re-applies its own change to the list as it then stands; a change that cannot be applied is refused in words rather than reported as done. Converting a contractor login to full access is one write, so nobody is momentarily left without a login.
  • The activity log, the SMS log and the provider directory each live in one record and are appended read-modify-write. A read that failed refuses rather than inserting a rival record — the appenders already swallow their own failures, so an action never fails because its log entry could not be written, and the history is never split between two records that readers pick from at random.
  • Gmail intake is idempotent on the message identifier, and a message whose already-imported check cannot be read is deferred to the next run rather than re-imported — reported as a count, not swallowed. Completing the OAuth grant refuses rather than risking a second connection record, and a connection that cannot be read is reported as “couldn’t check”, never as “not connected”.
  • Payment attribution refuses when the cycle’s payment history cannot be read: no payment record, no change to what the bill already says about earlier payments, the event document attached as evidence and flagged for review as a technical failure rather than a judgement. Reprocessing records it once, through the same idempotency key.
  • A read that failed is never used as an answer. Every database read behind the receipt queue, the expense ledger and the vendor memory checks whether it actually ran, so an outage cannot become a missing receipt, an empty month, a duplicate receipt row or a second copy of the vendor memory. The CSV export stamp reports a partial result as a refusal, and the screen re-reads the list rather than keeping its own optimistic copy.
  • The account’s member list — who may sign in, and with what — is written the same guarded way, and every check that decides whether an address is a staff login or a contractor’s runs INSIDE that write, against the list being written rather than a copy read beforehand. A read that failed is retried and then refused; it never becomes an empty team, a rival list, or a waived check. The account’s document rules and the ownership links are held to the same rule.
  • Recognising a merchant — by name, then by alias — is read-then-create, and both reads name their error. It runs on every arriving document, and the merchant table has no unique constraint behind it, so a failed read that answered “never heard of it” would genuinely have split the directory in two. It refuses instead: no merchant on the document, and the coding rules stay attached to the one record that has them. The directory import behaves the same way and counts what it could not check.
  • The ownership links behind the owner and company screens name their errors, and the People segment and the Directory each carry an honest load-failure surface rather than an empty list. The rule is that a COUNT which arms a warning — how many buildings a delete would leave without an owner — may never come from a read that did not run.
  • The rule holds hardest where deletion is permanent. The 30-day trash sweep’s one refusal — never purge a party a live tenancy still names — is read from the database, so that read throws rather than answering an empty set, and an unreadable check aborts the sweep before a single statement is issued. The tenant-roster sync is held to the same rule in the other direction: neither the identity table nor the tenancy table has a unique constraint behind it, so a read that failed would have written the duplicate itself.
  • The property and unit lists name their errors too, because in the import and the reconcile pass an empty answer is what AUTHORISES a create. Every screen in the authenticated app has an honest load-failure surface behind it, so a read that refuses is drawn as a retryable failure that states nothing was changed — never as a blank list, and never as a crash page.
  • The rule covers locks and negative results as well as writes. The signing freeze is a read, so a read that cannot run refuses the edit rather than waiving the freeze; the office’s approvals queue is a screen whose value is the empty state, so it reports that it could not check rather than drawing one. And where a read is the only copy of what a write is about to replace — the photo restore rewrites the whole inspection — it is taken before anything is touched.
  • The same rule covers the sweeps that act on many records at once. Where a pass rewrites each document from what it just read, a document it could not read is skipped rather than rewritten from an assumed-empty one, and the count of skipped documents is carried all the way to the person who pressed the button — a clean total that hides them is the thing being prevented, not merely the bad write.
  • It also covers the write that happens after something has already left the building. The record of a compliance notification is written once the message has gone, so losing it loses the proof AND re-queues the notice; that write now reports back, and the count of sent-but-unrecorded messages is carried to the person who pressed Send and into the nightly run’s totals.
  • The rule extends to any place where ABSENCE from a list is the instruction. The renewal reconcile closes a task whose building is not in the buildings list, so every read behind that list refuses rather than answering “none”; the planner itself says so at the line where the orphan rule lives, because that code cannot tell a deleted building from an unreadable one and must never be asked to.
  • Where a retry already exists, the rule is what arms it. The Telnyx callback route refuses and asks for the event again on any write that fails; the two delivery-status writers behind it used to answer “nothing to do” and “best-effort” instead, so the retry never fired. They report now.
  • A count of zero is a claim like any other. Where a write can fail, the result says so and names what it did not touch, rather than returning the number that means “there was nothing to do”. Where an allowance exists for an older database, the permanent case and the transient one are now told apart by the error itself rather than sharing one silent path.
  • The Accounting → Receipts workspace reads every receipt the account holds, verified against an independent count — never the first page of them — and filters on the local day rather than the server’s.
  • Checks that decide whether money is duplicated fail toward review, not toward approval. A read that did not answer is treated as an unanswered question and shown to you, and an allowance for an older database no longer doubles as an allowance for an outage.
  • Every date the system fills in is the local calendar day, from one place in the code that knows about daylight saving — so an evening entry is not filed as the next morning, and a deadline counted from an evening arrival is not a day long.
  • A check that could not see all of your history says so. The duplicate screen, merchant recognition, repeat-notice matching, rule training and ignore-rule previews either read the whole of what they are deciding from or report that they could not — they never answer from the part they happened to be given.
  • Shared lists — the activity log, the record of texts sent, ignore rules, the provider directory and account settings — are written only when they have not changed since they were read, so two people working at once cannot silently undo each other.
  • An action can be undone once. The mark that records it cannot be erased by somebody else’s action landing at the same moment.
  • A document is never overwritten by a note about it: when a payment cannot be matched, it goes to review either way, and the reason is added only if the document’s own record could be read first.
  • Approval standing is read fresh on every press and refuses when it cannot be read — an unavailable lookup never widens what somebody may do.
  • Undo, splitting and unsplitting a multi-property bill, the Gmail connection, the ignore rules and every count a run reports back all check what was written before claiming it. A run that could not park, restore or remove something says so instead of counting it.
  • Team changes, removing a login, deleting an owner, compliance saves, tenant work orders and utility payment attribution all report what was actually written. An owner is never deleted while their ownership links are still standing, and a work order is never confirmed to a tenant before the record exists.
  • The error log, health record, cost totals and member activity say when they could not be read instead of showing an empty, reassuring screen. Restore and Delete permanently report what actually happened, and a permanent delete refuses outright unless every stored file behind the record can be accounted for first.
  • Removing a letter from Incoming, restoring one, and writing, approving, retiring or deleting a notice rule all refuse out loud rather than reporting a change that did not save. The removal record is written before the letter leaves the queue, so the worst case is a letter listed under Removed and still visible in Incoming, not one that vanished with no record.
  • The reprocess sweep reports only what it wrote. Every write goes through one checked place, the totals are gated on it, changes it could not save are counted and shown, and the documents behind them are left untouched for the next run. The amount correction and its bill cycle are one change or none.
  • A bill is never approved onto the books with no property on it: if the property link cannot be written, the document goes back into review and the failure is named in the activity log. Every other write intake makes beside the document — autopay status, the sighting on a bill cycle, the recurrence clock, the link from a payment to its bill — reports rather than being discarded, and linking to a utility account counts what it linked rather than what it attempted.
  • Every write in the applications, maintenance, compliance and property stores reports rather than assuming it landed — including the three-part ownership delete, which stops at the first failure instead of leaving the ownership graph half true, and the alert throttle stamp its own code promised was reported.
  • The rule trainer refuses instead of previewing “0 matches”, training without your example, or compiling a rule with no property. A rule’s usage count is never reset by a failed read, and “Gmail isn’t connected” is never said about a connection that is simply unreachable.
  • The storage boundary tells a real absence from a failed lookup: downloading and stat-ing an object refuse on an outage and still report a genuinely missing file as missing. The welcome packet refuses rather than being assembled without a required document.
  • Every write in the inspection evidence store is checked — the record, the signature, the confirmation token and all three photo writes — and its reads refuse instead of answering “not yours”, “no photos” or “this link is not real”.
  • Tenant-token reads refuse instead of answering “not valid”: the four tenant requests answer 503 when the tenancy cannot be read, and keep the 404 for a token that genuinely is not ours. Every operator-side tenancy read refuses too.
  • The signing-record store refuses instead of answering with a blank, and the DocuSeal webhook answers 503 — asking for redelivery — when a completion could not be recorded. Events it genuinely does not own still answer 200.
  • Every read that answers “does this already exist?” refuses instead of answering no: the AppFolio guardrail, the split’s sibling scan, and both payment-pairing scans. A pairing that could not run is counted and reported, and the document is left in review.
  • All four read-then-write reads on a money document refuse rather than starting from a blank: the field merge, the attach guard, the undo snapshot and the status history — and the older-database compatibility catch cannot absorb any of those refusals.
  • Every read in the notice queue refuses instead of answering with an absence, including the duplicate scan — which is reported as unavailable rather than empty, so the letter and its deadline still open.
  • The account store refuses instead of answering with a blank: the current-password check is never skipped, an account is never rewritten from defaults, a save is never reported unchecked, and the gates that hold contractor logins out of the landlord app refuse to open when they cannot check.
  • The account settings row — the most widely read record in the product — refuses instead of answering with the defaults, and its save refuses instead of reporting a write it never checked. Every path that acts on Dev Mode, on the contractor directory, or on the reason-with-every-reveal requirement now fails closed.
  • Every read in the People store refuses instead of answering empty — including the three that are decisions rather than lists: who is only a renter, whether a property is already in a group, and whether a person exists here at all. Moving a tenant out and linking tenants to a lease report whether the write landed.
  • Every read that answers “is there a payment behind this?” refuses instead of answering none — the undo, the reversal lookup, the bill’s own payment list, and the cycle clean-up after a split. A split whose merged bill cycle survives is written down as money being counted twice, not swallowed.
  • The SMS consent trail refuses instead of answering empty — on the write as well as the read. A STOP that the database rejects now makes the carrier send the event again, and “never asked” is never inferred from an outage on any screen that can act on it.
  • Removing an access record reports the links it could NOT withdraw, not only the ones it did. A contractor link is a capability somebody already holds, so a failed revocation is a code still in circulation against a record nobody can see any more.
  • Everything the app keeps in a single record — the activity log, the SMS log, the provider directory, the tagging rules, the red-alert settings and log, the removals list, the account settings, the house rules, the AppFolio roster and the dashboard layout — is written read-modify-write, and every one of those reads now names its error. A failed read can no longer insert a rival record for later readers to pick between at random, and it can no longer be merged onto as though the record were empty. The red-alert settings are the one that decides who is interrupted: their defaults are permissive, so a failed read used to override an operator’s “off” rather than lose it.
  • Which building a bill belongs to is read before every write that depends on it — the utility auto-link, rule activation, both queue sweeps, the contractor split, the reviewer’s change and its undo — and every one of those reads checks that it ran. A document is never left carrying two property rows for readers to pick between, a contractor’s split is never inserted on top of one already decided, and the row that records what a property WAS is never deleted on the strength of a read that did not happen.
  • An action taken by a team member or a site administrator is filed under the account it happened to, not the actor’s own, and still names the actor.
  • Automated writers (the signature-provider callback, the nightly signature sweep) are labelled as processes rather than presented as people.
  • Report history: every inspection report that went out for signature and has since closed, with each signer’s outcome, months after the signing window shut. Cancelled rounds are shown as cancelled and never counted as signatures.
  • Messaging posture: whether texting can actually reach anyone from this deployment, which provider would send, and what is still awaiting a delivery receipt.
  • Integrations: every outside service the deployment uses, with “configured” and “working” shown as separate facts — a recorded result goes stale rather than standing in for a live check, and a service nothing has called reads as no health signal rather than green.
  • Notice detection on document intake: a violation, insurance cancellation, licence expiry, tax delinquency, collections letter or court summons is marked as a notice rather than an invoice, is never auto-approved by a rule, and is filterable from the Bills queue. Notices arriving as plain email with no attachment are ingested on their wording alone, so they reach the queue at all.
  • Incoming → Notices: a queue for everything that arrives and is not a bill — violations, inspections, licences, Section 8 and PHA paperwork, landlord cooperation, insurance, tax and liens, utility shutoff and delinquency, court filings, general correspondence and anything the reader could not place. Separate from Bills on purpose: a bill is worked by approving it, a notice by answering it before a date.
  • Each notice shows the property and unit, the agency, the notice date, the deadline or hearing or inspection date, the case or violation number, the amount if there is one, what is required, and the urgency — with the phrase every value was read from, so it can be checked against the letter shown beside it. A value the reader supplied rather than read says so.
  • Urgency is recomputed against today on every read, never taken from the stored row: a deadline that has since passed sorts to the top instead of sitting where it landed the day it arrived.
  • A notice is never auto-approved, never auto-filed and never treated as a paid bill: no rule, no utility match and no bulk approval can reach one, and it starts at “open”. Its status is what a person did about the letter, held separately from the billing review status on the same document.
  • Correction keeps the original reading underneath it, so a corrected value and a read one stay distinguishable; property matching, assignment, and duplicate suggestions that are never applied automatically; the original email and every attachment preserved, with the PDF viewable in place.
  • Deadlines, hearings and inspections appear on Today’s deadline list beside licence renewals and recurring tasks, linking to the notice. They are surfaced in the app only — nothing is sent because of a date.
  • Incoming → Gmail: the document-intake screen has its own window beside the Notices queue, showing the same connect / sync / disconnect surface as Accounting → Document intake, including attachments that failed to import — kept separate from attachments deliberately skipped, and from files the reader cannot open, which are named one by one with what to send instead rather than counted as left on purpose.
  • Mail arriving through a scanning or forwarding service is classified on the letter, never the envelope: the sender is taken from the cover sheet's “original sender”, from a forwarded header block, or from the letterhead of the scanned page. The carrier is reported as the carrier and is never returned as the author, and a covering message with no letter under it reads as unknown rather than as correspondence.
  • Senders are matched on a domain label boundary and the most specific department wins, so a lookalike domain cannot borrow an agency's name and Water Revenue, Public Health, Fire, the Office of Property Assessment, PHDC and PA Human Services are recognised in their own right rather than as the City generally.
  • A booking or rescheduling link found in a letter is read and shown with its destination host — never followed, fetched or submitted to, and never offered at all when it resolves inside this network.
  • Incoming → Tagging rules: the mailroom learns from corrections. Correcting a classification or an assignment suggests a reusable rule keyed on the sender address or domain, the sender inside a forward, subject or document wording, an account/parcel/case number or the agency — written down as a suggestion that matches nothing until a person approves it.
  • Every rule is visible as a sentence, editable, reversible and auditable: it can be tried against the post already in the account (a dry run that reports what it would tag and what it would change, and writes nothing at all), approved, retired and put back in use, with who did each and when kept on the rule itself and in the activity log. Editing what a live rule matches sends it back for approval; an approved rule is retired rather than deleted, so the notices it tagged stay explainable.
  • A SUGGESTION THAT CONTRADICTS A LIVE RULE CANNOT BE APPROVED. Where a suggestion looks for exactly what an active rule looks for and files it somewhere else, the screen says so before Approve is pressed — naming the rule, and what each of them would do, in words — the button is not offered, and the server refuses it underneath. Approving it would not replace the live rule; it would stack behind it, and the queue would then follow whichever was written first. A NARROWER rule is an exception rather than a conflict, and is left alone.
  • A rule can tag and route — category, agency, property, assignee, a label — and nothing else: it cannot approve, file, pay, resolve or delete a notice, and there is no field in a stored rule that could carry one. A rule with no conditions, or one so loose it would tag every letter in the account, is refused rather than approved.
  • Every notice says where its reading came from — an approved rule (with the rule, why it matched and what it set), the document itself, or the reader with little to go on — alongside the confidence and, for scanned post, the carrier and the original sender that was actually classified.
  • Remove from intake: anything that is not post for this business — marketing, a stranger's mail, a duplicate, an unreadable scan — comes off the working queue with a reason that has to be chosen, never a default one. Nothing is deleted: the notice, its files and the Gmail message stay exactly where they were, and Incoming → Removed from intake is the searchable list of everything taken out, with the reason, who took it out and a one-press Restore.
  • The removal index learns from the sender and the shape of the letter, never from its contents: the sending address and domain, the original sender inside a forward, a generalised subject pattern, the attachment type, the identifiers already extracted and the classification being corrected. The body of your mail is not a matching condition and there is no field in a stored removal rule that could hold one.
  • Marketing / promotional is both a classification and a removal reason. An advert is read as marketing from the WORDS — never from a sender’s domain, because the companies that advertise hardest also send disputes, fraud alerts, payment failures and account notices — and a real notice carrying an unsubscribe footer stays a notice. Removing something as marketing files it as marketing at the same time, with the correction recorded, so it does not sit in the record as general correspondence.
  • A SENDER THAT ALSO WRITES ABOUT MONEY CAN NEVER BE THE WHOLE OF A RULE. For a domain that carries account, payment, dispute, fraud, legal or service post, the queue refuses to propose the bare domain and proposes the exact address or the domain with a subject pattern instead — and at run time a domain-only rule is held for a person unless the letter itself was read as marketing. Mail that arrived through a scanning service is keyed on the original sender, never on the carrier.
  • Only three reasons can ever become a rule — marketing / promotional, spam or junk, and not property-related. Duplicate, wrong account, already handled, unreadable document and other describe one letter, are labelled as such before the choice is made, and are never generalised into a sender rule.
  • After three consistent removals a rule is written down as a SUGGESTION, matching nothing and removing nothing. A suggestion cannot be approved from the list — the approve control does not exist until the rule is opened and its evidence read — and the learning pass has no path to an active rule at all. Editing one sends it back for approval; an approved rule is retired rather than deleted, and a rule’s own removals are never learned from, so no rule can widen itself.
  • GOVERNMENT, COURT, L&I, PHA AND SECTION 8, UTILITY SHUTOFF, INSURANCE, TAX, TENANT AND LEGAL POST IS NEVER AUTO-REMOVED, whatever a rule says: a match is checked against the agency kind, the classification and the wording of the letter, and anything that could be one of those is held for a person instead. A held removal is written onto the notice as a reason it stayed.
  • Every automatic removal names the rule that made it and why it matched, in the Removed list and in the activity log, and can be undone from there. A removal never touches the Gmail message.
  • Every letter that arrived by email carries an “Open in Gmail” link to the real message — for the times a copy is not enough and a reply, a thread or the real headers are wanted. Nothing is fetched from Gmail to draw it and the message is never touched: it is a link, in a new tab, for a person.
  • POST THAT NAMES NO ADDRESS IS MATCHED BY A NUMBER ALREADY ON FILE. A licence renewal that says only “Business License Number: 853752” is matched to the property that licence was filed against — the join is EXACT, never a prefix or a substring, runs only where nothing on the document itself matched, and is refused outright when two properties carry the same number (one of those records is wrong, and picking either would bury it). The number has to be introduced as a licence, permit or certificate: a bare long number is as likely to be an invoice or a meter. Every notice now says in words what was compared to put it on its property.
  • A RED ALERT CAN RING YOUR PHONE. Calling is a third channel beside email and text, with its own number typed in on Site Admin → Alert recipients — never inherited from the text recipients, because permission to text somebody is not permission to ring them — and it is OFF until somebody turns it on. What is said is short, carries no link (nobody types a URL they heard), spells out initials so a speech engine does not read PGW as a word, states plainly that nothing has been answered or booked on anybody’s behalf, and repeats itself once. The exact words are on the preview before the first call is ever placed.
  • Calls are placed ONLY from the live site — not redirected to a sink, not in dev mode — and never to a number that has said STOP. A deployment without the voice credentials reports the channel as not set up, naming what is missing, rather than logging a call nobody received; that includes the webhook key, because without it the call would connect and say nothing. A channel that already got through is never rung again about the same letter.
  • POST BEING READ IN IS NOT POST ARRIVING. Connecting a mailbox hands over a year of letters at once, and none of it is news: an alert on a letter that reached this system more than thirty days after it was sent is RAISED and not delivered — recorded as withheld with the date and the reason, exactly like one held back by the sending switch — and the letter is left off the Today list unless its own date is still ahead. A letter with no arrival time of its own is treated as having just arrived, because a real shut-off warning silenced by a missing timestamp is the worse failure.
  • Today → “What the post is asking you to do”: the required action read out of every OPEN letter, word for word rather than paraphrased, with the property, the countdown and the letter one click away. Red-alert letters come first whatever their dates say, an undated demand says “no date” rather than showing a reassuring zero, and a truncated list says how many it left out. It is derived from the queue and has no tick box of its own — a row leaves when its letter is filed or resolved, so the list and the queue can never disagree about whether something was dealt with.
  • Incoming → Red alerts: a very short list of letters that cannot wait for somebody to open the queue. The first — and, deliberately, the only one — is PGW’s Landlord Cooperation Program telling an owner to book an appointment to shut the service off, because the cost of reading that late is a service switched off at a tenanted property.
  • IT IS SCOPED TO THE PROGRAMME, NOT TO THE COMPANY. The programme’s identity, the shut-off intent and the appointment must ALL be present, and enough of the rest — the act-by window, the LCP portal instructions, the verified sender including the original sender inside a forward — must be there on top. So the paragraph can be rewritten wholesale and still trip it, while ordinary pgworks.com post — bills, receipts, newsletters, adverts, even a service-appointment letter — never does, and the sender plus a date alone cannot.
  • The act-by date is counted from the day the letter arrived, and business days are counted as calendar days on purpose, which lands earlier than the true date rather than later. The property, the deadline, the access requirement, the account or reference number, the required action and the scheduling link are pulled out and carried in the alert itself — the link is printed, never followed, fetched or submitted to.
  • The letter is flagged red on the queue and on the letter itself, sorts to the top whatever its dates say, and shows the exact phrases it matched on so the flag can be argued with. A red alert also cancels an automatic removal: no pattern about a sender is a good enough reason for a shut-off instruction to leave the queue unread.
  • You are told by email, with the subject PGW ACTION NEEDED ASAP, and by text. Neither gate is bypassed: email goes through the outbound guard and the scheduled-sending switch, texts through the consent trail — INCLUDING for your own number, which must have agreed to texts like anyone else’s. Every attempt is logged as delivered, withheld, refused or failed, by name and with the reason, and a delivery that did not get through can be retried on that channel alone without sending a second copy to anybody who already had one.
  • Site Admin → Alert recipients is where who is told is decided, and it is the only place: the alert email address, the mobile number, email and text on or off, and each alert type on or off. Nothing about a recipient lives in the classifier. Every change is recorded field by field with who made it and when, on the settings themselves and in the activity log, because redirecting an alert is a quiet act with a loud consequence.
  • Preview shows the exact recipients and the exact words, built by the same code that sends them, and sends nothing. The test button is only reachable through that preview and needs a second, deliberate press — confirmation is checked on the server, not only in the dialog — because a test puts a real message on a real person’s phone.
  • A watch cannot change a letter. There is no category, status, property, removal or reply in it and no field that could carry one, and the watches themselves are code rather than rows — they can be switched off per channel from the screen, and cannot be widened from a browser.
  • PGW is recognised as two senders rather than one: lcp@pgworks.com is the Landlord Cooperation Program (access, transfers, shut-off appointments), the rest of the domain is PGW itself, and neither leans towards “bill” — a gas bill and a letter about turning the gas off come from the same company.
  • Compliance → Violations: the confirmed ones, filed from a reviewed notice by a person — nothing on intake, no rule and no classifier creates a violation. Each holds the property and unit, agency, violation type and description, case or violation number, notice and inspection dates, compliance deadline and hearing date, penalty, required corrective action, who it is assigned to, the original letters, proof of correction, notes and full activity history.
  • A FOLLOW-UP LETTER JOINS THE VIOLATION IT BELONGS TO rather than becoming a second one: agencies escalate, and a notice, a reminder, a citation and a hearing letter are four letters about one case. Matching is on the case number and the agency alone — a letter with no case number is never merged automatically, it is offered against what is already open at that property and a person decides, because collapsing two genuinely different violations means the second never gets fixed.
  • Status runs new, reviewing, work scheduled, corrected, proof submitted, awaiting re-inspection, resolved or disputed — and only “resolved” leaves the open count. “Corrected” means the work is done and the agency has not agreed yet, which is stated on screen where the status is chosen, because a case counted as closed while the fine accrues is the most expensive thing this list could say.
  • Overdue is recomputed against today on every read, never taken from the row, so a compliance date that has passed rises to the top instead of sitting where it landed the month the letter arrived — and the counts describe the whole portfolio rather than whatever filter is applied.
  • Every change is appended to the violation’s history in words, with who made it and when, and lands in the activity log. Nothing deletes a violation: one filed in error is disputed or resolved with a note saying why, because the note is the part that matters at a hearing.
  • Compliance → Landlord Cooperation: access, inspection and appointment requests, filed from a reviewed letter. Each holds the property, unit and tenant, the agency or programme, the notice date and the reply deadline, what they want access for, the scheduling link with its destination checked, the appointment date and time, the contact’s name, phone and email, the access instructions, who it is assigned to, the original letters and the full activity history.
  • A CLEAR “Schedule appointment” ACTION OPENS THE AGENCY’S OWN LINK, in a new tab, for a person. Nothing follows, fetches, prefetches or health-checks that address, and nothing chooses a slot or submits a form — a letter from a stranger must never become a request this system made.
  • The destination is stated before it is offered: whether the host belongs to the agency the letter names, to a DIFFERENT recognised agency (called out in red — that is the shape a convincing lure takes), to an unrecognised host (named without accusation, since agencies do use booking vendors), or to an address inside this network, which is never offered at all. Hosts are matched on a domain label boundary, so a lookalike cannot borrow an agency’s name.
  • Status runs new, needs scheduling, scheduled, access confirmed, completed, missed, reschedule required or disputed — and only “completed” leaves the open count. A date in the diary is not a door that opens, so a booked visit with no access arrangement recorded is flagged on the row and counted; a missed appointment is the most urgent item on the screen rather than a past event.
  • Nothing books anything. An appointment exists because a person typed one after arranging it, and the record says who — “the inspector was told Thursday” is a claim somebody owns when nobody is there on Thursday. Two letters about the same unit are never merged automatically, because an inspection and its re-inspection are two real visits.
  • Notifications on both compliance surfaces: a new urgent violation nobody has picked up, an access request with no date booked, a deadline, hearing, inspection or appointment inside the week, an appointment with no access arrangement recorded, a missed visit, and corrective action past its day. Staff hear about all of it; the tenant hears only about the visit to their own home.
  • EVERY MESSAGE IS READABLE BEFORE IT IS SENT, and what is shown is what goes — the preview is the sender’s own text, not a paraphrase of it. Nothing sends because a screen loaded, a panel opened or a status changed; a message goes when somebody presses Send, or when the daily job runs.
  • The daily job runs inside the global Scheduled Communications switch. While that switch is OFF every message is WITHHELD rather than skipped: the record keeps a withheld row saying why, nothing is marked as delivered, and the first run after it is switched on sends it. A switch that defers is a switch you can safely leave off. Pressing Send by hand is a person acting, not the clock, and is unaffected.
  • Texts go through the one consent gate the rest of the application uses, and a number that has not agreed is recorded as refused rather than retried. A tenant is reached on the tenant’s own email and phone, which are separate fields from the agency’s contact details — mixing those two would send a tenant’s access instructions to an inspector.
  • Delivered, withheld, refused and failed are four different words on the record, and only “delivered” stops a message being due again. “We told them” has to be a record rather than a memory, and “we did not” has to be just as visible.
  • Incoming → Rules vs. old post: a dry run of every approved tagging rule over the letters already on file. It shows which old letters a rule would touch, exactly what would change on each, which rule did it and why it matched — and, separately, HOW MANY of those a person has already read or filed, because that is the number that decides whether a backfill is safe.
  • IT WRITES NOTHING, AND THERE IS NO APPLY — not a disabled button, not a confirmation: absent. The endpoint behind it serves GET and nothing else. A rule approved today reaching back to re-tag a letter somebody already acted on would leave a record that no longer says what that person saw. Backfilling is a decision for whoever owns the records, and this exists so it can be taken with the facts in front of it.
  • Where two approved rules both want the same field, the dry run names the one that lost. Live, the first rule wins quietly — which reads as working right up until the day that first rule is retired.
  • Compliance → City Watch: Philadelphia’s public L&I complaints, violations and inspection results, and 311 requests, read for every building with an OPA parcel number once a day and on Check now. Daily, not real-time. Building and unit pages carry a City activity card.
  • THE FIRST COMPLETE READ OF EACH BUILDING AND FEED IS HISTORY, never news, and never alerts. After it, a new record or a status change — including closed then open again — is news, and every transition is kept as history.
  • A read that did not finish is reported as partial or failed, per building and feed, and a record missing from an incomplete read is never treated as closed. Feed health says which feeds were not read completely.
  • Matching is careful: L&I on the validated parcel number only; 311 by address, always labelled a POSSIBLE match. Proximity never puts a record on a unit and never makes it a confirmed violation; a unit card shows only records the city itself tied to that unit.
  • Needs review: acknowledge, dismiss with a note, or file an L&I record as a violation — a person’s act every time. Filing checks the case number and offers the violation already open on that case; a 311 request can never be filed.
  • City Watch alerts start OFF and only a site administrator can turn them on — and only once the Alert recipients have been SAVED and at least one of them has received a test alert. Unsaved starting addresses and untested recipients are never used. Alerts reuse the Red Alert Communications switch and each number’s text consent, and every message is recorded per recipient and channel — delivered, withheld, refused or failed — so a failed text never re-sends an email.
  • TURNING ALERTS ON STARTS FRESH. Anything City Watch found before that moment keeps its record and history and is never sent. A withheld or refused message is never resent automatically and never recorded as delivered; only a provider failure is tried again.

đź“‹Inspections

  • Move-In, Move-Out, and Mid-Lease inspection types.
  • Room-by-room condition checklists (Good / Fair / Poor / N/A) tailored to each room.
  • Multiple tenants per unit; new-vs-existing tenant tracking.
  • Autosave; draft / submitted / completed status.

📸Photos, video & audio

  • Upload photos and video per room, from camera or library (large files supported).
  • EXIF capture-time & GPS read on upload; recent-photo verification window.
  • Voice notes transcribed to text automatically.
  • Full-screen gallery: room navigation, captions, freehand markup, room-aware tags, filter, slideshow.
  • Optional AI assist (suggestion-only): one consolidated “Analyze room” pass suggests a rating per checklist item (with a short description + repair note only for Fair/Poor/Damaged), plus an on-demand per-photo read. You confirm everything; it describes visible condition without diagnosing cause.
  • “Teach the AI”: correct any suggestion (type or voice) and it becomes an editable, account-private house rule applied to future runs — guidance, not model training. Manage rules in Admin → AI assist.

✍️Tenant review & e-signature

  • Send tenants a private link (no login) to review the report, add photos/notes, and agree/disagree per room.
  • First-time tenants get a short branded welcome (what this is / what to do / what's coming) with an optional, compliant SMS opt-in (affirmative consent, versioned + timestamped log); after one Continue it goes straight to the review.
  • Disagreements are specific & reasoned (anchored to the room, an item, or a photo; category + typed/voice reason); rooms can be skipped with a reason; tenants can tag “this is my room.”
  • Signing windows: sending freezes the landlord's findings and starts a configurable clock (default 5 days); revise anytime with Unsend & resend.
  • Identity-verified, email-confirmed e-signature — a private link per tenant, each with their own attributed notes/photos and independent signature; daily reminders to unsigned tenants.
  • Tenants can sign, add input, or — after viewing — “Skip / defer” (a logged waiver, not a signature); skip stops reminders, is reversible, and stays distinct from no-response.
  • “Out for signing” dashboard: see every report awaiting signatures across your portfolio — who's signed, who's pending, who opened it, days left — and resend any tenant their link in one click.
  • Compiled report at window close (or once all respond): frozen findings + every tenant's responses + all signatures + each tenant's outcome (signed / viewed-and-deferred / offered-no-response). Missing signatures never block it.
  • Tamper-evident, hash-chained audit log of every signing event.
  • PDF report generated and emailed automatically on confirmation.

👥People — owners, companies & groups

  • Owners, companies, and property groups are first-class records: open any one to set contact info and a structured mailing address (line 1/2, city, state, ZIP) and see the buildings and groups it's tied to.
  • A company is owned by one or more people; a property's owner is a person or a company; groups are flexible buckets of buildings (a region or a portfolio).
  • Buildings show their owner(s) — “Owned by,” linked to the directory — and support co-owners (add several; remove any one without affecting the others).
  • Delete any owner, company, or group to Trash with an instant Undo, recoverable for 30 days. Deleting an owner that still owns buildings keeps the links and restores them on undo.

🏢Properties, tenants & LLC groups

  • Per-property page with current tenants, past tenants, and full inspection history.
  • Per-property room inventory: standard common rooms (incl. Laundry) + a Floor Ă— Position bedroom grid + flexible bathrooms (full/half). Inspections inherit it; comparison matches rooms by identity.
  • Appliance records per unit: gas/electric, serial number, warranty info, and a receipt photo.
  • Per-unit lease terms: lease start, end/renewal date, monthly rent, and security deposit.
  • Tag properties by owning LLC / portfolio group; filter the dashboard and units list by group.
  • Bulk import units & tenants from an AppFolio CSV (detects an owner/portfolio column).
  • Persistent per-unit tenant links for year-round checks.
  • Compliance dashboard, grouped by building: one shared rental license + year built per building, with lead paperwork (Lead-SAFE cert + Certificate of Analysis) and CRS per unit. Current / Expiring / Overdue status, a next-deadline column, summary tiles, sortable columns, photo/PDF upload, AI expiry-date OCR, and email alerts as expiry nears.
  • Property compliance tracker: the docs on file for each unit — Certificate of Rental Suitability (60-day validity), Lead-SAFE certification, Certificate of Analysis, and signed lease (auto-detected from a filed lease on the unit or building). Lead items auto-apply only to pre-1978 units. Color-coded, with a per-tenancy rollup. (Tenant-delivery items like the handbook, lead disclosure, and EPA pamphlet are handled by the welcome packet.)
  • Unit type (housing / commercial / storage / garage): lead paperwork and the CRS only apply to housing units. Non-housing units show those as N/A and are never counted against compliance.
  • (Philadelphia) One-click CRS: pull a unit's Certificate of Rental Suitability straight from Philadelphia's eCLIPSE portal using the building's rental-license number — returned as a writable PDF, saved with its certificate number and validity clock. If the city won't issue it, the reason is recorded as a compliance signal. Auto-refreshes near each lease renewal.
  • (Philadelphia) If a CRS is blocked by an owner tax-compliance flag, draft a ready-to-send owner notice (Philadelphia Tax Center steps + Revenue tax-clearance contacts) — company details from your branding, owner details saved for reuse.
  • Rental-license renewals run themselves: 60 days before a building's rental license expires, a renewal task opens automatically and stays open until a replacement license (with its new expiry) is filed. It walks the real steps — prep, then a required City tax-clearance check at 45 days (you run the check and record the result; nothing contacts the city for you), then an eligible “Begin renewal”. Filing a replacement license closes the old task and starts a fresh one, preserving history; renewals needing action surface on Today and the Compliance board under License renewals.
  • Every building page opens with a compact compliance banner beneath the header — Compliance current / N expiring / N action needed, or a gray Compliance unavailable when the source can't be loaded — reading from the same source as the Compliance board. When action is needed it lists each credential with its status, exact reason, expiry date + days remaining, and the exact building or unit, most-urgent first; the rental license offers View/Download or an honest upload, and unit issues link to their unit.
  • One reconciled compliance truth behind every surface: the overview, the building banner, the unit page, the documents section, and the issues report all read a single source-backed result that separates whether a credential is required, what was done to it, whether a document is on file, and whether that file still opens — so the same unit can never read “Missing” on one screen and “Complete” on another. A credential marked delivered with no file reads “Marked complete · No document uploaded” (amber, distinct from both Missing and Complete); a record whose stored file no longer opens reads “File unavailable · Needs reconciliation” (red) with a re-attach; genuinely disagreeing records read “Needs reconciliation”; legitimately-inapplicable ones read N/A. Nothing is inferred from a license number, and no record is auto-modified to resolve a disagreement.
  • A credential file attached to a move-in checklist item but never filed as a document is no longer invisible: it reads “File attached — needs filing” on the checklist (amber, never a green “Complete”) and appears as a read-only “Checklist file — needs filing” entry with View / Download on both the unit’s own document list and the portfolio Compliance › Documents report. Only files that actually open are shown; filing one properly replaces the entry with the real document, an archived superseded document does not hide one, and nothing is stored — the entries are derived on each read. A missing signed lease stays optional and missing.
  • Files stored before the app moved to owner-carrying storage locations open again across intake, the document library, applications, expenses, and unit and building documents — recognised as historical references and authorized against the record that names them. A file belonging to another account or organization, an altered location, a deleted record, or a location no record refers to is still refused. Nothing was moved, copied, renamed, or deleted.
  • Documents open on first load — a credential with a file on record shows View / Download immediately, no reload; attaching a file to an existing credential shows its View / Download the instant it saves (fresh authorized link, no re-upload); a broken file relationship shows an honest recovery action, never a dead View.
  • Explicit document actions on every credential row — “View document · Download · Replace file” (or “Upload file” when there’s no document, “File unavailable” when the stored file can’t be opened), placed with the status and dates, wrapping cleanly on a phone, each with a clear accessible name — replacing the old ambiguous edge-of-card “File →” link. The same wording carries through the move-in editor rows, the CRS history, and previous document versions.
  • Every credential lists its real recorded dates in one compact line — testing/sample date (lead paperwork), issue date, expiration date, and exact days remaining (e.g. “Tested Jul 15, 2026 · Issued Jul 29, 2026 · Expires Jul 29, 2030 · 1428 days remaining”), using the same date + days-remaining calculation as the overview and alerts. A missing date is named honestly (“Issue date not recorded”); the upload timestamp is never shown in place of an issue, testing, or expiration date.
  • A document workbench for correcting what a credential says and fixing which file it points at, with the PDF open beside the fields. It runs as a review session: the queue holds exactly the work the screen can finish (a real file with no record, a record whose stored file is proven gone, a record that never had one), filtered and searched by type, property, status, what it needs and whether the reader has read it, with those filters held in the URL so Previous/Next stay inside the set you chose. Remaining, Reviewed, Deferred and Needs-attention counts are themselves filters; documents can be deferred (kept on that computer only, never inferred, and said so on screen); Resume review returns to the last document opened; filing advances to the next one with a one-line confirmation and no undo; and n/p/d move without touching a single browser or PDF shortcut. Reprocess with AI re-reads the PDF and lays its findings next to what is on record — document type, certificate number, issue date, effective date, expiration date, plus the address, unit, result and vendor it read — each with a confidence and its own Accept. Nothing is saved by reading: suggestions have to be accepted, previewed and saved by you, a value that disagrees with the record or that the reader is unsure of is never swept up by “Accept all high-confidence”, and a field the document does not carry reads “Not found” instead of a guess. The upload date is listed as an upload date and is never offered as an issue or effective date. Typing over an accepted value makes it yours again. Each suggestion also shows the line it was read off, quoted, and a date the filing rule derived says which role it came from (“from the sampling date”). A field the reader never answered for reads “Not read” rather than “Not found”, and an incomplete reading is stated at the top of the panel. Where AI assist is switched off, the reader times out, or its reply cannot be made sense of, the panel says which of those happened and every manual edit keeps working.
  • Upload a missing PDF or replace a wrong one from the same screen, as an operation separate from correcting the metadata — so “I only changed the dates” and “I only changed the file” stay separately recorded. A record whose file is genuinely gone (proven by checking storage, never guessed from a viewer that failed to draw) offers a compact upload panel instead of an empty viewer. A replacement is a new file at a new location: the old one is never deleted or overwritten, its reference is kept in the document’s history and in the audit log, and a document that already has a working file cannot be silently overwritten by an upload meant for an empty one.
  • No unexplained percentage on Compliance › Documents: the “% current” ring states what is measured, its numerator, its denominator, and why the figure moves when the document population changes — adding properties or making previously invisible files countable enlarges the denominator and lowers the percentage without anything having expired. The ring’s centre carries the fraction, not a bare score.
  • A “Where the work is” panel breaks the expired documents and the missing-required gaps down by document type, each with a count and a share OF THAT CATEGORY, and each line a filter that lands the list on exactly the rows it counted (shown back as a clearable chip). Seven states are named and counted separately — no canonical record, a checklist file that physically exists but was never filed, a record with no file ever attached, a record whose stored object was proven absent, expired, expiring soon, and current — so “missing from canonical documents” is never conflated with “the PDF is missing”. File evidence is its own row of figures over the filed records only, each clickable. A third panel — shown only when there is something on it — names records that contradict themselves: two or more records of the same type in force on the same building or unit (which the app otherwise ignores, taking the first active record of a type and passing over the rest), and dates that cannot be true (an expiry before the effective date, or a year outside a plausible range). Each line opens the records unnarrowed so a clashing pair can be compared; nothing is repaired, ranked or decided. An absent date is not counted as an invalid one, and the panel states that it is not a report about missing files — separating a genuinely absent object from one this account simply cannot read needs the read-only provenance audit.
  • Search the Compliance board by address, unit, tenant, or LLC.
  • Email a selected set of a unit's documents as one package to a tenant or inspector.
  • Document version history: uploading a new rental license, lead cert, or CRS keeps the prior copy as a viewable “previous version” instead of overwriting it.
  • Bulk document intake: drop a pile of PDFs/photos and the AI sorts each one — type, property/unit, dates, identifiers — into a review queue you approve. A lease is read from its first pages for the rent, deposit, and term (a past end rolls forward to its renewal), with an on-demand full read for pets and additional occupants; on approve those write onto the unit, and a single-unit house files straight to its one unit. The type list is self-extending: a newly-detected kind (e.g. a Lease) is offered with one-click “Add as a document type.”
  • Per-building property profile: parking, water/trash/recycling/snow schedule, utility accounts, insurance, service contracts, and mortgage info — each section togglable. (Philadelphia) Real-estate taxes and trash/recycling days pull straight from the city's public property data by OPA/parcel number, kept as a year-by-year history.
  • City Watch records open in full (Details): everything the city recorded, plus links to the city’s own pages — a violation’s L&I case page and notice PDF, the property’s L&I history, and for 311 the city map’s list of requests near the address. The Compliance overview shows City Watch’s open violations, open complaints, new to review and recent 311 requests, each opening its list. Records on the same L&I case (complaint → inspection → violation) are linked by the city’s case number, and Details reads the city’s whole case file live: every violation code and what it is, resolutions, appeals, inspections, the complaint behind it, and for 311 the agency, notes and target date. A pie on the Compliance overview shows each building’s L&I standing — open violation, open complaint only, nothing open, or not checked — and every L&I record links to the city map’s L&I history (every inspection and its result) and to the city’s open-data record of it. A failed inspection that later passed on the same case, or whose violations have all complied, is marked “Not an issue”.
  • (Philadelphia) Fill missing OPA numbers: Compliance → Portfolio tools looks every building up in the city's property records and saves a parcel number only where exactly one parcel is recorded at exactly that address. Units, condos, several parcels and no match are listed for review; existing numbers are never changed.

🌀Maintenance checks

  • Tenant-submitted filter changes (old + new filter photos) and smoke/CO detector checks.
  • Camera-enforced, EXIF/GPS-verified submissions.
  • Record each unit's heating/cooling and filter size; units with no filter skip filter reminders.
  • Optional automatic email reminders to tenants when a filter/smoke check is overdue.

đź”§Repairs & to-do

  • Flag any inspection photo as needing landlord action, with a note.
  • Repairs page rolls up everything flagged, grouped by unit — mark done or reopen.
  • Send a vendor a clean private work-order page (no login) to Accept / Complete / decline each repair — responses show on your Repairs list.
  • Import your whole vendor directory from an AppFolio export (CSV or Excel) in one shot — contact, GL account, payment type, 1099, tags, and insurance/license expirations (which show as color-coded renewal chips). Re-importing updates vendors in place instead of duplicating.
  • Items flagged for repair are shown to the tenant during review and summarized in the report (per room + a full list).
  • Repair supplement: mark a flagged repair complete with after-photos + a note, then generate a before/after supplement report (download or email to the tenant) proving promised repairs were done. Internal items excluded.
  • Internal notes (landlord only): private photos/notes on an inspection that never reach the tenant or report — for things like structural/exterior work.
  • Every issue is classed Immediate or Long-term; the Repairs & To-Do tracker filters by it, and each property page shows that unit's open issues.
  • Record keys, fobs, mailbox keys, and access codes per inspection — with a photo of each key/fob set, included in the report.

đź’µAccounting & expenses

  • Snap or upload a receipt (photo or multi-page PDF) and AI reads the vendor, total, date, and invoice/confirmation #; speak a note or scribble the property and it tags it.
  • In-app document scanner on the contractor’s phone: it finds the edges of the receipt live, corrects the perspective on capture, and warns about blur, darkness, glare and bad framing while the paper is still in hand — warnings only, never a refusal. The original photograph is stored beside the corrected one. The camera roll and PDF upload remain available beside it, for a blocked camera or a supplier’s emailed invoice.
  • Optional third-party receipt reading, off per account until switched on: the vendor, date, total, tax and line items come back as a suggestion beside the paper, with a confidence and named flags where the reading was unsure — a total that does not add up is kept and flagged, never corrected. Reading happens in the background and cannot be lost or done twice: one receipt is one job, one answer is applied once, and a quarter-hourly sweep finishes anything whose completion notice never arrived. Pages go as short-lived links, the service is asked to keep nothing, and switching it on never re-reads anything already filed.
  • Receipts are coded to your real chart of accounts — AI picks the best-fit account (e.g. 6142 Plumbing), and capital work can post to Buildings / Improvements, not just operating expense.
  • Vendor memory: code a vendor once (Lowes → Materials) and the next receipt from them pre-codes automatically.
  • Smart property matching: a street number or property code on the receipt/note auto-tags the unit; if nothing matches it asks which property instead of guessing.
  • Review queue (Pending / Approved / Rejected): preview receipt pages, tag property & unit, edit every field, set a PO, then approve.
  • Add expenses by hand (no receipt) for mileage, cash, or online bills.
  • CSV export with a date range: pick from/to dates, see the count and total before downloading a plain bookkeeper CSV (the AppFolio bulk-upload file is the separate AppFolio export below), and every exported row is stamped “✓ exported” so the next export skips it (tick a box to re-include).
  • Reports: spend by property, by account, and by account group over month / year / all-time, split into Operating vs Capital; plus a searchable chart of accounts.
  • Bills (AP documents): invoices, statements, and receipts that arrive by email (Gmail), forwarding, or upload land in a Bills register under Accounting — read by AI and matched to a property and vendor. Open any bill to edit every field, set the property/unit and GL account, approve or reject, split a multi-property statement into one bill per address (with undo), link it to a utility account, or move it to Trash (restorable). A review queue groups look-alike senders for one-click bulk approval and one-tap reprocessing against your current rules — and the server holds back anything flagged for review, so a bulk click cannot file a notice as a paid bill. A utility statement is reconciled against its printed breakdown before anything is expensed: the carried balance is identified and only this period's charge is booked, and where the breakdown could not be read the bill stops for a person instead of being booked at its full total. It is one implementation shared by the full app and the focused Billing edition — AppFolio stays the system of record.
  • AppFolio: export approved bills in AppFolio's vendor-bill upload format (each property carries a code, defaulting to the street number; PO column configurable by property or unit). Upload your AppFolio roster and the app flags any property not yet in AppFolio.
  • Built natively — receipts live in your existing storage, amounts are kept to the penny, and AI spend shows in the cost dashboard, itemized by feature and by document type.

📝Rental applications

  • An application that is open twice says which copy is out of date. Two tabs, or a phone and a laptop, and whichever one saves second is working from an older copy of the answers — so the newer ones are not overwritten, and the person is told to reload rather than left looking at a form that has quietly stopped saving. The refusals somebody can fix by carrying on typing stay silent, because interrupting a half-written answer is its own kind of broken.
  • The page an application opens on is the unit, the next section, and a six-row checklist. The address and unit on one line, with “no application fee” where the fee is nothing; one card whose button names the next unfinished section; and six rows under a single counter — you and your household, rental history, income, your ID, animals, review — each saying not started, in progress or done, each one a link into that section — including a finished one, so a typo found on the review page is fixed where it was typed. A section that asks nothing of a particular person still appears, named as waiting on us rather than subtracted from their total, and carries that section’s own sentence saying why. The first row reads back who they said they are applying with. The bar across the top of a section is those same six rows, in the same order and under the same names, with the one being filled in marked and the rest linking to whichever page in them is still unfinished; “Next” at the foot of a section opens the next row that still needs something, and Review is the last of them rather than a step outside the list.
  • Starting an application asks for a mobile number, and texting is the only optional thing in the flow. The number is optional and the step cannot refuse anybody; the SMS consent box beside it is separate and unchecked, and the words on it are recorded with the agreement, so what somebody is shown is what they are recorded as having agreed to. Nothing is saved until the final step, no account is created, and no message is sent — a recorded consent is a permission, and sending also needs a switch somebody deliberately turned on. The published SMS terms name the application as an opt-in surface and quote that same disclosure.
  • Animals are two questions, asked separately, and pets are asked about one animal at a time. Whether any pets will live in the home, then how many, then a card each: name, type, breed, age and expected adult weight, with one tick to say that animal has no history of bites. Age and weight are bands rather than boxes, because nobody holds a rescue’s birth certificate and a household with a terrier and a Great Dane could not answer one weight question about both. Nothing asks for a bite story: there is no follow-up box, and an unticked box records nothing rather than recording the opposite. Then one yes or no about an assistance animal, with the whole of what that means printed beside it: not a pet, no pet fee, no size or breed limit, and no medical detail or paperwork asked for anywhere — and no card, no breed and no weight either, which is what keeps the pet questions away from it. Somebody with no animals finishes the section with two answers and nothing typed.
  • A public application door per unit. A prospective tenant opens one link, picks the unit, and works through the application a part at a time — each part saves on its own, so a half-finished application is never lost and nothing is submitted until the applicant says so.
  • Starting one is four short steps, and nothing exists until the last. The home, who you are, anyone else applying with you, then the screening criteria — one question a step, each saying what happens next. No application row, no draft and no saved answer is created until the last step is submitted, which is structural rather than a promise: the answers are held in the page, because a cookie may not carry a name and a URL may not carry an e-mail address. Somebody who has started one and comes back without their link asks for it on the recovery page, which answers with the same sentence whether or not an application matches the address they type — and typing the address of somebody who already has an application for that home does not start a second one: the link goes to the address, never to the browser that asked.
  • One photograph per listing, shown on the public list and on the unit’s own page. A unit’s Applications tab takes a single picture of the home — JPEG, PNG or WebP, under 10 MB — and uploading another replaces it; one is a decision rather than a limit of the control, so there is no gallery to fill and no carousel to swipe instead of reading the criteria. What a browser will actually draw is checked against the stored file rather than against what the upload claimed, so an iPhone’s HEIC is refused with the camera setting that produced it named in the refusal instead of becoming a broken image on an advertisement. A listing with no photograph shows one generic drawing of a building, the same one for every unit without one. The picture is served through a link that expires, never a permanent public URL, and taking a unit off the list takes its photograph with it.
  • The listing says what it costs and how big it is, from what you entered. A unit’s Applications tab takes a monthly asking rent, a bedroom count and a bathroom count (halves included) and the public page shows them. Nothing is inferred from a previous lease or from a room inventory, because neither of those is an asking price; a figure you have not entered is simply not shown.
  • One set of screening criteria names each property’s own landlord. Write {propertyOwnerName} where the landlord’s name belongs and every applicant reads the owner recorded against the home they are applying for — one published text for the account, not a copy per building that has to be kept in step. A property whose ownership records are missing or disagree is NOT given a guess and is not given another property’s landlord either: its criteria are withheld and the property is named, with which of the records is missing, so the gap is a thing somebody fixes rather than a sentence somebody signs. It is the one substitution the criteria allow; everything else is still the owner’s own words, verbatim.
  • The approved signing form can be checked against the criteria an applicant will actually read, before anybody attests to it. Paste the form’s id, confirm the owner, and the product opens the document at the e-signature provider and looks for the full criteria text inside it — word for word, with the landlord’s name already substituted, because a version number cannot tell you whose name is in the document. A form that does not contain them, is a scan with no readable text, or has been archived is reported with the id the provider echoed back, what it calls the form, when it last changed there and which fields it has: the four things somebody needs in the other tab. Requiring a signature cannot be switched on until the check has passed, and the check says plainly what it does NOT cover — whether the signature fields are placed correctly, and whether counsel approved the document.
  • If the criteria move on after somebody has signed off on the form, the applicant reads the wording that governs now before a signing session opens — the same criteria step they have already seen, with everything they entered saved. It happens only when the form was checked and the words no longer match, so it cannot stop an application that was already underway, and nothing already signed is re-read, re-stamped or invalidated.
  • The criteria have a plain-language short version, and it cannot drift. Every line of it is tied to a verbatim sentence of the published criteria; publish a version that words a rule differently and the whole short version is withheld rather than keeping a line that no longer matches. The full text is on the same page and is what governs.
  • The acknowledgment is a tick, not a scroll. Name, e-mail, a prominent link to the full criteria and a required tick-box sit directly under the property details — reachable on a phone without scrolling past the whole document. The tick is enforced on the server, and what is recorded is the criteria version, the moment, the exact sentence agreed to and a fingerprint of the text that was served.
  • The link to come back is e-mailed when the application is started, so it can be resumed on another day or another device. The name and e-mail given at the start are carried into the form rather than asked for twice, with a note saying where each came from.
  • Rental history counts the window rather than the boxes. The form says how much of the last three years the addresses entered account for, updates as somebody types, and names the months either side of a gap. The first address is labelled as the current one.
  • The income and the ID are a row each on the checklist, over a page each. They shared a row called “Income and documents” while the documents page collected the proof of income as well as the photograph, and one row cannot report on two pages: it said “in progress” to somebody whose ID was the only thing missing and “in progress” again to somebody who had sent nothing but the ID, and a returned photograph marked a row whose title was mostly about money. Six rows, one counter, one page apiece.
  • The proof of each income source sits under that source, and the ID has a page of its own. There is one proof card per source, named after it — “Proof for Ivy Bakehouse ($2,400.00 a month)” — so adding a job adds the card for its proof, and nobody has to work out which file belongs to which figure. What counts as proof is said once above the cards rather than printed under every job, and it deliberately does not lead with a payslip: a benefit or award letter, a pension statement, voucher paperwork, a tax return, bank statements, self-employment records or a note from whoever pays in cash are ordinary answers rather than exceptions. The ID is then one short page with one line and one card, and nothing on it asks about income.
  • The Equal Housing Opportunity logotype and slogan are in the footer of every applicant screen, and the full statement is on the pages that advertise a home. The mark is drawn by the one layout the whole applicant surface sits in, so a screen added later carries it without anybody remembering to; the statement appears on a listing, below the four steps, and at the foot of the published screening criteria. The wording is quoted from the federal regulation on advertising dwellings and not written here — including its own dated term — with the citation printed beside it, and it names only the bases that regulation names. It says nothing about state or local protections, which is a limit rather than an omission: a protected-class list written into software is a legal notice written by software, and the operator’s own wording belongs in the criteria they publish under their name. Nothing here has been reviewed by counsel and no part of it is a compliance guarantee — the platform terms say so too, and the fair-housing poster an office has to display is not something a web page can be.
  • The last page before sending reads the answers back and asks nothing new. What is left is a list of links into the sections that still have work in them — including the ID, which used to be the one line on it that could not be clicked — and the send button is there from the start, disabled, with the reason beside it, instead of appearing out of nowhere when the last section is finished. The identifier reads back as “Ending 8634” rather than as a sentence about what is kept; an empty section says “Not entered yet” in the same three words wherever it happens; the ID says “Sent” or “Not sent yet”, with “Accepted” still its own word because a file a reviewer has taken is not a file nobody has opened. Nothing on it asks for a signature and nothing on it collects a permission, and the fee line still says there is nowhere to pay.
  • And it stopped printing the things it could do nothing about. A card headed “Waiting on us, not on you” listed a permission nobody had been asked for and a fee nobody could pay; a row said no permissions had been given; a sentence said no bank check was running; a panel asked about text messages. Every one of them was true, and all four were about our software rather than about the application somebody was looking at. The rules behind them are untouched — what is ours rather than theirs is still decided in one place, which is what keeps it off the list of things to do — and the one fact among them anybody acts on, that there is nothing to pay, is on the fee line where a price belongs.
  • The back of an ID is not asked for. It was an optional second slot, which is still a row on a checklist that most people cannot complete and will try to — and the number of applications where the reverse of an ID decides anything is zero. The front is asked for, in one sentence that says it is the side with the photo and the name.
  • A document a reviewer sends back is marked on the part it was uploaded from, in the reviewer’s own words, whether or not that part is finished. The one optional slot — “anything else you would like us to see” — can come back without the part becoming unfinished and without ever blocking a household: an optional file is not required evidence, and treating one as a gap would leave somebody unapprovable over a document the product itself called optional.
  • The income part stops asking once somebody says there is none — the invitation, the fields and the add button go, no proof of income is required of them, and the review queue sees the declaration.
  • Each source of income is a card that asks what that kind of income has answers to. The first question is what it is — a job, self-employment, benefits, a pension, support payments, or something else — and the card follows: a job asks a job title, a band of hours and the employer’s name, phone and e-mail; self-employment asks the business and the hours and nobody to ring, because there is nobody else to ring; a benefit or a pension asks who pays it and how to reach them, and asks nothing about hours. No bank account number is asked for anywhere.
  • A tick says a job has been accepted but not started, instead of a start date in the future with nothing to explain it. Another says the hours and the pay are expected to hold — and only when it is left unticked does the form ask what is expected to change, so the question is put to the one person who has an answer to it. Neither box is ever pre-ticked: an empty box records that nobody answered, not the opposite.
  • The published income rule is quoted where income is entered, with the monthly rent beside it, including the sentence that applies the rule only to the share of rent a subsidised household pays itself. Nothing is multiplied, nothing is added up and nothing is judged: the page says outright that it is not a decision.
  • The screening criteria stand in front of the form. Before the questions open, whoever is applying is shown a six-line summary of what will be considered — no fee, who applies and who is listed instead, income against their own share of the rent, no minimum credit score, the occupancy guideline, and that an assistance animal is not a pet — with the full text one tap away on its own page, opened in a new tab so nothing already entered is lost. The box they tick records what can honestly be recorded: that the criteria were provided and that they had the opportunity to review them. The criteria are published by the landlord and versioned; the version each applicant confirmed is kept with their application.
  • A household, not a form. One application can carry a primary tenant, co-applicants, additional adult tenants and a guarantor. Every adult gets their own private link, their own answers and their own documents; one adult cannot see another's answers, cannot act for them, and cannot see the landlord's decision.
  • Two roles to choose from, not six. An applicant is asked whether they are applying as a tenant or a co-signer, because the rest of the list — co-applicant, additional adult tenant — was the letting team’s bookkeeping rather than anything an applicant knows about themselves; the mapping happens behind the question. Beside it is the sentence that says what a role is not: these are application roles, and the executed lease and guarantee documents establish the final obligations. An adult who will live in the unit without applying is no longer given a role at all.
  • The people who will live there and are not applying have their own section, not a role. “Who else will live here” takes a name, a relationship and an age for each of them — children and adult dependants both, since an adult family member and a child are in the same position — and nobody listed there is screened, charged, invited, asked to sign or given a link. An age is reported as unknown rather than guessed when nobody has given one, and nothing in the section decides anything: it does not count against an occupancy limit, change a fee or add a document to the application. A child recorded the old way, as a role beside the adults who are applying, can be moved into the section from their own row — which is what allowed that role to stop being offered. The move asks the one thing a role never recorded, how the person is related to the household, and takes the name off the row rather than asking for it twice; it is recorded as one person moving rather than as a child arriving and an applicant leaving.
  • Applicants say who they are applying with, instead of being shown a household somebody else filled in. “Who are you applying with?” takes a row per person — a name, whether they are a tenant or a co-signer, and an e-mail only if the applicant has one — or the answer that they are applying by themselves, which is recorded as an answer because an unasked question and an empty list are different things for a letting team to act on. Naming somebody sends them nothing, charges nothing and orders no report, and a typed address is stored without ever being looked up, so the question cannot reveal that the person it names has already applied. Each applicant sees the addresses on the rows they typed themselves and not on anybody else’s. The answer is read back on the page somebody reaches after sending their application in, under a heading that matches the question they were asked — the names and the proposed roles, and no addresses, because nothing there can be corrected any more. Saying they are applying by themselves is read back as the answer it is, and a question nobody answered is left unsaid rather than reported as a gap on a page where it cannot be filled in.
  • A co-signer is asked their own question rather than being shut out of the household one. “Who are you guaranteeing the rent for?” replaced a sentence telling them the household was not theirs to fill in — which was true, and no use to somebody who had an answer to give. Which question an applicant is asked is decided from their role on the server and cannot be chosen by what their browser sends, so an answer cannot be filed as the wrong one: a co-signer naming somebody records who they are guaranteeing, never a member of the household. The letting team sees one list with each row saying which question produced it, and “I am applying by myself” stays the household’s answer alone — a resident with a co-signer can still give it, and a co-signer cannot.
  • An applicant can invite one of the people they named, and the invitation grants that person nothing. The row gains an “Invite them” button where an e-mail address was given, and pressing it is the only thing on that screen that sends anybody anything — which the screen says, because the paragraph beside it promises that adding somebody does not. What goes out is a link to a page naming who asked them, which flat and who lets it, and nothing else: not the application’s status, not who else is on it, not the fee, because none of that is theirs to be told before they accept. Accepting is what creates their own application and their own private link, with the name and e-mail they give themselves rather than the ones somebody typed for them, and with the role taken from the row rather than from anything their browser sends. Until they accept, nothing exists for them: no fee, no report intended about them, no access to the application they were invited to. The invitation runs for a fortnight, only one is live at a time, it can be withdrawn — which stops the first link working — and it stops working by itself if the application reaches a reviewer in the meantime. The code is never shown to the applicant who sent it and never stored: the only copy is the one in the message, so a deployment that cannot send e-mail records no invitation at all rather than one nobody can act on, and the screen reports whether the message actually went rather than that the button worked. Each row says where its own invitation stands, and the letting team sees the same on their copy of the list.
  • Two applications for one home can turn out to be one household, and neither side learns anything until the person asked says so. When an applicant names somebody and types their e-mail address, nothing is looked up. If that person later starts their own application for the same home, the question goes to them — by e-mail only and never on a screen, because a link minted to whoever filled in a form proves nothing about who reads the inbox, and the reply to starting an application is identical whether a household named you or not. The message asks whether they are applying with the people who are actually applying on that household, for that home, and says nothing else: no status of either application, no fee, no role, no document, nobody’s answers, not even who lets the flat. Yes connects the two and merges nothing — each person keeps their own application, answers, uploads, link and submission state, and the only change is that the letting team can see the two are one household; no fee moves, no role moves and no report follows from it. No connects nothing, and the household that typed the address is never told it was asked. Addresses are compared as addresses: case and surrounding space are typing, and there is no dot-stripping, no +tag stripping and no comparing of names, because each of those is a guess about who somebody IS and a wrong one joins two strangers’ housing applications. The question runs seven days, is answerable once, shuts by itself when either side reaches a reviewer, and where two households on one home have each named the address the person asked chooses which. The code is never shown to anybody and never stored — the only copy is the one in the message.
  • Somebody who has lost their application link can have a new one e-mailed to themselves, and the page never says whether an application exists. Every request gets one sentence “if an application matches that email, we’ll send you a link to continue” — for an address that matched, for one that did not, for one that was never an address at all and for a deployment that cannot send e-mail, and the page says so before anybody types, because a reassuring reply to a mistyped address is how somebody waits for a message that is never coming and then starts a second application. Nothing else can be learned from it: no count, no name, no status, no different status code and no measurably faster answer, since every path is held to the same floor before it replies. The link that arrives works ONCE and runs out in an hour, and opening it needs a press rather than a page load, because a single-use link opened by a mail client’s own preview or a corporate scanner would be spent before the person it was sent to ever saw it. Opening it issues a fresh link to the SAME application — nothing is lost and nothing has to be done again — and stops the previous link working, which the page says before the button and not after it. The message names the legal owner so somebody applying for two homes can tell them apart, and names nothing else: not the reader, not the property, not the status, not the fee, because a message sits in a mailbox for years. Requests are limited per caller and per address so one form cannot be walked through an address list or used to flood one person’s inbox, the address is hashed before it is used as a rate-limit key, and an application nobody is collecting is skipped rather than mailed a link that could not work.
  • Each applicant is asked whether the role recorded for them is right, and the answer moves nobody’s role. Somebody else chose it — a member of staff when they added them, or another applicant by naming them — and until now the page stated it in a sentence with no way to disagree. “Are you applying as a tenant or a co-signer?” now sits directly under that sentence, with what the application currently records said plainly beside it so answering is a choice rather than a guess. What is stored is the ANSWER: a role decides whether a report is intended about somebody and whose the fee is, so an applicant able to set their own would be starting or cancelling both — and the screen says so rather than claiming a correction has been made or that anybody has been told. The letting team reads both sides on the row that carries the role change, with what it would cost beside it, and acting on it resolves the disagreement by itself because nothing stored a dispute anybody has to remember to clear. Moving somebody between two tenant roles is not read as a disagreement, since nobody is asked which of those they are.
  • “Your application is submitted” is not “your household is ready for review”, and the page says both. One sentence says where your own part is and names nobody else; a second says where the household is and counts the people who still have their own part to send in. The second is read from the same readiness gate that decides whether an application may move to review, so the page cannot call a household ready while that gate would refuse it — and when every part is in but something is still outstanding, that is said as its own answer rather than being rounded to one of the other two. What is outstanding is not named, because the list says whose consent and whose fee.
  • A private link, shown once. The link that reaches an applicant is theirs alone; it is displayed on the visit that follows starting the application and is never shown again, and it is never the same link for two people.
  • A link that has stopped working is not a dead end, and which kind of stopped it says what to do next. A link that ran out offers a new one, to the address it was sent to, and says the answers are still there. A link that was never valid says to check the message it came in — a link copied by hand loses its last characters — and promises nothing about work it cannot know exists. A link the office withdrew offers no new one at all and says so, because that was a decision somebody made rather than a clock running out, and a form on that screen would send somebody round a loop ending in the same refusal.
  • Pressing the button twice does not make two applications. Each start form carries one value identifying that submission, so a reply that never arrives — a timeout, a tunnel, a second tab — can be retried without creating a second application, and the screen now says that rather than claiming nothing was started, which it could not know. If the address already has an application for that home, nothing new is created and the private link is e-mailed to that address instead, so somebody who typed another person’s address gains nothing at all.
  • Answers saved from two tabs do not overwrite each other, and the screen offers the way out rather than only naming it. A save carrying a version the application has moved past is refused, said out loud rather than quietly like a half-typed answer — because nothing typed afterwards will ever make it save again — and the reload it asks for is a button, beside a sentence saying what reloading replaces.
  • Income and employment evidence is uploaded by the applicant and reviewed by a person. Nothing is scored automatically and no credit or background report is ordered — that is a separate decision the product deliberately does not make on its own.
  • A credit or background report is ordered, received, read and filed by hand, and the four are told apart on the screen. Nothing is sent to a provider and no report is pulled automatically: somebody opens the provider’s own tool, orders it there against a signed authorisation, and records each step here as they do it. Ordering says who ordered it and when; recording that it came back is not a record that anybody read it; reading it is its own act with its own date and the reader’s name; and filing the copy is a fourth, separate thing — said beside the buttons rather than in a policy document, because a report that came back three weeks ago and that nobody has opened reads, on a line that only says it came back, as finished evidence. The copy goes on that person’s own file, under “filed by the letting team” rather than among the documents they sent in: it is nothing the application asked them for, it cannot be accepted — accepting is a statement about a requirement — and it cannot be sent back, because they never sent it. It is not reachable through the applicant’s own link either, and the reply to asking for it is the same as for a document that is not theirs at all. A corrected report is filed beside the one it corrects, numbered in order of filing, and nothing is deleted to make room — the reading somebody recorded on the earlier version is what answers what was known when the decision was made. The reports panel says where the copy is and links to it, and says what is still outstanding while nobody has recorded reading one.
  • Whether an applicant has to sign is the landlord's setting, not a precondition of the product. “Require applicants to sign the application” sits with the signing form on the unit's Applications tab and applies to every property whose recorded legal owner is the one named there. It starts off: applications are completed, reviewed and sent in without a signature, and they arrive in the review queue marked as submitted without one. Nothing else is relaxed — the acknowledgment, the published criteria, the required answers and the uploaded evidence are all still required.
  • When it is on, the last step is a signature on a form the landlord has published. The form is a document a lawyer has approved, published once per legal owner and append-only afterwards — a correction is a new version, never an edit to the one somebody already signed. The setting cannot be turned on until there is such a form for that owner and a signing service to open it with, and the screen says which of those is missing.
  • The legal owner an applicant certifies to is read from one place per property, and from the place it was recorded: the owner linked on the building, then the ownership group the building belongs to, then the per-unit field, then the account default for a property with no owner recorded at all. Recording a company once against its group covers every property in it. Two owners linked to one building resolve to neither, because a certification names one owner — and none of this verifies ownership, it reports what was configured.
  • The application somebody signed can be opened again afterwards, by the applicant who signed it and by the member of staff deciding on it. The review page an applicant lands on after sending their application in carries a link to the document they put their name to, and the reviewer reads the same bytes from the person’s own file in the queue — because a screen that states an application was signed and offers nothing to open is the weakest kind of record on the screen where a tenancy is decided. The document is fetched from the e-signature provider and streamed through the product, so what reaches a browser is never the provider’s own self-authorising URL and no credential of ours is in it; the link is not a file sitting in a bucket and cannot be forwarded to somebody who is not on the application. It comes with the evidence that makes it worth keeping — when it was signed, which signing session produced it, and which revision of the form was signed — and if the answers moved after the signature was made, the reply says which answers, rather than letting a signed document stand in for a document that still describes the application. Four states are told apart rather than being reported as one missing file: a landlord who does not require a signature, an application nobody has signed yet, a provider this deployment has no credentials for, and a row that says signed while the provider has nothing — which is the one somebody has to act on. We keep a private copy of our own as well, with the digest of the bytes beside it, so an executed application survives the provider losing it or the account being closed — and a correction signed later lands beside the earlier version rather than over it. The copy is filed under the retention schedule that already exists and is already on hold, where no duration is set and nothing is deleted: how many years an executed instrument is kept, and the rule that destroys it, are the landlord’s to set rather than this software’s to assume, and that question is open.
  • Turning it off never strands anybody. Somebody already part-way through signing can send their application in, their unfinished form is left exactly as it was rather than being completed or back-dated, and a signature that arrives afterwards does not submit anything a second time or move the time the application arrived. No signature, signed document or completion time is ever generated for an application nobody signed.
  • Every decision carries a name and a date. Approving, declining, sending a document back and reopening a household are each recorded against the person who did it, and an applicant's own acts are recorded as theirs — the account holder's name is never attached to something an applicant did.
  • A record the account holder cannot rewrite. The counterparty to an application decision is the applicant, and the account holder is the party with write access to the row, so each application also carries a tamper-evident chain keyed to a server secret.
  • An applicant can withdraw their own application, and the control says withdraw rather than decline, because declining is what a landlord does and the two must not read as the same act. A confirmation asks first and says which of the two will happen: the primary tenant withdraws the application, and anybody else withdraws only themselves while the household carries on. Afterwards their part is locked — no more answers, no more documents, nothing further to submit — and everything they had entered is kept, which they can check for themselves, because their link still opens and still shows what they sent. It is never recorded as a landlord decision, and nothing is sent to anybody.
  • An application that should not exist can be deleted, and deleting it is reversible for thirty days. A test, a duplicate or the wrong home comes off every queue at once and the applicant’s link stops working immediately, and nothing is destroyed: it goes to a deleted list, where it can be restored exactly as it was — every answer, every document, the same link — or destroyed outright. Anything left there is destroyed automatically after thirty days, and the deleted list says of each row when that is. This is deliberately not a withdrawal: a withdrawal is part of an application’s history and stays on it, and a deletion says the row should not have been there, which is why they are recorded as different acts. Destroying one is a second, separate press on the deleted list, says in advance that the answers and the uploaded documents go with it, and cannot reach an application nobody has deleted. The unattended clean-up can only ever reach a row that has sat in the deleted list for a month, and what it destroyed is still named in the account-wide log afterwards.
  • A name is three fields everywhere — first, middle and last — and a middle name is answered rather than skipped. Either it is given, or a box says there is none, because “no middle name” and “nobody filled this in” are different facts and only the first is any use to whoever types the lease. It is never a blocker: one tick and the form moves on. On a phone a saved contact now fills the right part into the right box, which one combined field could not do. Names already on file are left exactly as they are — nothing guesses where one name ends and the next begins, because a record claiming a surname was a middle name would be stating something nobody said. The one place a split is guessed is an invitation form, where the person it is about is looking at it and corrects it before anything is saved.
  • A Social Security number is typed in the open, hides itself the moment you leave the box, and is asked for twice. Typing nine digits behind dots and then revealing them to check is the weakest proof there is that they are right; typing it again is an independent attempt, and the consequence of one wrong digit here is a report run against somebody else rather than a message on a screen. The second box is never stored and never sent anywhere, and the form will not save the section while the two disagree.
  • The application saves itself. There is no Save button — there were two, which were one action named twice and neither of which said the section had been stored. It saves when you leave a field and after a short pause; a bar fixed to the bottom of the screen carries the progress, the words Saved or Not saved, and the only button, which is the next section. A refused save leaves the text in the field to try again, and a half-written e-mail address does not produce an error while it is still being typed. The warning about leaving the page went with the buttons: it existed because leaving used to lose a finished answer, and a prompt that fires when nothing is at stake only teaches people to dismiss prompts.
  • A date of birth is three typed boxes rather than a calendar, because the phone picker opens on this month and moves a month at a time. Every adult on an application now gives a whole date — the question had asked for one all along and the product kept only the year — and so can a person listed on a household, which is what tells an adult who cannot legally sign apart from a child. A row that has only a year keeps only a year: nothing invents the first of January, and the applicant is asked for the month and the day instead.
  • Staff can separate somebody from a household without losing their application. They keep everything they entered, every document they uploaded and the link they already hold, and it becomes an application of its own for the same home with them as its primary tenant. The screen says that in advance and offers it only where it would actually be allowed — not for the primary tenant, not once a decision has been made, not where a fee has been settled or a payment is open.
  • A SIGNED APPLICATION IS KEPT HERE, NOT ONLY AT THE SIGNING SERVICE. When somebody finishes signing, the executed document is fetched and a private copy of it is stored in this account’s own folder, with the signing evidence beside it: when it completed, which form and which version of that form, the company it was signed for, and a digest of the file so the bytes served later can be shown to be the bytes captured then. Reading a signed application reads our copy first, so it still comes back if the signing service is unreachable or the account there has gone. A signature that arrives against answers which have since moved is preserved too — that is the case where the document matters most. If a copy could not be taken at the time, the next person to open the document takes one; a copy somebody deliberately deleted under the retention policy is never quietly taken again. The review screen says which of the three it is. How long a signed application is kept is a decision the owner has not made yet, so nothing deletes one.
  • THE LETTING TEAM CAN HAND SOMEBODY A CODE TO JOIN A HOUSEHOLD. A twelve-character code, made from the household screen and read out or passed on by whoever made it, which lets one more person start their own part of an application that is already open. Who joins with it will be a tenant or a co-signer, and that is chosen when the code is made rather than by whoever uses it, because the answer decides whether a report is intended about them and whose the fee is. One code is out at a time, it runs out after a fortnight, and it can be replaced or taken back; the screen shows the state of every code the household has had and never a code, because only a one-way hash of it is kept. Nothing is sent: there is no address to type and no message goes out, so this works in a deployment that cannot e-mail at all. The code itself is shown exactly once, at the moment it is made, and the screen says so before it can be closed.
  • A FILE A REVIEWER SENDS BACK CAN BE REPLACED, EVEN ON AN APPLICATION ALREADY SENT IN. Sending a document back is a request for a replacement, so the slot it was in opens again — that one slot and nothing else. The person is told on their own home page that something needs their attention, with the reviewer’s own reason for returning it, and the part drops back from done to in progress rather than reading as finished while the reviewer waits. Everything else stays shut: the answers cannot be changed, the other documents cannot be touched, a file that has been accepted stays frozen, and nothing can be removed — replacing is what was asked for, and deleting is not. The moment the replacement is sent the request disappears from their screen without a page reload, and the reviewer’s desk stops saying a required document is missing. Before this the refusal told the applicant to ask the letting team to reopen the file, and there was no such control for anybody to use.
  • A REVIEW AND A DECISION DO NOT WAIT ON A PERMISSION NOBODY CAN GIVE YET. The wording of the tenant-screening authorisation is with a lawyer, so it is never put to anybody — and while it sat among the things an application needed to be complete, no application in any deployment could ever be reviewed or decided. A household whose evidence is otherwise in can now be taken to review and decided on that evidence. Nothing is assumed in anybody’s favour: the missing permission is still listed as outstanding on the household’s page, with the sentence that a preliminary review may go ahead without it and a final approval may not, and a missing document or an unsubmitted part still holds the application exactly as before. Ordering a screening report still refuses without the permission, which is the thing the permission is actually for.
  • SOMEBODY APPLYING CAN OPEN A FILE THEY SENT US. Every document in a slot on their own documents screen has an Open control beside it, including one the letting team has already accepted — which is the one they can no longer replace and the one a decision will rest on. The link is signed, lasts minutes, and is made at the moment of the click, so nothing openable sits in a page or a browser history; the file travels from private storage straight to their browser and never through this application. Only their own files: the request names no person and no household, so there is no way to ask for anybody else’s, and a file belonging to somebody else on the same application gets the same answer as a file that does not exist. Opening one is written into the application’s history, with which kind of document it was and never what it was called.
  • Starting an application for a home you have already applied for does not create a second one, and neither does accepting an invitation to join a household on it. The link to carry on with the first is e-mailed to that address, nothing is created, and the invitation is left unspent so the household can still invite whoever they meant and the person can still try the address they actually use. Sending the same form twice — a double tap, a retried request, a flaky connection — also produces one application rather than two, keyed on the submission itself rather than on the e-mail address, so the check cannot be used to find out whether an address has applied.
  • An invitation to apply with somebody opens with the name and e-mail already filled in, and both are editable. What the person who invited you typed is their guess — often a work address or a maiden name — and your own answer is the one that is kept.
  • Closing one is not the end of it, in either direction. The application’s history shows that the applicant closed it themselves and when, and staff can reopen that same application — the one that was closed, not a copy — which puts it back where work can continue. And the household can start a new application on their own, without asking anybody here first.
  • A SCREENING REPORT THE LETTING TEAM PULLED OUT OF THE PROVIDER’S TOOL CAN BE FILED ON THE PERSON IT IS ABOUT. Reports are ordered by hand outside this product, and until now there was nowhere to put the PDF that came back: the only thing that could add a document to an application was the applicant’s own upload, so a consumer report could exist here only if the person it was about had sent it in themselves. A member of staff opens that person’s own documents page and presses “File a screening report for this person”, and the copy lands in a section of its own headed “Filed by the letting team”, numbered in order of filing. The screening panel says whether a copy is filed and links straight to that page.
  • AND A FILED REPORT IS NEVER SHOWN AS SOMETHING THE APPLICANT CHOSE TO SEND. It used to land in the optional “anything else you would like us to see” slot, described as theirs, with send-this-back offered on it — a destructive control aimed at somebody who never uploaded it. Filed reports are their own section with no verdict offered, and the applicant’s own link cannot open one. Three things stay three separate acts, and each screen says which it is: recording that a report came back, filing the copy, and recording that somebody read it. None of them orders a report, and none of them approves anybody.
  • EVERY DEAD END ON AN APPLICANT’S OWN PATH NOW HAS SOMETHING TO PRESS. A link that has run out offers a new one; a link that was never valid says so without promising that saved work is waiting; a link somebody withdrew offers nothing at all and says why, rather than inviting a request that has already been refused. The refusal that used to say “reload the page” carries a button, because on a phone there is no visible reload. And two sentences stopped over-claiming: when the connection drops mid-send, the screen says it did not hear back and that pressing again will not send twice, instead of asserting that nothing was sent — which is what was making people start a second application.
  • AN APPLICATION WITH NOTHING TO PAY CAN BE REVIEWED, WHICH IT COULD NOT. The fee is $0 on this account and every fee-eligible adult was still reported as owing it, so the readiness gate held every household out of the queue behind a payment with nowhere to make it — and told them they were waiting on us. What an application charges is now read from the application’s own snapshot everywhere the question is asked, so $0 means there is no payment step rather than an unsettleable one.
  • A REQUEST FOR A DOCUMENT OPENS THE PAGE THAT COLLECTS IT. Being asked for a photo of an ID takes the applicant to the page that takes one, and a request for a proof of income to the page that takes that — from the one table the applicant’s own review page already used, so the two screens cannot disagree. A request that does not say which document goes to the checklist, deliberately: sending somebody to the ID page for a missing payslip is worse than showing them the list with both rows unfinished.
  • AND BOTH SIDES CAN SEE WHEN WHAT WAS ASKED FOR HAS TURNED UP. The applicant is told the thing has been sent and that nobody has confirmed it yet. The reviewer is told the same above the close buttons, with what to do: open it, and close the request as answered if it does answer the question. Neither screen says accepted, approved or complete, and nothing closes itself — closing a request stays a named person’s act. Where neither side can tell, both say nothing rather than claiming nothing arrived.
  • A FILE THAT WAS SENT BACK SAYS SO, TO THE PERSON WHO SENT IT. Not that nothing arrived — they answered the request, and what they sent was returned for a replacement, which another copy answers.

🔑Leasing & turnover

  • Move-In workflow: one guided path per unit that takes it from applicant to keys — choose who's moving in (current tenant, an approved applicant, or a new occupant, which pre-fills the rest), build the welcome packet, build the lease, review the required documents, send for e-signature, and mark Move-In Ready. Each step shows Done / In progress / To-do / Blocked, and links straight to the tool that does the work.
  • Lease Builder (Beta): assemble a draft residential lease for a unit from a standard 50-module library — rent & late fees, security deposit, maintenance & repairs, pets & assistance animals, required insurance, early termination, casualty & habitability, default & remedies, and the Philadelphia/federal disclosures with real code citations — pre-filled from the unit's property, tenants, rent, and term. Read a full sample lease (every module, fictional data) before you build a real one, then send the draft to tenants to e-sign.
  • Edit lease clauses in-app (Leasing → Lease modules): browse every clause in the library, read the full text, and (site admins) edit any clause — your edit applies to the leases you generate and send, with one-click revert to the vetted default; edits are validated so a broken placeholder can't ship.
  • Rent-at-renewal escalation is written into the generated lease itself — the Lease Summary, End-of-Lease section, and Sign & Accept recap each state that every automatic renewal raises the monthly rent 3% over the prior term, compounding year over year, unless the landlord gives written notice of a different amount (higher or lower) at least 75 days before the Lease End Date, with skipping a year or raising under 3% never waiving the right in later years; it's standard clause language (no per-lease slider) that site admins can edit in Leasing → Lease modules, with one-click revert to the default.
  • Per-person water billing: set water to “per person” with a $/person rate in the packet/lease config and the lease's monthly water charge is computed as rate Ă— number of occupants (tenants + minors + additional adults) — e.g. $35/person Ă— 3 occupants = $105/month, where it previously showed just the per-person rate.
  • Pet policy now offers four options — No pets, Cats only, Dogs only (newly added), and Dogs & cats — derived from the unit's pet records on a real lease (the sample previewer has an explicit dropdown), and each approved pet now prints its breed and weight on the lease (e.g. “Rex — Dog (Labrador Retriever), 40 lbs”).
  • Lease reader: upload a signed lease PDF and AI extracts the whole record — landlord, tenants, guarantors/cosigners, additional occupants, property, term, rent (+ rent-increase addenda), deposit, pets, insurance, utilities, compliance, move-out and default clauses — with a confidence score, flags, and duplicate detection.
  • One-click apply: match an extracted lease to the unit and its current tenants, then push rent, deposit, lease dates, and tenant contact info onto the record (non-destructive — fills gaps, adds new tenants).
  • Additional occupants (named on the lease but not signing): captured per unit, with a flag when an adult (18+) should be a lease signer.
  • Lease end is tracked as a renewal date — a past end rolls forward by 12-month renewals to the next anniversary.
  • Renewals: every lease ending soon, color-coded by urgency, flagged “new lease” vs “auto-renews.”
  • Vacancies: every unit with no active tenant, plus a “Moving out” list with expected dates and a “tenant lined up” badge.
  • Move-out process: start a move-out (expected date) → line up the incoming tenant → run a move-out inspection (the tenant can self-document via their link) → finalize, which swaps the incoming tenant in (or marks the unit vacant) and archives the prior tenancy.
  • Building type (Single Family House / Multi-Unit / Commercial / Storage) anchors house-vs-apartment and which compliance applies; one click backfills it from unit counts.

📦Welcome packets & document library

  • Generate a branded tenant welcome packet PDF per unit — assembled from the unit's data: contacts, color-coded emergency steps (911 / gas → PGW / urgent), the move-in report deadline, water shutoff, trash & recycling, heat/water/parking/HVAC, pets, house rules, voter registration, and a dated compliance-document acknowledgment with signature lines per tenant.
  • Guided readiness checklist per packet: shows the packet's completeness at a glance, lists exactly what's missing, and blocks sending when a legally-required document (CRS, rental license, or lead paperwork) isn't on file yet. Every “Missing” item links straight to where you fix it — a packet field, the unit's compliance documents, or the building's year built.
  • Send the whole packet to tenants to e-sign (DocuSeal): track who's signed, resend a link, or download the signed packet; a no-signature reference copy is one click away.
  • When every signer finishes, the bundled credentials (CRS, Lead-SAFE cert, Certificate of Analysis) are automatically marked Delivered on the unit's move-in checklist — no manual step, the unit stops reading “move-in incomplete” on its own.
  • Per-unit settings: heat-included, mailbox combo, lock type, water billing + access code, parking permit, street cleaning (with days/hours), and contacts — blank fields fall back to property/lease defaults.
  • Optionally send the welcome packet and the lease as ONE document, signed once. Off by default. When it is on, a lease sent for signature is a single PDF — the welcome pages and this unit’s certificates first, then the lease, then one signature page — and tenants sign once instead of twice. The packet’s own Lead-Based Paint and Bed-Bug forms are left out because the lease itself carries that text from the same source, so one disclosure is not signed twice on two days; the certificates stay attached, and Appendix B stays in, because nothing in the lease carries it. A form is only ever left out when the lease section replacing it is genuinely in that lease — untick the bed-bug module and the packet’s form comes back rather than the disclosure disappearing from both. The e-mail says it is the lease AND the welcome packet, and the preview you check is the document that gets sent.
  • Document library: upload reusable boilerplate (handbook, lead disclosure, EPA pamphlet, bed-bug notice, forms) and mark what's bundled into each welcome packet; name your own document types as you go.

⚙️Accounts & admin

  • Multi-landlord: invite other landlords, each with a private, isolated portfolio.
  • Sign in with Google or with an email + password.
  • Per-account settings: report BCC, auto-email, signing rules, photo tags, dev/test mode.
  • Site Admin (site admins only): manage logins, View-as a landlord to troubleshoot, system health bar, and an AI cost dashboard.
  • Site Admin → Scheduled sending: one switch over everything the clock sends on its own — the nightly reminders, signing-window reminders, signed-report delivery and compliance alerts. It is OFF by default and off is also what an unreadable setting means, so a deployment never starts sending because a check could not be made. Sending something yourself is never affected. While it is off each scheduled run still works out what is due and reports what it withheld, so nothing has to be switched on to find out. Turning it on requires typing a confirmation phrase and is recorded with who did it and when.
  • Built-in error monitoring: server and browser crashes are captured automatically into an Errors panel (with a 24-hour count); a friendly crash screen replaces blank pages.
  • One-click full data backup (JSON export of every record) for safekeeping.

đź“§Reports & messaging

  • Branded PDF reports, emailed via Resend with optional BCC.
  • Per-LLC branding: logo, business name, contact, and footer on reports/packages — an account default with per-ownership-group overrides.
  • Editable message templates for tenant texts/emails, the report email, reminders, and vendor work orders (with the required SMS opt-out line locked in).
  • Tenant texting, and every other text the app can send, goes through one consent gate: nothing reaches a phone without a recorded opt-in, a STOP reply revokes it in whichever format the carrier reports it, an unreadable consent trail refuses rather than assumes, and the same message is not sent twice inside a minute. Site admins can send one test message from Site Admin after seeing exactly what would go out and to which number.
  • Text-message consent tracking (Directory → Text messaging): every current tenant shown as opted in, opted out, asked and waiting, declined, or never asked — with the date, the source and the exact wording behind each answer. “Never asked” is never displayed as a refusal.
  • Ask a tenant by email whether you may text them: a single-use link to a page showing the number and the full consent wording, with “Yes” and “No thanks” equally plain. Declining is recorded as a decline and never revokes a consent given elsewhere; the link is spent once answered so a forwarded or prefetched email cannot re-grant permission.
  • A tenant who replies STOP can turn texting back on themselves with START, YES, UNSTOP or RESUME — accepted only on a carrier callback whose signature verifies.
  • An Inbox listing every conversation this account is in, most recently active first, across residents, backers and vendors together — flagged awaiting reply when the last message came from them. The flag is derived from the messages on every read, never stored, so it cannot disagree with the conversation.
  • A number the directory does not match is shown as an unknown number rather than given a guessed name; conversations with people who have since opted out still appear, marked as such.
  • A conversation view per number — every text sent and received, in order, with the carrier's delivery word on each — and a reply box that appears only for a number with a recorded opt-in. Plus an account-wide message log, filterable and searchable, with undelivered messages called out.
  • The log records what happened, not what was attempted: a refused, suppressed or blocked send never appears in it, so a gap means nothing went out.
  • Co-signers and guarantors are tracked for consent beside residents, and the screen can be narrowed to one kind of person — permission to text a resident is not permission to text the person who backs them.
  • Bulk actions on the consent screen: tick the people you mean and either email them all a request for permission or send one text to everyone selected. Each button counts only the people it may act on, everyone excluded is named with the reason before anything runs, and the sends go one at a time so a failure is reported against the person it happened to.
  • A consent ring at the top of the screen shows the five answers as shares of whoever is on screen — narrowing to co-signers recounts it, so the chart and the table can never disagree.
  • Vendor texting has its own tracking screen (Directory → Vendor texting) with the same five answers, evidence and bulk actions — a different job from the resident list, not a different rulebook. One consent trail underneath: a number that opted out is opted out on both screens.
  • The emailed request is worded for whoever gets it — a vendor is asked about work and told that declining costs them no work, rather than being reassured about a tenancy they do not have.
  • Every message names the owner it is sent on behalf of — “Property Unify, on behalf of Strawberry Mansion Estates LLC” — resolved from the ownership group on the lease and carried through the email, the opt-in page, the consent sentence and the opt-out footer, so one message names one company everywhere it is read.
  • Replies to a request for permission reach the manager’s own address, not the platform’s sending mailbox.
  • Preview before sending: “Ask by email” shows the exact message — from, reply-to, subject and body — with Send now underneath. The preview mints no link, records no invitation and sends nothing; the message you read and the message that goes out are built by the same code.
  • Owner-worded consent is recorded under its own version id, so a record always names the wording the person was actually shown.
  • Photos travel both ways on a text thread: a tenant can send one and you can attach one to a reply. They are stored as this account’s own files under the same per-organization rule as every other document, shown through short-lived signed links, and never left as the carrier’s expiring URL.
  • A photo that could not be kept is stated on the thread rather than omitted — the message says a picture was sent that we do not have, so a silent gap can never read as a text-only message.
  • An attached photo that cannot be proven to belong to this account refuses the whole send; the consent gate is unchanged, so a number with no recorded opt-in has no composer and no attach control.
  • A court-ready export of the text message record (Directory → Message export): the complete history for a chosen period as a formatted PDF and as CSV, with participants, numbers, property and unit, direction, delivery status and carrier message IDs, and the consent trail — every opt-in, STOP and START — alongside it.
  • Times are shown in Eastern with the zone named, and the stored UTC timestamp is printed beside each one, so the conversion can be checked rather than taken on trust. The cover carries the export date, the period, the account and the organization; every page is numbered “Page N of M”.
  • Photographs are shown in the document where they can be rendered, and the original files travel in a ZIP alongside the document, both spreadsheets and a manifest giving a SHA-256 checksum for every file. A separate checksum is taken over the records themselves, so the same messages exported twice produce the same value and a changed record produces a different one.
  • The export can be emailed as a complete attachment rather than an expiring link, with both checksums in the message so the recipient can check the file before opening it. Emailing asks twice: the address is typed, shown back, and confirmed.
  • It states its own limits on the document — a photograph that could not be read back, a period where the history may be incomplete, a message whose delivery was never confirmed. Producing an export writes nothing: it is a read of the rows as they were written when the events happened.
  • Property access records (Operations → Access, and an Access section on every property and unit): lockboxes, key safes and keypads with the exact location, what each one opens, the instructions, status, effective and expiry dates, and when the code was last changed and last checked in person.
  • The code itself is encrypted with a server-only key and bound to the record it belongs to, so a stored value cannot be moved into another record and opened there. No screen, list or property page ever receives it — not even encrypted. Without the key a code is refused rather than stored in the clear.
  • A phone portal at access.propertyunify.com, built for one hand at a front door: address search first, favourites and recent properties, the property and the box shown before any code, and the code masked until Reveal. A revealed code hides itself again after a minute or as soon as the phone is put away.
  • Every sight of a code is written down before it is shown — who revealed it, who copied it, who created or changed or retired it — and the trail never contains a code. Replacing a live code or taking a record out of use each require a confirmation the server insists on, not only the screen.
  • An account can additionally require a typed REASON before a code is shown, recorded with the reveal. It is off unless switched on, it is enforced on the server rather than only on the screen, and it governs what is asked — never what is kept: every reveal is logged with or without a reason, and no setting turns that off.
  • A refused reveal prints its reason on the row you pressed rather than at the top of a long property list, because a warning nobody scrolls back to read is indistinguishable from a button that does nothing.
  • A record entered by mistake — a duplicate, or one filed against the wrong property — can be removed, and removal is not erasure: the versions and the audit trail stay, and every live contractor link on that record is withdrawn in the same act, with the confirmation saying how many people that cuts off. A box that has come off the door belongs at status “inactive” instead, which keeps the record of what used to open it.
  • Contractors get an expiring link, never the code in a text message. It shows one record and nothing else, can be capped at a number of opens, can be withdrawn at any time, stops working the moment the record is taken out of use, and records when it was sent, opened, expired or revoked. Texting it goes through the same consent gate as every other message.
  • “Send access instructions” on a maintenance send: pick the record, see exactly what the contractor will receive, and it goes with the job. Nothing is chosen for you — an address that merely looks similar never picks a lockbox on your behalf.
  • An access record can also hold the alarm: the disarm code, which panel it is and how to use it, and who to call if it goes off anyway. The alarm code is encrypted and revealed under the same audited path as the box code, and named separately in the trail; the instructions and the call details are ordinary text, because somebody with a keypad counting down should read them rather than request them.
  • A contractor link carries the alarm code alongside the box code, under the same expiry, cap and withdrawal — a contractor who can open the door but not the panel has a siren — and the send screen says so before anything goes. If an alarm code cannot be decrypted the visit is not cancelled: the door code still works and the page says to call the number first.
  • Access records are grouped one line per property and opened with a press — the closed line says how many records the building has, how many carry a code, how many have never been checked in person, and in red how many hold a code that cannot be read.
  • A single contractor link can carry more than one access record: a unit’s box together with the building front door, on one page, under one expiry, one view cap and one withdrawal. Extra codes are never pre-selected, are offered only from the same building, and are capped at four records to a link. Sharing and opening are recorded against every record the link carries.
  • A code on a multi-record link that was taken out of use after it was sent reads as unavailable in words rather than as an empty field, and the other codes on the link still work.
  • Repairs & To-Do opens with a status band — open work, with vendor, vendor can’t do, completed — where every tile is a filter and every count comes from the same rule the rows use. Expanding a repair shows the tenant on the source inspection with a dialable number, resolved by an id join rather than by matching the address, and says plainly when no contact was recorded.
  • Compliance → Requirements counts the portfolio by credential rather than by property: what each requirement stands at, how many places it is open, what lapses next, and — on opening a row — every building or unit it is open on, most urgent first. A credential that is legitimately N/A, or whose applicability cannot be determined, is counted apart from the total rather than folded into it.

đź§°Contractor logins & receipt capture

  • A contractor portal at my.propertyunify.com: contractors sign in with Google against the address you invited, and a login with no live vendor record on this account is not a login. Every request re-reads the record, so suspending or revoking somebody takes effect on their next tap rather than whenever a session happens to expire.
  • Two levels, and a level is a CEILING rather than a grant. An Assigned Vendor sees the jobs dispatched to them and nothing else; a Master Vendor can be given more, one thing at a time. Every one of the eleven permissions a login can hold is written on the access screen with what it means in practice, what the level does not carry and why, and which ones stay inert until tenant contact or access codes are switched on as well. Any of them can be switched off for one person without demoting them.
  • A Master Vendor can be given the whole portfolio — every property on the account, including ones added later — as one explicit switch that is off until somebody turns it on and is written to the audit trail with their name on it. Without it, buildings are granted individually; scope is never implied by a level.
  • The portal says WHY a list is empty: a search that matched nothing, nothing granted yet, or genuinely none. Its home page names the areas that are not switched on for that login rather than quietly leaving the tiles out, so “where is my access list” is answered on the screen instead of by a phone call.
  • A contractor’s number is asked for as a MOBILE, because everything it carries — job details, scheduling, site access — arrives as a text and an office line receives none of it without appearing to fail. A number too short to reach is flagged where it is typed.
  • The row says whether they may be texted at all: opted in with the date, stopped, said no, asked with no answer, not asked yet, or no number yet — read from the same source the send-time gate reads, never a separate tally. There is no button to opt somebody in from the office: a contractor is asked on their own first sign-in, and a decline is recorded and never re-posed.
  • Granting is bulk-editable where the lists get long: both the property list and the vendor list carry a count with Select all and Clear. Selecting all names the properties that exist today, which is deliberately distinct from the standing “whole portfolio” switch that also covers properties added later.
  • Receipt capture from a phone: photograph a till roll page by page, reorder or drop a page before sending, and file the lot as ONE receipt. The pages travel under one batch id, and pressing Done twice on a bad signal merges rather than filing it twice.
  • The money lives on the receipt, not on a page — the total, the category and the split — so re-taking a blurred first photograph or reordering the pictures cannot move or lose it. A receipt can be split across several buildings, and the split has to add up to the total: the phone shows the remainder as it is typed and the server refuses one that is short or over.
  • A share with no building is a real answer: overheads across the portfolio, or “I do not know — the office decides”. An address a contractor typed that matches no building is kept as they typed it and marked unmatched; it is never guessed at a property and never dropped.
  • What a contractor was allowed to do is recorded on the receipt at the moment they send it, and re-proved on the server: an assigned vendor may only file against a job they hold, and a Master Vendor only against a property in their grant.
  • In the office, Incoming → Receipts shows what the contractor typed and what was read off the photographs side by side, as two claims rather than one number — with the disagreement marked in the amount itself, the page and characters each value was read from, and every page of the receipt on screen.
  • A read that FAILED says so and names the reason, so an extraction that produced nothing and one that could not run are never confused. The receipt is never the thing that is lost: the pages are kept and the row is marked as needing extraction.
  • A receipt sent twice is raised as a question, never resolved as an answer. The same photograph under a new batch — or the same contractor, the same amount to the cent and the same shop or the same day — puts both in front of a person under the existing duplicate/separate decision. Nothing is merged and nothing is deleted, and an amount on its own is deliberately not enough to raise it.
  • “Needs more from the contractor” records the question on the receipt, holds it in Incoming, and puts it in the sender’s own portal. They answer on the SAME receipt — their reply and any extra pages come back to that row, never as a second one. Nothing is sent: no text, no email, so a question that cannot wait is still a telephone call, and the screen says so.
  • Answering with a photograph is a first-class answer: the pages are added to the receipt already there, everything the contractor typed stays as it was, the hold comes off, and the page count before and after goes on the receipt’s history. Pages sent by anybody else on the account are refused with a reason rather than added to a receipt that is not theirs.
  • No writer on a receipt can erase one it never saw. The reviewer, the contractor answering a question, the approval and the reading service all write the same record, and each write now checks the receipt has not changed since it was read — re-reading and re-applying its own change if it has, and reporting a failure rather than a false success if it cannot. A split typed onto a receipt a colleague has just approved is refused by name, and there is no unguarded way to write one: the unconditional save is off the repository interface, so the compiler refuses a new caller.
  • A reading that fails never replaces one that worked. Every submission of a capture is read again, including a retry on a bad signal and every page added in answer to a question, so a receipt already read could be emptied and marked “needs extraction” by one bad minute at the reader. A reading that SUCCEEDS still replaces one that failed; where both failed, both reasons are kept, oldest first.
  • And the answer is FINDABLE, which is the whole point when nothing is sent in either direction: the reply or the pages show above the receipt with the question they answer, Incoming marks the row “Contractor answered”, and Accounting → Receipts counts, filters and flags them. A question asked again outranks any answer before it, so a receipt waiting on somebody a second time is never listed as answered.
  • A contractor can see what became of every receipt they sent — waiting on them, with the office, accepted, already sent, or not accepted — because somebody who cannot tell whether a receipt arrived sends it again, and a second photograph of the same till roll is a second review row and, on a bad day, a second charge. It shows them their own receipt and nothing around it: no reviewer, no internal note, no correction history. Where the office recorded a different amount they are told, but only once the decision is final.
  • Accounting → Receipts is the review workspace: status, contractor, property, date, amount, a reading that failed, an unanswered duplicate, “needs information” and the receipts a contractor has since answered, over the same rows Incoming shows and through the same single approve path. Approval is limited to an owner, an administrator or accounting-authorised staff — a vendor login can never approve, including its own receipt — with the boundary shaped to take an amount threshold or a second signature later.
  • What a reviewer confirms is what gets filed: the amount, the vendor and the building come from the confirmation first, then the contractor’s claim, then the reading, and the record says which of the three each came from. The receipt is filed on the date of the PURCHASE rather than the date of the review, so a receipt photographed on the 28th and approved on the 3rd lands in the right month. The contractor’s split is never rescaled to fit a corrected total — the office can place the shares itself, and what the contractor claimed is kept beside it.
  • A reading that fails is retried once, and only where retrying could help: a timeout or a 5xx, never a refused credential, a malformed request or a photograph nothing can make out. Beyond that a person presses “Read it again”, and every attempt and error is kept in order.
  • Nothing a contractor sends is approved, coded, posted, paid or reimbursed by arriving. It lands pending, in the review queue, exactly like every other document.
  • One approved receipt files one payable, enforced by the books rather than by timing. Approving reads the receipt and then spends real time copying pages and reading them again before it writes anything, so two reviewers — or one reviewer whose request was retried — could each produce a bill for the same purchase. An approved receipt is now filed under its own identity: the second attempt finds the first already there and stops before writing, neither overwriting the split the first placed nor discarding it, and the person who pressed second is told that nothing was filed twice.

🗑️Safety & housekeeping

  • Trash with restore, permanent delete, bulk actions, and 30-day auto-purge.
  • Deleting a photo or room asks to confirm; deleted photos go to a per-inspection “Recently deleted” you can restore from for 30 days.
  • Move-in vs. move-out photo comparison.
  • One-click move-out deposit package: condition changes, side-by-side photos, and an itemized deductions worksheet (download or email; doubles as the itemized list of damages).
  • Each landlord's data is isolated per account, with a tamper-evident signing audit log — both backed by automated tests.
  • Privacy Policy, Terms, and SMS Policy pages.

Interested in using Property Unify for your properties?

Sign in to get started

Access is by invitation — reach out to Property Unify to be added.