Welcome to the Resi API
Read and write multifamily property, unit, pricing, media, and lead data programmatically.
The Resi API gives you programmatic access to the same property data that powers Resi websites, widgets, and leasing workflows: portfolios, properties, buildings, floor plans, units, pricing, amenities, fees, media, content, reviews, and leads.
It exists for two kinds of builders:
- Third-party vendors in the multifamily space — ILS and syndication platforms, CRMs, leasing AI, tour providers, reputation tools, accessibility overlays — who need a reliable read of a client's inventory and a way to write results back.
- Client internal teams — ops, marketing, and BI — who want to automate work that would otherwise be done by hand in the Resi app.
The three APIs
Resi exposes three APIs, and they are not generations of the same thing. Each serves a different job, and many integrations use more than one. Which API should I use? walks through the choice.
| V2 — the management API | V1 — the public delivery API | Sites API — the website API | |
|---|---|---|---|
| Base URL | https://v2.getresi.com/api/v2 | https://v2.getresi.com/api/v1 | https://v2.getresi.com/api/sites/v1 |
| Auth | Bearer token pinned to one account | None — public endpoints | Bearer token scoped to one website |
| Called from | Your server | A browser, widget or edge function | The website's server |
| Addressing | UUIDs | Property UUIDs (slugs on connection-scoped portfolio routes) | Slugs |
| Shape | REST resources, full CRUD, paginated collections | Purpose-built read payloads + public write endpoints | Render-ready payloads for one website |
| Built for | Integrations that manage data | WordPress property sites, widgets, and public lead and tour forms | New Next.js property and centralized leasing websites |
| Use it when | You need to read or change records across an account | You need what one property's website renders, or you need to submit a lead or book a tour from a public page | You are building a website on the Sites API |
V1 is public. It serves the marketing content a property website already displays, addressed by property UUID, so it can be called from a browser without holding a credential. Treat every field it returns as published content.
Most vendors start on V2 for inventory and use V1's public lead and tour endpoints for anything a public-facing form needs to call without holding a secret. If you are building a website, start with the Sites API overview instead.
The rest of this page is about V2.
Your first request
1. Get a token. API tokens are created per account in the Resi app under Account Settings → API Tokens, or with POST /api/v2/tokens if you already hold a token. Full detail in Authentication & API tokens.
2. Confirm who you are with GET /api/v2/me.
curl https://v2.getresi.com/api/v2/me \
-H "Authorization: Bearer $RESI_TOKEN" \
-H "Accept: application/json"{
"data": {
"id": "9ecee553-ece2-4a9c-90c3-5484b5ccfefa",
"name": "Integration Service Account",
"email": "integrations@example.com",
"is_staff": false,
"email_verified_at": null,
"accounts": [
{
"id": "019dd603-889a-73be-8975-58a30f17b4e8",
"name": "Example Property Management",
"role": "admin",
"role_id": "019fafd9-d110-72de-b170-d76b5276e1d2",
"role_name": "Admin"
}
]
}
}accounts lists every account the user belongs to. Your token is pinned to one of them, and every account-scoped V2 endpoint runs against that account by default. If the user belongs to several accounts, you can point a single request at another of them with the optional account_id parameter. Every account-scoped response carries an X-Resi-Account-Id header naming the account it ran against.
3. Read some inventory with GET /api/v2/units.
curl "https://v2.getresi.com/api/v2/units?is_available=true&per_page=50" \
-H "Authorization: Bearer $RESI_TOKEN" \
-H "Accept: application/json"{
"data": [
{
"id": "019dd605-61bc-71bf-acf9-1f1dd97ac1ca",
"property_id": "019dd604-8468-7388-9a52-4c31a2e1209a",
"building_id": "019eb254-e966-71d2-8b14-2b6fdc8a9fc4",
"floor_plan_id": "019dd605-5bf2-739a-8725-9425f8e631e1",
"is_enabled": true,
"number": "149-304",
"bedrooms": 1,
"bathrooms": 1,
"interior_sqft": 777,
"is_available": true,
"available_at": "2024-11-12T00:00:00.000000Z",
"min_rent": 1510,
"max_rent": null,
"reference_id": "23820098",
"updated_at": "2026-06-10T16:20:34.000000Z"
}
],
"links": { "first": "…?page=1", "last": "…?page=17", "prev": null, "next": "…?page=2" },
"meta": { "current_page": 1, "per_page": 50, "total": 843, "last_page": 17 }
}The unit above is trimmed; the full shape is in Core concepts & data model.
That is the whole model: authenticate once, filter a collection, and page through it. Page URLs in links do not carry your filters, so request the next page yourself — see Pagination, filtering & sorting.
Conventions you can rely on
- UUIDs everywhere. Every record id is a UUID, and a path id that is not a UUID is a
404. Ids are stable across syncs and safe to store as your foreign key to Resi. (API token ids are the one exception: they are integers.) - JSON in, JSON out. Send
Content-Type: application/jsonon writes andAccept: application/jsonon everything. Without theAcceptheader, a missing or invalid token produces an HTML error page instead of a JSON401. PATCHfor updates. Send only the fields you are changing.PUTis accepted and behaves identically — it is not a full replace.- Envelopes. A single resource returns
{ "data": { … } }. A collection returns{ "data": [ … ], "links": { … }, "meta": { … } }. The exception is a single property:GET,POSTandPATCHon a property return the property object itself, with nodatawrapper. - Timestamps are UTC ISO-8601, e.g.
2026-06-10T16:20:34.000000Z. - Numbers are JSON numbers. Rents, deposits, bedroom and bathroom counts, and square footage arrive as numbers (
1510,1.5), ornullwhen unknown. reference_idis yours. Most resources carry a nullablereference_idfor the id this record has in your system (or in the PMS it synced from). Use it to reconcile.
Where to go next
| If you want to… | Read |
|---|---|
| Pick the right API for your job | Which API should I use? |
| Understand how accounts, properties, and units relate | Core concepts & data model |
| Page through and filter large collections | Pagination, filtering & sorting |
| Keep an external system continuously in sync | Syncing inventory |
| Push photos, floor plans, or virtual tours in | Media |
| Capture a lead or book a tour from your own UI | Leads & tours |
| Build a property or leasing website | Sites API overview |
| See a complete worked integration | Any page under Use cases |
Getting help
Include the following when you contact support and you will get a much faster answer: the endpoint and method, the account id the request ran against (the X-Resi-Account-Id response header), the request and response bodies with tokens, credentials and personal data removed, and the timestamp in UTC. Never send a token to support.
Last updated on