curl --request POST \
--url https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"account_id": "{account_id}",
"time_period": "next_12_months",
"interval": "month"
}
'import requests
url = "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts"
payload = {
"account_id": "{account_id}",
"time_period": "next_12_months",
"interval": "month"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({account_id: '{account_id}', time_period: 'next_12_months', interval: 'month'})
};
fetch('https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'account_id' => '{account_id}',
'time_period' => 'next_12_months',
'interval' => 'month'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts"
payload := strings.NewReader("{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}"
response = http.request(request)
puts response.read_body{
"rows": [
{
"property_name": "The Livingston",
"market_name": "Madison, WI Metro Area",
"submarket_name": "Downtown Madison",
"property_id": 781245,
"address": "1025 E Washington Ave",
"city": "Madison",
"state": "WI",
"zip_code": "53703",
"latitude": 43.0836,
"longitude": -89.3723,
"unified_status": "stabilized",
"unit_count": 186,
"number_of_stories": 6,
"year_built": 2018,
"year_renovated": null,
"property_class": "A",
"property_type": "Multifamily",
"management_company_names": [
"Northstar Residential"
],
"ownership_company_names": [
"Lakeview Multifamily Fund"
],
"period": "2026-07",
"rent_growth_rate_yoy": 0.0312,
"rent_growth_rate_yoy_downside": 0.0175,
"rent_growth_rate_yoy_upside": 0.0468,
"occupancy_percent": 0.9412,
"occupancy_percent_downside": 0.9224,
"occupancy_percent_upside": 0.9588
},
{
"property_name": "Summit Row",
"market_name": "Madison, WI Metro Area",
"submarket_name": "West Madison",
"property_id": 781266,
"address": "711 Junction Rd",
"city": "Madison",
"state": "WI",
"zip_code": "53717",
"latitude": 43.0719,
"longitude": -89.5264,
"unified_status": "lease_up",
"unit_count": 244,
"number_of_stories": 5,
"year_built": 2024,
"year_renovated": null,
"property_class": "A",
"property_type": "Multifamily",
"management_company_names": [
"Crescent Urban Living"
],
"ownership_company_names": [],
"period": "2026-08",
"rent_growth_rate_yoy": null,
"rent_growth_rate_yoy_downside": null,
"rent_growth_rate_yoy_upside": null,
"occupancy_percent": 0.8721,
"occupancy_percent_downside": 0.8365,
"occupancy_percent_upside": 0.9018
}
],
"pagination": {
"current_page": 1,
"total_pages": 4,
"total_count": 100,
"per_page": 25
}
}{
"error": "<string>",
"message": "<string>",
"quota_limit": 123,
"quota_usage": 123
}{
"error": "<string>",
"message": "<string>",
"quota_limit": 123,
"quota_usage": 123
}"You have exceeded the rate limit for this API.\n"Bulk Property Forecasts
Retrieve bulk property forecast rows using optional property filters, requested forecast fields, and pagination.
curl --request POST \
--url https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"account_id": "{account_id}",
"time_period": "next_12_months",
"interval": "month"
}
'import requests
url = "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts"
payload = {
"account_id": "{account_id}",
"time_period": "next_12_months",
"interval": "month"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({account_id: '{account_id}', time_period: 'next_12_months', interval: 'month'})
};
fetch('https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'account_id' => '{account_id}',
'time_period' => 'next_12_months',
'interval' => 'month'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts"
payload := strings.NewReader("{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.apartmentiq.io/apartmentiq/api/v2/properties/bulk_forecasts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"account_id\": \"{account_id}\",\n \"time_period\": \"next_12_months\",\n \"interval\": \"month\"\n}"
response = http.request(request)
puts response.read_body{
"rows": [
{
"property_name": "The Livingston",
"market_name": "Madison, WI Metro Area",
"submarket_name": "Downtown Madison",
"property_id": 781245,
"address": "1025 E Washington Ave",
"city": "Madison",
"state": "WI",
"zip_code": "53703",
"latitude": 43.0836,
"longitude": -89.3723,
"unified_status": "stabilized",
"unit_count": 186,
"number_of_stories": 6,
"year_built": 2018,
"year_renovated": null,
"property_class": "A",
"property_type": "Multifamily",
"management_company_names": [
"Northstar Residential"
],
"ownership_company_names": [
"Lakeview Multifamily Fund"
],
"period": "2026-07",
"rent_growth_rate_yoy": 0.0312,
"rent_growth_rate_yoy_downside": 0.0175,
"rent_growth_rate_yoy_upside": 0.0468,
"occupancy_percent": 0.9412,
"occupancy_percent_downside": 0.9224,
"occupancy_percent_upside": 0.9588
},
{
"property_name": "Summit Row",
"market_name": "Madison, WI Metro Area",
"submarket_name": "West Madison",
"property_id": 781266,
"address": "711 Junction Rd",
"city": "Madison",
"state": "WI",
"zip_code": "53717",
"latitude": 43.0719,
"longitude": -89.5264,
"unified_status": "lease_up",
"unit_count": 244,
"number_of_stories": 5,
"year_built": 2024,
"year_renovated": null,
"property_class": "A",
"property_type": "Multifamily",
"management_company_names": [
"Crescent Urban Living"
],
"ownership_company_names": [],
"period": "2026-08",
"rent_growth_rate_yoy": null,
"rent_growth_rate_yoy_downside": null,
"rent_growth_rate_yoy_upside": null,
"occupancy_percent": 0.8721,
"occupancy_percent_downside": 0.8365,
"occupancy_percent_upside": 0.9018
}
],
"pagination": {
"current_page": 1,
"total_pages": 4,
"total_count": 100,
"per_page": 25
}
}{
"error": "<string>",
"message": "<string>",
"quota_limit": 123,
"quota_usage": 123
}{
"error": "<string>",
"message": "<string>",
"quota_limit": 123,
"quota_usage": 123
}"You have exceeded the rate limit for this API.\n"Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
ApartmentIQ account ID used to set the request account context.
Forecast horizon.
next_12_months, next_3_years, next_5_years Forecast period bucket.
month, quarter, year Forecast metric field names to include in each property row.
rent_growth_rate_yoy, rent_growth_rate_yoy_downside, rent_growth_rate_yoy_upside, occupancy_percent, occupancy_percent_downside, occupancy_percent_upside Filters used to select properties and constrain the metric aggregation date range.
Show child attributes
Show child attributes
Page number. Values less than 1 are treated as 1.
x >= 1Matched properties per page. Values above 100 are capped at 100. Interval-based rows expand each matched property into one row per period, so the number of rows returned can be greater than per_page.
1 <= x <= 100Response
Bulk property forecast rows and pagination metadata.
Paginated property forecast export results.
Property forecast rows for the matched properties on the current page. Each matched property is expanded into one row per interval period, so the number of rows returned can be greater than the per_page value. Each row includes property identity fields, an output period, and any requested forecast fields.
Show child attributes
Show child attributes
Pagination details for matched properties, not the expanded interval-period rows.
Show child attributes
Show child attributes