If you build a listings app, a lead form, or even a spreadsheet for RERA registered projects in Noida, you will get bad RERA numbers. Some are typos. Some say "applied." A few are made up.
A regex can catch the first two in milliseconds. It cannot catch the third. That second step needs the state portal, and no code shortcut replaces it.
This post covers both parts: a short Python validator for Uttar Pradesh and Haryana formats, and a data model that records whether a human actually checked the number.
What a RERA number tells you
Under the Real Estate (Regulation and Development) Act, 2016, most residential projects must register with the state authority before they are marketed. The registration number is the key to the public filing.
That filing holds the useful stuff: approved plans, carpet areas, the promised completion date, and quarterly progress updates. The number itself is just a pointer. If the pointer is wrong, everything you show next to it is unverified.
Two states, two formats
Delhi NCR buyers usually deal with two authorities. Noida and Greater Noida fall under UP RERA. Gurugram falls under Haryana RERA (HARERA). Their formats look nothing alike.
UP RERA (Noida)
UP project numbers start with UPRERAPRJ and six digits. Newer ones add a month and year suffix.
Two real examples from the UP RERA portal:
- Estate 128, Sector 128, Phase I:
UPRERAPRJ446459 - Estate 105, Sector 105:
UPRERAPRJ529777/03/2026
Note that Estate 128 has a second number for Phase II (UPRERAPRJ294911). One project can have several registrations. Keep that in mind for the data model below.
HARERA (Gurugram)
Haryana is messier. Older registrations read like "87 of 2024." Newer ones use a long slash path.
Real examples from the HARERA site:
- Estate 360, Sector 36A:
HRERA No. 87 OF 2024 - Estate 361, Sector 36A:
RC/REP/HARERA/GGM/1012/744/2025/115
The GGM part refers to the Gurugram bench. If you cover other Haryana districts, loosen that part of the pattern.
The validator
import re
PATTERNS = {
"UP": re.compile(r"^UPRERAPRJ\d{6}(/\d{2}/\d{4})?$"),
"HR_NEW": re.compile(r"^RC/REP/HARERA/GGM/\d+/\d+/\d{4}/\d+$"),
"HR_OLD": re.compile(r"^(HRERA\s+NO\.?\s*)?\d{1,4}\s+OF\s+\d{4}$"),
}
def check_rera(raw: str) -> dict:
# collapse spaces and uppercase before matching
s = " ".join(raw.strip().upper().split())
for name, pat in PATTERNS.items():
if pat.match(s):
return {"normalized": s, "format": name, "shape_ok": True}
return {"normalized": s, "format": None, "shape_ok": False}
samples = [
"UPRERAPRJ446459",
"UPRERAPRJ529777/03/2026",
"RC/REP/HARERA/GGM/1012/744/2025/115",
"HRERA No. 87 of 2024",
"RERA applied",
]
for s in samples:
print(s, "->", check_rera(s))
The first four pass. The last one fails, which is the point. "RERA applied" or "RERA pending" in a listing should never pass as registered.
Keep the patterns strict on structure and loose on whitespace. Users paste numbers with odd spaces and lowercase letters, and that is not fraud.
Shape vs existence
Here is the trap. UPRERAPRJ123456 passes the regex. It may not exist. Or it may exist and belong to a different project in a different city.
So the regex is a filter, not a verdict. After it passes, someone has to open the portal, search the number, and compare three fields:
- Project name on the filing
- Promoter (developer) name
- Phase or tower list
If any of the three differ from the listing, flag it.
A word on automation: both portals use captchas and session checks. Scraping them is fragile and may break their terms of use. For a small app, a manual lookup with a stored timestamp is the honest option.
A data model for a listings app
Store the check, not just the number. A minimal table:
from dataclasses import dataclass
from datetime import date
from typing import Optional
@dataclass
class ReraRecord:
project_slug: str
rera_id: str
state: str # "UP" or "HR"
phase: Optional[str] # "Phase I", "Tower 4", etc.
shape_ok: bool
verified_on: Optional[date] # None until a human checks
source_url: Optional[str] # portal page used for the check
Two design choices matter here.
First, phase is its own field. Since one project can hold several registrations, a single rera_id column on the project table will be wrong sooner or later.
Second, verified_on stays empty until a person checks it. Your UI can then show "format valid" and "verified on 12 Oct 2026" as two different badges. Users understand the gap better than you might expect.
Red flags worth a code path
These show up often enough to deserve explicit handling:
- The number appears only inside an image, never as text
- The listing says "RERA approved" with no number at all
- The number matches the format but the portal shows a different promoter
- The number covers Phase I while the listing sells a Phase II tower
- The completion date in the ad is earlier than the date in the filing
None of these prove bad intent. They do mean the listing needs a second look before you show it as clean.
Next steps
If you want to test the validator against live data, the Estate 105 project page lists its UP RERA number in the footer. Compare it with the portal entry: Estate 105 in Sector 105, Noida.
For broader context on how listed developers in the region publish project data, the Max Estates blog archive and the Delhi NCR Properties guide are both useful starting points.
A regex will never replace the portal. It just stops the obvious junk before a human wastes time on it.
Disclosure: this post was written by a digital marketing consultant who works with Max Estates. All RERA numbers above are public and can be checked on the state portals.
Top comments (0)