This reference covers authentication, every endpoint, the request and response envelopes, rate limits, and ready-to-run examples in cURL, JavaScript, and PHP.
https://buyrealestatedata.com/wp-json/pdm/v1
Overview
The API is a read-only JSON REST API. You send authenticated GET requests with query-string filters and receive a predictable JSON envelope. Every data endpoint lives under the base URL above.
- Format: JSON over HTTPS. All responses use a consistent
{ success, data }envelope. - Auth: a Bearer API key on every data request.
- Scope: you can query the data types and states included in your subscription. Requests outside that scope are declined.
- Limits: a per-minute rate limit plus your plan's request quota.
Authentication
Authenticate by sending your API key as a Bearer token in the Authorization header on every request to a protected endpoint:
Authorization: Bearer YOUR_API_KEYKeys are issued with your subscription from your account dashboard. Keep them secret — a key carries your plan's access and quota. If a key is missing or malformed you'll get 401; if it's invalid or inactive you'll get 403.
| Condition | Status | Error code |
|---|---|---|
No Authorization header | 401 | rest_unauthorized |
| Key invalid, revoked, or inactive | 403 | rest_forbidden |
Quick start
Three steps to your first response:
- Get your key from your account dashboard after subscribing.
- Call an endpoint with your filters and the Bearer header.
- Read the envelope — your results are in
data, totals inmeta.
A first request for FSBO listings in Texas:
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/properties?pdm_state=TX&pdm_data_type=fsbo&pdm_per_page=5' \
-H 'Authorization: Bearer YOUR_API_KEY'Requests & headers
All data endpoints are GET requests. Filters are passed as URL query parameters. Recommended headers:
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes (protected endpoints) |
Accept | application/json | Recommended |
CORS: the API is cross-origin friendly. It echoes the request Origin, allows the Authorization header, answers OPTIONS preflight, and exposes the rate-limit headers (X-RateLimit-*, Retry-After) to browser clients. Cookies/credentials are not used.
Unknown parameters are rejected. Every endpoint declares the exact parameters it accepts; sending anything else returns 400. Stick to the documented filters.
Rate limits
Requests are rate limited per key, per minute. Every pdm/v1 response includes the current state in headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the current window |
X-RateLimit-Remaining | Requests left in the window |
X-RateLimit-Reset | Seconds until the window resets |
Retry-After | Seconds to wait — sent only on a 429 |
Exceed the limit and you receive 429 with code rest_rate_limited. Honor Retry-After before retrying. This minute-window limit is separate from your plan's overall quota described next.
Quotas & entitlements
Two independent limits apply:
- Rate limit — short-term burst protection (per minute, above).
- Plan quota — the total number of data requests your subscription allows, and which data types and states it covers. Each successful data request consumes one slot (automatically refunded if the upstream source fails).
Two parameters are easy to confuse but mean different things:
| Parameter | Purpose |
|---|---|
pdm_data_type | Your entitlement bucket — the product you subscribed to: for_sale, fsbo, for_rent (rentals), sold, or agents. Access is checked against your plan. |
pdm_status | A listing-lifecycle filter applied within the results (e.g. for_sale, pending, sold). |
pdm_data_type or pdm_state outside your subscription, the call is declined with 403. For example, an FSBO-Texas plan can't pull for_rent data or another state.Response format
Every response uses one of three envelope shapes.
Single object
{
"success": true,
"data": { "...": "a single resource" }
}List
Results are in data (an array); pagination and totals are in meta.
{
"success": true,
"data": [ { "...": "item" }, { "...": "item" } ],
"meta": {
"total": 1842,
"page": 1
}
}Error
{
"success": false,
"error": {
"code": "rest_forbidden",
"message": "Invalid or inactive API Key",
"status": 403
}
}\"trial\": true to meta, cap total at 100, and return at most 12 items per page.Pagination
Control paging with pdm_page and pdm_per_page. The total result count comes back in meta.total, so the number of pages is ceil(meta.total / pdm_per_page).
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/properties?pdm_state=FL&pdm_data_type=for_sale&pdm_page=2&pdm_per_page=50' \
-H 'Authorization: Bearer YOUR_API_KEY'| Parameter | Default | Range |
|---|---|---|
pdm_page | 1 | 1–10000 |
pdm_per_page | 12 | 1–100 |
Errors
Errors return the error envelope with a machine-readable code, a message, the HTTP status, and optional details.
| Status | Code | Meaning & fix |
|---|---|---|
400 | rest_invalid_param | A parameter was unknown or failed validation. Use only documented filters; pdm_state must be a 2-letter code. |
401 | rest_unauthorized | Missing Authorization header. Add Bearer YOUR_API_KEY. |
403 | rest_forbidden | Key invalid/inactive, quota exhausted, or the data type/state isn't in your plan. |
429 | rest_rate_limited | Too many requests this minute. Wait Retry-After seconds. |
5xx | varies | Temporary upstream/data-source issue. Your quota slot is refunded — retry shortly. |
Filter parameters
These apply to the list endpoints (properties and agents). Price/size filters are ignored for agents.
| Parameter | Type | Required | Description |
|---|---|---|---|
pdm_data_type | string | recommended | Entitlement bucket: for_sale, fsbo, for_rent / rentals, sold, agents. Must be within your subscription. |
pdm_state | string | — | Two-letter US state code, e.g. TX. Must be within your subscription. |
pdm_city | string | — | City name (max 100 chars). |
pdm_postal_code | string | — | ZIP/postal code. |
pdm_status | string | — | Listing status filter: for_sale, fsbo, for_rent, sold, pending. |
pdm_min_price | integer | — | Minimum price. |
pdm_max_price | integer | — | Maximum price. |
pdm_beds | integer | — | Minimum bedrooms (0–50). |
pdm_baths | number | — | Minimum bathrooms (0–50). |
pdm_sqft_min | integer | — | Minimum living area in square feet. |
pdm_page | integer | — | Page number (default 1). |
pdm_per_page | integer | — | Results per page (default 12, max 100). |
List properties
/propertiesSearch property listings with the filter parameters. Requires authentication and consumes one quota slot. Returns a paginated list.
Example request
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/properties?pdm_state=TX&pdm_data_type=fsbo&pdm_beds=3&pdm_min_price=200000&pdm_per_page=20' \
-H 'Authorization: Bearer YOUR_API_KEY'Example response
{
"success": true,
"data": [
{
"property_id": "123456789",
"list_price": 329000,
"address": "123 Main St, Austin, TX 78701",
"beds": 3,
"baths": 2,
"sqft": 1840,
"status": "for_sale"
}
],
"meta": { "total": 1842, "page": 1 }
}Get a property
/properties/{id}Fetch a single property by its property_id. Requires authentication.
| Path parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | The listing identifier (alphanumeric, dashes/underscores). |
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/properties/123456789' \
-H 'Authorization: Bearer YOUR_API_KEY'List agents
/agentsSearch agent records. Accepts the same schema as properties (location and paging filters apply; price/size filters are ignored). Requires authentication and consumes one quota slot.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/agents?pdm_state=CA&pdm_city=San%20Diego&pdm_per_page=25' \
-H 'Authorization: Bearer YOUR_API_KEY'Get an agent
/agents/{id}Fetch a single agent by id. Requires authentication.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/agents/AGENT_ID' \
-H 'Authorization: Bearer YOUR_API_KEY'Suggestions
/suggestionsLightweight location autocomplete, handy for search boxes. Requires authentication.
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | — | Partial query string (max 100 chars). |
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/suggestions?q=aus' \
-H 'Authorization: Bearer YOUR_API_KEY'Account
/meReturns the account, plan, and current usage tied to your key. Requires authentication but does not consume a data quota slot — useful for showing remaining quota in your own dashboard.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/me' -H 'Authorization: Bearer YOUR_API_KEY'Analytics
/analyticsUsage analytics for your key (request volume over time). Requires authentication; no quota consumed.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/analytics' -H 'Authorization: Bearer YOUR_API_KEY'Preview (no auth)
/preview/properties/preview/agentsPublic, unauthenticated endpoints for testing and free-tier front-ends. No key required. They accept the same filters but are capped: up to 5 pages, 20 results per page, and a total of 100. They're the fastest way to see the live response shape.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/preview/properties?pdm_state=NY&pdm_per_page=5'Health
/healthPublic status probe for uptime monitoring. No auth, no quota, no upstream calls.
{
"status": "ok",
"version": "x.y.z",
"timestamp": "2026-06-02T00:00:00Z",
"checks": { "db": "ok" }
}Code examples
A typical authenticated list request in three languages.
curl -s 'https://buyrealestatedata.com/wp-json/pdm/v1/properties?pdm_state=TX&pdm_data_type=fsbo&pdm_per_page=20' \
-H 'Authorization: Bearer YOUR_API_KEY'const res = await fetch(
'https://buyrealestatedata.com/wp-json/pdm/v1/properties?' + new URLSearchParams({
pdm_state: 'TX',
pdm_data_type: 'fsbo',
pdm_per_page: '20',
}),
{ headers: { Authorization: 'Bearer ' + API_KEY } }
);
const json = await res.json();
if (!json.success) throw new Error(json.error.message);
console.log(json.meta.total, json.data);<?php
$url = 'https://buyrealestatedata.com/wp-json/pdm/v1/properties?' . http_build_query([
'pdm_state' => 'TX',
'pdm_data_type' => 'fsbo',
'pdm_per_page' => 20,
]);
$res = wp_remote_get($url, [
'headers' => ['Authorization' => 'Bearer ' . $api_key],
'timeout' => 30,
]);
$body = json_decode(wp_remote_retrieve_body($res), true);
if (empty($body['success'])) {
// handle $body['error']
}
$listings = $body['data'];
$total = $body['meta']['total'];Troubleshooting
- I'm getting
401 Missing Authorization Header - Add the header
Authorization: Bearer YOUR_API_KEY. Some HTTP clients strip it on redirects — send it explicitly. - I'm getting
403on every request - Either the key is inactive, your quota is used up, or you're requesting a
pdm_data_type/pdm_stateoutside your plan. Check /me for your entitlements and remaining quota. - I'm getting
400 - A parameter is unknown or invalid. Only the documented filters are accepted, and
pdm_statemust be a 2-letter code. - I'm getting
429 - You exceeded the per-minute limit. Wait the number of seconds in the
Retry-Afterheader, then retry. WatchX-RateLimit-Remainingto pace requests. datais empty- Your filters may be too narrow, or you're on a preview/trial response (capped at 100 results). Broaden the filters or confirm your plan covers the requested type and state.
buyrealestatedata.com/wp-json/pdm/v1