Developer Documentation
Platform Overview
API Services
Overview Accounts Accounts: Associations Accounts: Metadata Accounts: Profile Appstore: Users Broker Distributions Broker Tours Consumers Consumers: Linked Agents Contacts Contacts: Activity Contacts: Export Contacts: Tags Contacts: Portal Accounts Developers: Identities Developers: Keys Developers: Authorizations Developers: Billing Summary Developers: Change History Developers: Domains Developers: News Feed Webhooks Developers: Roles Developers: Syndications Developers: Templates Developers: Usage Detail Developers: Usage Summary Devices Flexmls: Email Links Flexmls: Listing Meta Origins Flexmls: Listing Meta Translations Flexmls: Listing Meta Field List Translations Flexmls: Listing Reports Flexmls: Mapping Layers Flexmls: Mapping Shapegen IDX IDX Links Listing Carts Listing Carts: Portal/VOW Carts Incomplete Listings Incomplete Listings: Documents Incomplete Listings: Documents Metadata Incomplete Listings: Document Uploads Incomplete Listings: Floor Plans Incomplete Listings: FloPlans Incomplete Listings: Photos Incomplete Listings: Photos Metadata Incomplete Listings: Photo Uploads Incomplete Listings: Required Documents Incomplete Listings: Rooms Incomplete Listings: Tickets Incomplete Listings: Units Incomplete Listings: Videos Incomplete Listings: Videos Metadata Incomplete Listings: Virtual Tours Incomplete Listings: Virtual Tours Metadata Listings Listings: Clusters Listings: Documents Listings: Documents Metadata Listings: Floor Plans Listings: FloPlans Listings: Historical Listings: History Listings: Hot Sheet Parameters Listings: Notes Listings: Search Parameters Listings: Open Houses Listings: Photos Listings: Photos Metadata Listings: Photo Uploads Listings: Document Uploads Listings: Rental Calendar Listings: Required Documents Listings: Rooms Listings: Rules Listings: Tour of Homes Listings: Tickets Listings: Units Listings: Validation Listings: Videos Listings: Videos Metadata Listings: Virtual Tours Listings: Virtual Tours Metadata Listing Meta: Custom Fields Listing Meta: Custom Field Groups Listing Meta: Field Order Listing Meta: Field Relations Listing Meta: Property Types Listing Meta: Rooms Listing Meta: Standard Fields Listing Meta: Units Registered Listings Market Statistics News Feed News Feed: Curation News Feed: Events News Feed: Groups News Feed: Metadata News Feed: Restrictions News Feed: Schedule News Feed: Settings News Feed: Templates Notifications Open Houses Overlays Overlays: Geometries Portals Portals: Listing Categories Portals: Metadata Preferences Saved Searches Saved Searches: Provided Saved Searches: Restrictions Saved Searches: Tags Search Templates: Quick Searches Search Templates: Views Search Templates: Sorts Shared Links System Info System Info: Languages System Info: Search Templates
Supporting Documentation
Terms of Use

Rules Grammar

The rules validation system is an implementation of the RETS 1.8 specification for Validation Expressions. The design consists of three key components: a Field that the rule is defined for (E.g. ListPrice), a keyword or Action (as used in spark) to apply to the Field and (optionally) an Expression for determining if or how to apply the Action. The expression language is documented here for reference.

The following grammar is spark's implementation of the expression grammar referenced in the RETS specification. The expression language provides a means to express criteria for requiring an Action, or to set the value for a rule's Field. The Expression may reference the rule's Field or other fields to enable the rule builder to access the new or existing values for a resource.

RESO 1.8 Grammar Rules Implementation

This document explains the grammar rules for the rules expression language syntax. We take a few shortcuts to accomodate a LALR(1) implentation using RACC. Refer back to the full spec in the reference document.

Grammar Rules

Root: Each expression is a full fledged expression result

       : exp
       | /* none */   


Expressions are boolean or arithemetic operations, or special system functions that return a literal value.

     : orExp

Conjunctive expressions using .AND. or .OR..

     : andExp
     | orExp OR andExp 
     : notExp
     | andExp AND notExp 

Logic expressions using .NOT., =, !=, >, >=, <, <=, .CONTAINS. or .IN..

     : eqExpr
     | NOT notExp 
     : cmpExp
     | cmpExp EQ cmpExp 
     | cmpExp NE cmpExp 
     : cntExp
     | cntExp GE cntExp 
     | cntExp LE cntExp  
     | cntExp LT cntExp 
     | cntExp GT cntExp 
     : sumExp
     | sumExp CONTAINS sumExp 
     | sumExp IN list         
     | sumExp IN funcExp      

Arithmetic expressions using +, -, *, / or %.

     : prodExp
     | sumExp PLUS prodExp    
     | sumExp MINUS prodExp   
     | sumExp CONCAT prodExp  
     : atomExp
     | prodExp MULTIPLY atomExp 
     | prodExp DIVIDE atomExp   
     | prodExp MODULUS atomExp  


Functions can take the place of an expression and must have a single return type (although some may return an list of one type).

Name Description Example
fbsAbs Return the absolute value for a number. fbsAbs(-1.0) = 1
fbsCoalesce Return the default value if the first argument is nil fbsCoalesce(.EMPTY., 100)
fbsCustomField Find a custom field for the record being processed. This function requires a group name and field name. fbsCustomField('Group Name', 'Field Name')
fbsGetOldValue Return the existing value of a field. fbsGetOldValue(StandardStatus) = 'Pending' .AND. StandardStatus = 'Active'
fbsInterval Add or substract a well defined time interval from a time. Supports hours, days, and weeks. ListDate + interval('90 days')
fbsLookup Returns the current restricted list of values for a PICKLIST field, as it has been modified by any SET_PICKLIST or RESTRICT_PICKLIST actions. fbsLookup(City)
fbsNumSelected Returns the the count of fields in a group that are present with a value. fbsNumSelected("Custom Field Group")) > 2 .AND. StandardStatus = 'Active'
fbsPicklist Return all the list values for a single field. For fields that require a related field, the function supports passing this field as a second parameter. fbsPicklist(PostalCode,City)
fbsSize Return how many elements are in a list. fbsSize((1,0,3,9)) = 4
fbsType Return the type of the field as a character string (one of 'CHAR', 'INT', 'FLOAT', 'TIME','DATE','TIMESTAMP', 'BOOLEAN', and 'PICKLIST') The types are a string reflecting their namings as defined in of the RETS 1.8 document fbsType(City) = 'CHAR'
IFF Return one of two possible values based on a condition. IFF(ListPrice > 0.0 .AND. StandardStatus = 'Active', .EMPTY., .ENTRY.)
LOWER Convert a character value to lowercase LOWER('Fargo') = 'fargo'
STRLEN Return the length of a character string STRLEN('Fargo') = 5
SUBSTR Return a portion of a character string. The second parameter is a 1-indexe location to start, and the option final parameter is for the length of the substring. SUBSTR('Fargo', 2, 3) = 'arg
UPPER Convert a character value to uppercase UPPER('Fargo') = 'FARGO'
     : func LPAR params RPAR 


This rule handles wrapping nested values and expressions

     : list
     | value
     | funcExp


Lists are used for .IN. actions. They differ from nested expressions in that they are comma delimmited and are associated with a list action. They are similar to function parameters, but those are processed separately below.

     : LPAR RPAR             
     | LPAR list_items RPAR  
     : exp
     | list_items COMMA exp 


Parameters are specifically for function input. These can be expressions, but they are evaluated prior to calling the function.

     : param
     | params COMMA param 
     : exp


Values contain literals, fields and special context values. These are static in nature and should generally be predetermined before the rule evaluation begins.

     : specValue
     | charValue
     | intValue
     | floatValue
     | fieldName
     | timeValue
     | dateValue


Variable special values are either user or rule specific. For example, use .OLDVALUE. to access the old record value of the current rule field.

     : TRUE     
     | FALSE    
     | VARIABLE 
     | NULL     
   charValue:   CHARACTER ;
   intValue:    INTEGER   ;
   floatValue:  DECIMAL   ;


The format for time is ISO-8601, surrounded by pound signs.

  • RETSDATETIME ::= "#" (date-time | partial-date-time) "#"


NOTE: Experimental and subject to change or removal. The RESO docs do not indicate the presence of a date type, however the SparkAPI has one. This is to align with that.

  • DATE ::= #YYYY-MM-DD#
     : DATE 


The field names refer to the value of the field in the new record. Accessing the old record is possible using the fbsGetOldValue(FieldName) function.

     : FIELD