Docs
Sites API

Sites API overview

The website delivery API — everything a property website or centralized leasing site reads from Resi, scoped to one website.

The Sites API serves one job: giving a website everything it renders. A token belongs to one website, and every response is limited to that website's own properties, floor plans, units, content, forms and integrations. A property website sees its one property; a centralized leasing site sees its whole portfolio through the same endpoints.

Base URL: https://v2.getresi.com/api/sites/v1

The machine-readable contract is the OpenAPI 3 document at /openapi/sites.json. Every response object in it lists all of its keys as required and allows no others, and Resi's test suite validates real responses against it, so generated types are safe to rely on.

How it differs from V1 and V2

Sites APIV1V2
Base path/api/sites/v1/api/v1/api/v2
Scoped toOne websiteOne property (by UUID)One account
AuthBearer token, one per websiteNoneBearer token, per account
Called fromThe site's serverA browserAn integration's server
AddressingSlugsUUIDsUUIDs
Built forNext.js property and centralized leasing sitesWordPress sites and widgetsManaging data

Server-side only. The website token reads data that is not public, such as lead routing rules, and it can create leads. Call the API from route handlers, server components or build steps. It must never be shipped to a browser.

Your first request

A site scaffolded by Resi has four environment variables written at provisioning:

VariableHolds
RESI_DELIVERY_API_URLhttps://v2.getresi.com/api/sites/v1
RESI_DELIVERY_TOKENThe website's bearer token
RESI_WEBSITE_IDThe website's id, for the X-Resi-Website header
RESI_CACHE_WEBHOOK_SECRETThe key that verifies the cache-clear webhook
curl "$RESI_DELIVERY_API_URL/site" \
  -H "Authorization: Bearer $RESI_DELIVERY_TOKEN" \
  -H "X-Resi-Website: $RESI_WEBSITE_ID" \
  -H "Accept: application/json"
{
  "data": {
    "website": { "id": "01a0b9f5-b5bc-711c-9d7b-6c67aec47953", "name": "Example Apartments", "type": "portfolio", "platform": "nextjs", "status": "live", "locale": "en_US", "environment": "production" },
    "domains": [{ "hostname": "www.example-apartments.com", "is_primary": true, "managed_by": "vercel" }],
    "tracking": { "gtm_id": "GTM-XXXXXXX" },
    "redirects": [{ "from": "/old", "to": "/new", "status": 301 }],
    "routing": {
      "patterns": {
        "property": "/property/{slug}",
        "property_archive": "/properties",
        "floor_plan": "/floor-plan/{slug}",
        "floor_plan_archive": "/floor-plans",
        "unit": "/unit/{slug}",
        "unit_archive": "/units"
      },
      "uniform": true
    },
    "properties": [{ "id": "01000000-0000-4000-8000-000000000002", "slug": "contract-property", "name": "Contract Property", "path": "/property/contract-property", "...": "..." }],
    "theme": { "tokens": null }
  },
  "meta": { "cache": { "tags": ["inventory:0100…0002", "property:0100…0002", "site"], "ttl": 3600 } }
}

A typical build

  1. GET /site — domains, tracking, redirects, URL patterns and a card per property.
  2. GET /paths — every path to generate statically, and the sitemap. GET /content-types — the content types the site renders and their fields.
  3. Per page: GET /properties/{slug}?include=…, GET /floor-plans, GET /units, GET /entries/{type}/{slug}.
  4. Per property: GET /integrations, GET /lead-sources, GET /forms.
  5. At request time: GET /resolve?path=… for paths not generated, GET /availability for what moves, and the POST endpoints for leads, tours and analytics.
  6. Hold responses by meta.cache.tags and drop them when the cache-clear webhook names a tag.

Guides

Last updated on

On this page