What the API returns
The API is aggregate-first. Sale and rent are separate market populations in storage, calculations and responses. It returns market-level evidence with observation counts, confidence and time windows—not raw listing descriptions, images, contacts or exact addresses.
Price evidence
For sale: total asking price and EUR/m². For rent: monthly asking rent and EUR/m²/month. The two modes are never combined.
Supply evidence
Active supply, new observations and removals for eligible cities, neighbourhoods and property kinds.
Quality evidence
Priced observation counts, source diversity, maximum source share and medium or high confidence.
Historical delivery
Up to 366 daily aggregate snapshots per request for Data Delivery and Enterprise licences.
Authentication and key handling
The production design uses an organisation API key as a Bearer token. Once key management is provisioned, named administrators create and revoke keys inside the secure account area; the secret is displayed once and is never sent by email.
- Keep keys in a server-side secret manager or environment variable.
- Never place a production key in browser JavaScript, source control, logs, prompts or support messages.
- Use separate keys per production system and revoke a key immediately when a system or administrator changes.
- Send a unique X-Client-Request-Id so requests can be traced without exposing business data.
curl --request GET \
--url 'https://bulgarian-listings.152-53-109-83.sslip.io/api/v1/market/snapshot?area_id=bg-sofia-lozenets&market_mode=sale&property_kind=apartment&as_of=2026-07-18' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'X-Client-Request-Id: portfolio-review-2026-07-19'Response contract
Every successful response separates licensed data from operational metadata. Snapshot and time-series requests require market_mode=sale or market_mode=rent. Preserve the mode and metadata when storing or presenting results.
| Field | Meaning |
|---|---|
data | The requested aggregate market result. |
data.market_mode | sale or rent. This dimension must be retained; results from different modes must not be merged. |
meta.request_id | Trace identifier to include in support requests. |
meta.generated_at | UTC time at which the response was generated. |
meta.observation_window | Dates of the observations supporting the result. |
meta.weighted_data_units | Billable units consumed by this response. |
Production v1 endpoints
Availability depends on the licensed tier, quality-gated coverage and permitted use in the order form.
| Method | Path | Returns | Starting tier |
|---|---|---|---|
| GET | /markets/coverage | Discover eligible area IDs and separate sale/rent coverage; optionally filter by market_mode. | Insights |
| GET | /market/snapshot | Return one aggregate snapshot for the required sale or rent market mode. | Insights |
| GET | /market/timeseries | Return up to 366 daily points for one required market mode, area and property kind. | Data Delivery |
Sale snapshot example
Illustrative sale values only. They are not current market statistics and must not be used for a decision. For rent, price fields mean monthly asking rent and EUR/m²/month.
{
"data": {
"area_id": "bg-sofia-lozenets",
"market_mode": "sale",
"property_kind": "apartment",
"as_of": "2026-07-18",
"active_listings": 418,
"new_listings": 19,
"removed_listings": 14,
"priced_listings": 391,
"median_asking_price_eur": 286000,
"median_asking_price_per_sqm_eur": 2840,
"p25_asking_price_per_sqm_eur": 2370,
"p75_asking_price_per_sqm_eur": 3310,
"source_count": 3,
"max_source_share": 0.42,
"confidence": "high",
"calculation_version": "market-api-daily-v2",
"published_at": "2026-07-19T08:30:00Z"
},
"meta": {
"request_id": "req_01JZ8W5Y6M9R7Q2F4A",
"generated_at": "2026-07-19T08:30:00Z",
"observation_window": {
"from": "2026-07-18",
"to": "2026-07-18"
},
"weighted_data_units": 1
}
}Sale time-series example
A series contains exactly one market mode. Each point retains its mode and observation count so a consumer can distinguish movement from a changing sample.
{
"data": {
"area_id": "bg-sofia-lozenets",
"market_mode": "sale",
"property_kind": "apartment",
"date_from": "2026-07-15",
"date_to": "2026-07-18",
"points": [
{"area_id": "bg-sofia-lozenets", "market_mode": "sale", "property_kind": "apartment", "as_of": "2026-07-15", "active_listings": 402, "new_listings": 12, "removed_listings": 9, "priced_listings": 378, "median_asking_price_eur": 281000, "median_asking_price_per_sqm_eur": 2815, "p25_asking_price_per_sqm_eur": 2350, "p75_asking_price_per_sqm_eur": 3280, "source_count": 3, "max_source_share": 0.43, "confidence": "high", "calculation_version": "market-api-daily-v2", "published_at": "2026-07-16T01:10:00Z"},
{"area_id": "bg-sofia-lozenets", "market_mode": "sale", "property_kind": "apartment", "as_of": "2026-07-18", "active_listings": 418, "new_listings": 19, "removed_listings": 14, "priced_listings": 391, "median_asking_price_eur": 286000, "median_asking_price_per_sqm_eur": 2840, "p25_asking_price_per_sqm_eur": 2370, "p75_asking_price_per_sqm_eur": 3310, "source_count": 3, "max_source_share": 0.42, "confidence": "high", "calculation_version": "market-api-daily-v2", "published_at": "2026-07-19T08:30:00Z"}
]
},
"meta": {
"request_id": "req_01JZ8W8BQM5P3JY7VT",
"generated_at": "2026-07-19T08:30:00Z",
"observation_window": {"from": "2026-07-15", "to": "2026-07-18"},
"weighted_data_units": 1
}
}Caching and weighted data units
Licences are metered by data delivered. A snapshot costs one unit; coverage costs one unit per 100 areas; time series cost one unit per 30 daily points, rounded up.
- Use ETag and If-None-Match. A matching 304 response returns no payload and consumes zero data units.
- Read meta.weighted_data_units and the X-Data-Units-Remaining header after every successful call.
- A licence-wide monthly hard limit stops delivery before usage can exceed the contracted allowance.
- Honor Retry-After on HTTP 429 and use exponential backoff with jitter for retryable 5xx responses.
X-Request-Id: req_01JZ8W5Y6M9R7Q2F4A
X-Data-Units-Used: 1
X-Data-Units-Remaining: 24841
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
ETag: "snapshot-bg-sofia-lozenets-sale-2026-07-18"Errors and retries
Errors use stable machine-readable codes and include the same request identifier available in response headers.
| HTTP | Code | Client action |
|---|---|---|
400 | invalid_parameter | Correct the request; do not retry unchanged. |
401 | invalid_api_key | Stop and rotate or replace the credential. |
403 | licence_scope_denied | The endpoint is outside the key or licence scope. |
403 | licence_inactive | Contact the organisation owner or PazarenRadar. |
404 | not_found | Verify the canonical identifier using /markets/coverage. |
429 | rate_limited | Wait for Retry-After, then retry with jitter. |
429 | monthly_usage_exhausted | Wait for the next month or arrange a larger allowance. |
500/503 | temporary_failure | Retry up to three times with exponential backoff. |
{
"error": {
"code": "not_found",
"message": "not found",
"request_id": "req_01JZ8WBZ4R8Q1C6K9N"
}
}Instructions for AI agents
Treat the API as a licensed analytical tool, not as unrestricted browsing data. Give these rules to any agent that can call it.
- Resolve locations with GET /markets/coverage before analysis. Never guess an area_id.
- Select exactly one market_mode for each analysis. Never merge, average or compare sale and rent price fields as if they had the same unit.
- Use only fields and enum values in the issued OpenAPI contract; do not fabricate missing metrics.
- State market mode, as-of date, observation window, priced listing count and confidence alongside conclusions.
- For sale, price fields are total asking price and EUR/m². For rent, they are monthly asking rent and EUR/m²/month. Neither is a completed transaction price.
- Do not use aggregates to identify a person, contact, exact property or exact address.
- Keep API credentials outside the model context. Give the agent a narrow server-side tool, never the raw key.
- Estimate unit cost before long time-series ranges and request human approval for high-volume actions.
- Retry only 429 and temporary 5xx responses. Never loop on 400, 401, 403 or 404.
- Preserve request_id in citations or audit logs so every claim can be traced to a response.
Suggested agent policy
Use PazarenRadar only for aggregate Bulgarian property-market analysis. Resolve canonical locations through the coverage tool. Select exactly one market_mode: sale or rent. Never combine the two. For sale, interpret price fields as total asking price and EUR/m²; for rent, interpret them as monthly asking rent and EUR/m²/month. Never invent an area ID, metric, date or missing value. Include market mode, as-of date, observation window, priced listing count and confidence in every market conclusion. Neither mode contains completed transaction prices. Never expose credentials, personal data or exact addresses. Ask for human confirmation before high-unit time-series ranges. Honor licence scope, Retry-After and hard usage limits.
Example tool definition
Expose a narrow tool to the agent. Your application—not the model—adds the Bearer credential and enforces allowed areas, metrics and budget.
{
"name": "get_market_snapshot",
"description": "Get aggregate asking-price, supply and movement evidence for one licensed Bulgarian market area.",
"input_schema": {
"type": "object",
"properties": {
"area_id": {
"type": "string",
"description": "Canonical area ID returned by GET /markets/coverage."
},
"property_kind": {
"type": "string",
"enum": ["all", "apartment", "one-room", "two-room", "three-room", "four-plus-room", "house"]
},
"market_mode": {
"type": "string",
"enum": ["sale", "rent"],
"description": "Required. Never combine sale and rent evidence."
},
"as_of": {
"type": "string",
"format": "date"
}
},
"required": ["area_id", "market_mode", "property_kind"],
"additionalProperties": false
}
}Integration examples
These examples call the production base URL. They require an active scoped key issued to your organisation.
curl --request GET \
--url 'https://bulgarian-listings.152-53-109-83.sslip.io/api/v1/market/snapshot?area_id=bg-sofia-lozenets&market_mode=sale&property_kind=apartment&as_of=2026-07-18' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'X-Client-Request-Id: portfolio-review-2026-07-19'const parameters = new URLSearchParams({
area_id: 'bg-sofia-lozenets',
market_mode: 'sale',
property_kind: 'apartment',
as_of: '2026-07-18',
});
const response = await fetch(
`https://bulgarian-listings.152-53-109-83.sslip.io/api/v1/market/snapshot?${parameters}`,
{
headers: {
Accept: 'application/json',
Authorization: `Bearer ${process.env.PAZARENRADAR_API_KEY}`,
'X-Client-Request-Id': crypto.randomUUID(),
},
},
);
if (response.status === 429) {
throw new Error(`Retry after ${response.headers.get('retry-after')}s`);
}
if (!response.ok) throw new Error(await response.text());
const snapshot = await response.json();
console.log(snapshot.data.median_asking_price_per_sqm_eur);import os
import uuid
import requests
response = requests.get(
"https://bulgarian-listings.152-53-109-83.sslip.io/api/v1/market/snapshot",
params={
"area_id": "bg-sofia-lozenets",
"market_mode": "sale",
"property_kind": "apartment",
"as_of": "2026-07-18",
},
headers={
"Accept": "application/json",
"Authorization": f"Bearer {os.environ['PAZARENRADAR_API_KEY']}",
"X-Client-Request-Id": str(uuid.uuid4()),
},
timeout=20,
)
response.raise_for_status()
snapshot = response.json()
print(snapshot["data"]["median_asking_price_per_sqm_eur"])Need a production contract?
We qualify the use case, confirm data coverage and define volume, retention, display and derived-output rights before issuing production access.
The signed data licence and order form control permitted use, volume, retention and derived-output rights.