### API Query Examples Source: https://docs.datadistributionqc.centris.ca/getting-started A collection of example API queries demonstrating efficient data retrieval using $select for specific fields and $expand for nested resources. These queries are designed to optimize request performance. ```http /Lookup?$expand=Translations /StateRegion?$expand=Translations /CityOrTownship?$expand=Neighborhoods(expand=Translations) /Office?$expand=OtherPhones,OfficeSocialMedia,Media,Translations /Member?$expand=MemberOtherPhone,MemberSocialMedia,Media,Translations /Property?$expand=ListAgentOffices,Translations /Property?$select=ListingKey,ModificationTimestamp&$expand=Media /Property?$select=ListingKey,ModificationTimestamp&$expand=Rooms(expand=Translations) /Property?$select=ListingKey,ModificationTimestamp&$expand=Units(expand=Translations) ``` -------------------------------- ### Authentication using API Key Source: https://docs.datadistributionqc.centris.ca/getting-started Provides instructions and an example for authenticating API requests using an API key. ```APIDOC ## Authentication using API Key ### Description Centris Data Distribution API uses an API Key for authentication. The API key should be provided in the `Authorization` header of each request. ### Method GET (Example for metadata endpoint) ### Endpoint `https://datadistributionqc.centris.ca/v1/odata/$metadata` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ``` GET https://datadistributionqc.centris.ca/v1/odata/$metadata Authorization: Bearer your_api_key ``` ### Response #### Success Response (200) - **metadata** (object) - API metadata details. #### Response Example (Response will vary based on the endpoint and success of the request) ```json { "@odata.context": "https://datadistributionqc.centris.ca/v1/odata/$metadata" } ``` ``` -------------------------------- ### OData Querying Source: https://docs.datadistributionqc.centris.ca/getting-started Guidance on querying the API using the OData protocol, including supported operators and example queries. ```APIDOC ## Querying the API with OData ### Description The API follows the OData (Open Data Protocol) specification for interacting with REST APIs. OData is used as the query language to facilitate data exchange and reduce system friction. Libraries are available for various programming languages to simplify integration. ### OData Query Example ``` /Property?$select=ListingKey,ListPrice&$filter=StandardStatus eq 'Active'&$orderby=ModificationTimestamp&$count=true ``` This query retrieves the `ListingKey` and `ListPrice` for active listings, ordered by `ModificationTimestamp`, and includes the total count of results. ### Response Example ```json { "@odata.count": 133, "value": [ { "ListPrice": 123412.00, "ListingKey": "14689588" }, { "ListPrice": 567632.00, "ListingKey": "14239483" }, { "ListPrice": 890221.00, "ListingKey": "23659600" } ] } ``` ### Supported OData Operators | Operator | Description | |------------|--------------------------------------------| | $select | Defines the fields to project. | | $filter | Defines the filter to apply. | | $orderby | Defines the order to apply. | | $count | Defines whether to include the total count. | | $expand | Defines relational navigations to include. | | $skip | Defines the number of records to skip. | | $top | Defines the number of records to return. | ``` -------------------------------- ### OData API Query Example Source: https://docs.datadistributionqc.centris.ca/getting-started This example demonstrates an OData query to the API. It selects specific fields ('ListingKey', 'ListPrice'), filters for 'Active' listings, orders by 'ModificationTimestamp', and requests the total count of matching records. ```odata /Property?$select=ListingKey,ListPrice&$filter=StandardStatus eq 'Active'&$orderby=ModificationTimestamp&$count=true ``` -------------------------------- ### Nested Translations Expansion Example Source: https://docs.datadistributionqc.centris.ca/getting-started Demonstrates how to retrieve translations for nested resources by chaining expansion parameters. For instance, fetching translations for both 'Property' and its nested 'Expenses' resource. ```http Property?$expand=Translations,Expenses(expand=Translations) ``` -------------------------------- ### Building Efficient Queries Source: https://docs.datadistributionqc.centris.ca/getting-started Recommendations for constructing optimized API requests using `$select` and `$expand` operators to improve performance and reduce data transfer. ```APIDOC ## Building Efficient Queries ### Description Strategies to optimize API requests by selecting specific fields with `$select` and retrieving related resources with `$expand`, leading to faster responses. ### Query Operators - **`$select`**: Retrieve only the necessary fields to minimize payload size. * **Prefer**: `/Member?$select=MemberKey,ModificationTimestamp,MemberFirstName,MemberLastName` * **Over**: `/Member` - **`$expand`**: Fetch nested resources in a single request instead of making separate calls. * **Prefer**: `/Property?$expand=Rooms` * **Over**: `/PropertyRooms` ### Handling Large Responses - **Split Requests**: If a request returns a large dataset or times out, break it down into smaller, more manageable requests. * **Prefer**: `/Property?$expand=Translations,Media` and `/Property?$select=ListingKey,ModificationTimestamp&$expand=Rooms,Expenses,Equipment` * **Over**: `/Property?$expand=Translations,Media,Rooms,Expenses,Equipment` ### Example Queries ``` /Lookup?$expand=Translations /StateRegion?$expand=Translations /CityOrTownship?$expand=Neighborhoods(expand=Translations) /Office?$expand=OtherPhones,OfficeSocialMedia,Media,Translations /Member?$expand=MemberOtherPhone,MemberSocialMedia,Media,Translations /Property?$expand=ListAgentOffices,Translations /Property?$select=ListingKey,ModificationTimestamp&$expand=Media /Property?$select=ListingKey,ModificationTimestamp&$expand=Rooms(expand=Translations) /Property?$select=ListingKey,ModificationTimestamp&$expand=Units(expand=Translations) ``` ``` -------------------------------- ### Client-Side Pagination Example Source: https://docs.datadistributionqc.centris.ca/getting-started Illustrates client-side pagination strategy using OData operators like '$filter', '$top', and '$orderby'. This method requires manually providing the last value from a previous response to the '$filter' operator to fetch subsequent data. ```http /Property?$filter=ModificationTimestamp gt 2024-02-05T17:03:58Z ``` -------------------------------- ### Replicating Resources Incrementally Source: https://docs.datadistributionqc.centris.ca/getting-started A strategy for periodically updating your system with the latest data by using modification timestamps and handling pagination. ```APIDOC ## Replicating Resources Incrementally ### Description This strategy outlines how to periodically fetch the latest data changes to keep your system synchronized, using modification timestamps and handling paginated responses. ### Process Overview 1. **Determine Latest Timestamp**: Retrieve the most recent `ModificationTimestamp` from your local data store for the resource you are replicating. 2. **Initial/Incremental Fetch**: Make a GET request to the resource endpoint, filtering for records with a `ModificationTimestamp` greater than your stored timestamp. If it's the initial replication, omit the filter. 3. **Update Timestamp**: After receiving a successful response, extract the latest `ModificationTimestamp` from the returned data. 4. **Persist Timestamp**: Update your stored `ModificationTimestamp` for that resource with the latest one found. 5. **Handle Pagination**: Use the `@odata.nextLink` provided in the response to fetch subsequent pages of data, repeating steps 3-5 until no `@odata.nextLink` is returned. ### Code Example (Conceptual C#) ```csharp // Retrieve the most recent modification timestamp of the given resource from your system (e.g. 2024-10-03T07:17:43Z). // This can be inferred from your replicated resources but we suggest persisting a snapshot somewhere else in case you need to start over the replication. var mostRecentModificationTimestamp = GetLookupMostRecentModificationTimestamp(); // Start with an initial request based on the most recent modification timestamp. // If this is your initial replication (i.e. you don't have a modification timestamp), simply don't provide it and you will start from the beginning. var response = await httpClient.GetAsync($"https://datadistributionqc.centris.ca/v1/odata/Lookup?$filter=ModificationTimestamp gt {mostRecentModificationTimestamp}"); mostRecentModificationTimetamp = GetMostRecentModificationTimestampFromResponse(response); // If you use a snapshot to keep track of your timestamps, update it. // The important thing here is to use the most recent timestamp of the resource, not the current UTC timestamp. UpdateLookupMostRecentModificationTimestamp(mostRecentModificationTimestamp); // Then use the next link (@odata.nextLink) provided in the previous response for your next request. var nextLink = GetNextLinkFromResponse(response); // Repeat until the next link is no longer returned. while (!string.IsNullOrEmpty(nextLink)) { response = await httpClient.GetAsync(nextLink); mostRecentModificationTimetamp = GetMostRecentModificationTimestampFromResponse(response); UpdateLookupMostRecentModificationTimestamp(mostRecentModificationTimestamp); nextLink = GetNextLinkFromResponse(response); } ``` ### Key Recommendations - **Initial Replication**: The first replication will take longer; subsequent replications will be faster incremental updates. - **Timestamp Management**: Maintain separate modification timestamps for each resource type (e.g., `Lookup`, `Member`, `Property`). - **Error Handling**: Do not restart from the beginning upon encountering errors (like 429 Too Many Requests or server errors). Always resume from the last known successful `ModificationTimestamp`. ``` -------------------------------- ### Authentication using OpenID Connect Source: https://docs.datadistributionqc.centris.ca/getting-started Details on how to obtain an access token using OpenID Connect (Client Credentials flow) and use it for API authentication. ```APIDOC ## Authentication using OpenID Connect ### Description This section outlines the process for authenticating with the Centris Data Distribution API using OpenID Connect (OIDC). It involves obtaining an access token via the Client Credentials flow and including it in the `Authorization` header. ### Method POST (for token endpoint), GET (for data endpoint) ### Endpoint Token Endpoint: `https://accounts.centris.ca/connect/token` API Endpoint Example: `https://datadistributionqc.centris.ca/v1/odata/$metadata` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body (Token Endpoint) - **grant_type** (string) - Required - Set to `client_credentials`. - **client_id** (string) - Required - Your application's client ID. - **client_secret** (string) - Required - Your application's client secret. ### Request Example (Token Endpoint) ``` POST https://accounts.centris.ca/connect/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&client_id=your_client_id&client_secret=your_client_secret ``` ### Response (Token Endpoint) #### Success Response (200) - **access_token** (string) - The JWT access token. - **expires_in** (integer) - The lifetime of the access token in seconds. - **token_type** (string) - The type of token, usually "Bearer". #### Response Example (Token Endpoint) ```json { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…", "expires_in": 3600, "token_type": "Bearer" } ``` ### Request Example (API Request with Access Token) ``` GET https://datadistributionqc.centris.ca/v1/odata/$metadata Authorization: Bearer your_access_token ``` ### Response (API Request) #### Success Response (200) - **data** (object) - The requested data from the API. #### Response Example (API Request) (Response will vary based on the endpoint and success of the request) ```json { "@odata.context": "https://datadistributionqc.centris.ca/v1/odata/$metadata" } ``` ``` -------------------------------- ### Webhook Payload Example Source: https://docs.datadistributionqc.centris.ca/getting-started This is an example of the JSON payload received when a record is updated via webhook. It includes resource name, key, and URL. ```json { "ResourceName": "Property", "ResourceRecordKey": "18634444", "ResourceRecordUrl": "https://datadistributionqc.centris.ca/v1/odata/Property('18634444')" } ``` -------------------------------- ### OpenHouse (Visites Libres) Resource Source: https://docs.datadistributionqc.centris.ca/migration-guide/siiq-listing This section details the mapping for the OpenHouse resource, accessible via Property.OpenHouse. It outlines the transformation of 'Before' fields to 'After' fields, along with their corresponding 'Comments'. ```APIDOC ## OpenHouse (Visites Libres) Resource ### Description This resource provides information about open houses for properties. It maps legacy fields to the new structure under `Property.OpenHouse`. ### Method GET ### Endpoint /websites/datadistributionqc_centris_ca/openhouse ### Parameters #### Query Parameters - **ListingKey** (string) - Required - The unique identifier for the listing. - **OpenHouseStartTime** (datetime) - Required - The start date and time of the open house. - **OpenHouseEndTime** (datetime) - Required - The end date and time of the open house. - **OpenHouseRemarks** (string) - Optional - Remarks or comments about the open house. - **OpenHouseType** (string) - Optional - The type of open house (e.g., 'Visite Libre', 'Caravan Tour'). - **LivestreamOpenHouseURL** (string) - Optional - URL for a livestream open house. ### Request Example ```json { "ListingKey": "A1234567", "OpenHouseStartTime": "2023-10-27T14:00:00Z", "OpenHouseEndTime": "2023-10-27T17:00:00Z", "OpenHouseRemarks": "Popular area, expect crowds.", "OpenHouseType": "Visite Libre", "LivestreamOpenHouseURL": "https://example.com/livestream" } ``` ### Response #### Success Response (200) - **OpenHouse** (array) - An array of open house objects. - **ListingKey** (string) - The unique identifier for the listing. - **OpenHouseStartTime** (datetime) - The start date and time of the open house. - **OpenHouseEndTime** (datetime) - The end date and time of the open house. - **OpenHouseRemarks** (string) - Remarks or comments about the open house. - **OpenHouseType** (string) - The type of open house. - **LivestreamOpenHouseURL** (string) - URL for a livestream open house. #### Response Example ```json { "OpenHouse": [ { "ListingKey": "A1234567", "OpenHouseStartTime": "2023-10-27T14:00:00Z", "OpenHouseEndTime": "2023-10-27T17:00:00Z", "OpenHouseRemarks": "Popular area, expect crowds.", "OpenHouseType": "Visite Libre", "LivestreamOpenHouseURL": "https://example.com/livestream" } ] } ``` ``` -------------------------------- ### Webhooks Usage Source: https://docs.datadistributionqc.centris.ca/faq Provides guidance on whether to use webhooks for resource replication and the implications of their use. ```APIDOC ## Webhooks Usage ### Description This section discusses the use of webhooks as an optional replication process for receiving resource updates promptly. It highlights potential issues and recommends a best practice for implementation. ### Method N/A (Informational) ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A **Key Points:** - Webhooks provide quick updates but are less resilient than pulling and reconciling. - Potential issues include errors in receiving endpoints or delays due to high notification volume, which can lead to temporary interruptions. - **Recommendation:** Always implement pulling and reconciling, and optionally supplement it with webhooks. ``` -------------------------------- ### PropertyEquipment Resource Source: https://docs.datadistributionqc.centris.ca/resources/PropertyEquipment Provides information about equipment included with a property. ```APIDOC ## PropertyEquipment Resource ### Description The resource PropertyEquipment provides a list of equipment included with the property, such as generators, conveyors, milk tanks, etc. This is generally used for farms. > This resource or some of its fields may not be available depending on your configuration. > This resource supports translations. ### Fields - **EquipmentBrand** (string) - The brand of the equipment. - **EquipmentCount** (integer) - The number of equipment items. - **EquipmentKey** (string) - The unique identifier assigned to each record in the system. - **EquipmentType** (string) - The type of equipment. See also EquipmentType. - **EquipmentTypeOther** (string) - The other type of equipment if not listed. - **EquipmentYear** (integer) - The year the equipment was manufactured or installed. - **ListingId** (string) - The ListingId of the related listing. - **ListingKey** (string) - The unique identifier for the listing. - **ModificationTimestamp** (datetime) - The date and time when the record was last modified. - **Order** (integer) - The order or sequence of the equipment entry. - **Listing** (object) - The listing this relates to. This is a navigation field to Property. - **Translations** (array) - The translations of the resource. This is a navigation field to Translation. ``` -------------------------------- ### Media (Additional Links) Resource Source: https://docs.datadistributionqc.centris.ca/migration-guide/siiq-listing This section details the mapping for the Media resource with MediaCategory set to 'Branded Virtual Tour', accessible via Property.Media. It outlines the transformation of 'Before' fields to 'After' fields. ```APIDOC ## Media (Additional Links) Resource ### Description This resource represents additional media links for a property, such as branded virtual tours. It maps legacy fields to the new structure under `Property.Media` where `MediaCategory` is 'Branded Virtual Tour'. ### Method GET ### Endpoint /websites/datadistributionqc_centris_ca/media/branded-virtual-tour ### Parameters #### Query Parameters - **ResourceRecordKey** (string) - Required - The unique identifier for the property resource. - **Order** (integer) - Required - The order in which the media should be displayed. - **VirtualTourType** (string) - Required - The type of virtual tour. - **MediaURL** (string) - Required - The URL of the media. ### Request Example ```json { "ResourceRecordKey": "A1234567", "Order": 1, "VirtualTourType": "3D Tour", "MediaURL": "https://example.com/virtualtour" } ``` ### Response #### Success Response (200) - **Media** (array) - An array of media objects. - **ResourceRecordKey** (string) - The unique identifier for the property resource. - **Order** (integer) - The order in which the media should be displayed. - **VirtualTourType** (string) - The type of virtual tour. - **MediaURL** (string) - The URL of the media. #### Response Example ```json { "Media": [ { "ResourceRecordKey": "A1234567", "Order": 1, "VirtualTourType": "3D Tour", "MediaURL": "https://example.com/virtualtour" } ] } ``` ``` -------------------------------- ### OData API Response Example (JSON) Source: https://docs.datadistributionqc.centris.ca/getting-started This JSON structure is an example response to an OData query. It includes the total count of matching records in the '@odata.count' field and an array 'value' containing the requested data objects, each with 'ListPrice' and 'ListingKey'. ```json { "@odata.count": 133, "value": [ { "ListPrice": 123412.00, "ListingKey": "14689588" }, { "ListPrice": 567632.00, "ListingKey": "14239483" }, { "ListPrice": 890221.00, "ListingKey": "23659600" } ] } ``` -------------------------------- ### Data Replication Source: https://docs.datadistributionqc.centris.ca/getting-started The API is designed to allow other systems to replicate MLS data. This involves strategies for initial system setup and ongoing synchronization to keep data up-to-date. ```APIDOC ## Data Replication ### Description The primary objective of the API is to allow other systems to replicate MLS data. This involves two main phases: initial system setup and keeping the system up-to-date. ### Initializing Your System * **Purpose:** To populate your system with MLS data when it contains no existing data. * **Method:** Request resources starting from an empty state and paginate through the results using `nextLink`. * **Example Endpoint (for Property resource):** `/Property` ### Keeping Your System Up-to-Date There are two strategies for maintaining data synchronization: 1. **Getting the latest changes by continuously pulling:** * **Method:** GET * **Endpoint:** Resource endpoint (e.g., `/Property`) * **Query Parameters:** `$filter=ModificationTimestamp gt [timestamp]` * **Description:** Requests records updated after a specific timestamp. Track the last `ModificationTimestamp` of resources to determine the filter value. * **Example Request:** `/Property?$filter=ModificationTimestamp gt 2024-02-05T17:03:58Z` 2. **Reconciling Your System:** * **Method:** GET * **Endpoint:** Resource endpoint (e.g., `/Property`) * **Query Parameters:** `$select=ListingKey,ModificationTimestamp` * **Description:** Compares the list of resource keys and modification timestamps between your system and the API to ensure data integrity. This process helps identify and rectify records that should be deleted, created, or updated. * **Example Request:** `/Property?$select=ListingKey,ModificationTimestamp` ### Important Considerations for Replication: * Records can be removed from the API due to expirations, off-market status, or inactive agents/offices. * Records can be added to the API if agents or offices decide to share their data. * Reconciliation is crucial for ensuring data integrity. ``` -------------------------------- ### Office Resource Migration Source: https://docs.datadistributionqc.centris.ca/migration-guide/siiq-office-member Details the mapping changes for Office and Firmes (Offices) data. ```APIDOC ## Office (Bureaux) ### Description This section details the mapping from the 'Before' fields to the 'After' fields for Office data. ### Method N/A (This is a documentation of data mapping changes) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ## Office (Firmes) ### Description This section details the mapping from the 'Before' fields to the 'After' fields for Firmes (Offices) data. ### Method N/A (This is a documentation of data mapping changes) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Reconciling Resources Source: https://docs.datadistributionqc.centris.ca/getting-started This section explains how to periodically compare keys and timestamps between your system and the API to ensure data consistency. It provides an example implementation for reconciling lookup resources. ```APIDOC ## GET /v1/odata/Lookup ### Description Fetches lookup resources with specified fields to facilitate reconciliation with your system. This endpoint is designed to be paginated using `@odata.nextLink`. ### Method GET ### Endpoint https://datadistributionqc.centris.ca/v1/odata/Lookup ### Parameters #### Query Parameters - **$select** (string) - Required - Comma-separated list of fields to include in the response. Using only `LookupKey` and `ModificationTimestamp` maximizes the page size to 1,000 records. Including additional fields reduces the page size to 100 records. - **$filter** (string) - Optional - Filters the results. Can be used with the `in` operator to specify a list of `LookupKey` values for reconciliation. ### Request Example ```json { "example": "GET https://datadistributionqc.centris.ca/v1/odata/Lookup?$select=LookupKey,ModificationTimestamp" } ``` ### Response #### Success Response (200) - **LookupKey** (string) - The unique identifier for the lookup resource. - **ModificationTimestamp** (string) - The timestamp indicating when the resource was last modified. - **@odata.nextLink** (string) - A URL to the next page of results, if available. #### Response Example ```json { "example": "{\n \"@odata.context\": \"https://datadistributionqc.centris.ca/v1/odata/$metadata#Lookup(LookupKey,ModificationTimestamp)\",\n \"value\": [\n {\n \"LookupKey\": \"AccessibilityFeatures.Visitable\",\n \"ModificationTimestamp\": \"2023-10-27T10:00:00Z\"\n }\n // ... more records ...\n ],\n \"@odata.nextLink\": \"https://datadistributionqc.centris.ca/v1/odata/Lookup?$select=LookupKey,ModificationTimestamp&$skip=1000\"\n}" } ``` ### Reconciliation Logic 1. **Initial Fetch**: Fetch resources using `$select=LookupKey,ModificationTimestamp` to get an initial set of records and the `@odata.nextLink`. 2. **Paginate**: Repeatedly use the `@odata.nextLink` to fetch all available records until no further links are provided. 3. **Compare**: Compare the fetched `LookupKey` and `ModificationTimestamp` pairs with your system's data: - **Missing in your system**: Records present in the API but not your system need to be added. - **Missing in API**: Records in your system but not in the API should be removed or flagged as obsolete. - **Timestamp Mismatch**: Records with the same `LookupKey` but different `ModificationTimestamp` require an update in your system. - **Timestamps Match**: Records with matching `LookupKey` and `ModificationTimestamp` are synchronized. 4. **Delta Fetch (if needed)**: If specific records need to be retrieved (e.g., for updates), use the `$filter=LookupKey in ('key1', 'key2', ...)`. **Note**: For large datasets, chunk the `LookupKey` values when using the `in` operator due to potential query string length limitations. ``` -------------------------------- ### Media (Photos) Resource Source: https://docs.datadistributionqc.centris.ca/migration-guide/siiq-listing This section details the mapping for the Media resource with MediaCategory set to 'Photo', accessible via Property.Media. It outlines the transformation of 'Before' fields to 'After' fields, including image descriptions and URLs. ```APIDOC ## Media (Photos) Resource ### Description This resource represents photos for a property, accessible via `Property.Media` where `MediaCategory` is 'Photo'. It maps legacy fields to the new structure, including image descriptions and URLs. ### Method GET ### Endpoint /websites/datadistributionqc_centris_ca/media/photos ### Parameters #### Query Parameters - **ResourceRecordKey** (string) - Required - The unique identifier for the property resource. - **Order** (integer) - Required - The order in which the photos should be displayed. - **ImageOf** (string) - Optional - A description of what the image depicts. - **ShortDescription** (string) - Optional - A short description of the photo (localized). - **MediaURL** (string) - Required - The URL of the photo. - **SourceSystemResourceVersion** (string) - Optional - The version of the photo in the source system. - **ModificationTimestamp** (datetime) - Optional - The timestamp when the photo was last modified (UTC). ### Request Example ```json { "ResourceRecordKey": "A1234567", "Order": 1, "ImageOf": "Exterior View", "ShortDescription": "Beautiful front view of the house.", "MediaURL": "https://example.com/photos/image1.jpg", "SourceSystemResourceVersion": "v1.2", "ModificationTimestamp": "2023-10-26T10:00:00Z" } ``` ### Response #### Success Response (200) - **Media** (array) - An array of photo objects. - **ResourceRecordKey** (string) - The unique identifier for the property resource. - **Order** (integer) - The order in which the photos should be displayed. - **ImageOf** (string) - A description of what the image depicts. - **ShortDescription** (string) - A short description of the photo (localized). - **MediaURL** (string) - The URL of the photo. - **SourceSystemResourceVersion** (string) - The version of the photo in the source system. - **ModificationTimestamp** (datetime) - The timestamp when the photo was last modified (UTC). #### Response Example ```json { "Media": [ { "ResourceRecordKey": "A1234567", "Order": 1, "ImageOf": "Exterior View", "ShortDescription": "Beautiful front view of the house.", "MediaURL": "https://example.com/photos/image1.jpg", "SourceSystemResourceVersion": "v1.2", "ModificationTimestamp": "2023-10-26T10:00:00Z" } ] } ``` ``` -------------------------------- ### Example MLS Data Response with Translations Source: https://docs.datadistributionqc.centris.ca/getting-started Illustrates the JSON structure of an MLS resource response, including a 'Translations' array. This array contains locale-specific values for fields like 'MemberIntroduction' and 'MemberCorporationType'. ```json { "MemberKey": "1234", "MemberStatus": "Active", "MemberIntroduction": "My introduction in English", "MemberCorporationType": "My corporation type", "Translations": [ { "Locale": "fr", "Values": [ { "FieldName": "MemberIntroduction", "Value": "Mon introduction en Français" }, { "FieldName": "MemberCorporationType", "Value": "Mon type de corporation" } ] }, { "Locale": "en", "Values": [ { "FieldName": "MemberIntroduction", "Value": "My introduction in English" }, { "FieldName": "MemberCorporationType", "Value": "My corporation type" } ] } ] } ``` -------------------------------- ### OpenHouse Resource API Source: https://docs.datadistributionqc.centris.ca/resources/OpenHouse Provides details about open house events for properties. This resource may have field availability dependent on configuration and supports translations. ```APIDOC ## OpenHouse Resource ### Description The OpenHouse resource provides scheduling and descriptive information about open house events for properties. This resource or some of its fields may not be available depending on your configuration. This resource supports translations. ### Method GET ### Endpoint `/websites/datadistributionqc_centris_ca/OpenHouse` ### Parameters #### Query Parameters - **ListingId** (integer) - Optional - The ListingId of the related listing. - **ListingKey** (string) - Optional - The unique identifier for the listing. - **LivestreamOpenHouseURL** (string) - Optional - A link to an open house livestream event. - **ModificationTimestamp** (string) - Optional - The date and time when the record was last modified. - **OpenHouseDate** (string) - Optional - The date on which the open house will occur. - **OpenHouseEndTime** (string) - Optional - The time the open house ends. - **OpenHouseKey** (string) - Optional - The unique identifier assigned to each record in the system. - **OpenHouseRemarks** (string) - Optional - Comments, instructions or information about the open house. - **OpenHouseStartTime** (string) - Optional - The time the open house begins. - **OpenHouseType** (string) - Optional - The type of open house (i.e., Public, Broker, Office, Association, Private (invitation or targeted publication)). - **OriginalEntryTimestamp** (string) - Optional - The date and time when the entry was originally created. - **OriginatingSystemID** (string) - Optional - The RESO Unique Organization Identifier (UOI) OrganizationUniqueId of the originating record provider. - **OriginatingSystemKey** (string) - Optional - The unique identifier of the originating system. - **OriginatingSystemName** (string) - Optional - The name of the originating system from which this data is derived from. ### Request Example ```json { "message": "GET request to retrieve OpenHouse data" } ``` ### Response #### Success Response (200) - **ListingId** (integer) - The ListingId of the related listing. - **ListingKey** (string) - The unique identifier for the listing. - **LivestreamOpenHouseURL** (string) - A link to an open house livestream event. - **ModificationTimestamp** (string) - The date and time when the record was last modified. - **OpenHouseDate** (string) - The date on which the open house will occur. - **OpenHouseEndTime** (string) - The time the open house ends. - **OpenHouseKey** (string) - The unique identifier assigned to each record in the system. - **OpenHouseRemarks** (string) - Comments, instructions or information about the open house. - **OpenHouseStartTime** (string) - The time the open house begins. - **OpenHouseType** (string) - The type of open house. - **OriginalEntryTimestamp** (string) - The date and time when the entry was originally created. - **OriginatingSystemID** (string) - The RESO Unique Organization Identifier (UOI) OrganizationUniqueId of the originating record provider. - **OriginatingSystemKey** (string) - The unique identifier of the originating system. - **OriginatingSystemName** (string) - The name of the originating system. - **Listing** (object) - The listing this relates to. - **Media** (array) - The media related to the OpenHouse record. - **Translations** (array) - The translations of the resource. #### Response Example ```json { "ListingId": 12345, "ListingKey": "ABCDEF12345", "LivestreamOpenHouseURL": "https://example.com/livestream", "ModificationTimestamp": "2023-10-27T10:00:00Z", "OpenHouseDate": "2023-11-01", "OpenHouseEndTime": "17:00:00", "OpenHouseKey": "OHKEY98765", "OpenHouseRemarks": "Come visit us this Saturday!", "OpenHouseStartTime": "13:00:00", "OpenHouseType": "Public", "OriginalEntryTimestamp": "2023-10-26T09:00:00Z", "OriginatingSystemID": "ORG123", "OriginatingSystemKey": "SYSKEYXYZ", "OriginatingSystemName": "Example Realty", "Listing": {}, "Media": [], "Translations": [] } ``` ``` -------------------------------- ### PropertyUnit API Documentation Source: https://docs.datadistributionqc.centris.ca/resources/PropertyUnit Documentation for the PropertyUnit resource, which provides details on individual units within a multi-unit property. ```APIDOC ## PropertyUnit Resource ### Description The PropertyUnit resource provides data about individual units within a multi-unit property, such as apartments or condos. To get aggregated information on units, see PropertyUnitTypes. This resource or some of its fields may not be available depending on your configuration. This resource supports translations. All dollar amounts are in Canadian Dollar (CAD). ### Fields - **Furnished** (string) - The property being leased is furnished, unfurnished or partially furnished. See also Furnished - **ListingId** (string) - The ListingId of the related listing. - **ListingKey** (string) - The unique identifier for the listing. - **ModificationTimestamp** (datetime) - The date and time when the record was last modified. - **Order** (integer) - The position of the unit within the list of units. - **RentExcludes** (array of strings) - Items or services that are not included in the rent for the unit. See also RentIncludes - **RentExcludesOther** (string) - Additional exclusions from rent not covered by predefined categories. - **RentIncludes** (array of strings) - Items or services that are included in the rent for the unit. See also RentIncludes - **RentIncludesOther** (string) - Additional inclusions in rent not covered by predefined categories. - **UnitAboveGroundBedroomsTotal** (integer) - Total number of bedrooms located above ground level in the unit. - **UnitArea** (number) - The total area of the unit. - **UnitAreaSquareFeet** (number) - The area of the unit measured in square feet. - **UnitAreaUnits** (string) - The unit of measurement used for the unit area. See also AreaUnits - **UnitBasementBedroomsTotal** (integer) - Total number of bedrooms located in the basement of the unit. - **UnitBathroomsFullTotal** (integer) - Total number of full bathrooms in the unit. - **UnitBathroomsPartialTotal** (integer) - Total number of partial bathrooms in the unit. - **UnitBedroomsTotal** (integer) - Total number of bedrooms in the unit. - **UnitBlockSaleYN** (boolean) - Indicates whether the unit is part of a block sale (Yes/No). - **UnitBusinessName** (string) - The name of the business operating in the unit, if applicable. - **UnitCurrentUse** (string) - The current use or function of the unit (residential, commercial, etc.). See also CurrentOrPossibleUse - **UnitExistingLeaseType** (string) - The type of lease currently in place for the unit. See also ExistingLeaseType - **UnitFranchiseContractEndDate** (date) - The end date of the franchise contract for the unit. - **UnitFranchiseRenewalTermYears** (integer) - The number of years for the renewal term of the franchise. - **UnitFranchiseRenewalYN** (boolean) - Indicates whether the franchise has a renewal option (Yes/No). - **UnitFranchiseYN** (boolean) - Indicates whether the unit is part of a franchise (Yes/No). - **UnitKey** (string) - The unique identifier assigned to each record in the system. - **UnitLaundryFeatures** (array of strings) - Details about laundry facilities or features in the unit. See also LaundryFeatures - **UnitLeaseEndDate** (date) - The end date of the lease for the unit. - **UnitLeaseFeatures** (array of strings) - Features or terms associated with the lease of the unit. See also LeaseFeatures - **UnitLeaseRenewalTermYears** (integer) - The number of years for the lease renewal term. - **UnitLeaseRenewalYN** (boolean) - Indicates whether the lease has a renewal option (Yes/No). - **UnitLeaseStartDate** (date) - The start date of the lease for the unit. - **UnitMlsId** (string) - The MLS identifier associated with the unit. - **UnitMlsSpecialType** (string) - Special classification of the unit in the MLS system. - **UnitMlsSubType** (string) - Subtype classification of the unit in the MLS system. - **UnitMlsType** (string) - Main type classification of the unit in the MLS system. - **UnitMonthlyGrossIncome** (number) - The total gross income generated by the unit per month. - **UnitMonthlyGrossIncomeDate** (date) - The date associated with the reported monthly gross income. - **UnitMonthlyGrossScheduledIncome** (number) - The scheduled gross income expected from the unit per month. - **UnitNumber** (string) - The identifying number of the unit. - **UnitRoomsTotal** (integer) - Total number of rooms in the unit. - **UnitType** (string) - The type or classification of the unit. See also UnitTypeType - **UnitTypeOther** (string) - Other unit type not covered by predefined categories. - **UnitYearBusinessOperationStart** (integer) - The year the business operation started in the unit. ### Navigation Fields - **AdditionalSpaces** - Navigation to PropertyAdditionalSpace. - **Listing** - Navigation to Property. - **Parkings** - Navigation to PropertyParking. - **Rooms** - Navigation to PropertyRooms. - **Subdivisions** - Navigation to PropertySubdivision. - **Translations** - Navigation to Translation. ``` -------------------------------- ### GET /v1/odata/Resource('key') Source: https://docs.datadistributionqc.centris.ca/getting-started Retrieves a single resource by its unique key. Supports selecting fields and expanding related data. ```APIDOC ## GET /v1/odata/Resource('key') ### Description Gets a single resource identified by its key. This endpoint also supports field selection and expanding related data. ### Method GET ### Endpoint /v1/odata/Resource('key') ### Parameters #### Path Parameters - **key** (string) - Required - The unique identifier of the resource to retrieve. #### Query Parameters - **$select** (string) - Optional - Specifies which fields to include in the response. Example: `$select=ListingKey,ModificationTimestamp`. - **$expand** (string) - Optional - Includes related data in the response. Example: `$expand=ListAgent`. ### Request Example ```json GET https://datadistributionqc.centris.ca/v1/odata/Property('12345')?$select=ListingKey,ModificationTimestamp&$expand=ListAgent(select=MemberFullName) ``` ### Response #### Success Response (200) - **Resource Object** - The resource object matching the provided key. #### Response Example ```json { "ListingKey": "12345", "ModificationTimestamp": "2024-02-01T12:00:00Z", "ListAgent": { "MemberFullName": "John Doe" } } ``` **Note:** - If no result matches the request, a `404 Not Found` response will be returned. ``` -------------------------------- ### GET /v1/odata/$metadata Source: https://docs.datadistributionqc.centris.ca/getting-started Retrieves the data model of the system. The response is in XML by default, but can be obtained in JSON by appending the optional `$format=application/json` parameter. ```APIDOC ## GET /v1/odata/$metadata ### Description Gets the data model of the system. An optional parameter `$format` can be provided to get the response in JSON instead of XML. (`$format=application/json`). ### Method GET ### Endpoint /v1/odata/$metadata ### Parameters #### Query Parameters - **$format** (string) - Optional - Specifies the response format. Use `application/json` for JSON output. ### Request Example ```json GET https://datadistributionqc.centris.ca/v1/odata/$metadata ``` ### Response #### Success Response (200) - **XML/JSON** - The data model of the system, including available resources, fields, data types, and navigation properties. #### Response Example ```json { "example": "XML or JSON representation of the data model" } ``` **Information Retrievable:** - Resources available (e.g., `Member`, `Office`, `Property`). - Fields available (e.g., `Member.MemberKey`, `Member.MemberFirstName`, `Property.ListPrice`). - Data types of fields (e.g., `String`, `Decimal`) and their size information (e.g., `Max length`, `Precision`). - Navigation fields (e.g., `Member.MemberSocialMedia`). ``` -------------------------------- ### GET /v1/odata/Resource Source: https://docs.datadistributionqc.centris.ca/getting-started Retrieves a collection of resources (e.g., Property, Member, Office). Supports filtering, sorting, selecting fields, expanding related data, and counting results. ```APIDOC ## GET /v1/odata/Resource ### Description Gets a collection of resources. This endpoint supports various OData query options for flexible data retrieval. ### Method GET ### Endpoint /v1/odata/Resource ### Parameters #### Query Parameters - **$select** (string) - Optional - Specifies which fields to include in the response. Example: `$select=ListingKey,ModificationTimestamp`. - **$filter** (string) - Optional - Filters the results based on specified criteria. Example: `$filter=StandardStatus eq 'Active'`. - **$orderby** (string) - Optional - Orders the results based on specified fields. Example: `$orderby=ModificationTimestamp`. - **$count** (boolean) - Optional - If set to `true`, includes the total count of matching results. Example: `$count=true`. - **$expand** (string) - Optional - Includes related data in the response. Example: `$expand=ListAgent`. ### Request Example ```json GET https://datadistributionqc.centris.ca/v1/odata/Property?$select=ListingKey,ModificationTimestamp&$filter=StandardStatus eq 'Active'&$orderby=ModificationTimestamp&$count=true&$expand=ListAgent(select=MemberFullName) ``` ### Response #### Success Response (200) - **value** (array) - An array of resource objects matching the query. - **@odata.nextLink** (string) - Present if there are more results available for pagination. #### Response Example ```json { "value": [ { "ListingKey": "14689588", "ModificationTimestamp": "2024-02-01T12:00:00Z" }, { "ListingKey": "14239483", "ModificationTimestamp": "2024-02-01T12:05:00Z" } ], "@odata.nextLink": "https://datadistributionqc.centris.ca/v1/odata/Property?$select=ListingKey%2CModificationTimestamp&$filter=StandardStatus%20eq%20%27Active%27&$orderby=ModificationTimestamp&$skip=10" } ``` **Note:** - If no results match, a `200 OK` response with an empty collection is returned. - Using unauthorized fields with `$orderby` or `$filter` will result in a `400 Bad Request` error. ```