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.

Last updated: 2026-04-26

/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
MethodGET
AuthX-API-Key header (B2B) or veacon_session cookie (Syncle SSO)
Quota cost1 call (regardless of period count)
Period cap12 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:

ParamTypeRequiredNotes
sigungu_codestringYes5-digit (e.g. "11680" = 강남구)
periodsstringYes (or use range)Comma-separated, max 12 — "2025-Q1,2025-Q2,..."
from_period + to_periodstringYes (or use list)Inclusive range (same kind on both sides)
property_typestringNooffice / retail / commercial_complex / mixed_use
transaction_typestringNosale / chartered_lease / monthly_lease
geo_precisionstringNosigungu (default) / dong (Pro+)
dongstringNoUsed 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

json
{
  "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

FieldTypeNotes
periods_requestedstring[]What you asked for (post-expansion if range was used)
periods_returnedstring[]Distinct periods present in data (sorted)
missing_periodsstring[]periods_requested - periods_returned. Periods with zero rows.
countnumberTotal data row count across all periods
confidencestringWorst confidence across all returned rows (matches /pulse semantics)
source_mixobjectAggregated 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

bash
# 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:

CodeWhen
INVALID_PARAMSperiods array is empty / count > 12 / contains an invalid period
INVALID_PARAMSfrom_period xor to_period provided (must be paired)
INVALID_PARAMSrange expansion would exceed 12 periods
INVALID_PARAMSMixed period kinds (2025-Q1,2025-12)
INVALID_PARAMSNeither 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