Consumer Documentation for EntityEvent Push Replication

Our Producer API leverages the RESO EntityEvent Resource model to push data efficiently and directly to your Consumer API using webhooks. This eliminates the need for continuous polling by your system and simplifies event-driven data replication.

API Endpoint Requirements

To integrate with our Producer API, you must set up an API endpoint to receive EntityEvents:.

  • HTTP Method: POST
  • Content-Type: application/json
  • Authorization: OAuth2 Bearer Token

Authentication

Your endpoint must support OAuth2 Bearer Token authentication. You may provide us with either:

  • A fixed token
  • Or credentials for dynamic token generation:
    • ClientId
    • ClientSecret
    • AccessTokenURL
    • GrantType

Additionally, you must provide a PostEndpoint URL for delivering events.

Example Request Header

Authorization: Bearer <your_oauth_token>

Payload Structure

Each event payload will be sent using the RESO EntityEvent structure along with a custom Data object containing the actual data resource, e.g., Property, Member, Office, or an internal resource such as Media.

Example Payload

{
  "@reso.context": "urn:reso:metadata:2.0:resource:entityevent",
  "value": [
    {
      "EntityEventSequence": 1101,
      "ResourceName": "Property",
      "ResourceRecordKey": "235021",
      "Data": {
        // Complete RESO Property object
      }
    },
    {
      "EntityEventSequence": 1111,
      "ResourceName": "Media",
      "ResourceRecordKey": "ABC123",
      "Data": {
        "ResourceRecordID": "ABC123",
        "OriginatingSystemName": "YourSystemName",
        "Media": [
          // Media array
        ]
      }
    }
  ]
}

Consumer API Expectations

  • Accept HTTP POST requests
  • Respond promptly (typically within a few seconds)
  • Handle batches of events gracefully
  • Implement polite behaviors for backpressure scenarios:
    • Respond with HTTP 429 if overwhelmed
    • Include a Retry-After header to indicate retry delay

Example Successful Response

HTTP/2 200
Content-Type: application/json

Example Retry Response

HTTP/2 429
Content-Type: application/json
Retry-After: 60

RESO Requirements for Consumer API

To ensure compatibility with the RESO standardized Push Replication using Webhooks, your Consumer API must meet the following requirements:

  • Consumers MUST implement an API endpoint that can receive EntityEvents
  • Consumers MUST establish authorization with the provider, using an OAuth2 bearer token

Building Your Consumer Endpoint

This section provides guidance on how to design and implement your consumer-side POST endpoint to receive and process EntityEvent payloads efficiently.

Endpoint Design Recommendations

When building your consumer endpoint, consider the following architectural approach:

  • Create a lightweight POST endpoint that accepts incoming EntityEvent payloads and responds quickly
  • Validate the incoming request by checking the authorization header and basic payload structure
  • Acknowledge receipt immediately by returning an HTTP 200 response before heavy processing
  • Offload processing to a background worker by placing the payload onto a message queue

Using a Message Queue for Processing

We strongly recommend attaching a message queue (such as Amazon SQS, Azure Service Bus, RabbitMQ, or any queue system of your choice) to your POST endpoint. This approach offers several benefits:

  • Decoupled Processing: Your endpoint can respond quickly while actual data processing happens asynchronously
  • Reliability: Messages are persisted in the queue, ensuring no data is lost if your processor experiences issues
  • Scalability: You can scale your queue consumers independently based on processing load
  • Backpressure Handling: The queue acts as a buffer during high-volume periods
  • Retry Logic: Failed messages can be automatically retried or moved to a dead-letter queue for investigation

Processing Flow

A typical processing flow would be:

  1. Your POST endpoint receives the EntityEvent payload
  2. The endpoint validates the request and immediately enqueues the payload to your message queue
  3. The endpoint returns an HTTP 200 response to our Producer API
  4. A separate queue consumer picks up messages from the queue
  5. The consumer processes each EntityEvent, extracting and transforming the data as needed
  6. The consumer persists the data to your database or downstream systems

Payload Structure Overview

Each payload you receive will contain a @reso.context field indicating the metadata version and a value array containing one or more EntityEvent objects. Each EntityEvent includes:

  • EntityEventSequence: A unique sequence number for the event
  • ResourceName: The type of resource (e.g., Property, Media, Member, Office)
  • ResourceRecordKey: The unique identifier for the resource record
  • EntityEventType: The type of event (e.g., Create, Update, Delete)
  • ModificationTimestamp: The timestamp when the modification occurred
  • OriginatingSystemName: The name of the originating system
  • Data: The complete resource object containing the actual data

Flexible Data Mapping

You have complete flexibility in how you handle and store the incoming data:

  • Define Your Own Data Models: Create custom objects that match your system's requirements and data structures
  • Map Only the Fields You Need: You are not required to store all fields from the payload; extract and map only the fields relevant to your use case
  • Transform Data as Needed: Apply any transformations, validations, or enrichments during processing
  • Handle Multiple Resource Types: Route different resource types (Property, Media, Member, etc.) to different handlers or storage destinations
  • Use Your Preferred Serialization: Deserialize the JSON payload using any library or framework that suits your technology stack

Example: Custom Data Models

Below is an example of how you might define your own simplified classes to capture only the fields relevant to your use case:

// Your custom payload wrapper - map only what you need
public class MyEntityEventsPayload
{
    [JsonProperty("@reso.context")]
    public string ResoContext { get; set; }

    [JsonProperty("value")]
    public List<MyEntityEvent> Events { get; set; }
}

// Your simplified EntityEvent - include only fields you care about
public class MyEntityEvent
{
    public long? EntityEventSequence { get; set; }
    public string ResourceName { get; set; }
    public string ResourceRecordKey { get; set; }
    public string EntityEventType { get; set; }  // or use your own enum
    public DateTimeOffset? ModificationTimestamp { get; set; }
    
    // Data can be deserialized to your own Property/Media/Member models
    public object Data { get; set; }
}

// Your custom Property model - extract only the fields you need
public class MyProperty
{
    public string ListingKey { get; set; }
    public string ListingId { get; set; }
    public decimal? ListPrice { get; set; }
    public string City { get; set; }
    public string StateOrProvince { get; set; }
    public string PostalCode { get; set; }
    public int? BedroomsTotal { get; set; }
    public int? BathroomsTotalInteger { get; set; }
    public decimal? LivingArea { get; set; }
    // Add only the fields your application requires
}

This approach allows you to ignore the hundreds of available RESO fields and focus only on the data points that matter for your specific integration.

Best Practices

  • Keep your POST endpoint logic minimal to ensure fast response times
  • Implement idempotent processing using the EntityEventSequence to handle potential duplicate deliveries
  • Log incoming requests and processing results for debugging and monitoring
  • Set up alerts for queue depth and processing failures
  • Consider storing the raw payload alongside your transformed data for audit purposes
  • Use the ResourceName field to route events to appropriate handlers for each resource type

Handling Media Resources

Media resources will be included as objects within the Data property. Your system should be prepared to retrieve and store these media files.

Citations