Skip to content
getgeolens.com

List Dataset Refresh Runs

GET
/datasets/{dataset_id}/refresh-runs
curl --request GET \
--url 'https://example.com/datasets/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/refresh-runs?skip=0&limit=50'

Refresh history for a dataset: every attempt, including the failures.

Durable across the ingest_jobs retention purge — that purge is why this table exists rather than the jobs table serving as the record (#1219).

Access follows Rule 1 on the read path, and ADR-002 Decision 4e adds field redaction on top: a caller who is neither the dataset owner nor an admin sees the timeline and outcomes but not who triggered each run, nor the failure text, nor the schema diff. Without that, a PUBLIC dataset’s history enumerates its editors and leaks origin detail through error strings. The redaction is tested against a NAMED signed-in third party as well as an anonymous reader; a requester-scoped check that only exercises the anonymous case reads as complete and is not.

The owner-or-admin predicate (can_view_dataset_provenance) was extracted to authorization.py under #1316, which applies the same rule to dataset reads and /versions/ — this endpoint’s redaction is no longer the odd one out among the three.

dataset_id
required
Dataset Id
string format: uuid
skip
Skip
integer
0
limit
Limit
integer
default: 50 >= 1 <= 200

Successful Response

Media type application/json
DatasetRefreshRunListResponse
object
runs
required
Runs
Array<object>
DatasetRefreshRunResponse

One refresh attempt, success or failure (ADR-002 Decision 4).

Five fields are redacted for callers who are neither the dataset owner nor an admin: triggered_by, triggered_by_username, error_code, error_message and schema_diff. A public dataset’s refresh history otherwise enumerates who edits it, and failure text leaks internal origin detail. The redaction is enumerated against NAMED third-party readers as well as anonymous ones — a signed-in stranger is the case that gets missed.

object
id
required
Id
string format: uuid
dataset_id
required
Dataset Id
string format: uuid
dataset_version_id
Any of:
string format: uuid
ingest_job_id
Any of:
string format: uuid
origin_kind
required
Origin Kind

The run’s execution door, not the dataset’s origin: upload, postgis, service, stac, or raster. The two can visibly diverge; for example a STAC-imported raster’s pending or failed replace run is recorded ‘upload’ while the dataset’s origin stays ‘stac’ until the replace succeeds. ‘raster’ itself is reserved for a future, distinct raster-replace door label, with today’s raster-replace runs recorded ‘upload’.

string
trigger
required
Trigger

Manual, api, or cli

string
status
required
Status

Pending, running, succeeded, failed, or cancelled

string
triggered_by
Any of:
string format: uuid
triggered_by_username
Any of:
string
started_at
required
Started At

Dispatch time, not claim time — queue wait is visible

string format: date-time
claimed_at
Any of:
string format: date-time
finished_at
Any of:
string format: date-time
feature_count_before
Any of:
integer
feature_count_after
Any of:
integer
schema_diff
Any of:
SchemaDiff
object
columns_added
required
Columns Added

Columns present in new but not old schema

Array<object>
ColumnChange
object
name
required
Name
string
type
required
Type
string
columns_removed
required
Columns Removed

Columns present in old but not new schema

Array<object>
ColumnChange
object
name
required
Name
string
type
required
Type
string
type_changes
required
Type Changes

Columns whose data type changed

Array<object>
TypeChange
object
name
required
Name
string
old_type
required
Old Type
string
new_type
required
New Type
string
row_count_old
required
Any of:
integer
row_count_new
required
Any of:
integer
row_count_delta
required
Any of:
integer
error_code
Any of:
string
error_message
Any of:
string
total
required
Total
integer
Example generated
{
"runs": [
{
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"dataset_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"dataset_version_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"ingest_job_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"origin_kind": "example",
"trigger": "example",
"status": "example",
"triggered_by": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"triggered_by_username": "example",
"started_at": "2026-04-15T12:00:00Z",
"claimed_at": "2026-04-15T12:00:00Z",
"finished_at": "2026-04-15T12:00:00Z",
"feature_count_before": 1,
"feature_count_after": 1,
"schema_diff": {
"columns_added": [
{
"name": "example",
"type": "example"
}
],
"columns_removed": [
{
"name": "example",
"type": "example"
}
],
"type_changes": [
{
"name": "example",
"old_type": "example",
"new_type": "example"
}
],
"row_count_old": 1,
"row_count_new": 1,
"row_count_delta": 1
},
"error_code": "example",
"error_message": "example"
}
],
"total": 1
}

Bad request — invalid payload

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Unauthorized — missing or invalid credentials

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Forbidden — caller lacks access to this resource

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Not found

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Conflict — resource state prevents the operation

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Validation error

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Too many requests — retry after the advertised interval

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}
Retry-After
integer

Seconds until the request may be retried

Internal server error

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}

Service unavailable — the database could not serve the request

Media type application/problem+json
ProblemDetail
object
type
Type
string
default: about:blank
title
required
Title
string
status
required
Status
integer
detail
required
Any of:
string
Example
{
"detail": "Dataset not found",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}