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

Example: OpenID+OAuth 2 Hybrid Flow

For most of our examples, the first step is Step 1: Authentication. This example explains that initial step detail.

  1. Obtaining User Authorization
  2. Token Exchange
  3. Requesting Data
  4. Refreshing Expired Sessions

Step 1: Obtaining User Authorization

The User Authorization step is, for many developers, the most confusing step in the Hybrid auth flow, as it involves the third party user and our endpoint rather than a direct request from an API client (or curl) to Spark® API.

In the example URI below, fill in your personal credentials for the following parameters:[redirect_uri]&openid.spark.client_id=[client_id]&openid.spark.combined_flow=true

This is the URI your end users will be directed to in their web browser to authorize your application to access their data.

Once directed to our endpoint, the user will be prompted to:

  1. Log in.
  2. Allow (or Deny) your application access to their data.

Step 2: Token Exchange

After the end user allows your application access to their data, they will be redirected to the location specified by your redirect URI. Extracting the value from the openid.spark.code parameter will supply us with the code we need to complete the Token Exchange and obtain an access token.[code]&openid.mode=id_res

Using this code along with your credentials, we can finally jump to the command line and make the following curl request (modified with your credentials and the code above, of course).

$ curl "" -H "Authorization: OAuth MY_OAUTH2_ACCESS_TOKEN"  -H 'Content-Type: application/json' -X POST --data '{"client_id": "[client_id]","client_secret":  "[client_secret]","grant_type": "authorization_code","code": "[code]", "redirect_uri": "[redirect_uri]"}'
  "access_token": "[access_token]",
  "refresh_token": "[refresh_token]",
  "expires_in":  86400

Step 3: Requesting Data

Most of our other example pages exercise this step. To try an authenticated request against the API with your access_token from the previous step, try out Step 4: Retrieving list item values for the City field from our Displaying Standard Field Labels examples.

Step 4: Refreshing Expired Sessions

Most applications prefer not to make end users log in again once their access token expires, and the Refresh Token action provides such a solution.

There are only two differences between the Token Exchange and the Token Refresh steps:

  1. The grant_type attribute in the POST body is set to "refresh_token", instead of "code".
  2. The code attribute is replaced with the refresh_token attribute, and takes the refresh_token value from the Token Exchange.

$ curl "" -H "Authorization: OAuth MY_OAUTH2_ACCESS_TOKEN"  -H 'Content-Type: application/json' -X POST --data '{"client_id": "[client_id]","client_secret":  "[client_secret]","grant_type": "refresh_token","refresh_token": "[refresh_token]", "redirect_uri": "[redirect_uri]"}'
  "access_token": "[access_token]",
  "refresh_token": "[refresh_token]",
  "expires_in":  86400