This advanced developer example shows how to use the IDX Broker API to create multiple Saved Links from one existing Saved Link, with each new link using a different price range.
This can be useful when creating Saved Links such as:
$100,000 to $200,000$200,000 to $300,000$300,000 to $400,000$400,000 to $500,000
IDX Broker Saved Links are managed in Design → Website → Saved Links, and they can be used to create reusable IDX results pages based on search criteria. (IDX Broker)
Important Notes
Developer Note: This example is intended for experienced developers familiar with PHP, cURL, JSON, and the IDX Broker API.
Before using this example, review the following:
- Do not expose API keys in public URLs.
- Do not disable SSL verification in production.
- Confirm the current API version before hardcoding an
apiversionheader. - Test all generated Saved Links before using them on a live site.
- Older examples may contain outdated API versioning, unsafe credential handling, or incomplete query string logic.
Project Overview
This project uses two PHP files and one temporary JSON file:
| File | Purpose |
|---|---|
get-saved-links.php | Retrieves existing Saved Links from the account |
create-saved-links.php | Creates new Saved Links with iterated price ranges |
params.json | Temporarily stores Saved Link names and query strings |
The workflow is:
- Enter an IDX Broker API key.
- Retrieve existing Saved Links from the account.
- Select one Saved Link as the base.
- Remove any existing
lpandhpprice parameters. - Create new Saved Links with updated price ranges.
Security Recommendations
Do Not Pass API Keys in URLs
Avoid links like this:
create-saved-links.php?q=0&key=API_KEY_HERE
Passing API keys in URLs can expose credentials through:
- Browser history
- Server logs
- Analytics tools
- Referrer headers
- Screenshots
Use a PHP session instead.
Do Not Disable SSL Verification in Production
Avoid this in production:
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
Use the default SSL verification settings unless you have a controlled development reason to disable them temporarily.
File 1: get-saved-links.php
This file retrieves the account’s existing Saved Links and lets the user choose which Saved Link should be used as the base.
<?php
session_start();
$paramsFile = __DIR__ . '/params.json';
file_put_contents($paramsFile, json_encode([]));
function h($value) {
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['api_key'])) {
$_SESSION['idx_api_key'] = trim($_POST['api_key']);
}
$apiKey = $_SESSION['idx_api_key'] ?? '';
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Create Price Range Saved Links</title>
</head>
<body>
<h1>Create Price Range Saved Links</h1>
<p>Select an existing Saved Link to use as the base. New Saved Links will be created with updated low and high price ranges.</p>
<?php if (!$apiKey): ?>
<form method="post">
<label>
API Key:
<input type="password" name="api_key" required>
</label>
<button type="submit">Get Saved Links</button>
</form>
<?php
exit;
endif;
$url = 'https://api.idxbroker.com/clients/savedlinks';
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'accesskey: ' . $apiKey,
'outputtype: json'
];
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($handle);
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
echo '<p>HTTP response code: ' . h($code) . '</p>';
if ($code < 200 || $code >= 300) {
echo '<p>Unable to retrieve Saved Links. Check the API key and try again.</p>';
exit;
}
$savedLinks = json_decode($response, true);
if (!is_array($savedLinks)) {
echo '<p>Unexpected API response.</p>';
exit;
}
$params = [];
foreach ($savedLinks as $index => $savedLink) {
$linkName = $savedLink['linkName'] ?? '';
$queryString = $savedLink['queryString'] ?? '';
$uid = $savedLink['uid'] ?? '';
$params[] = [
'link_name' => $linkName,
'query_string' => $queryString
];
echo '<hr>';
echo '<p><strong>Link Name:</strong> ' . h($linkName) . '</p>';
echo '<p><strong>Query String:</strong> ' . h($queryString) . '</p>';
echo '<p><strong>UID:</strong> ' . h($uid) . '</p>';
echo '<p><a href="create-saved-links.php?q=' . h($index) . '"><button>Create price range links</button></a></p>';
}
file_put_contents($paramsFile, json_encode($params, JSON_PRETTY_PRINT));
?>
</body>
</html>
File 2: create-saved-links.php
This file creates new Saved Links based on the selected Saved Link.
The example below creates Saved Links in $100,000 increments up to $500,000.
<?php
session_start();
function h($value) {
return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
}
function removePriceParams($queryString) {
parse_str(ltrim($queryString, '?'), $params);
unset($params['lp'], $params['hp']);
return $params;
}
$apiKey = $_SESSION['idx_api_key'] ?? '';
if (!$apiKey) {
echo 'Missing API key. Return to get-saved-links.php first.';
exit;
}
$index = isset($_GET['q']) ? (int) $_GET['q'] : -1;
$file = __DIR__ . '/params.json';
if (!file_exists($file)) {
echo 'Missing params.json. Return to get-saved-links.php first.';
exit;
}
$savedLinks = json_decode(file_get_contents($file), true);
if (!isset($savedLinks[$index])) {
echo 'Invalid Saved Link selection.';
exit;
}
$baseLinkName = $savedLinks[$index]['link_name'];
$baseQueryString = $savedLinks[$index]['query_string'];
$baseParams = removePriceParams($baseQueryString);
echo '<h1>Saved Links with Price Ranges</h1>';
echo '<p><strong>Base Link:</strong> ' . h($baseLinkName) . '</p>';
$priceStep = 100000;
$maxPrice = 500000;
for ($lowPrice = 100000; $lowPrice < $maxPrice; $lowPrice += $priceStep) {
$highPrice = $lowPrice + $priceStep;
$queryParams = $baseParams;
$queryParams['lp'] = $lowPrice;
$queryParams['hp'] = $highPrice;
$newLinkName = $baseLinkName . '-' . $lowPrice . '-to-' . $highPrice;
$data = [
'linkName' => $newLinkName,
'pageTitle' => $newLinkName,
'linkTitle' => $newLinkName,
'queryString' => $queryParams
];
$encodedData = http_build_query($data);
$headers = [
'Content-Type: application/x-www-form-urlencoded',
'accesskey: ' . $apiKey,
'outputtype: json'
];
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, 'https://api.idxbroker.com/clients/savedlinks');
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($handle, CURLOPT_POSTFIELDS, $encodedData);
$response = curl_exec($handle);
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
echo '<hr>';
echo '<p><strong>Created Link:</strong> ' . h($newLinkName) . '</p>';
echo '<p><strong>HTTP Code:</strong> ' . h($code) . '</p>';
if ($code >= 200 && $code < 300) {
echo '<p>Saved Link created successfully.</p>';
} else {
echo '<p>Saved Link may not have been created. Review the API response.</p>';
echo '<pre>' . h($response) . '</pre>';
}
}
What Was Updated from the Legacy Example
The older lesson used the same general concept, but several parts should be modernized before publication.
Updates include:
- Removed API key from the URL string.
- Stored the API key in a PHP session instead.
- Removed hardcoded
apiversion: 1.2.1. - Corrected the HTTP response check from
||to&&. - Fixed the missing
$injson_decode($response, true). - Removed SSL bypass options from the production example.
- Rebuilt the query string using
parse_str()andhttp_build_query(). - Ensured the new
lpandhpvalues are actually added to the Saved Link query. - Corrected the temporary file name to
params.json.
Polygon Saved Links
Polygon Saved Links may require additional handling because latitude and longitude values can introduce encoding issues. IDX Broker’s older developer example notes that polygon Saved Link creation may require removing plus signs from latitude and longitude query values. (IDX Broker Developer)
If adapting this script for polygon Saved Links:
- Test the generated Saved Link carefully.
- Confirm the polygon still loads correctly.
- Review encoded spaces and coordinate values.
- Avoid assuming all query strings can be rebuilt the same way.
Best Practices
Test with One Saved Link First
Before bulk creating links, test with one Saved Link and confirm:
- Search criteria are correct
- Price ranges are correct
- Link names are acceptable
- Results pages load as expected
Review Created Links in the Dashboard
After running the script, check:
Design → Website → Saved Links
Confirm each generated Saved Link appears correctly. IDX Broker’s Saved Link manager displays created links and related details such as type, creation date, and views. (IDX Broker)
Keep the Script Private
This utility should not be publicly accessible.
Recommended protections:
- Password-protect the directory
- Restrict by IP address
- Remove the script after use
- Avoid storing API keys in files
Confirm API Behavior Before Use
IDX Broker API access uses request headers and API keys from the IDX Broker control panel. (IDX Broker Developer)
Before using this script in production:
- Confirm the client’s API key is active
- Confirm API access is enabled
- Confirm the expected request format for Saved Links
- Confirm whether an API version header is required for that account
Summary
This script can speed up the process of creating multiple price-based Saved Links from one existing Saved Link.
Use it when you need predictable Saved Link variations such as:
- city pages by price range
- neighborhood pages by price range
- property type pages by price range
- SEO landing pages with consistent search criteria
Because this is a developer utility, it should be tested carefully and kept private.