Docs
Sites API

Lead sources & integrations

Attribute a visit to a lead source, swap tracking phone numbers, and render the third-party tools each property has switched on.

Both resources come in two forms: website-wide (one block per property, paginated, so a centralized site builds from one call) and per property.

Lead sources

GET /lead-sources (?property=, page, per_page default 25, ceiling 100) · GET /properties/{property}/lead-sources. Tag: lead-sources:{property_id}.

{
  "property": { "id": "0100…0002", "slug": "contract-property", "name": "Contract Property" },
  "fallback_phone": "+1 555 0100",
  "fallback_email": "leasing@contract-property.test",
  "external_source_field": "lead_source",
  "sources": [
    { "id": 1, "name": "google_paid", "code": "GOA", "phone": "+1 555 0111", "email": "google@contract-property.test" }
  ],
  "resolution": {
    "source_observation_endpoint": "/api/sites/v1/source-observations",
    "click_id_params": ["gclid", "gbraid", "wbraid", "msclkid", "fbclid", "ttclid"],
    "rules": [
      {
        "id": 1,
        "priority": 1,
        "lead_source_id": 1,
        "condition_operator": "all",
        "conditions": [{ "type": "exact_query_param", "parameter": "utm_source", "pattern": "google", "value": null }]
      }
    ]
  }
}

Lead source and rule ids are integers, unlike the UUIDs elsewhere.

Picking a source for a visit

The rules are published so the site can evaluate them in the browser, on landing, without a round trip:

  1. Walk resolution.rules in the order given; they arrive sorted by priority.
  2. A rule matches when all (or any, per condition_operator) of its conditions hold against the landing URL's query parameters, the referrer and the click ids named in click_id_params.
  3. The first match's lead_source_id names the source. Show its phone and email in place of the property's; with no match, use fallback_phone and fallback_email.
  4. Remember the choice for the session, and send it with every lead as context.resi_source_key (the source's code) and context.resi_source_name.
  5. Report what you saw to POST /source-observations, through your server.

external_source_field is the form field this property's CRM reads the source from. If the landing URL carries a parameter of that name, keep its value and report it as external_source_value.

The lead-source payload holds tracking numbers and rule logic but no credentials. It is safe to pass to the browser once your server has fetched it; the token is what must stay server-side.

Integrations

GET /integrations (?property=, ?category=, page, per_page default 25, ceiling 100) · GET /properties/{property}/integrations (?category=). Tag: integrations:{property_id}.

{
  "id": "01000000-0000-4000-8000-00000000001f",
  "type": "sight-map",
  "key": "sightMap",
  "name": "SightMap",
  "category": "website",
  "settings": {
    "embed_url": "https://sightmap.com/embed/contract",
    "show_on_unit_modal": true,
    "enable_fee_calculator": false,
    "locate_mode": "unit_id"
  },
  "tour_types": []
}

key is type in camelCase, for use as an object key. category filters with ?category= — for example chatbots, accessibility, analytics, tour; an unknown category is a 422.

What is listed, and what is published

A connection appears only if it renders something on a page: it publishes at least one setting, or it offers a tour type. PMS, CRM, listing-feed and hosting connections never appear at all, and a disabled connection is never listed.

settings holds only the keys its connection type explicitly publishes — never a credential, mapping id or inbox:

Connection typePublished settings
accessibe, audio-eye, user-wayembed_code
better-botembed_code
knock-chatbotpublic_api_token, scope_id
perqscript_url
rentgratawidget_key
heapapp_id
google-analyticsga_tracking_id
peekembed_url
sight-mapembed_url, show_on_unit_modal, enable_fee_calculator, locate_mode

settings is {} for a connection listed only for its tour types. Treat the table as growing: render the types you know, ignore the rest.

Tour types

A tour-capable connection lists what it offers:

"tour_types": [
  {
    "type": "in_person_tour",
    "label": "In Person Tour",
    "redirect_url": null,
    "fields": [ { "…": "one booking form field: its type and definition" } ]
  }
]
  • redirect_url set — the provider hosts the booking; send the visitor there.
  • redirect_url null — build the form from fields and book through the API. The same schema validates the reservation, so a form built from fields cannot send a key the API will reject.

The connection's id is the connection_id that POST /tours/availability and POST /tours/reservations expect.

Last updated on

On this page