> ## Documentation Index
> Fetch the complete documentation index at: https://docs.permitcore.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Data freshness

> Nightly refresh cadence, the `as_of_utc` timestamp, and field-level data-quality flags.

PermitCore refreshes permit data **nightly** from each metro's open-data
portal. Cohort classification, DQ flagging, and parcel join happen in the
same nightly pipeline.

## Refresh cadence

* **Source pull:** every metro's open-data portal is pulled once per
  24 hours, scheduled per metro to land before 02:00 local time.
* **Cohort classify + DQ flag:** runs immediately after each source pull.
  Adds \~15 minutes per metro for the classifier pass.
* **Site + API publish:** updated rows land in the API by 02:30 local
  time per metro. The cohort distribution endpoint caches 1 hour
  (`Cache-Control: max-age=3600`).

## The `as_of_utc` field

Every API response that returns aggregated state includes an `as_of_utc`
timestamp marking when the underlying data was last computed:

```json theme={null}
{
  "jurisdiction_slug": "nyc",
  "as_of_utc": "2026-05-24T02:00:00Z",
  ...
}
```

Use this to detect stale cached responses, drive your own UI freshness
indicators, and reconcile multi-source pipelines.

## ISR caching on the site

The PermitCore site (permitcore.io) consumes the same cohort distribution
endpoint via Next.js ISR with `revalidate: 3600`. So the site's cohort
breakdowns lag the underlying data by **at most 1 hour** beyond the
upstream pipeline's own latency.

For real-time-critical use cases (e.g., webhook-driven CRM lead loading),
use the [`/v1/permits`](/api-reference/permits) endpoint directly. A
webhook event stream is on the roadmap and not yet available.

## Field-level data-quality flags

Every permit row carries a 12-key `dq_flags` object surfaced per field.
The flags come from the **WS-PE-DQ-2 bounds-rule registry** and tell you
which fields the pipeline's rules flagged as suspect — `false` on a flag
means *the rule has not flagged this value*, NOT *the value was
independently verified clean* (the SD-039 semantic).

NULL silver flag values are coerced to `false` per the same SD-039 rule.
All 12 keys are always present when `dq_flags` is non-null.

| Flag                               | What it flags                                              |
| ---------------------------------- | ---------------------------------------------------------- |
| `issued_date_is_parse_bug`         | `issued_date` came through a known adapter parse bug       |
| `issued_date_is_placeholder`       | `issued_date` looks like a placeholder (e.g. `1900-01-01`) |
| `issued_date_is_future_dated`      | `issued_date` is in the future                             |
| `valuation_usd_is_placeholder`     | `valuation_usd` looks like a placeholder (e.g. `$1`, `$0`) |
| `valuation_usd_is_oob`             | `valuation_usd` is out of plausible bounds                 |
| `units_residential_is_placeholder` | `units_residential` looks like a placeholder               |
| `units_residential_is_oob`         | `units_residential` is out of plausible bounds             |
| `units_commercial_is_placeholder`  | `units_commercial` looks like a placeholder                |
| `units_total_is_placeholder`       | `units_total` looks like a placeholder                     |
| `units_total_is_oob`               | `units_total` is out of plausible bounds                   |
| `geocode_is_sentinel`              | `lat`/`lng` is a sentinel value (e.g. metro centroid)      |
| `geocode_is_oob`                   | `lat`/`lng` is outside the jurisdiction's bounding box     |

The `dq_flags` object is emitted today on both
[`GET /v1/permits`](/api-reference/permits) and
[`GET /v1/permits/by-canonical-uid/{canonical_uid}`](/api-reference/permits-by-canonical-uid),
landed with the 2026-06-04 enrichment promotion — see the
[changelog](/changelog).

For NYC permits the detail endpoint also returns a nested `pluto`
object (`{is_placeholder, oob}`) reporting the PLUTO parcel-data
presence + DQ status with the same SD-039 semantic. That object is
**list-endpoint NULL by design** — the PLUTO JOIN adds \~75ms p95 and
disqualifies for the browse path.

## How freshness interacts with your billing

Tier-aware quotas reset on the **first of each month UTC**. Your usage
counters update in near-real-time on cache invalidation (typically
within 10 seconds of a successful request).

See [Rate limits →](/concepts/rate-limits) for current tier quotas.
