Developer Documentation
Platform Overview
Authentication
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: Floor Plans Metadata Incomplete Listings: Floor Plan Uploads 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: Document Uploads Listings: Floor Plans Listings: Floor Plans Metadata Listings: Floor Plan Uploads 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: 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
Examples
RESO Web API
RETS
Terms of Use

Spark API Quick Start Guide

This guide will walk you through the basics of the Spark® API — from getting your credentials to searching listings — in under 20 minutes. You can follow along using curl, Python, JavaScript, Ruby, or PHP.

  1. Prerequisites
  2. Step 1 — Get an Access Token
  3. Step 2 — Search Listings
  4. Step 3 — Get a Specific Listing
  5. Step 4 — Get Listing Photos
 

Prerequisites

Before you start, you need API credentials. Register as a developer at sparkplatform.com to receive:

All requests must be made over HTTPS.

 

Step 1 — Get an Access Token

The Spark API uses OAuth 2 for authentication. To get an access token, POST your credentials to the token endpoint. Replace [client_id], [client_secret], and [code] with your actual values.

Note: If your account was provided a pre-configured access_token and refresh_token, skip this step.

 
curl
curl -X POST "https://sparkapi.com/v1/oauth2/grant" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "[client_id]",
    "client_secret": "[client_secret]",
    "grant_type": "authorization_code",
    "code": "[code]",
    "redirect_uri": "[redirect_uri]"
  }'
 
Python
import requests

response = requests.post(
    "https://sparkapi.com/v1/oauth2/grant",
    json={
        "client_id": "[client_id]",
        "client_secret": "[client_secret]",
        "grant_type": "authorization_code",
        "code": "[code]",
        "redirect_uri": "[redirect_uri]"
    }
)

data = response.json()
access_token = data["access_token"]
print("Access token:", access_token)
 
JavaScript (Node.js)
const response = await fetch("https://sparkapi.com/v1/oauth2/grant", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    client_id: "[client_id]",
    client_secret: "[client_secret]",
    grant_type: "authorization_code",
    code: "[code]",
    redirect_uri: "[redirect_uri]"
  })
});

const { access_token } = await response.json();
console.log("Access token:", access_token);
 
Ruby
require "net/http"
require "json"

uri = URI("https://sparkapi.com/v1/oauth2/grant")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri.path, "Content-Type" => "application/json")
request.body = JSON.generate(
  client_id: "[client_id]",
  client_secret: "[client_secret]",
  grant_type: "authorization_code",
  code: "[code]",
  redirect_uri: "[redirect_uri]"
)

response = http.request(request)
data = JSON.parse(response.body)
access_token = data["access_token"]
puts "Access token: #{access_token}"
 
PHP
<?php
$ch = curl_init("https://sparkapi.com/v1/oauth2/grant");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "client_id"     => "[client_id]",
    "client_secret" => "[client_secret]",
    "grant_type"    => "authorization_code",
    "code"          => "[code]",
    "redirect_uri"  => "[redirect_uri]"
]));

$data = json_decode(curl_exec($ch), true);
$access_token = $data["access_token"];
echo "Access token: " . $access_token;
 

A successful response looks like:

{
  "access_token": "your_access_token_here",
  "refresh_token": "your_refresh_token_here",
  "expires_in": 86400
}
 

Step 2 — Search Listings

Use your access_token in an Authorization header to search for listings. The example below searches for listings in Portland with at least 3 bedrooms.

 
curl
curl "https://sparkapi.com/v1/listings?_filter=City+Eq+'Portland'+And+BedsTotal+Ge+3&_limit=5" \
  -H "Authorization: OAuth [access_token]"
 
Python
import requests

access_token = "your_access_token_here"

response = requests.get(
    "https://sparkapi.com/v1/listings",
    headers={"Authorization": f"OAuth {access_token}"},
    params={
        "_filter": "City Eq 'Portland' And BedsTotal Ge 3",
        "_limit": 5
    }
)

listings = response.json()["D"]["Results"]
for listing in listings:
    fields = listing["StandardFields"]
    print(listing["Id"], fields.get("StreetFull"), fields.get("ListPrice"))
 
JavaScript (Node.js)
const accessToken = "your_access_token_here";
const params = new URLSearchParams({
  _filter: "City Eq 'Portland' And BedsTotal Ge 3",
  _limit: 5
});

const response = await fetch(`https://sparkapi.com/v1/listings?${params}`, {
  headers: { Authorization: `OAuth ${accessToken}` }
});

const { D: { Results: listings } } = await response.json();
listings.forEach(l => {
  const f = l.StandardFields;
  console.log(l.Id, f.StreetFull, f.ListPrice);
});
 
Ruby
require "net/http"
require "json"

access_token = "your_access_token_here"
uri = URI("https://sparkapi.com/v1/listings")
uri.query = URI.encode_www_form(
  "_filter" => "City Eq 'Portland' And BedsTotal Ge 3",
  "_limit"  => 5
)

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri, "Authorization" => "OAuth #{access_token}")

response = http.request(request)
listings = JSON.parse(response.body)["D"]["Results"]
listings.each do |l|
  f = l["StandardFields"]
  puts "#{l['Id']} #{f['StreetFull']} #{f['ListPrice']}"
end
 
PHP
<?php
$access_token = "your_access_token_here";
$query = http_build_query([
    "_filter" => "City Eq 'Portland' And BedsTotal Ge 3",
    "_limit"  => 5
]);

$ch = curl_init("https://sparkapi.com/v1/listings?" . $query);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: OAuth $access_token"]);

$data = json_decode(curl_exec($ch), true);
foreach ($data["D"]["Results"] as $listing) {
    $f = $listing["StandardFields"];
    echo $listing["Id"] . " " . $f["StreetFull"] . " " . $f["ListPrice"] . "\n";
}
 

A successful response looks like:

{
  "D": {
    "Success": true,
    "Results": [
      {
        "Id": "20100000000000000000000000",
        "ResourceUri": "/v1/listings/20100000000000000000000000",
        "StandardFields": {
          "StreetFull": "123 Main St",
          "City": "Portland",
          "BedsTotal": 3,
          "BathsTotal": 2,
          "ListPrice": 450000
        }
      }
    ],
    "Pagination": {
      "TotalRows": 142,
      "PageSize": 5,
      "CurrentPage": 1,
      "TotalPages": 29
    }
  }
}

For more on search syntax, see Spark API Parameters.

 

Step 3 — Get a Specific Listing

Retrieve full details for a single listing using its Id from the search results above.

 
curl
curl "https://sparkapi.com/v1/listings/20100000000000000000000000" \
  -H "Authorization: OAuth [access_token]"
 
Python
listing_id = "20100000000000000000000000"

response = requests.get(
    f"https://sparkapi.com/v1/listings/{listing_id}",
    headers={"Authorization": f"OAuth {access_token}"}
)

listing = response.json()["D"]["Results"][0]
fields = listing["StandardFields"]
print(f"{fields['StreetFull']}, {fields['City']} — ${fields['ListPrice']:,}")
 
JavaScript (Node.js)
const listingId = "20100000000000000000000000";

const response = await fetch(`https://sparkapi.com/v1/listings/${listingId}`, {
  headers: { Authorization: `OAuth ${accessToken}` }
});

const { D: { Results: [listing] } } = await response.json();
const { StreetFull, City, ListPrice } = listing.StandardFields;
console.log(`${StreetFull}, ${City} — $${ListPrice}`);
 
Ruby
listing_id = "20100000000000000000000000"
uri = URI("https://sparkapi.com/v1/listings/#{listing_id}")

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri, "Authorization" => "OAuth #{access_token}")

response = http.request(request)
listing = JSON.parse(response.body)["D"]["Results"][0]
fields = listing["StandardFields"]
puts "#{fields['StreetFull']}, #{fields['City']} — $#{fields['ListPrice']}"
 
PHP
<?php
$listing_id = "20100000000000000000000000";

$ch = curl_init("https://sparkapi.com/v1/listings/$listing_id");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: OAuth $access_token"]);

$data = json_decode(curl_exec($ch), true);
$f = $data["D"]["Results"][0]["StandardFields"];
echo "{$f['StreetFull']}, {$f['City']} — \${$f['ListPrice']}";
 

Step 4 — Get Listing Photos

Retrieve photos for a listing using the Listing Photos sub-resource.

 
curl
curl "https://sparkapi.com/v1/listings/20100000000000000000000000/photos" \
  -H "Authorization: OAuth [access_token]"
 
Python
response = requests.get(
    f"https://sparkapi.com/v1/listings/{listing_id}/photos",
    headers={"Authorization": f"OAuth {access_token}"}
)

photos = response.json()["D"]["Results"]
for photo in photos:
    print(photo["Uri800"])  # URL to the 800px-wide version of the photo
 
JavaScript (Node.js)
const response = await fetch(
  `https://sparkapi.com/v1/listings/${listingId}/photos`,
  { headers: { Authorization: `OAuth ${accessToken}` } }
);

const { D: { Results: photos } } = await response.json();
photos.forEach(photo => console.log(photo.Uri800));
 
Ruby
uri = URI("https://sparkapi.com/v1/listings/#{listing_id}/photos")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri, "Authorization" => "OAuth #{access_token}")

response = http.request(request)
photos = JSON.parse(response.body)["D"]["Results"]
photos.each { |p| puts p["Uri800"] }
 
PHP
<?php
$ch = curl_init("https://sparkapi.com/v1/listings/$listing_id/photos");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: OAuth $access_token"]);

$data = json_decode(curl_exec($ch), true);
foreach ($data["D"]["Results"] as $photo) {
    echo $photo["Uri800"] . "\n";
}
 

A successful response looks like:

{
  "D": {
    "Success": true,
    "Results": [
      {
        "Id": "photo_id_here",
        "Uri800": "https://cdn.sparkapi.com/listings/photos/800/photo1.jpg",
        "UriThumb": "https://cdn.sparkapi.com/listings/photos/thumb/photo1.jpg",
        "Primary": true,
        "Caption": "Front of home"
      }
    ]
  }
}
 

Next Steps