Content Pages, Area Pages & Home Page

Part of the Content API. Endpoints for the site’s pages: content pages, agent landing pages, market report pages, area pages, the home page, page templates and revisions.

Content pages

GETPOST/api/v3/content/pages/
GETPUTPATCHDELETE/api/v3/content/pages/<id>/

Regular content pages. Scopes: pages:read / pages:write. Agent landing pages and market report pages have their own endpoints; coming soon pages and valuation pages are managed in the admin and are not visible here.

Field Type Notes
id, path, url, level, children_count Read-only.
slug string Required; letters, numbers, -, _, /.
parent int / null Id of the parent page; read as {"id", "slug", "path"}.
anchor_text string ≤256 Required; the page name used in navigation.
title, meta_description, meta_keywords string SEO fields.
content HTML Sanitized.
template string One of GET /api/v3/content/templates/; default Page with Search.
listing_header string Header above the property listings.
number_of_properties int One of 0, 3, 5, 6, 10, 12, 15, 20, 24, 25, 30, 40, 50, 60, 75, 100, 120; default 12.
property_display_location above / below Listings above or below the content; default below.
search_header string Header above the search form.
search_form_type default / typeahead Which search form the page shows.
search_field_defaults same as search Saved search whose criteria pre-fill the search form; null to clear.
sidebar int / null Id of a sidebar; read as {"id", "name"}.
search see below The saved search whose listings the page shows; null to detach.
extra_content object Template-specific areas, see below.
footer int / null Id of a footer; read as {"id", "name", "default"}.
banner int / null Id of a banner to show across the top of the page; read as {"id", "name"}.
landscape_image_override see below The big image/video at the top of the page.
landscape_image_override_alt_text string ≤100
landscape_image_override_content_type MIME Derived from the URL’s extension when omitted.
banner_id int / null Read-only; the same id as banner, kept for older clients.
capture_form_id, require_capture Read-only; managed in the admin.

landscape_image_override is null to use the site’s header image, "none" to hide the landscape section, or a file URL (image or .mp4 video; see Files). Area pages and the home page take the same fields.

The search field

search reads as {"id", "short_id", "description", "criteria", "site_criteria"} where criteria is {field: [values]}. To set it, send a saved search’s short_id (the base36 id in the site’s search URLs), its numeric id, or a criteria object such as {"city": ["Riverside"], "list_price_min": 1000000}. A criteria object is validated against the site’s search field catalog, unknown fields are rejected with a 422 naming them, and the resulting search is saved (or reused if identical). Area pages and the home page take the same sidebar, search and footer values.

site_criteria holds what the site’s own settings add to every search, such as the MLS boards a site is limited to. You don’t need to send it: the site applies it again on save. Sending criteria back, with or without site_criteria merged in, is accepted and gives the same search.

Location values (city, county, zip, subdivision and the site’s other location fields) are matched exactly when listings are searched, so "McLean" would find nothing on an MLS that spells it "Mclean". Criteria objects are therefore checked against the values the site’s search knows: a value that matches one known value apart from capitalization is saved in the MLS spelling, and the response’s criteria shows what was stored. A value that matches no known value, or several that differ only in capitalization, is saved as sent, and the write succeeds with a warning (unknown_value or ambiguous_value) naming up to three close matches:

{"id": 12,
 "warnings": [{
   "code": "unknown_value",
   "field": "search",
   "criterion": "city",
   "value": "Riversid",
   "suggestions": ["Riverside"],
   "message": "city \"Riversid\" is not a
     known value for this site, so the
     search may find no listings"}]}

Other fields, such as prices, are not checked.

To discover the fields and values a site accepts, and to test criteria before attaching them, see Property Searches.

Template areas (extra_content)

Some templates add fields, listed per template by GET /content/templates/. They read and write as an object keyed by the area name with spaces as underscores; on write, keys are merged into what is stored (send null to clear one), unknown keys are a 422, and changing template drops areas the new template lacks. Values by area type: text is a string, rich_text is sanitized HTML, file is a file URL, reorder_agents is a list of Agent Detail page ids.

  • Agent Detail Page: Agent_Name, Agent_Photo (file URL), Cell_Phone_Number, Fax_Number, Email, Company, Address, Testimonials (HTML). Create one with "template": "Agent Detail Page".
  • About Page: Testimonials (HTML) and Agent_Ordering (ids). An About page also carries a read-only agents list, the site’s Agent Detail pages in display order as {"id", "name", "path", "url", "photo_url"}; pages not in Agent_Ordering follow the ordered ones.

Validation, filters and limits

Validation mirrors the admin: the resulting URL must be unique across all pages, must not be a path Real Geeks reserves (search, market reports, the blog root, …), and a parent change must not create a loop.

List filters: slug, path (e.g. ?path=/resources/buyers/), parent (id or null), template, q (anchor text / title / slug contains), ordering (slug, level, id). List results leave out content, extra_content and agents; fetch a single page for those.

Pages nest at most 10 levels deep and a page URL is at most 200 characters. Deleting a page with children returns 409 conflict; pass ?orphan_children=true to delete it and make the children top-level pages.

From the command line: geekcli pages list, geekcli pages get /about/, geekcli pages update /about/ --content-file about.md with geekcli (see the geekcli guide).

Agent landing pages

GETPOST/api/v3/content/agent-pages/
GETPUTPATCHDELETE/api/v3/content/agent-pages/<id>/

Content pages tied to a CRM agent: leads from the page go to that agent instead of the site’s round robin. Same fields and rules as content pages plus agent_id (writable; an id from GET /content/agents/, or null) and read-only agent_name. These pages are separate from /content/pages/ (neither lists the other). Scopes: pages:*.

GET /content/agents/ returns the site’s CRM agents as {"results": [{"id", "name"}]}; 502 crm_unavailable if the CRM cannot be reached, and writing agent_id is refused with the same code until it can be checked.

From the command line: geekcli agents, geekcli agent-pages create --agent-id <id> with geekcli (see the geekcli guide).

Market report pages

GETPOST/api/v3/content/market-report-pages/
GETPUTPATCHDELETE/api/v3/content/market-report-pages/<id>/

A market report page shows market statistics and tables of active, pending and sold listings for one saved search. These pages are separate from /content/pages/ (neither lists the other), the template is fixed, and the fields are the ones the admin offers. Scopes: pages:*.

Field Type Notes
slug, parent, anchor_text, title, meta_description, meta_keywords As on content pages; slug and anchor_text are required.
search see The search field Required: the area the report covers. It cannot be null.
header string ≤127 Optional text at the top of the report, above the sign-up call to action.
content HTML Sanitized.
sold_within int Months of sold listings in the Sold table: one of 1, 2, 3, 4, 5, 6, 12, 18. Default 6.
number_of_properties int Rows in each listings table, 1 to 50. Default 6.
search_field_defaults same as search Pre-fills the search form; null to clear.
footer int / null As on content pages.
{"slug": "riverside-market",
 "anchor_text": "Riverside Market Report",
 "search": {"city": ["Riverside"]},
 "sold_within": 12}

There is no template, sidebar, banner, extra_content or landscape override on a market report. List filters, ordering, pagination, PUT, DELETE with ?orphan_children=true and revisions work as on content pages. Pages are live as soon as they are created.

Area pages

GETPOST/api/v3/content/area-pages/
GETPUTPATCHDELETE/api/v3/content/area-pages/<id>/

Same shape as content pages without template/extra_content, plus area_name (required) and featured (bool). Extra filter: featured=true|false. Scopes: area_pages:*.

An area page’s listings come only from its search; area_name does not filter them. A write that leaves an area page without a search succeeds with a no_search warning (the page shows no listings), and one whose search has nothing beyond the site’s built-in limits (such as the MLS boards a site is limited to) succeeds with a no_filter warning (the page shows every listing on the site). Either can be deliberate, such as an “all homes for sale” page. A limit field counts as a filter when it picks some of the values the site allows, such as one city on a site limited to several. On update the check applies only when search is sent (always on PUT, which replaces the page).

search_header, the heading above the search form, defaults to anchor_text on create when it is not sent; send null or "" for the site’s generic search title.

From the command line: geekcli area-pages list, geekcli area-pages update /riverside/ with geekcli (see the geekcli guide).

Home page

GETPATCH/api/v3/content/home-page/

The site’s single home page. Scopes: home_page:*. Writable: title, meta_description, meta_keywords, content, sidebar, footer, banner, tile_group (a Featured Pages group id or null, anna-modern), the landscape override fields, the property display options search, listing_header, number_of_properties, property_display_location, property_display_type (carousel, grid or null), and the search form options search_header, search_subheader, search_form_type, search_form_tabs (bool), search_field_defaults, search_image (file URL or null), and featured_agents (see Featured agents).

Some of these only render on some designs (for example property_display_type and search_form_tabs on anna-modern), matching the admin. A site without a home page returns 404 home_page_missing; create it in the admin.

featured_agents is the list of agents shown on the home page as cards with a photo and bio. It is a list of Agent Detail page ids: content pages with "template": "Agent Detail Page", listed by GET /content/pages/?template=Agent Detail Page. They are page ids, not the CRM agent ids from GET /content/agents/.

Send the full list to replace it, and [] (or null) to remove every card. Ids that are not Agent Detail pages, duplicates and non-integers are a 422. The list picks which agents are featured, not their order. The cards render on the anna-modern home page, and on anna in page sidebars when the site has featured agents in the sidebar enabled; other designs ignore the field.

{"featured_agents": [42, 57]}

Each card is built from the Agent Detail page itself; there is nothing to edit on the home page beyond the list. To change what a card shows, PATCH /content/pages/<id>/ on that page:

On the card Comes from
Name (heading) The page’s title (not anchor_text or extra_content.Agent_Name).
Bio text The page’s content, with HTML tags stripped, shown in full.
Photo extra_content.Agent_Photo, a file URL (upload it with Files first). With none set the card has no photo.
“Learn More” link The page’s slug (/<slug>).

The same page is the agent’s profile page and appears on the About page, so one edit updates all three.

From the command line: geekcli home-page get, geekcli home-page update with geekcli (see the geekcli guide).

Page templates

GET/api/v3/content/templates/

The page templates this site can use, with their extra content areas. Accepts any valid key.

{"results": [
  {"name": "About Page",
   "description": "...",
   "extra_content_areas": [
     {"name": "Testimonials",
      "type": "rich_text"}]}]}

From the command line: geekcli templates list with geekcli (see the geekcli guide).

Revisions and undo

GET.../revisions/
GET.../revisions/<rev>/
POST.../revisions/<rev>/revert/

Almost everything the API can change can be undone. Each of these keeps a revision history at its own revisions/ path:

Resource Revisions at
Content pages /content/pages/<id>/revisions/
Agent landing pages /content/agent-pages/<id>/revisions/
Market report pages /content/market-report-pages/<id>/revisions/
Area pages /content/area-pages/<id>/revisions/
Home page /content/home-page/revisions/
Blog posts /blog/posts/<id>/revisions/
Footers /content/footers/<id>/revisions/
Sidebars /content/sidebars/<id>/revisions/
Navigation bars /content/navigation-bars/<id>/revisions/
Featured pages /content/featured-pages/<id>/revisions/
Banners /content/banners/<id>/revisions/
Site settings /settings/revisions/
Design /design/revisions/

A revision covers every field you can write on the resource. On pages that includes slug, parent, title, the meta_* fields, banner, the landscape image and, on agent landing pages, agent_id; on blog posts it includes categories and the comment switches. A sidebar’s revision covers its name and its whole list of items, a navigation bar’s its whole list of links, and a featured pages group’s its title, blurb and tiles, each list with its order.

For content this is the same history as the Versions page in the site admin, so changes made in the admin appear here and can be reverted here, and the other way round. One request is one revision, however much it changes: a PATCH of a sidebar’s name and items, or a PUT of a navigation bar’s links, is undone in one step. Revisions are attributed to the API key that made them.

  • GET .../revisions/ lists revisions newest first: {"id", "at", "by", "action": "created|changed|reverted", "changed_fields", "revertible"}, where by names the person the key belongs to and the key used. Admin edits have api_key: null.
  • GET .../revisions/<rev>/ adds preview: per changed field, the value now and the value a revert would restore. Lists (items, links, tiles) are shown the way the resource shows them, and categories as ids.
  • POST .../revisions/<rev>/revert/ (write scope) undoes that revision and every later one, returning the resource. The revert is itself a revision, so it can be undone the same way. The creation revision cannot be reverted; delete the object instead.

When a revert is refused. A revert answers 409 conflict and changes nothing when the earlier state can no longer be restored: another page now has that URL, the earlier parent has since been moved under the page, another sidebar, banner or featured pages group has taken the name, or (design) the earlier template is no longer offered.

List entries that a revert brings back, such as a deleted sidebar item, navigation link or tile, are new entries with new ids. Entries that still exist keep theirs.

Settings and design. Their revisions come from the site’s settings history. They list only changes to the settings this API exposes, whoever made them: by.api_key is set for changes made through the API, and by.name is the person or tool recorded for the others. The list goes back over the site’s 500 most recent settings saves. Design revisions have changed_fields of template and styles. In a settings preview null means the site had no value of its own, so reverting returns it to the inherited default. A revert is validated like any other settings or design change.

What cannot be undone. Deleting an object: its revisions go with it. Blog categories and the blog home page are recorded in the site’s change log only. Files have their own undo, for 90 days: see Restoring files.

From the command line: geekcli pages revisions /buying/, geekcli posts revision <slug> <rev>, geekcli footers revert 1 <rev> with geekcli (see the geekcli guide). The same three subcommands work on pages, agent pages, area pages, posts, footers and the home page.