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.
- Prerequisites
- Step 1 — Get an Access Token
- Step 2 — Search Listings
- Step 3 — Get a Specific Listing
- Step 4 — Get Listing Photos
Prerequisites
Before you start, you need API credentials. Register as a developer at sparkplatform.com to receive:
client_id— Your application's unique identifier.client_secret— Your application's secret key. Keep this private.access_token— Some developer accounts come with a pre-provisioned single-session token. If you have one, you can skip Step 1 and jump straight to Step 2.
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 -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]"
}'
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)
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);
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
$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 "https://sparkapi.com/v1/listings?_filter=City+Eq+'Portland'+And+BedsTotal+Ge+3&_limit=5" \
-H "Authorization: OAuth [access_token]"
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"))
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);
});
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
$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 "https://sparkapi.com/v1/listings/20100000000000000000000000" \
-H "Authorization: OAuth [access_token]"
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']:,}")
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}`);
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
$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 "https://sparkapi.com/v1/listings/20100000000000000000000000/photos" \
-H "Authorization: OAuth [access_token]"
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
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));
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
$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
- Explore all listing fields and services.
- Learn about search filters and pagination.
- Try the RESO Web API Quick Start Guide if your MLS uses the RESO standard.
- Browse community API client libraries for faster development.