Artifact workflows
Runnable, end-to-end recipes for producing an artifact — a point-in-time, org-scoped GeoParquet export of your First-Mile data — and downloading it. Where the Artifacts endpoints describe each call in isolation, these workflows show how they chain together, which variables thread between steps, and where each stage hands off to the next.
Every artifact — however it is created — walks the same lifecycle
(queued → processing → completed) and is downloaded the same way (mint
short-lived signed URLs once it is completed). The two workflows differ
only in what triggers generation and how the scope is set.
▶The two paths
| Collection | Shape | Choose it when |
|---|---|---|
| On-Demand (standard path) | Explicit — POST /artifacts with a scope filter → poll → mint. You author the scope and drive each stage. | You want an arbitrary slice (a facility, a supplier, a name), a periodic export, or a regulatory pack — decoupled from any single upload. |
| Fast Path (at ingestion) | One call — create_artifact: true on the upload; the worker auto-generates a bundle scoped to that upload. Collapses to upload → poll → mint. | The natural unit of export is "the batch I just sent" and you don't want to author a filter or make a second call. |
Both converge on the same artifact resource and the same signed-URL download.
"Slow" vs "fast" is about the number of calls, not the generation time. Generation itself takes the same amount of work either way — the fast path simply removes the explicit
POST /artifactsstep by folding it into the upload.
▶What each workflow demonstrates
| Workflow | Trigger | Scope | Highlights |
|---|---|---|---|
| On-Demand | POST /artifacts | The single eq filter you supply | Full control of scope; idempotency key; poll → mint → download |
| Fast Path | create_artifact: true on POST /ingestions/assets | Exactly the upload (assets.task_id) | No second call, no filter; discover the artifact via the task's artifact_id |
▶Endpoint map
▶On-Demand (standard path)
| Step | Method | Path | Threads to next |
|---|---|---|---|
| 01 | POST | /artifacts (a single eq scope filter; optional idempotency key) | ad_artifact_id |
| 02 | GET | /artifacts/:id (poll until completed) | — |
| 03 | POST | /artifacts/:id/signed-urls (mint download URLs) | signed URLs |
| 04 | GET | /artifacts/:id/signed-urls (audit the minted URLs) | — |
▶Fast Path (at ingestion)
| Step | Method | Path | Threads to next |
|---|---|---|---|
| 01 | POST | /ingestions/assets (create_artifact:true, metrics:[…]) | task id, signed upload_url |
| 01b | PUT | {upload_url} — the signed URL from step 01 (raw file bytes) | uploads the bytes |
| 02 | GET | /ingestions/:id (poll; capture the task's artifact_id) | artifact id |
| 03 | GET | /artifacts/:id (poll until completed) | — |
| 04 | POST | /artifacts/:id/signed-urls (mint download URLs) | signed URLs |
Then GET each signed URL out-of-band to download the GeoParquet bundle —
no API key needed on the signed URL itself.
▶Prerequisites
- An API key with
artifacts:write(create),artifacts:read(poll / list), andartifacts:sign(mint download URLs). The fast path also needsingestions:write. - The fast path requires
metricsto include at least one metric in the same upload request, so the exported bundle carries metric / assessment slices rather than being empty.
See the Artifacts endpoints overview for the lifecycle, scope model, manifest, and consuming recipes (DuckDB, GeoPandas, QGIS) these workflows drive.