{"openapi":"3.1.0","info":{"title":"Century 21 Global — Ingestion API","description":"CRM-facing feed ingestion & validation. REAXML is the first inbound adapter into the canonical superset model. Use POST /v1/validate to test a feed without persisting.","version":"0.1.0"},"components":{"schemas":{}},"paths":{"/healthz":{"get":{"summary":"Health check","tags":["system"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"}}}}}}}}},"/v1/validate":{"post":{"summary":"Validate a feed (dry-run, no persistence)","tags":["ingestion"],"description":"Parse → map → validate a feed against the canonical model and return the preview + issues. POST raw XML as application/xml (context via query) or JSON { xml, context, format }. format=reaxml (default) or reso (RESO Web API JSON in the xml field). A currency is required because neither format carries one.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["xml"],"additionalProperties":false,"properties":{"xml":{"type":"string","description":"Raw REAXML <propertyList> document"},"mode":{"type":"string","enum":["full","incremental"],"description":"full = reconcile (archive absent, under circuit breaker); incremental = upsert only"},"format":{"type":"string","enum":["reaxml","reso"],"description":"Inbound feed format (default reaxml)"},"context":{"type":"object","additionalProperties":false,"properties":{"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO-4217 currency for this office/country"},"defaultCountry":{"type":"string","description":"ISO-3166 alpha-2 fallback (default AU)"},"sourceLocale":{"type":"string","description":"Source text locale (default en-AU)"},"sourceOfficeId":{"type":"string","description":"Override office id (else uses <agentID>)"}}}}}}}},"parameters":[{"schema":{"type":"string"},"in":"query","name":"currency","required":false,"description":"ISO-4217 (raw-XML path)"},{"schema":{"type":"string"},"in":"query","name":"country","required":false,"description":"ISO-3166 alpha-2 fallback"},{"schema":{"type":"string"},"in":"query","name":"locale","required":false,"description":"Source text locale"},{"schema":{"type":"string"},"in":"query","name":"officeId","required":false,"description":"Override office id"},{"schema":{"type":"string","enum":["full","incremental"]},"in":"query","name":"mode","required":false,"description":"Raw-XML path mode selector"},{"schema":{"type":"string","enum":["reaxml","reso"]},"in":"query","name":"format","required":false,"description":"Inbound feed format (default reaxml)"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"counts":{"type":"object","properties":{"parsed":{"type":"integer"},"valid":{"type":"integer"},"invalid":{"type":"integer"}}},"issues":{"type":"array","items":{"type":"object","properties":{"level":{"type":"string","enum":["error","warning"]},"code":{"type":"string"},"message":{"type":"string"},"listingIndex":{"type":"integer"},"uniqueId":{"type":"string"},"path":{"type":"string"}}}},"listings":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/feeds":{"post":{"summary":"Ingest a REAXML feed (validate + persist)","tags":["ingestion"],"description":"Validate a feed and upsert every valid listing into the system of record. Returns per-listing actions (inserted/updated/unchanged/stale_ignored). Newest-wins on modTime with a content-hash no-op. mode=full also reconciles (archives absent listings) under the mass-delete circuit breaker. Requires the feed key (Authorization: Bearer <key> or x-feed-token) and a configured database (else 503).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["xml"],"additionalProperties":false,"properties":{"xml":{"type":"string","description":"Raw REAXML <propertyList> document"},"mode":{"type":"string","enum":["full","incremental"],"description":"full = reconcile (archive absent, under circuit breaker); incremental = upsert only"},"format":{"type":"string","enum":["reaxml","reso"],"description":"Inbound feed format (default reaxml)"},"context":{"type":"object","additionalProperties":false,"properties":{"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO-4217 currency for this office/country"},"defaultCountry":{"type":"string","description":"ISO-3166 alpha-2 fallback (default AU)"},"sourceLocale":{"type":"string","description":"Source text locale (default en-AU)"},"sourceOfficeId":{"type":"string","description":"Override office id (else uses <agentID>)"}}}}}}}},"parameters":[{"schema":{"type":"string"},"in":"query","name":"currency","required":false,"description":"ISO-4217 (raw-XML path)"},{"schema":{"type":"string"},"in":"query","name":"country","required":false,"description":"ISO-3166 alpha-2 fallback"},{"schema":{"type":"string"},"in":"query","name":"locale","required":false,"description":"Source text locale"},{"schema":{"type":"string"},"in":"query","name":"officeId","required":false,"description":"Override office id"},{"schema":{"type":"string","enum":["full","incremental"]},"in":"query","name":"mode","required":false,"description":"Raw-XML path mode selector"},{"schema":{"type":"string","enum":["reaxml","reso"]},"in":"query","name":"format","required":false,"description":"Inbound feed format (default reaxml)"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"counts":{"type":"object","properties":{"parsed":{"type":"integer"},"valid":{"type":"integer"},"invalid":{"type":"integer"}}},"summary":{"type":"object","description":"Upsert action tally","properties":{"inserted":{"type":"integer"},"updated":{"type":"integer"},"unchanged":{"type":"integer"},"stale_ignored":{"type":"integer"}}},"upserts":{"type":"array","items":{"type":"object","properties":{"listingKey":{"type":"string"},"action":{"type":"string","enum":["inserted","updated","unchanged","stale_ignored"]}}}},"reconcile":{"type":"object","additionalProperties":true},"issues":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/listings":{"get":{"summary":"Search published listings","tags":["listings"],"description":"Filter the catalog by country, category, sale mode, price and bedrooms. Returns published, non-deleted listings ordered by recency. (Search moves to OpenSearch at scale.)","parameters":[{"schema":{"type":"string"},"in":"query","name":"country","required":false,"description":"ISO-3166 alpha-2"},{"schema":{"type":"string"},"in":"query","name":"office","required":false,"description":"Filter to a single office (source office id)"},{"schema":{"type":"string"},"in":"query","name":"category","required":false},{"schema":{"type":"string","enum":["sale","rent","both"]},"in":"query","name":"saleMode","required":false},{"schema":{"type":"number"},"in":"query","name":"minPrice","required":false},{"schema":{"type":"number"},"in":"query","name":"maxPrice","required":false},{"schema":{"type":"number"},"in":"query","name":"minBedrooms","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":24},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"listings":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/listings/{office}/{uniqueId}":{"get":{"summary":"Fetch a single canonical listing","tags":["listings"],"description":"Returns the canonical record AS THE PLATFORM STORES IT (identity is composite: office + uniqueID).","parameters":[{"schema":{"type":"string"},"in":"path","name":"office","required":true},{"schema":{"type":"string"},"in":"path","name":"uniqueId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/agents":{"get":{"summary":"Agent directory","tags":["directory"],"description":"Distinct agents with their office, contact and active-listing count. Filter by country/name.","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"in":"query","name":"country","required":false,"description":"ISO-3166 alpha-2"},{"schema":{"type":"string","maxLength":200},"in":"query","name":"office","required":false,"description":"Exact office (source office id)"},{"schema":{"type":"string","maxLength":120},"in":"query","name":"query","required":false,"description":"Free-text filter (name / locality)"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":60},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"agents":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/offices":{"get":{"summary":"Office finder","tags":["directory"],"description":"Distinct offices with their localities, listing count and a representative location. Filter by country/name.","parameters":[{"schema":{"type":"string","pattern":"^[A-Za-z]{2}$"},"in":"query","name":"country","required":false,"description":"ISO-3166 alpha-2"},{"schema":{"type":"string","maxLength":200},"in":"query","name":"office","required":false,"description":"Exact office (source office id)"},{"schema":{"type":"string","maxLength":120},"in":"query","name":"query","required":false,"description":"Free-text filter (name / locality)"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":60},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0,"default":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"offices":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/countries":{"get":{"summary":"Countries with listings","tags":["directory"],"description":"Distinct countries that have published listings, most active first. Powers country filters.","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"countries":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"listingCount":{"type":"integer"}}}}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/fx":{"get":{"summary":"Current FX rates","tags":["system"],"description":"Rates relative to the base currency, for converting prices at render. A static snapshot in dev; production serves cached live rates (ECB + backup).","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"base":{"type":"string"},"asOf":{"type":"string"},"rates":{"type":"object","additionalProperties":{"type":"number"}}}}}}}}}},"/v1/leads":{"post":{"summary":"Submit a consumer enquiry","tags":["leads"],"description":"Verifies (honeypot + Turnstile + consent), persists the lead, resolves the recipient via the agent→office→dead-letter cascade, and returns 202. Requires a configured database.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["listing","contact","consent"],"properties":{"listing":{"type":"object","required":["office","uniqueId"],"properties":{"office":{"type":"string"},"uniqueId":{"type":"string"}}},"contact":{"type":"object","required":["email","message"],"properties":{"name":{"type":"string","maxLength":120},"email":{"type":"string","maxLength":254},"phone":{"type":"string","maxLength":40},"message":{"type":"string","maxLength":2000}}},"consent":{"type":"boolean","description":"Consumer consent to share details with the office"},"turnstileToken":{"type":"string"},"website":{"type":"string","description":"Honeypot — leave empty"}}}}}},"responses":{"202":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/admin/blocklist":{"get":{"summary":"List blocked enquiry senders","tags":["admin"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"summary":"Block an email or domain","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kind","value"],"properties":{"kind":{"type":"string","enum":["email","domain"]},"value":{"type":"string","minLength":3,"maxLength":254},"reason":{"type":"string","maxLength":200},"force":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"summary":"Unblock a row by id, or an email/domain by value","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","maxLength":64},"kind":{"type":"string","enum":["email","domain"]},"value":{"type":"string","maxLength":254}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/stats":{"get":{"summary":"Dashboard stats: listings, directory, leads, quarantine, blocklist","tags":["admin"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/leads":{"get":{"summary":"List enquiries (newest first), filterable by status or dead_letter","tags":["admin"],"parameters":[{"schema":{"type":"string","enum":["pending","delivered","failed","purged","dead_letter"]},"in":"query","name":"status","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/leads/{id}/retry":{"post":{"summary":"Re-queue a failed lead for delivery","tags":["admin"],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/quarantine":{"get":{"summary":"List quarantined ingest events (circuit-breaker trips) awaiting review","tags":["admin"],"parameters":[{"schema":{"type":"boolean"},"in":"query","name":"includeResolved","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/quarantine/{id}/resolve":{"post":{"summary":"Mark a quarantine item reviewed","tags":["admin"],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/listings":{"get":{"summary":"Browse all listings (including hidden/unpublished) for moderation","tags":["admin"],"parameters":[{"schema":{"type":"string","maxLength":100},"in":"query","name":"q","required":false},{"schema":{"type":"boolean"},"in":"query","name":"hidden","required":false},{"schema":{"type":"integer","minimum":1,"maximum":200},"in":"query","name":"limit","required":false},{"schema":{"type":"integer","minimum":0},"in":"query","name":"offset","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/listings/visibility":{"post":{"summary":"Hide or show a listing (operator override; survives re-ingest)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["officeId","uniqueId","hidden"],"properties":{"officeId":{"type":"string","minLength":1,"maxLength":100},"uniqueId":{"type":"string","minLength":1,"maxLength":100},"hidden":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/site":{"get":{"summary":"Site chrome: settings, navigation, published pages","tags":["site"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/site/pages/{slug}":{"get":{"summary":"A published site page by slug","tags":["site"],"parameters":[{"schema":{"type":"string","maxLength":80},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/site/settings":{"put":{"summary":"Set a site setting (identity | seo | favicon)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key","value"],"properties":{"key":{"type":"string","enum":["identity","seo","favicon"]},"value":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/site/nav":{"put":{"summary":"Replace the site navigation (empty list restores the default nav)","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["links"],"properties":{"links":{"type":"array","maxItems":20,"items":{"type":"object","required":["kind","ref"],"properties":{"kind":{"type":"string","enum":["builtin","page","custom"]},"ref":{"type":"string","minLength":1,"maxLength":500},"label":{"type":"object","additionalProperties":{"type":"string","maxLength":20000},"nullable":true},"visible":{"type":"boolean"},"newTab":{"type":"boolean"}}}}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/site/pages":{"get":{"summary":"List all pages (drafts included)","tags":["admin"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"post":{"summary":"Create a page","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug","title","body"],"properties":{"slug":{"type":"string","maxLength":80},"title":{"type":"object","additionalProperties":{"type":"string","maxLength":20000}},"body":{"type":"object","additionalProperties":{"type":"string","maxLength":20000}},"description":{"type":"object","additionalProperties":{"type":"string","maxLength":20000},"nullable":true},"published":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/site/pages/{slug}":{"get":{"summary":"A page by slug, draft or published","tags":["admin"],"parameters":[{"schema":{"type":"string","maxLength":80},"in":"path","name":"slug","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/admin/site/pages/id/{id}":{"put":{"summary":"Update a page","tags":["admin"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","maxLength":80},"title":{"type":"object","additionalProperties":{"type":"string","maxLength":20000}},"body":{"type":"object","additionalProperties":{"type":"string","maxLength":20000}},"description":{"type":"object","additionalProperties":{"type":"string","maxLength":20000},"nullable":true},"published":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}},"delete":{"summary":"Delete a page","tags":["admin"],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"in":"path","name":"id","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"503":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}}},"tags":[{"name":"ingestion","description":"CRM feed ingestion & validation"},{"name":"listings","description":"Public listing search & detail"},{"name":"directory","description":"Agent & office directory (derived from listings)"},{"name":"leads","description":"Consumer enquiry intake & routing"},{"name":"admin","description":"Admin: operator console (blocklist, leads, moderation, site content)"},{"name":"site","description":"Site chrome: settings, navigation, operator pages"},{"name":"system","description":"Service health & metadata"}]}