GET /real-estate/pulse/series
Multi-period sibling of /pulse — N-period pulls in one call. Cap 12 periods. Drop-in replacement for the analyst's YoY/QoQ loop.
/api/v1/real-estate/pulse/series returns the same row shape as
/pulse for multiple consecutive periods in one
call. Designed for institutional analysts pulling year-over-year /
quarter-over-quarter portfolio comparisons.
GET https://veacon.io/api/v1/real-estate/pulse/series
| Method | GET |
| Auth | X-API-Key header (B2B) or veacon_session cookie (Syncle SSO) |
| Quota cost | 1 call (regardless of period count) |
| Period cap | 12 periods per request — quarterly = 3 years, monthly = 1 year |
Why this endpoint exists
Today, an analyst running a 12-quarter portfolio comparison loops
/pulse?period=2024-Q1, /pulse?period=2024-Q2, ..., /pulse?period=2026-Q4.
That's 12 round-trips, 12x quota, 12x latency.
/pulse/series collapses it to one call. Same data, same envelope, same
trust semantics — just denormalized along the period axis.
Query parameters
Same filters as /pulse, with one period selector required:
| Param | Type | Required | Notes |
|---|---|---|---|
sigungu_code | string | Yes | 5-digit (e.g. "11680" = 강남구) |
periods | string | Yes (or use range) | Comma-separated, max 12 — "2025-Q1,2025-Q2,..." |
from_period + to_period | string | Yes (or use list) | Inclusive range (same kind on both sides) |
property_type | string | No | office / retail / commercial_complex / mixed_use |
transaction_type | string | No | sale / chartered_lease / monthly_lease |
geo_precision | string | No | sigungu (default) / dong (Pro+) |
dong | string | No | Used when geo_precision='dong' |
Period syntax
Each period must be either calendar month (YYYY-MM) or calendar quarter
(YYYY-Qn). Mixed kinds are rejected — all-month or all-quarter, not
both. Rolling windows (last_3m, etc.) are intentionally not supported on
this endpoint; rolling windows have no clear "next period" semantics.
Range expansion
from_period=2025-Q1&to_period=2026-Q1 expands to
["2025-Q1", "2025-Q2", "2025-Q3", "2025-Q4", "2026-Q1"]. The expanded list
must fit within the 12-period cap.
Response shape
{
"data": [
{
"sigungu_code": "11680",
"sigungu": "강남구",
"property_type": "office",
"transaction_type": "sale",
"period": "2025-Q4",
"sample_count": 18,
"median_price": 4180000000,
"p25_price": 3900000000,
"p75_price": 4500000000,
"avg_area_m2": "162.3",
"confidence": "high",
"source_mix": { "rtms_official": 14, "rone_index_derived": 4 },
"source_means": { "rtms_official": 4180000000, "rone_index_derived": 4220000000 },
"confidence_factors": {
"distinct_sources": 2,
"relative_spread": 0.0096,
"sample_count": 18,
"ladder_reason": "2+ sources, spread <= 20%"
}
},
{
"...": "one row per (cohort × period) — see /pulse for full row schema"
}
],
"_meta": {
"service": "veacon",
"api_version": "v1",
"vertical": "real_estate",
"tier": "pro",
"auth_method": "api_key",
"data_sources": ["rtms_official", "rone_index_derived", "public_assessment"],
"coverage_estimate": null,
"coverage_note": "...",
"lease_data_status": "absent",
"known_limitations": ["..."],
"disclosure_url": "https://veacon.io/data-trust",
"confidence": "medium",
"source_mix": { "rtms_official": 56, "rone_index_derived": 16 },
"count": 12,
"periods_requested": ["2025-Q1", "2025-Q2", "2025-Q3", "2025-Q4", "2026-Q1"],
"periods_returned": ["2025-Q2", "2025-Q4", "2026-Q1"],
"missing_periods": ["2025-Q1", "2025-Q3"],
"rate_limit": { "limit_per_min": 120, "remaining": 119 }
}
}
Series-specific envelope fields
| Field | Type | Notes |
|---|---|---|
periods_requested | string[] | What you asked for (post-expansion if range was used) |
periods_returned | string[] | Distinct periods present in data (sorted) |
missing_periods | string[] | periods_requested - periods_returned. Periods with zero rows. |
count | number | Total data row count across all periods |
confidence | string | Worst confidence across all returned rows (matches /pulse semantics) |
source_mix | object | Aggregated source_mix across all periods + cohorts |
Sparse-data behavior
When some periods have data and others don't, the endpoint returns 200
with rows for the populated periods and the empty periods listed in
missing_periods. Callers can render gaps without re-deriving from the
data array.
When every requested period is empty (e.g. wrong sigungu code, all
out-of-coverage), the endpoint returns 404 — but the envelope is still
present, including missing_periods containing all requested periods.
ADR-015 acceptance criterion.
curl
# Comma-separated list
curl -H "X-API-Key: $VEACON_API_KEY" \
"https://veacon.io/api/v1/real-estate/pulse/series?sigungu_code=11680&property_type=office&periods=2025-Q1,2025-Q2,2025-Q3,2025-Q4,2026-Q1"
# Range expansion (same result as above)
curl -H "X-API-Key: $VEACON_API_KEY" \
"https://veacon.io/api/v1/real-estate/pulse/series?sigungu_code=11680&property_type=office&from_period=2025-Q1&to_period=2026-Q1"
Errors
Same error matrix as /pulse, with these series-specific 400 cases:
| Code | When |
|---|---|
INVALID_PARAMS | periods array is empty / count > 12 / contains an invalid period |
INVALID_PARAMS | from_period xor to_period provided (must be paired) |
INVALID_PARAMS | range expansion would exceed 12 periods |
INVALID_PARAMS | Mixed period kinds (2025-Q1,2025-12) |
INVALID_PARAMS | Neither periods nor from_period+to_period supplied |
Pricing intent
/pulse/series charges 1 call per request, regardless of period count.
This is intentional: Veacon's pricing tiers are plan-based with monthly
call limits, not per-row consumption. The endpoint exists to reduce
analyst friction and cohort 1 perceived value, not to multiply revenue.
When to use /pulse instead
Use /pulse (single-period) when:
- You need a rolling window (
last_3m,last_6m,last_12m) — series only accepts calendar periods. - You're building a real-time dashboard polling for the latest period only.
- Period count = 1 (no benefit; same request shape).
For everything else — portfolio analysis, time-series modeling, YoY/QoQ
comparison — prefer /pulse/series.
See also
/pulse— single-period sibling- Confidence Score — Layer 3 ladder formula
- Methodology — source provenance + DDQ pre-answer