Mint Signed URLs
Mint download URLs for every file in the artifact.
Signing is all-or-nothing: every file in storage_objects is covered in a single batch with a shared expires_at. Every successful call appears in List Signed URL Audit.
See the Artifacts overview for consumption recipes (DuckDB, GeoPandas, QGIS).
▶The requested lifetime picks the mechanism
The lifetime you ask for decides what kind of URL you get back. There is no separate endpoint or flag — just the TTL.
| Requested lifetime | What you get | Lives in |
|---|---|---|
| ≤ 7 days (604 800s) | A time-limited signed URL per file, plus links.dashboard_url. Not stored anywhere — once expired it cannot be replayed. | Nothing persisted |
| > 7 days, up to 180 days | A persistent download link: one durable, revocable URL per file. Each hit re-issues a fresh short-lived URL behind the scenes, so the link keeps working for its whole lifetime, plus a links.dashboard_url tied to that link. | A managed link you can retune or revoke |
7 days is the hard ceiling for a signed URL, so anything longer is served by the persistent-link mechanism instead. Persistent links are the ones you can retune or revoke, and they appear in the list endpoint as artifact_download_link rows.
A download link is a bearer credential. Anyone holding the URL can download the artifact without authenticating, until it expires or you revoke it. Share it deliberately, and revoke it if it leaks.
▶Use cases
- Hand off the bundle to a BI tool that reads HTTPS-served parquet directly (DuckDB
httpfs, GeoPandas, QGIS) — a short TTL is enough. - Give a colleague or auditor a link that still works weeks later — request a lifetime beyond 7 days and share the persistent URL.
- Open
dashboard_urlto inspect the artifact in Epoch's dashboard without minting your own URLs.
▶Path parameters
| Param | Type | Description |
|---|---|---|
id | uuid | Artifact ID. Must be visible to your organization and in the completed state. |
▶Request body
The body is optional — a request with no body (or {}) uses the default TTL. Give the lifetime either as an absolute deadline or as a relative window; supplying both is rejected.
| Field | Type | Required | Description |
|---|---|---|---|
expires_at | ISO 8601 | no | Absolute expiry, and the preferred form — you state the deadline rather than computing a window against Epoch's clock. Must be in the future and no more than 180 days out. Mutually exclusive with ttl_seconds. |
ttl_seconds | int | no | Lifetime in seconds, relative to now. Between 1 and 15 552 000 (180 days). Defaults to 3 600 (1 hour). Mutually exclusive with expires_at. |
Every URL in files[] shares the same expires_at regardless of which form you use.
▶Response schema (data)
data)| Field | Type | Description |
|---|---|---|
type | "artifact_signed_urls" | Always "artifact_signed_urls". |
id | uuid | Artifact ID these URLs cover. |
▶attributes
attributes| Field | Type | Description |
|---|---|---|
ttl_seconds | int | The lifetime applied to every URL in files[]. |
expires_at | ISO 8601 | Absolute expiry. Identical for every entry in files[]. |
files | array | One entry per file in the artifact's storage_objects. Single-file artifacts return exactly one entry; partitioned artifacts return one per file. Always iterate this array — there is no top-level signed_url field. |
▶files[]
files[]| Field | Type | Description |
|---|---|---|
relative_path | string | Identifies which file in storage_objects this URL belongs to. |
signed_url | string | The download URL. For a short-lived request this is a direct storage URL; for a persistent link it is a durable Epoch URL that redirects to freshly-issued storage URLs on each hit. Either way, it stops working at expires_at. |
▶Top-level links
links| Key | Type | Description |
|---|---|---|
self | string (URL) | This endpoint. |
dashboard_url | string (URL) | Deep link that opens this artifact in Epoch's dashboard. Expires at expires_at. For a persistent link it is tied to that link, so revoking the link closes the dashboard too. |
▶Managing a persistent link
The persistent URL contains a token that identifies the link. Pass that token to Retune Download Link to change the expiry, or Revoke Download Link to kill it. The token is returned only once, here — Epoch stores only a hash of it, so keep the URL if you intend to manage the link later. If you lose it, revoke the link by listing it and mint a fresh one.
▶Status codes
200— Success. Every file in the artifact is covered.400— Invalidid(not a UUID);ttl_secondsout of range;expires_atin the past or more than 180 days out; or both lifetime fields supplied at once.401— Missing or invalid API key.403— Caller lacks theartifacts:signscope.404— Artifact does not exist or is not visible to your organization.409—artifact_not_completed: the artifact is not yet in the completed state. Download URLs are only available for completed artifacts.409—artifact_purged: the artifact completed, but its files have aged out of retention (status: "purged"). Nothing can be minted for it — request a new artifact with the same filters. The response names thepurged_atdate.
Required scope:
artifacts:sign
artifacts:signis intentionally separate fromartifacts:write. A key that can read or generate artifacts does not implicitly receive the ability to mint download URLs.