On this page
Quality metrics reference
Read Golden daily snapshots and on-demand quality measurements, and understand coverage, distribution, and issue ranking.
Golden stores two kinds of quality observation: daily snapshots for closed UTC days, and on-demand measurements with their actual measurement time. Both contain the same quality and issue-ranking payloads. The Quality screen lets readers select either kind as the picture to display.
Reads allow VIEWER, STEWARD, and ADMIN with access to the table. Requesting
a new measurement requires ADMIN. Aggregates cover the whole table, including
for readers restricted to a row scope; responses report aggregateScope: ENTITY.
Request an on-demand measurement
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $GOLDEN_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"entity":"sample-customer-entity","label":"After phone correction"}' \
"$GOLDEN_URL/api/quality/measurements"
| Field | Requirement |
|---|---|
entity | Required entity identifier; one entity per request |
label | Optional label, at most 120 characters; blank means no label |
A successful request returns HTTP 200 with entity and a queued run.
Follow run.id with GET /api/jobs/runs/{id} until it reaches a terminal state.
The operation measures the entity’s table as it stands; it does not recalculate
records first. If Golden detects a measurement of the entity already in flight,
it returns 409. This is not an idempotency guarantee: do not retry a request
whose outcome is unknown.
A table with quality disabled or without a quality definition cannot produce a new picture. Inspect the run outcome and message rather than assuming that an accepted request wrote a measurement. The measurement writes its quality and issue-ranking payloads together.
Read on-demand measurements
TODAY=$(date -u +%F)
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $GOLDEN_TOKEN" \
"$GOLDEN_URL/api/metrics/tables/sample_customer/measurements?fromDay=$TODAY&toDay=$TODAY"
fromDay and toDay are required, inclusive UTC dates. The range may include
today, must not be inverted, and may span at most 366 days. The response contains
at most 200 measurements, newest first. Narrow the window when you need older
observations. A valid empty window returns 200 with measurements: [].
Each entry in measurements contains:
| Field | Meaning |
|---|---|
table | Table measured |
measuredAt | Actual measurement instant shared by both payloads |
label | Optional saved label |
requestedBy | Identifier of the principal requesting the measurement |
quality | Quality payload described below |
issues | Issue-ranking payload described below |
The response also identifies table, fromDay, toDay, and aggregateScope.
Measurements are retained separately from daily snapshots; deleting a table
also removes its measurements. Reinstalling Aurelia starts a new sample history.
Read daily snapshots
GET /api/metrics/tables/{table}/families/{family}?fromDay=<ISO>&toDay=<ISO>
| Part | Value |
|---|---|
table | A table identifier, for example sample_customer |
family | quality or quality-issues |
fromDay, toDay | ISO yyyy-MM-dd. Both required, both inclusive, both UTC days |
The family is the lowercase identifier, not an upper-case enum constant.
.../families/quality works; .../families/QUALITY answers “Metric family
QUALITY not found.”
Four rules bound the window:
- it may not be inverted;
- it must end on a day that has already closed;
- it may span at most 366 days; and
- a valid window holding no snapshots answers
200with an emptysnapshotslist, not404.
An unknown table or an unknown family answers 404.
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer ${GOLDEN_TOKEN}" \
"${GOLDEN_URL}/api/metrics/tables/sample_customer/families/quality?fromDay=2026-08-13&toDay=2026-09-11"
{
"table": "sample_customer",
"family": "quality",
"fromDay": "2026-08-13",
"toDay": "2026-09-11",
"snapshots": [],
"aggregateScope": "ENTITY"
}
aggregateScope is always ENTITY: snapshots are computed over the whole
table, not over the caller’s data scope. A reader restricted to part of a
table still sees table-wide aggregates here.
Snapshot fields
Every snapshot, whatever its family, has the same envelope:
| Field | Meaning |
|---|---|
table | The business table the snapshot describes |
day | The UTC day, identifying [00:00Z, next 00:00Z) |
family | The family identifier |
familyVersion | The version of that family’s payload schema and calculation semantics |
calculatedAt | When the aggregation was actually taken. May be after the day closed |
Exactly one payload member is set: quality, issues, or the untyped
payload object for a registered family this API version has no typed view of.
Write clients that read the family first and the payload second.
The quality family
| Field | Meaning |
|---|---|
totalRecordCount | Every current record of the table. History records are never counted |
currentQualityRecordCount | Records measured under the definition this payload names |
coveragePercentage | 100 × current / total, two decimals. Null when the table held no records |
averageQuality | Mean of current record scores, two decimals. Null when no current record carries one |
minimumQuality, maximumQuality | Lowest and highest score among current records |
histogram | Exactly ten counts: 0–9, 10–19, … 80–89, and 90–100 |
totalErrorCount, totalWarningCount | Sums of the stored finding counts |
recordsWithErrorsCount | Current records carrying at least one error |
recordsWithIssuesCount | Current records carrying at least one error or warning |
qualityDefinition | The combined quality definition the aggregation was taken against |
The final histogram bucket covers 90–100 inclusively. Include score 100
when rendering that bucket.
totalErrorCount and recordsWithErrorsCount are different questions.
The first sums findings, the second counts records. One record with three
errors contributes 3 and 1.
recordsWithIssuesCount is never below recordsWithErrorsCount.
The quality-issues family
This family ranks the problem types, most occurrences first.
| Field | Meaning |
|---|---|
entries | The ranked problem types, at most the stored limit |
otherOccurrenceCount | Occurrences belonging to types beyond that limit |
otherTypeCount | Types beyond that limit |
totalOccurrenceCount | Every finding on every current record, stored types and beyond alike |
totalTypeCount | Every distinct problem type, stored or not |
qualityDefinition | The definition the aggregation was taken against |
entries contains only the stored ranking. Use otherTypeCount and
otherOccurrenceCount to account for problem types beyond that limit.
Reading the same data in the web application
The Quality screen uses the selected observation for its summary, distribution, and issue ranking. Its trend combines scheduled and on-demand points within the chosen window. Use this mapping to compare the screen with the payload:
| On screen | In the payload |
|---|---|
| The average and its trend | averageQuality for the selected picture and across the window |
| Record count over time | totalRecordCount across the window |
| What is wrong with them | The quality-issues entries |
| Where the quality sits | histogram |
| Measurement coverage | coveragePercentage, with its two record counts |
The initial Aurelia records average 88.25 when their current scores are calculated. Distinguish that calculation from a stored snapshot and check its measurement date and coverage. See the quality exercise.
Interpreting a metric
Compare a metric with entity state, completed tasks, and configuration changes
before drawing a conclusion. A change in qualityDefinition can change scores
without business values changing, and calculatedAt can be well after the day
it describes.
A metric is evidence of a product outcome, not a diagnosis of its cause.
Golden 3.0 compatibility
The /api/metrics, /api/metrics/date/{date},
/api/metrics/range/{from}/{to}, /api/metrics/entity/{entity}, and
DELETE /api/metrics/{id} operations no longer exist and answer 404.
Metrics are now scoped to a table and a family, not to an entity
and a metric name. Update any integration that still calls them.