{"openapi":"3.0.3","info":{"title":"Quardlyn CRM API","version":"v1"},"servers":[{"url":"/api/v1/crm"}],"paths":{"/api/v1/crm/health":{"get":{"summary":"Read CRM API health"}},"/api/v1/crm/capabilities":{"get":{"summary":"Read CRM API capabilities"}},"/api/v1/crm/version":{"get":{"summary":"Read CRM API version"}},"/api/v1/crm/schema":{"get":{"summary":"Read CRM API schema"}},"/api/v1/crm/openapi":{"get":{"summary":"Read CRM API OpenAPI contract"}},"/api/v1/crm/properties":{"get":{"summary":"List properties visible to this integration"},"post":{"summary":"Create or upsert a CRM property event"}},"/api/v1/crm/properties/lookup":{"get":{"summary":"Lookup a CRM property by source identity"}},"/api/v1/crm/properties/{externalRef}":{"get":{"summary":"Read a CRM property by external reference"},"put":{"summary":"Replace a CRM property payload"},"patch":{"summary":"Update a CRM property payload"},"delete":{"summary":"Delete, withdraw, or inactivate a CRM property"}},"/api/v1/crm/properties/{externalRef}/withdraw":{"post":{"summary":"Withdraw a CRM property"}},"/api/v1/crm/properties/{externalRef}/archive":{"post":{"summary":"Archive a CRM property"}},"/api/v1/crm/properties/{externalRef}/restore":{"post":{"summary":"Restore an archived property"}},"/api/v1/crm/properties/{externalRef}/reactivate":{"post":{"summary":"Reactivate a previously inactive property"}},"/properties":{"get":"List properties","post":"Create property"},"/properties/{external_ref}":{"get":"Get property","put":"Replace/update property","patch":"Partial update property","delete":"Delete/withdraw property"}},"components":{"schemas":{"CrmEventEnvelope":{"required":["event_id","event_type","event_version","occurred_at","property_ref","payload"],"fields":{"event_id":"Stable unique event id from the CRM. Used for idempotency/replay.","event_type":"property.created/property.updated/property.withdrawn/property.deleted/property.archived/property.restored/property.reactivated","event_version":"Envelope version. Use v1.","occurred_at":"ISO-8601 UTC timestamp when the source event occurred.","branch_ref":"Provider branch/office reference when available.","property_ref":"Provider property reference. Also becomes property.external_ref if payload omits it.","sequence":"Monotonically increasing per-property source sequence, preferred for ordering.","source_version":"Alias for sequence when the CRM uses source versions.","source_updated_at":"Fallback ordering timestamp when no sequence is available.","payload":"Canonical CRM property object, not a second custom schema."},"legacy_body":"Existing non-envelope {property:{...}} requests remain accepted, but certified integrations should use the envelope."},"CanonicalProperty":{"schema":"Quardlyn canonical import property model","required_for_ingestion":["external_ref","department","display_address"],"required_for_live_publish":["external_ref","department","postcode","price or price_display"],"field_groups":{"identity_control":["external_ref","department","marketing_status","published","status_id","trans_type_id"],"address_coordinates":["display_address","address_1","address_2","address_3","address_4","town","county","country","postcode","postcode1","postcode2","latitude","longitude","lat","lng"],"property_details":["property_type","property_subtype","beds","baths","receptions","new_home_flag"],"pricing_sale_auction_commercial":["price","price_display","price_qualifier","tenure","tenure_type_id","size_min","size_max","area_size_unit_id","price_per_unit"],"lettings":["rent_frequency","deposit","available_from","let_min_term","let_type_id","let_furn_id","is_student_accommodation","is_house_share","pets_policy","bills_included"],"content_features":["summary","description","features"],"media_documents":["media_image_00..69","image_0..10","image_caption_0..10","media_floorplan_00..19","floorplan","epc_image","epc_pdf","brochure_pdf","media_document_00..19","virtual_tour"],"ownership_future_ready":["source_type","feed_connection_id","external_property_id","managed_mode","last_sync_at","sync_status","sync_error","seen_in_run_id"]}},"ErrorResponse":{"shape":{"success":false,"error":["code","message","details","request_id","support_reference","retryable"]},"codes":["unauthorized","forbidden","not_found","method_not_allowed","validation_failed","duplicate_request","already_processing","rate_limited","payload_too_large","conflict","internal_error"],"safe_messages_only":true,"no_internal_diagnostics":["tokens","passwords","raw signatures","stack traces","SQL","filesystem paths"]}}}}