Runtime API
REST API of the dltHub Runtime control plane: organizations, workspaces, deployments, configurations, jobs and job runs. The dlthub CLI, the Python SDK and the dltHub web app are built on it.
Base URL
https://api.dlthub.com
Authentication
Send an API key as a bearer token:
Authorization: Bearer <api key>
Create keys in the dltHub web app. The plaintext key is shown once, and deleting a key revokes it immediately. Keys expire after 90 days unless set otherwise when created (at most 365).
- Personal keys (
dlt_u_…), under account settings, act as you, with your roles in every organization and workspace you belong to. - Workspace keys (
dlt_sa_…), under workspace settings, act for one workspace with a fixed role: DEVELOPER (deploy and run jobs) or VIEWER (read, and run jobs that use the read-onlyaccessprofile, such as interactive jobs). Use them for CI and other automation. Workspace keys cannot callGET /api/v1/me.
Data plane
Workspace variables, deployment and configuration files, run logs and telemetry are kept on the data plane of the workspace's region and served by the Dataplane, Logs and Telemetry APIs. GET /api/v1/workspaces/{workspace_id} returns its address as dataplane_url, and POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token the token to call it with.
Versioning
The API version is part of the path. Endpoints under /v1 are stable: breaking changes ship
only under a new version prefix. New endpoints, optional parameters and response fields can
be added to /v1 at any time, so ignore fields and enum values you do not know.
Configurations
List configurations
GET /api/v1/workspaces/{workspace_id}/configurations
Lists the configurations of a workspace as a paginated list, newest version first unless sort
is given.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
Query parameters
| Name | Type | Description |
|---|---|---|
version | integer or null | Exact match on version. |
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: version, created_at. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/configurations" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/configurations",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profiles": ["<profiles>"],
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
items[].created_at | string (date-time) | When it was created. |
items[].created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
items[].file_count | integer | Number of files in the package. |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].profiles | array of string | Profile names found in <profile>.config.toml / <profile>.secrets.toml file names, sorted. |
items[].size_bytes | integer | Size of the uploaded package in bytes. |
items[].updated_at | string (date-time) | When it was last changed. |
items[].version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
items[].workspace_id | string (uuid) | The ID of the workspace it belongs to. |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Issue upload configuration
POST /api/v1/workspaces/{workspace_id}/configurations/-issue-upload
Prepares the upload of a new configuration. Send a multipart POST with file (the package) to
upload_url, with Authorization: Bearer <upload_token>, within 10 minutes. The configuration
exists, under configuration_id, only after the upload succeeds.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/configurations/-issue-upload" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/configurations/-issue-upload",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"upload_token": "<upload_token>",
"upload_url": "<upload_url>"
}
| Field | Type | Description |
|---|---|---|
configuration_id | string (uuid) | ID the uploaded configuration will be created under |
upload_token | string | Token for the upload; send it as Authorization: Bearer <upload_token>. Valid for 10 minutes. |
upload_url | string | Data plane URL to send the multipart upload POST to. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Get latest configuration
GET /api/v1/workspaces/{workspace_id}/configurations/latest
Gets the latest and therefore active configuration for a workspace.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/configurations/latest" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/configurations/latest",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profiles": ["<profiles>"],
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
file_count | integer | Number of files in the package. |
id | string (uuid) | Unique ID (a UUID). |
profiles | array of string | Profile names found in <profile>.config.toml / <profile>.secrets.toml file names, sorted. |
size_bytes | integer | Size of the uploaded package in bytes. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
workspace_id | string (uuid) | The ID of the workspace it belongs to. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Get configuration
GET /api/v1/workspaces/{workspace_id}/configurations/{configuration_id}
Gets a configuration for a workspace by its ID. Find one by version number with list_configurations.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
configuration_id | string (uuid) | ID of the configuration |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/configurations/$CONFIGURATION_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/configurations/<configuration_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profiles": ["<profiles>"],
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
file_count | integer | Number of files in the package. |
id | string (uuid) | Unique ID (a UUID). |
profiles | array of string | Profile names found in <profile>.config.toml / <profile>.secrets.toml file names, sorted. |
size_bytes | integer | Size of the uploaded package in bytes. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
workspace_id | string (uuid) | The ID of the workspace it belongs to. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Dataplanes
List dataplanes
GET /api/v1/dataplanes
Lists the regions (data planes) an organization can choose with set_region_organization.
Request
- curl
- Python
curl "https://api.dlthub.com/api/v1/dataplanes" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/dataplanes",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"description": "<description>",
"id": "<id>",
"name": "<name>",
"region": "<region>"
}
]
}
| Field | Type | Description |
|---|---|---|
items | array of object | The available data planes. |
items[].description | string or null | Optional note about the data plane; null when there is none. |
items[].id | string | Data plane id, e.g. eu1; also the subdomain of its URL. |
items[].name | string | Human-readable data plane name. |
items[].region | string | Cloud region the data plane runs in, e.g. europe-west4. |
401Unauthorized403Forbidden500Internal Server Error
Each error returns the error body.
Deployments
List deployments
GET /api/v1/workspaces/{workspace_id}/deployments
Lists the deployments of a workspace as a paginated list, newest version first unless sort
is given.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
Query parameters
| Name | Type | Description |
|---|---|---|
version | integer or null | Exact match on version. |
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: version, created_at. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/deployments" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/deployments",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"requirements_size_bytes": 0,
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
items[].created_at | string (date-time) | When it was created. |
items[].created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
items[].file_count | integer | Number of files in the package. |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].requirements_size_bytes | integer | Size of the uploaded requirements file in bytes. |
items[].size_bytes | integer | Size of the uploaded package in bytes. |
items[].updated_at | string (date-time) | When it was last changed. |
items[].version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
items[].workspace_id | string (uuid) | The ID of the workspace it belongs to. |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Issue upload deployment
POST /api/v1/workspaces/{workspace_id}/deployments/-issue-upload
Prepares the upload of a new deployment. Send a multipart POST with file (the package) and requirements_file to
upload_url, with Authorization: Bearer <upload_token>, within 10 minutes. The deployment
exists, under deployment_id, only after the upload succeeds.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/deployments/-issue-upload" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/deployments/-issue-upload",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"upload_token": "<upload_token>",
"upload_url": "<upload_url>"
}
| Field | Type | Description |
|---|---|---|
deployment_id | string (uuid) | ID the uploaded deployment will be created under |
upload_token | string | Token for the upload; send it as Authorization: Bearer <upload_token>. Valid for 10 minutes. |
upload_url | string | Data plane URL to send the multipart upload POST to. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Get latest deployment
GET /api/v1/workspaces/{workspace_id}/deployments/latest
Gets the latest and therefore active deployment for a workspace.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/deployments/latest" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/deployments/latest",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"requirements_size_bytes": 0,
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
file_count | integer | Number of files in the package. |
id | string (uuid) | Unique ID (a UUID). |
requirements_size_bytes | integer | Size of the uploaded requirements file in bytes. |
size_bytes | integer | Size of the uploaded package in bytes. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
workspace_id | string (uuid) | The ID of the workspace it belongs to. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Get deployment
GET /api/v1/workspaces/{workspace_id}/deployments/{deployment_id}
Gets a deployment for a workspace by its ID. Find one by version number with list_deployments.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
deployment_id | string (uuid) | ID of the deployment |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/deployments/$DEPLOYMENT_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/deployments/<deployment_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"content_hash": "<content_hash>",
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"file_count": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"requirements_size_bytes": 0,
"size_bytes": 0,
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
content_hash | string | Hash of the package contents: base64 SHA3-256 over each file's path and digest, as dlt computes when building the package; identical file sets give identical hashes. |
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who uploaded it. |
file_count | integer | Number of files in the package. |
id | string (uuid) | Unique ID (a UUID). |
requirements_size_bytes | integer | Size of the uploaded requirements file in bytes. |
size_bytes | integer | Size of the uploaded package in bytes. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number within the workspace, starting at 1 and incremented by each upload. |
workspace_id | string (uuid) | The ID of the workspace it belongs to. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Job runs
List job runs
GET /api/v1/workspaces/{workspace_id}/job-runs
Gets the job runs of a workspace as a paginated list, newest first.
Search with q over the job name and the names of the pipelines a run reported; a number
also matches the run number. Filter by status, attention reason, run number, job, job type,
job category, trigger, trigger kind, who started the run (triggered_by), profile,
duration, upstream run (previous_job_run_id, giving the runs one run triggered), or a
created_at window; sort with paired sort and order lists.
trigger_kind matches the kind of trigger a run fired with, which for a run started through
the API may be the job's default trigger, e.g. schedule:. Use triggered_by to find runs a
person started.
System runs, such as the dashboard job, are excluded unless job_id or
previous_job_run_id names one, or include_system_job_runs is set. Naming a
category does not lift the exclusion.
Set downstream_job_runs_limit to attach, to each run, the runs its outcome
triggered.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
Query parameters
| Name | Type | Description |
|---|---|---|
q | string or null | Case-insensitive substring match on the job name and the pipeline names the run produced. A numeric value also matches the exact run number. |
status | array of string or null | Exact match on status. Repeat the parameter to match any of several values. One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
attention_reason | array of string or null | Match runs an operator has to look at, for any of the given reasons: failed, empty_run (completed but loaded no rows), long_running (completed after more than 5 hours). A run lists every reason that applies in attention_reasons. One of: failed, empty_run, long_running. |
number | integer or null | Exact match on number. |
job_id | string (uuid) or null | Exact match on job_id. |
previous_job_run_id | string (uuid) or null | Exact match on previous_job_run_id. |
job_type | array of string or null | Exact match on job_type. Repeat the parameter to match any of several values. One of: batch, interactive, stream. |
category | array of string or null | Match runs of jobs declaring any of the given expose.category values. Most jobs declare none and match nothing here. One of: pipeline, mcp, dashboard, notebook, background_agent. |
exclude_category | array of string or null | Drop runs of jobs declaring any of the given expose.category values. A run of a job declaring none is kept. One of: pipeline, mcp, dashboard, notebook, background_agent. |
trigger | array of string or null | Exact match on trigger. Repeat the parameter to match any of several values. |
trigger_kind | array of string or null | Match runs by the kind of trigger that fired them, whatever its expression. A run started through the API carries the trigger it was started with, which may be the job's default trigger; use triggered_by to find runs a person started. One of: schedule, every, once, webhook, http, job.success, job.fail, manual. |
triggered_by | array of string (uuid) or null | Exact match on the identity that started the run. Repeat the parameter to match any of several values. |
profile | array of string or null | Exact match on profile. Repeat the parameter to match any of several values. |
min_duration_seconds | number or null | Inclusive range over duration_seconds, given as min_duration_seconds and max_duration_seconds. Either bound may stand alone. |
max_duration_seconds | number or null | Inclusive range over duration_seconds, given as min_duration_seconds and max_duration_seconds. Either bound may stand alone. |
start | string (date-time) or null | Lower bound (inclusive) on created_at, as a naive local time read in timezone, e.g. 2026-03-01T00:00:00. |
end | string (date-time) or null | Upper bound (exclusive) on created_at, as a naive local time read in timezone, e.g. 2026-03-11T00:00:00. |
timezone | string | IANA timezone in which start and end are read, e.g. Europe/Berlin. Default UTC. |
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: created_at, number, duration_seconds, started_at, finished_at. |
include_system_job_runs | boolean | Include runs of system jobs such as the dashboard. |
downstream_job_runs_limit | integer or null | Attach this many of the runs each run triggered, newest first. Only runs started by the run's outcome are linked. |
downstream_job_runs_category | string or null | Attach only downstream runs whose job declares this category, so the newest of that kind is found however many other runs came after it. One of: pipeline, mcp, dashboard, notebook, background_agent. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/job-runs" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/job-runs",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"attention_reasons": ["failed"],
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [
{
"dataset_name": "<dataset_name>",
"destination_name": "<destination_name>",
"duration_ms": 0,
"finished_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"pipeline_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2026-01-01T00:00:00Z",
"status": "succeeded",
"total_rows": 0,
"transaction_id": "<transaction_id>"
}
],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].attention_reasons | array of string | Why the run needs an operator's look, every reason that applies in a fixed order: it failed, it completed but loaded no rows, it completed after more than 5 hours. A run still in progress is never flagged. Empty when nothing applies. One of: failed, empty_run, long_running. |
items[].configuration_id | string (uuid) | The ID of the configuration the run uses. |
items[].created_at | string (date-time) | When it was created. |
items[].deployment_id | string (uuid) | The ID of the deployment the run uses. |
items[].downstream_job_runs | array of object or null | Runs this run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Only runs started by this run's outcome are linked, so a manually started one is absent. |
items[].downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
items[].downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
items[].downstream_job_runs[].id | string (uuid) | The run ID |
items[].downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
items[].downstream_job_runs[].job_ref | string | The job's canonical reference |
items[].downstream_job_runs[].name | string | The job's display name |
items[].downstream_job_runs[].number | integer | The run number within the job |
items[].downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
items[].downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
items[].downstream_job_runs[].trigger | string | The trigger that started the downstream run |
items[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
items[].finished_at | string (date-time) or null | When the run finished; null until it has. |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
items[].interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
items[].job | object | The run's job as it is now; it may have been redeployed since the run. |
items[].job.created_at | string (date-time) | When it was created. |
items[].job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
items[].job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
items[].job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
items[].job.description | string or null | The description of the job |
items[].job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
items[].job.id | string (uuid) | Unique ID (a UUID). |
items[].job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
items[].job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
items[].job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
items[].job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
items[].job.job_definition | object | Job definition from the dlt deployment manifest. |
items[].job.job_definition_engine_version | integer | Version of the job definition format. |
items[].job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
items[].job.job_ref | string | Canonical job reference, unique per workspace |
items[].job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
items[].job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
items[].job.name | string or null | Display name for the job |
items[].job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
items[].job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
items[].job.profile | string | The profile the job runs under |
items[].job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
items[].job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
items[].job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
items[].job.updated_at | string (date-time) | When it was last changed. |
items[].job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
items[].job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
items[].job_version | object | Job version that this run was dispatched with — carries the exact job_definition, provider and max_run_time_seconds used. |
items[].job_version.created_at | string (date-time) | When it was created. |
items[].job_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
items[].job_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
items[].job_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
items[].job_version.description | string or null | The description of the job |
items[].job_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
items[].job_version.id | string (uuid) | Unique ID (a UUID). |
items[].job_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
items[].job_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
items[].job_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
items[].job_version.job_definition | object | Job definition from the dlt deployment manifest. |
items[].job_version.job_definition_engine_version | integer | Version of the job definition format. |
items[].job_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
items[].job_version.job_id | string (uuid) | The ID of the job the job version belongs to |
items[].job_version.job_ref | string | Canonical job reference, unique per workspace |
items[].job_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
items[].job_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
items[].job_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
items[].job_version.name | string or null | Display name for the job |
items[].job_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
items[].job_version.profile | string | The profile the job runs under |
items[].job_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
items[].job_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
items[].job_version.updated_at | string (date-time) | When it was last changed. |
items[].job_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
items[].job_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
items[].job_version_id | string (uuid) | The ID of the job version the run uses. |
items[].logs_url | string or null | A link to the logs of the run |
items[].number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
items[].pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
items[].pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
items[].pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
items[].pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
items[].pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
items[].pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
items[].pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
items[].pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
items[].pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
items[].pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
items[].pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
items[].previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
items[].profile | string | The name of the profile that was used for the run |
items[].started_at | string (date-time) or null | When the run started; null until it has. |
items[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
items[].trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
items[].triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
items[].updated_at | string (date-time) | When it was last changed. |
items[].workspace_id | string (uuid) | The ID of the workspace the run belongs to |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Create job run
POST /api/v1/workspaces/{workspace_id}/job-runs
Starts a run of the job's latest version with the workspace's latest deployment and
configuration, under profile or the job's own profile. A paused job still runs; pausing
only stops scheduled runs.
mode controls run creation:
always(default): always creates a new run (201).when_not_running: returns the job's pending, starting or running run (200) if it has one, otherwise creates a new one (201).
Answers 400 for an archived job, and 404 when the job has no version or the workspace has no
deployment or configuration yet. A run the platform declines to start answers 409 or 403 with
a code naming why and the reasons in extra: upstream_not_fresh, outside_job_interval,
job_concurrency_limit, organization_concurrency_limit (409), trial_expired,
compute_minutes_exhausted (403), or run_not_started for any other reason (409).
Requires the viewer role (or higher) in the workspace. Viewers may only run jobs that use the
read-only access profile (by default interactive and agent jobs); any other profile needs
the developer role and answers 403.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
| Field | Type | Description |
|---|---|---|
job_id | string (uuid) | Required. The ID of the job to run. |
mode | string | How to create a run: always creates a new run; when_not_running returns the job's pending, starting or running run if it has one, otherwise creates a new one. One of: always, when_not_running. Default: "always". |
profile | string or null | The profile to run under; defaults to the job's own profile. |
refresh | boolean | Start the run as a refresh: the job's progress goes back to its interval start and the run receives refresh: true in its run context, leaving what to reload to the job's code. The progress of the jobs downstream of it is reset too. Ignored when the job's refresh_propagation is block. Default: false. |
skip_freshness | boolean | Start the run even if its upstream jobs are not fresh. When false and an upstream is stale, no run is created and the call answers 409 upstream_not_fresh. Default: false. |
trigger | string | Required. The trigger recorded on the run, e.g. manual:jobs.my_job, schedule:0 8 * * *. Must be a valid trigger string. |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/job-runs" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"job_id": "<job_id>", "trigger": "<trigger>"}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/job-runs",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={"job_id": "<job_id>", "trigger": "<trigger>"},
)
response.raise_for_status()
print(response.json())
Response (200, 201, 4xx, 5xx)
- Example
- Fields
- Errors
{
"attention_reasons": ["failed"],
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [
{
"dataset_name": "<dataset_name>",
"destination_name": "<destination_name>",
"duration_ms": 0,
"finished_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"pipeline_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2026-01-01T00:00:00Z",
"status": "succeeded",
"total_rows": 0,
"transaction_id": "<transaction_id>"
}
],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
attention_reasons | array of string | Why the run needs an operator's look, every reason that applies in a fixed order: it failed, it completed but loaded no rows, it completed after more than 5 hours. A run still in progress is never flagged. Empty when nothing applies. One of: failed, empty_run, long_running. |
configuration_id | string (uuid) | The ID of the configuration the run uses. |
created_at | string (date-time) | When it was created. |
deployment_id | string (uuid) | The ID of the deployment the run uses. |
downstream_job_runs | array of object or null | Runs this run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Only runs started by this run's outcome are linked, so a manually started one is absent. |
downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
downstream_job_runs[].id | string (uuid) | The run ID |
downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
downstream_job_runs[].job_ref | string | The job's canonical reference |
downstream_job_runs[].name | string | The job's display name |
downstream_job_runs[].number | integer | The run number within the job |
downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
downstream_job_runs[].trigger | string | The trigger that started the downstream run |
duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
finished_at | string (date-time) or null | When the run finished; null until it has. |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
job | object | The run's job as it is now; it may have been redeployed since the run. |
job.created_at | string (date-time) | When it was created. |
job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job.description | string or null | The description of the job |
job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job.id | string (uuid) | Unique ID (a UUID). |
job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job.job_definition | object | Job definition from the dlt deployment manifest. |
job.job_definition_engine_version | integer | Version of the job definition format. |
job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job.job_ref | string | Canonical job reference, unique per workspace |
job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
job.name | string or null | Display name for the job |
job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job.profile | string | The profile the job runs under |
job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job.updated_at | string (date-time) | When it was last changed. |
job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
job_version | object | Job version that this run was dispatched with — carries the exact job_definition, provider and max_run_time_seconds used. |
job_version.created_at | string (date-time) | When it was created. |
job_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_version.description | string or null | The description of the job |
job_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_version.id | string (uuid) | Unique ID (a UUID). |
job_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
job_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_version.job_definition | object | Job definition from the dlt deployment manifest. |
job_version.job_definition_engine_version | integer | Version of the job definition format. |
job_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_version.job_id | string (uuid) | The ID of the job the job version belongs to |
job_version.job_ref | string | Canonical job reference, unique per workspace |
job_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
job_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
job_version.name | string or null | Display name for the job |
job_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_version.profile | string | The profile the job runs under |
job_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
job_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_version.updated_at | string (date-time) | When it was last changed. |
job_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
job_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_version_id | string (uuid) | The ID of the job version the run uses. |
logs_url | string or null | A link to the logs of the run |
number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
profile | string | The name of the profile that was used for the run |
started_at | string (date-time) or null | When the run started; null until it has. |
status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
updated_at | string (date-time) | When it was last changed. |
workspace_id | string (uuid) | The ID of the workspace the run belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Cancel job runs
POST /api/v1/workspaces/{workspace_id}/job-runs/-cancel
Requests cancellation of the given runs in a single transaction. Each run moves to
cancelling and then to cancelled once stopped.
Answers a receipt: succeeded runs were moved to cancelling, skipped runs were already
finished or already being cancelled, and failed lists ids that name no run in the
workspace. Use dry_run=true to preview without cancelling.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
| Field | Type | Description |
|---|---|---|
dry_run | boolean | Preview which runs would be cancelled, without cancelling them. Default: false. |
job_run_ids | array of string (uuid) | Required. Runs to cancel; a run that is already finished or being cancelled is skipped. |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/job-runs/-cancel" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"job_run_ids": ["<job_run_ids>"]}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/job-runs/-cancel",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={"job_run_ids": ["<job_run_ids>"]},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"failed": [
{
"detail": "<detail>",
"ref": "<ref>"
}
],
"skipped": [
{
"job_ref": "<job_ref>",
"job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_run_number": 0,
"previous_status": "pending"
}
],
"succeeded": [
{
"job_ref": "<job_ref>",
"job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_run_number": 0,
"previous_status": "pending"
}
]
}
| Field | Type | Description |
|---|---|---|
failed | array of object | Requested runs that do not exist in the workspace. |
failed[].detail | string | Why it failed. |
failed[].ref | string | The item that failed, by its id or natural key. |
skipped | array of object | Runs already finished or already being cancelled. |
skipped[].job_ref | string | Job reference of the cancelled run. |
skipped[].job_run_id | string (uuid) | ID of the cancelled run. |
skipped[].job_run_number | integer | Number of the run within its job; numbers repeat across jobs. |
skipped[].previous_status | string | Status of the run when the cancel request arrived. One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
succeeded | array of object | Runs moved to cancelling (or that would be, in dry-run). |
succeeded[].job_ref | string | Job reference of the cancelled run. |
succeeded[].job_run_id | string (uuid) | ID of the cancelled run. |
succeeded[].job_run_number | integer | Number of the run within its job; numbers repeat across jobs. |
succeeded[].previous_status | string | Status of the run when the cancel request arrived. One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Get job run
GET /api/v1/workspaces/{workspace_id}/job-runs/{job_run_id}
Gets a run for a workspace by ID.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_run_id | string (uuid) | ID of the job run |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/job-runs/$JOB_RUN_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/job-runs/<job_run_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"attention_reasons": ["failed"],
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [
{
"dataset_name": "<dataset_name>",
"destination_name": "<destination_name>",
"duration_ms": 0,
"finished_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"pipeline_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2026-01-01T00:00:00Z",
"status": "succeeded",
"total_rows": 0,
"transaction_id": "<transaction_id>"
}
],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
attention_reasons | array of string | Why the run needs an operator's look, every reason that applies in a fixed order: it failed, it completed but loaded no rows, it completed after more than 5 hours. A run still in progress is never flagged. Empty when nothing applies. One of: failed, empty_run, long_running. |
configuration_id | string (uuid) | The ID of the configuration the run uses. |
created_at | string (date-time) | When it was created. |
deployment_id | string (uuid) | The ID of the deployment the run uses. |
downstream_job_runs | array of object or null | Runs this run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Only runs started by this run's outcome are linked, so a manually started one is absent. |
downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
downstream_job_runs[].id | string (uuid) | The run ID |
downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
downstream_job_runs[].job_ref | string | The job's canonical reference |
downstream_job_runs[].name | string | The job's display name |
downstream_job_runs[].number | integer | The run number within the job |
downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
downstream_job_runs[].trigger | string | The trigger that started the downstream run |
duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
finished_at | string (date-time) or null | When the run finished; null until it has. |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
job | object | The run's job as it is now; it may have been redeployed since the run. |
job.created_at | string (date-time) | When it was created. |
job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job.description | string or null | The description of the job |
job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job.id | string (uuid) | Unique ID (a UUID). |
job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job.job_definition | object | Job definition from the dlt deployment manifest. |
job.job_definition_engine_version | integer | Version of the job definition format. |
job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job.job_ref | string | Canonical job reference, unique per workspace |
job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
job.name | string or null | Display name for the job |
job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job.profile | string | The profile the job runs under |
job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job.updated_at | string (date-time) | When it was last changed. |
job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
job_version | object | Job version that this run was dispatched with — carries the exact job_definition, provider and max_run_time_seconds used. |
job_version.created_at | string (date-time) | When it was created. |
job_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_version.description | string or null | The description of the job |
job_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_version.id | string (uuid) | Unique ID (a UUID). |
job_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
job_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_version.job_definition | object | Job definition from the dlt deployment manifest. |
job_version.job_definition_engine_version | integer | Version of the job definition format. |
job_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_version.job_id | string (uuid) | The ID of the job the job version belongs to |
job_version.job_ref | string | Canonical job reference, unique per workspace |
job_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
job_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
job_version.name | string or null | Display name for the job |
job_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_version.profile | string | The profile the job runs under |
job_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
job_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_version.updated_at | string (date-time) | When it was last changed. |
job_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
job_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_version_id | string (uuid) | The ID of the job version the run uses. |
logs_url | string or null | A link to the logs of the run |
number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
profile | string | The name of the profile that was used for the run |
started_at | string (date-time) or null | When the run started; null until it has. |
status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
updated_at | string (date-time) | When it was last changed. |
workspace_id | string (uuid) | The ID of the workspace the run belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Cancel job run
POST /api/v1/workspaces/{workspace_id}/job-runs/{job_run_id}/-cancel
Requests cancellation of a run. The run moves to cancelling and then to cancelled once
stopped. A run that is already finished or cancelling answers 400.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_run_id | string (uuid) | ID of the job run |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/job-runs/$JOB_RUN_ID/-cancel" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/job-runs/<job_run_id>/-cancel",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"attention_reasons": ["failed"],
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [
{
"dataset_name": "<dataset_name>",
"destination_name": "<destination_name>",
"duration_ms": 0,
"finished_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"pipeline_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2026-01-01T00:00:00Z",
"status": "succeeded",
"total_rows": 0,
"transaction_id": "<transaction_id>"
}
],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
attention_reasons | array of string | Why the run needs an operator's look, every reason that applies in a fixed order: it failed, it completed but loaded no rows, it completed after more than 5 hours. A run still in progress is never flagged. Empty when nothing applies. One of: failed, empty_run, long_running. |
configuration_id | string (uuid) | The ID of the configuration the run uses. |
created_at | string (date-time) | When it was created. |
deployment_id | string (uuid) | The ID of the deployment the run uses. |
downstream_job_runs | array of object or null | Runs this run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Only runs started by this run's outcome are linked, so a manually started one is absent. |
downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
downstream_job_runs[].id | string (uuid) | The run ID |
downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
downstream_job_runs[].job_ref | string | The job's canonical reference |
downstream_job_runs[].name | string | The job's display name |
downstream_job_runs[].number | integer | The run number within the job |
downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
downstream_job_runs[].trigger | string | The trigger that started the downstream run |
duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
finished_at | string (date-time) or null | When the run finished; null until it has. |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
job | object | The run's job as it is now; it may have been redeployed since the run. |
job.created_at | string (date-time) | When it was created. |
job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job.description | string or null | The description of the job |
job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job.id | string (uuid) | Unique ID (a UUID). |
job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job.job_definition | object | Job definition from the dlt deployment manifest. |
job.job_definition_engine_version | integer | Version of the job definition format. |
job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job.job_ref | string | Canonical job reference, unique per workspace |
job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
job.name | string or null | Display name for the job |
job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job.profile | string | The profile the job runs under |
job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job.updated_at | string (date-time) | When it was last changed. |
job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
job_version | object | Job version that this run was dispatched with — carries the exact job_definition, provider and max_run_time_seconds used. |
job_version.created_at | string (date-time) | When it was created. |
job_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_version.description | string or null | The description of the job |
job_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_version.id | string (uuid) | Unique ID (a UUID). |
job_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
job_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_version.job_definition | object | Job definition from the dlt deployment manifest. |
job_version.job_definition_engine_version | integer | Version of the job definition format. |
job_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_version.job_id | string (uuid) | The ID of the job the job version belongs to |
job_version.job_ref | string | Canonical job reference, unique per workspace |
job_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
job_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
job_version.name | string or null | Display name for the job |
job_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_version.profile | string | The profile the job runs under |
job_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
job_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_version.updated_at | string (date-time) | When it was last changed. |
job_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
job_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_version_id | string (uuid) | The ID of the job version the run uses. |
logs_url | string or null | A link to the logs of the run |
number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
profile | string | The name of the profile that was used for the run |
started_at | string (date-time) or null | When the run started; null until it has. |
status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
updated_at | string (date-time) | When it was last changed. |
workspace_id | string (uuid) | The ID of the workspace the run belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Jobs
List jobs
GET /api/v1/workspaces/{workspace_id}/jobs
Gets the jobs of a workspace as a paginated list, most recent run first; jobs that never ran come last.
Search with q over the job name; filter by ref, type, archived or paused state, profile,
pipeline, the status of the latest run, trigger kind, category, tags (given without the
tag: prefix) or a created_at window; sort with paired sort and order lists.
Archived and live jobs are both listed unless is_archived says which to keep.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
Query parameters
| Name | Type | Description |
|---|---|---|
q | string or null | Case-insensitive substring match on name. |
ref | string or null | Exact match on job_ref. |
job_type | array of string or null | Exact match on job_type. Repeat the parameter to match any of several values. One of: batch, interactive, stream. |
is_archived | boolean or null | Match is_archived. Omit to list both. |
is_paused | boolean or null | Match is_paused. Omit to list both. |
profile | array of string or null | Exact match on profile. Repeat the parameter to match any of several values. |
pipeline_name | array of string or null | Exact match on pipeline_name. Repeat the parameter to match any of several values. |
status | array of string or null | Exact match on the status of the job's most recent run. Repeat the parameter to match any of several values. One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
trigger_kind | array of string or null | Match jobs declaring a trigger of any given kind. A job may declare several kinds at once; manual reflects the job's expose.manual setting, which is on by default. One of: schedule, every, once, webhook, http, job.success, job.fail, manual. |
is_self_firing | boolean or null | Match jobs by whether they declare a trigger that starts them with no person involved: a schedule, an interval, a one-off time, a webhook, an HTTP endpoint, or another job's outcome. |
category | array of string or null | Match jobs declaring any of the given expose.category values. Most jobs declare none and match nothing here. One of: pipeline, mcp, dashboard, notebook, background_agent. |
exclude_category | array of string or null | Drop jobs declaring any of the given expose.category values. A job declaring none is kept. One of: pipeline, mcp, dashboard, notebook, background_agent. |
tags | array of string or null | Match jobs carrying any of the given tags. |
start | string (date-time) or null | Lower bound (inclusive) on created_at, as a naive local time read in timezone, e.g. 2026-03-01T00:00:00. |
end | string (date-time) or null | Upper bound (exclusive) on created_at, as a naive local time read in timezone, e.g. 2026-03-11T00:00:00. |
timezone | string | IANA timezone in which start and end are read, e.g. Europe/Berlin. Default UTC. |
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: last_run_at, last_run_ended_at, name, next_scheduled_run_at, created_at. |
recent_job_runs_limit | integer or null | Attach this many of the job's most recent runs. |
downstream_job_runs_limit | integer or null | Attach this many of the runs each run triggered, newest first. Only runs started by the run's outcome are linked. |
downstream_job_runs_category | string or null | Attach only downstream runs whose job declares this category, so the newest of that kind is found however many other runs came after it. One of: pipeline, mcp, dashboard, notebook, background_agent. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"current_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"latest_job_run": {
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"recent_job_runs": [
{
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"rows_loaded": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending"
}
],
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].created_at | string (date-time) | When it was created. |
items[].created_by | string (uuid) | The organization_membership_id of the member who created the job. |
items[].current_version | object or null | The active job version, carrying its provider, instance size, and resolved hardware. |
items[].current_version.created_at | string (date-time) | When it was created. |
items[].current_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
items[].current_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
items[].current_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
items[].current_version.description | string or null | The description of the job |
items[].current_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
items[].current_version.id | string (uuid) | Unique ID (a UUID). |
items[].current_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
items[].current_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
items[].current_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
items[].current_version.job_definition | object | Job definition from the dlt deployment manifest. |
items[].current_version.job_definition_engine_version | integer | Version of the job definition format. |
items[].current_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
items[].current_version.job_id | string (uuid) | The ID of the job the job version belongs to |
items[].current_version.job_ref | string | Canonical job reference, unique per workspace |
items[].current_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
items[].current_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
items[].current_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
items[].current_version.name | string or null | Display name for the job |
items[].current_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
items[].current_version.profile | string | The profile the job runs under |
items[].current_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
items[].current_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
items[].current_version.updated_at | string (date-time) | When it was last changed. |
items[].current_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
items[].current_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
items[].default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
items[].deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
items[].description | string or null | The description of the job |
items[].downstream_job_runs | array of object or null | Runs the job's last run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Empty when the last run triggered nothing, since a chained job fires only once its upstream run reaches a terminal state. |
items[].downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
items[].downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
items[].downstream_job_runs[].id | string (uuid) | The run ID |
items[].downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
items[].downstream_job_runs[].job_ref | string | The job's canonical reference |
items[].downstream_job_runs[].name | string | The job's display name |
items[].downstream_job_runs[].number | integer | The run number within the job |
items[].downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
items[].downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
items[].downstream_job_runs[].trigger | string | The trigger that started the downstream run |
items[].freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
items[].interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
items[].is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
items[].is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
items[].job_definition | object | Job definition from the dlt deployment manifest. |
items[].job_definition_engine_version | integer | Version of the job definition format. |
items[].job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
items[].job_ref | string | Canonical job reference, unique per workspace |
items[].job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
items[].job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
items[].latest_job_run | object or null | The latest run of the job; null if it has never run. |
items[].latest_job_run.configuration_id | string (uuid) | The ID of the configuration the run uses. |
items[].latest_job_run.created_at | string (date-time) | When it was created. |
items[].latest_job_run.deployment_id | string (uuid) | The ID of the deployment the run uses. |
items[].latest_job_run.duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
items[].latest_job_run.finished_at | string (date-time) or null | When the run finished; null until it has. |
items[].latest_job_run.id | string (uuid) | Unique ID (a UUID). |
items[].latest_job_run.interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
items[].latest_job_run.interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
items[].latest_job_run.job_version_id | string (uuid) | The ID of the job version the run uses. |
items[].latest_job_run.logs_url | string or null | A link to the logs of the run |
items[].latest_job_run.number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
items[].latest_job_run.pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
items[].latest_job_run.pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
items[].latest_job_run.pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
items[].latest_job_run.pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
items[].latest_job_run.pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
items[].latest_job_run.pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
items[].latest_job_run.pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
items[].latest_job_run.pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
items[].latest_job_run.pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
items[].latest_job_run.pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
items[].latest_job_run.pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
items[].latest_job_run.previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
items[].latest_job_run.profile | string | The name of the profile that was used for the run |
items[].latest_job_run.started_at | string (date-time) or null | When the run started; null until it has. |
items[].latest_job_run.status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
items[].latest_job_run.trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
items[].latest_job_run.triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
items[].latest_job_run.updated_at | string (date-time) | When it was last changed. |
items[].latest_job_run.workspace_id | string (uuid) | The ID of the workspace the run belongs to |
items[].name | string or null | Display name for the job |
items[].next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
items[].pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
items[].profile | string | The profile the job runs under |
items[].public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
items[].public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
items[].recent_job_runs | array of object or null | The job's most recent runs, newest first. Included only when recent_job_runs_limit is requested; null otherwise. |
items[].recent_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
items[].recent_job_runs[].id | string (uuid) | The run ID |
items[].recent_job_runs[].rows_loaded | integer or null | Total rows loaded across the run's pipeline runs; null when not reported. |
items[].recent_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
items[].recent_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
items[].triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
items[].updated_at | string (date-time) | When it was last changed. |
items[].version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
items[].workspace_id | string (uuid) | The ID of the workspace the job belongs to |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Trigger jobs
POST /api/v1/workspaces/{workspace_id}/jobs/-trigger
Triggers jobs by job_ids and/or by selectors. A job named in job_ids fires its
default_trigger, or manual:<job_ref> if it has none. A selector is matched against each
job's triggers with shell-style wildcards, e.g. tag:backfill, schedule:*,
manual:jobs.my_module.*; a bare trigger type like schedule means schedule:*, and batch
(or job), interactive and stream select every trigger of jobs of that type. A job
matched by a selector fires the trigger it matched. When a job is matched both by id and by
selector, it fires its default_trigger if that is among the matched triggers, otherwise
one of the matched triggers. Archived jobs are never matched.
Jobs start upstream first, and each must pass the freshness check: a job whose upstream is
also triggered in this request is skipped with skipped_upstream_pending, and a job whose
upstream is not fresh is skipped with skipped_fresh. To start a single job regardless of
its upstreams, use create_job_run with skip_freshness=true.
Runs start one by one; a failure part-way through leaves the runs created before it.
Answers a receipt: succeeded jobs started a run, skipped jobs did not (their status and
reasons say why), and failed lists requested ids that name no job or an archived job.
dry_run previews which jobs match and pass the freshness check, without creating runs.
Requires the viewer role (or higher) in the workspace. Viewers may only run jobs that use the
read-only access profile (by default interactive and agent jobs); any other profile needs
the developer role, and a single such job rejects the whole request with 403.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
| Field | Type | Description |
|---|---|---|
dry_run | boolean | Preview which jobs match and pass the freshness check, without creating runs. Limits checked only when a run starts (concurrency, trial, compute minutes, interval bounds) are not evaluated. Default: false. |
job_ids | array of string (uuid) or null | Jobs to trigger, each fired via its default_trigger (or manual:<ref> when it has none). At least one of job_ids or selectors must be non-empty. |
profile | string or null | Profile override for all triggered runs. |
refresh | boolean | Start each triggered job as a refresh, as refresh does for create_job_run; the progress of the jobs downstream of them is reset too. Ignored for a job whose refresh_propagation is block. Skipped jobs are not refreshed. Default: false. |
selectors | array of string or null | Selectors matched against each job's triggers with shell-style wildcards; a matching job fires the trigger it matched. A bare trigger type like schedule means schedule:*; batch (or job), interactive and stream select every trigger of jobs of that type. Examples: tag:backfill, schedule:*, batch, manual:jobs.my_module.*. At least one of job_ids or selectors must be non-empty. |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/-trigger" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"dry_run": false,
"job_ids": ["<job_ids>"],
"profile": "<profile>",
"refresh": false,
"selectors": ["<selectors>"]
}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/-trigger",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={
"dry_run": False,
"job_ids": ["<job_ids>"],
"profile": "<profile>",
"refresh": False,
"selectors": ["<selectors>"],
},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"failed": [
{
"detail": "<detail>",
"ref": "<ref>"
}
],
"skipped": [
{
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_run": {
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"matched_triggers": ["<matched_triggers>"],
"reasons": ["<reasons>"],
"status": "triggered",
"trigger": "<trigger>"
}
],
"succeeded": [
{
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_run": {
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"matched_triggers": ["<matched_triggers>"],
"reasons": ["<reasons>"],
"status": "triggered",
"trigger": "<trigger>"
}
]
}
| Field | Type | Description |
|---|---|---|
failed | array of object | Requested job ids that name no job in the workspace, or an archived job. |
failed[].detail | string | Why it failed. |
failed[].ref | string | The item that failed, by its id or natural key. |
skipped | array of object | Jobs that did not start; their status and reasons say why. |
skipped[].job_id | string (uuid) | The ID of the matched job. |
skipped[].job_ref | string | The job reference of the matched job. |
skipped[].job_run | object or null | The created run; null in dry-run mode or when skipped. |
skipped[].job_run.configuration_id | string (uuid) | The ID of the configuration the run uses. |
skipped[].job_run.created_at | string (date-time) | When it was created. |
skipped[].job_run.deployment_id | string (uuid) | The ID of the deployment the run uses. |
skipped[].job_run.duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
skipped[].job_run.finished_at | string (date-time) or null | When the run finished; null until it has. |
skipped[].job_run.id | string (uuid) | Unique ID (a UUID). |
skipped[].job_run.interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
skipped[].job_run.interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
skipped[].job_run.job_version_id | string (uuid) | The ID of the job version the run uses. |
skipped[].job_run.logs_url | string or null | A link to the logs of the run |
skipped[].job_run.number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
skipped[].job_run.pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
skipped[].job_run.pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
skipped[].job_run.pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
skipped[].job_run.pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
skipped[].job_run.pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
skipped[].job_run.pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
skipped[].job_run.pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
skipped[].job_run.pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
skipped[].job_run.pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
skipped[].job_run.pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
skipped[].job_run.pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
skipped[].job_run.previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
skipped[].job_run.profile | string | The name of the profile that was used for the run |
skipped[].job_run.started_at | string (date-time) or null | When the run started; null until it has. |
skipped[].job_run.status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
skipped[].job_run.trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
skipped[].job_run.triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
skipped[].job_run.updated_at | string (date-time) | When it was last changed. |
skipped[].job_run.workspace_id | string (uuid) | The ID of the workspace the run belongs to |
skipped[].job_run_id | string (uuid) or null | The ID of the created run; null in dry-run mode or when skipped. |
skipped[].matched_triggers | array of string | Every trigger that selected this job: its default trigger when named in job_ids, plus any selector matches. |
skipped[].reasons | array of string or null | Human-readable reasons for a skip, e.g. which upstream jobs are not fresh; null when the job was triggered or no reasons were recorded. |
skipped[].status | string | Whether the job started a run: triggered if it did; otherwise why not. skipped_fresh: an upstream job is not fresh (see reasons). skipped_upstream_pending: an upstream job is triggered in the same request. skipped_out_of_interval: the run would fall outside the job's interval_start / interval_end. skipped_concurrency_limit: the job is already running as many runs as it allows. skipped_org_concurrency_limit: the organization has reached its limit of concurrent runs. skipped_trial_expired: the organization's trial has ended. skipped_minutes_limit: the organization has used up its compute minutes. skipped_workspace_archived: the workspace is archived. One of: triggered, skipped_fresh, skipped_upstream_pending, skipped_out_of_interval, skipped_concurrency_limit, skipped_already_covered, skipped_trial_expired, skipped_minutes_limit, skipped_org_concurrency_limit, skipped_paused, skipped_workspace_archived. Default: "triggered". |
skipped[].trigger | string | The trigger the job fires with. |
succeeded | array of object | Jobs that started a run, or in dry-run mode would pass the freshness check. |
succeeded[].job_id | string (uuid) | The ID of the matched job. |
succeeded[].job_ref | string | The job reference of the matched job. |
succeeded[].job_run | object or null | The created run; null in dry-run mode or when skipped. |
succeeded[].job_run.configuration_id | string (uuid) | The ID of the configuration the run uses. |
succeeded[].job_run.created_at | string (date-time) | When it was created. |
succeeded[].job_run.deployment_id | string (uuid) | The ID of the deployment the run uses. |
succeeded[].job_run.duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
succeeded[].job_run.finished_at | string (date-time) or null | When the run finished; null until it has. |
succeeded[].job_run.id | string (uuid) | Unique ID (a UUID). |
succeeded[].job_run.interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
succeeded[].job_run.interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
succeeded[].job_run.job_version_id | string (uuid) | The ID of the job version the run uses. |
succeeded[].job_run.logs_url | string or null | A link to the logs of the run |
succeeded[].job_run.number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
succeeded[].job_run.pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
succeeded[].job_run.pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
succeeded[].job_run.pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
succeeded[].job_run.pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
succeeded[].job_run.pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
succeeded[].job_run.pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
succeeded[].job_run.pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
succeeded[].job_run.pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
succeeded[].job_run.pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
succeeded[].job_run.pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
succeeded[].job_run.pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
succeeded[].job_run.previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
succeeded[].job_run.profile | string | The name of the profile that was used for the run |
succeeded[].job_run.started_at | string (date-time) or null | When the run started; null until it has. |
succeeded[].job_run.status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
succeeded[].job_run.trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
succeeded[].job_run.triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
succeeded[].job_run.updated_at | string (date-time) | When it was last changed. |
succeeded[].job_run.workspace_id | string (uuid) | The ID of the workspace the run belongs to |
succeeded[].job_run_id | string (uuid) or null | The ID of the created run; null in dry-run mode or when skipped. |
succeeded[].matched_triggers | array of string | Every trigger that selected this job: its default trigger when named in job_ids, plus any selector matches. |
succeeded[].reasons | array of string or null | Human-readable reasons for a skip, e.g. which upstream jobs are not fresh; null when the job was triggered or no reasons were recorded. |
succeeded[].status | string | Whether the job started a run: triggered if it did; otherwise why not. skipped_fresh: an upstream job is not fresh (see reasons). skipped_upstream_pending: an upstream job is triggered in the same request. skipped_out_of_interval: the run would fall outside the job's interval_start / interval_end. skipped_concurrency_limit: the job is already running as many runs as it allows. skipped_org_concurrency_limit: the organization has reached its limit of concurrent runs. skipped_trial_expired: the organization's trial has ended. skipped_minutes_limit: the organization has used up its compute minutes. skipped_workspace_archived: the workspace is archived. One of: triggered, skipped_fresh, skipped_upstream_pending, skipped_out_of_interval, skipped_concurrency_limit, skipped_already_covered, skipped_trial_expired, skipped_minutes_limit, skipped_org_concurrency_limit, skipped_paused, skipped_workspace_archived. Default: "triggered". |
succeeded[].trigger | string | The trigger the job fires with. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Get job
GET /api/v1/workspaces/{workspace_id}/jobs/{job_id}
Gets a job for a workspace by its ID. Find a job by its ref with list_jobs.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
Query parameters
| Name | Type | Description |
|---|---|---|
recent_job_runs_limit | integer or null | Attach this many of the job's most recent runs. |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"current_version": {
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"instance_size": "small",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"job_type": "batch",
"max_run_time_seconds": 0,
"memory_mib": 0,
"name": "<name>",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"provider": "tower",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"vcpu": 0,
"version": 0
},
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"downstream_job_runs": [
{
"category": "pipeline",
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"job_ref": "<job_ref>",
"name": "<name>",
"number": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>"
}
],
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"latest_job_run": {
"configuration_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"created_at": "2026-01-01T00:00:00Z",
"deployment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"duration_seconds": 0,
"finished_at": "2026-01-01T00:00:00Z",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"job_version_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"logs_url": "<logs_url>",
"number": 0,
"pipeline_run_summaries": [
{
"dataset_name": "<dataset_name>",
"destination_name": "<destination_name>",
"duration_ms": 0,
"finished_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"pipeline_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"started_at": "2026-01-01T00:00:00Z",
"status": "succeeded",
"total_rows": 0,
"transaction_id": "<transaction_id>"
}
],
"previous_job_run_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"profile": "<profile>",
"started_at": "2026-01-01T00:00:00Z",
"status": "pending",
"trigger": "<trigger>",
"triggered_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"updated_at": "2026-01-01T00:00:00Z",
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
},
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"recent_job_runs": [
{
"duration_seconds": 0,
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"rows_loaded": 0,
"started_at": "2026-01-01T00:00:00Z",
"status": "pending"
}
],
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
current_version | object or null | The active job version, carrying its provider, instance size, and resolved hardware. |
current_version.created_at | string (date-time) | When it was created. |
current_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
current_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
current_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
current_version.description | string or null | The description of the job |
current_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
current_version.id | string (uuid) | Unique ID (a UUID). |
current_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
current_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
current_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
current_version.job_definition | object | Job definition from the dlt deployment manifest. |
current_version.job_definition_engine_version | integer | Version of the job definition format. |
current_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
current_version.job_id | string (uuid) | The ID of the job the job version belongs to |
current_version.job_ref | string | Canonical job reference, unique per workspace |
current_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
current_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
current_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
current_version.name | string or null | Display name for the job |
current_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
current_version.profile | string | The profile the job runs under |
current_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
current_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
current_version.updated_at | string (date-time) | When it was last changed. |
current_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
current_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
downstream_job_runs | array of object or null | Runs the job's last run triggered, newest first. Included only when downstream_job_runs_limit is requested; null otherwise. Empty when the last run triggered nothing, since a chained job fires only once its upstream run reaches a terminal state. |
downstream_job_runs[].category | string or null | The category the job declares in expose.category, null when it declares none. Callers that want one kind of downstream run, such as agents, filter on this. One of: pipeline, mcp, dashboard, notebook, background_agent. |
downstream_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
downstream_job_runs[].id | string (uuid) | The run ID |
downstream_job_runs[].job_id | string (uuid) | The ID of the job that ran |
downstream_job_runs[].job_ref | string | The job's canonical reference |
downstream_job_runs[].name | string | The job's display name |
downstream_job_runs[].number | integer | The run number within the job |
downstream_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
downstream_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
downstream_job_runs[].trigger | string | The trigger that started the downstream run |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
latest_job_run | object or null | The latest run of the job; null if it has never run. |
latest_job_run.configuration_id | string (uuid) | The ID of the configuration the run uses. |
latest_job_run.created_at | string (date-time) | When it was created. |
latest_job_run.deployment_id | string (uuid) | The ID of the deployment the run uses. |
latest_job_run.duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
latest_job_run.finished_at | string (date-time) or null | When the run finished; null until it has. |
latest_job_run.id | string (uuid) | Unique ID (a UUID). |
latest_job_run.interval_end | string (date-time) or null | End of the interval the run processes; null for a job without intervals. |
latest_job_run.interval_start | string (date-time) or null | Start of the interval the run processes; null for a job without intervals. |
latest_job_run.job_version_id | string (uuid) | The ID of the job version the run uses. |
latest_job_run.logs_url | string or null | A link to the logs of the run |
latest_job_run.number | integer | Number of the run within its job, counting up from 1; numbers repeat across jobs. |
latest_job_run.pipeline_run_summaries | array of object | One entry per dlt pipeline name the run reported; a pipeline that ran more than once shows its latest report. In no particular order, and empty until telemetry has received the reports. |
latest_job_run.pipeline_run_summaries[].dataset_name | string or null | Name of the dataset the pipeline wrote to |
latest_job_run.pipeline_run_summaries[].destination_name | string or null | Name of the destination the pipeline wrote to |
latest_job_run.pipeline_run_summaries[].duration_ms | integer or null | Duration of the pipeline run in milliseconds |
latest_job_run.pipeline_run_summaries[].finished_at | string (date-time) or null | When the pipeline run finished |
latest_job_run.pipeline_run_summaries[].pipeline_name | string | Name of the dlt pipeline |
latest_job_run.pipeline_run_summaries[].pipeline_run_id | string (uuid) or null | Telemetry ID of the pipeline run |
latest_job_run.pipeline_run_summaries[].started_at | string (date-time) or null | When the pipeline run started |
latest_job_run.pipeline_run_summaries[].status | string or null | Status of the pipeline run One of: succeeded, failed. |
latest_job_run.pipeline_run_summaries[].total_rows | integer or null | Total number of rows loaded by the pipeline |
latest_job_run.pipeline_run_summaries[].transaction_id | string or null | Transaction ID of the pipeline run |
latest_job_run.previous_job_run_id | string (uuid) or null | The upstream run whose completion started this one, through a job.success: / job.fail: trigger or a freshness dependency; null for a run started manually, by its own schedule, or by a trigger request. |
latest_job_run.profile | string | The name of the profile that was used for the run |
latest_job_run.started_at | string (date-time) or null | When the run started; null until it has. |
latest_job_run.status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
latest_job_run.trigger | string | The trigger the run fired with, e.g. schedule:0 8 * * *, manual:jobs.my_job, job.success:jobs.upstream. |
latest_job_run.triggered_by | string (uuid) or null | The organization_membership_id of the member who started the run; set for any run started through the API, null for runs the scheduler, another job or a public URL started. |
latest_job_run.updated_at | string (date-time) | When it was last changed. |
latest_job_run.workspace_id | string (uuid) | The ID of the workspace the run belongs to |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
recent_job_runs | array of object or null | The job's most recent runs, newest first. Included only when recent_job_runs_limit is requested; null otherwise. |
recent_job_runs[].duration_seconds | number or null | Duration of the run in seconds, possibly fractional; null until it has finished. |
recent_job_runs[].id | string (uuid) | The run ID |
recent_job_runs[].rows_loaded | integer or null | Total rows loaded across the run's pipeline runs; null when not reported. |
recent_job_runs[].started_at | string (date-time) or null | When the run started, null if not yet started |
recent_job_runs[].status | string | The status of the run One of: pending, starting, running, completed, failed, cancelled, skipped, cancelling. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Archive job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-archive
Archives a job. An archived job cannot be run (neither manually nor by schedule);
listings include it unless is_archived filters it out. Archiving clears the job's schedule
and pause, and its public URL stops working until it is unarchived. Idempotent.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-archive" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-archive",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Pause job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-pause
Pauses a job's scheduled runs. The scheduler stops starting it, including a scheduled run
that was waiting for its upstream jobs. Manual runs, trigger_jobs and runs started by
another job's success or failure still run.
Only a job with next_scheduled_run_at can be paused; an archived job or one without a
schedule answers 400.
next_scheduled_run_at keeps advancing while the job is paused, so resuming produces one run
covering the whole period. A deploy that removes the schedule also removes the pause;
otherwise a deploy leaves it alone. The public URL is untouched. Idempotent.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-pause" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-pause",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Publish job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-publish
Enables or regenerates the public URL for a job. This creates a new public_secret that
gives access to the job without authentication. Calling it again generates a new
public_secret, invalidating any previous public URL. The URL does not work while the job
is archived.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-publish" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-publish",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Resume job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-resume
Resumes a paused job, so the scheduler starts it again. The first run after resuming covers the whole period the job was paused for. Idempotent.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-resume" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-resume",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Unarchive job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-unarchive
Unarchives a job so it can run again, restoring the schedule and default trigger from its definition; a pause is not restored. Idempotent.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-unarchive" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-unarchive",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Unpublish job
POST /api/v1/workspaces/{workspace_id}/jobs/{job_id}/-unpublish
Disables the public URL for a job by clearing its public_secret. Afterwards the job is
no longer reachable through its public URL, and public_url is null.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
job_id | string (uuid) | ID of the job |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/jobs/$JOB_ID/-unpublish" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/jobs/<job_id>/-unpublish",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"created_by": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"default_trigger": "<default_trigger>",
"deployment_module": "<deployment_module>",
"description": "<description>",
"freshness": ["<freshness>"],
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"interval_end": "2026-01-01T00:00:00Z",
"interval_start": "2026-01-01T00:00:00Z",
"is_archived": false,
"is_paused": false,
"job_definition": {},
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"job_ref": "<job_ref>",
"job_type": "batch",
"job_url": "<job_url>",
"name": "<name>",
"next_scheduled_run_at": "2026-01-01T00:00:00Z",
"pipeline_name": "<pipeline_name>",
"profile": "<profile>",
"public_secret": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"public_url": "<public_url>",
"triggers": ["<triggers>"],
"updated_at": "2026-01-01T00:00:00Z",
"version": 0,
"workspace_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
created_by | string (uuid) | The organization_membership_id of the member who created the job. |
default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
description | string or null | The description of the job |
freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
id | string (uuid) | Unique ID (a UUID). |
interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_definition | object | Job definition from the dlt deployment manifest. |
job_definition_engine_version | integer | Version of the job definition format. |
job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_ref | string | Canonical job reference, unique per workspace |
job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
name | string or null | Display name for the job |
next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
profile | string | The profile the job runs under |
public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
updated_at | string (date-time) | When it was last changed. |
version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
workspace_id | string (uuid) | The ID of the workspace the job belongs to |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Me
Get me
GET /api/v1/me
Gets your user profile and organization memberships. primary_organization is where new
workspaces are created by default; latest_organization and latest_workspace are the ones
you used last. Workspaces are listed per organization by get_organization_me.
Each call also accepts your pending invites and creates your playground workspace in any organization that lacks one. On the first call for a user who has no organization yet, it creates a personal organization and a playground workspace, so a freshly authenticated user always gets a 200.
Requires a personal API key or a user login; a workspace API key answers 403.
Request
- curl
- Python
curl "https://api.dlthub.com/api/v1/me" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/me",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"email": "<email>",
"latest_organization": {
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
},
"latest_workspace": {
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
},
"name": "<name>",
"organization_membership_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"organization_memberships": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_active": false,
"organization": {
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
},
"role": "owner"
}
],
"primary_organization": {
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
},
"user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
| Field | Type | Description |
|---|---|---|
email | string | The email of the current user |
latest_organization | object | The organization you used most recently. |
latest_organization.created_at | string (date-time) | When it was created. |
latest_organization.dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
latest_organization.description | string or null | Free-text description of the organization; null when none is set. |
latest_organization.id | string (uuid) | Unique ID (a UUID). |
latest_organization.name | string | The name of the organization |
latest_organization.updated_at | string (date-time) | When it was last changed. |
latest_workspace | object or null | The workspace you used last; null when none is recorded yet. |
latest_workspace.archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
latest_workspace.created_at | string (date-time) | When it was created. |
latest_workspace.dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
latest_workspace.dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
latest_workspace.description | string or null | Free-text description of the workspace; null when none is set. |
latest_workspace.id | string (uuid) | Unique ID (a UUID). |
latest_workspace.is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
latest_workspace.name | string | The name of the workspace |
latest_workspace.organization_id | string (uuid) | The ID of the parent organization |
latest_workspace.predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
latest_workspace.updated_at | string (date-time) | When it was last changed. |
name | string or null | The user's display name (full name); null if the identity provider supplied none. |
organization_membership_id | string (uuid) | Your membership id in latest_organization. |
organization_memberships | array of object | All organizations the user is a member of |
organization_memberships[].id | string (uuid) | The ID of the organization membership |
organization_memberships[].is_active | boolean | Whether the membership is active |
organization_memberships[].organization | object | The organization. |
organization_memberships[].organization.created_at | string (date-time) | When it was created. |
organization_memberships[].organization.dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
organization_memberships[].organization.description | string or null | Free-text description of the organization; null when none is set. |
organization_memberships[].organization.id | string (uuid) | Unique ID (a UUID). |
organization_memberships[].organization.name | string | The name of the organization |
organization_memberships[].organization.updated_at | string (date-time) | When it was last changed. |
organization_memberships[].role | string | The role of the user in the organization One of: owner, member, collaborator. |
primary_organization | object | The organization where new workspaces are created by default. |
primary_organization.created_at | string (date-time) | When it was created. |
primary_organization.dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
primary_organization.description | string or null | Free-text description of the organization; null when none is set. |
primary_organization.id | string (uuid) | Unique ID (a UUID). |
primary_organization.name | string | The name of the organization |
primary_organization.updated_at | string (date-time) | When it was last changed. |
user_id | string (uuid) | The ID of the current user |
401Unauthorized403Forbidden500Internal Server Error
Each error returns the error body.
Organization me
GET /api/v1/organizations/{organization_id}/me
Gets your context in an organization: the organization, your role and membership id there, and the workspaces you can access in it with your role in each.
Any organization member, including collaborators.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
organization_id | string (uuid) | ID of the organization |
curl "https://api.dlthub.com/api/v1/organizations/$ORGANIZATION_ID/me" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/organizations/<organization_id>/me",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"email": "<email>",
"organization": {
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
},
"organization_membership_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"role": "owner",
"user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"workspace_memberships": [
{
"role": "owner",
"workspace": {
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
}
]
}
| Field | Type | Description |
|---|---|---|
email | string | The email of the current user |
organization | object | The organization. |
organization.created_at | string (date-time) | When it was created. |
organization.dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
organization.description | string or null | Free-text description of the organization; null when none is set. |
organization.id | string (uuid) | Unique ID (a UUID). |
organization.name | string | The name of the organization |
organization.updated_at | string (date-time) | When it was last changed. |
organization_membership_id | string (uuid) | The ID of the organization member for this organization |
role | string | The role of the user in this organization One of: owner, member, collaborator. |
user_id | string (uuid) | The ID of the current user |
workspace_memberships | array of object | The workspaces you can access in this organization, with your role in each: those you belong to plus, unless you are a collaborator, those you reach through a workspace's default member role. Archived workspaces are not listed. |
workspace_memberships[].role | string | The role of the user in the workspace One of: owner, developer, viewer. |
workspace_memberships[].workspace | object | The workspace |
workspace_memberships[].workspace.archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
workspace_memberships[].workspace.created_at | string (date-time) | When it was created. |
workspace_memberships[].workspace.dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
workspace_memberships[].workspace.dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
workspace_memberships[].workspace.description | string or null | Free-text description of the workspace; null when none is set. |
workspace_memberships[].workspace.id | string (uuid) | Unique ID (a UUID). |
workspace_memberships[].workspace.is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
workspace_memberships[].workspace.name | string | The name of the workspace |
workspace_memberships[].workspace.organization_id | string (uuid) | The ID of the parent organization |
workspace_memberships[].workspace.predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
workspace_memberships[].workspace.updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Workspace me
GET /api/v1/workspaces/{workspace_id}/me
Gets your context in a workspace: the workspace, your role in it, its organization and your role and membership id there.
Also records this workspace as your latest, which get_me returns in latest_workspace.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/me" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/me",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"email": "<email>",
"organization": {
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
},
"organization_membership_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"organization_role": "owner",
"user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"workspace": {
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
},
"workspace_role": "owner"
}
| Field | Type | Description |
|---|---|---|
email | string | The email of the current user |
organization | object | The workspace's organization. |
organization.created_at | string (date-time) | When it was created. |
organization.dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
organization.description | string or null | Free-text description of the organization; null when none is set. |
organization.id | string (uuid) | Unique ID (a UUID). |
organization.name | string | The name of the organization |
organization.updated_at | string (date-time) | When it was last changed. |
organization_membership_id | string (uuid) | The ID of the organization member in the parent organization |
organization_role | string | The role of the user in the parent organization One of: owner, member, collaborator. |
user_id | string (uuid) | The ID of the current user |
workspace | object | The workspace |
workspace.archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
workspace.created_at | string (date-time) | When it was created. |
workspace.dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
workspace.dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
workspace.description | string or null | Free-text description of the workspace; null when none is set. |
workspace.id | string (uuid) | Unique ID (a UUID). |
workspace.is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
workspace.name | string | The name of the workspace |
workspace.organization_id | string (uuid) | The ID of the parent organization |
workspace.predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
workspace.updated_at | string (date-time) | When it was last changed. |
workspace_role | string | The role of the user in this workspace One of: owner, developer, viewer. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Organizations
List organizations
GET /api/v1/organizations
Lists all organizations the current user is a member of, as a paginated list.
Requires any valid credential; no particular role is needed.
Request
- Parameters
- curl
- Python
Query parameters
| Name | Type | Description |
|---|---|---|
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: created_at, name. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/organizations" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/organizations",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].created_at | string (date-time) | When it was created. |
items[].dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
items[].description | string or null | Free-text description of the organization; null when none is set. |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].name | string | The name of the organization |
items[].updated_at | string (date-time) | When it was last changed. |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden500Internal Server Error
Each error returns the error body.
Get organization
GET /api/v1/organizations/{organization_id}
Gets information about an organization.
Any organization member, including collaborators.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
organization_id | string (uuid) | ID of the organization |
curl "https://api.dlthub.com/api/v1/organizations/$ORGANIZATION_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/organizations/<organization_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
description | string or null | Free-text description of the organization; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
name | string | The name of the organization |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Set organization region
POST /api/v1/organizations/{organization_id}/-set-region
Sets the organization's region, its data plane. This is one-time and
irreversible: a second attempt returns 409. An unknown dataplane_id returns 400. List the
available data planes with list_dataplanes.
Requires the organization owner role.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
organization_id | string (uuid) | ID of the organization |
| Field | Type | Description |
|---|---|---|
dataplane_id | string | Required. Data plane id for the organization's region. Cannot be changed once set. |
curl -X POST "https://api.dlthub.com/api/v1/organizations/$ORGANIZATION_ID/-set-region" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"dataplane_id": "<dataplane_id>"}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/organizations/<organization_id>/-set-region",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={"dataplane_id": "<dataplane_id>"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
created_at | string (date-time) | When it was created. |
dataplane_id | string or null | Data plane of the organization's workspaces; null until a region is set. |
description | string or null | Free-text description of the organization; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
name | string | The name of the organization |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Workspaces
List workspaces
GET /api/v1/organizations/{organization_id}/workspaces
Lists the workspaces under an organization visible to the caller, as a paginated list, oldest first by default. Organization owners see every workspace; members see the workspaces they belong to or reach through a workspace's default member role; collaborators see only the workspaces they belong to.
Each workspace includes member stats: its owners and the count of active members.
Playground workspaces of other members are not included; the caller only sees their own.
Archived workspaces are excluded by default; pass include_archived=true to list them.
Any organization member, including collaborators.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
organization_id | string (uuid) | ID of the organization |
Query parameters
| Name | Type | Description |
|---|---|---|
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: created_at, name. |
include_archived | boolean | Include archived workspaces. They are excluded unless set. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/organizations/$ORGANIZATION_ID/workspaces" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/organizations/<organization_id>/workspaces",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"member_count": 0,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"owner_members": [
{
"email": "<email>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"organization_membership_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"role": "owner",
"user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
items[].created_at | string (date-time) | When it was created. |
items[].dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
items[].dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
items[].description | string or null | Free-text description of the workspace; null when none is set. |
items[].id | string (uuid) | Unique ID (a UUID). |
items[].is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
items[].member_count | integer | Number of active human members in the workspace. |
items[].name | string | The name of the workspace |
items[].organization_id | string (uuid) | The ID of the parent organization |
items[].owner_members | array of object | The workspace's active human owners, in the order they joined. |
items[].owner_members[].email | string | The email of the user |
items[].owner_members[].id | string (uuid) | The ID of the workspace membership |
items[].owner_members[].name | string or null | Display name; null when the user has no name set. |
items[].owner_members[].organization_membership_id | string (uuid) | The ID of the member's organization membership, which created_by and triggered_by hold |
items[].owner_members[].role | string | The role of the user in the workspace One of: owner, developer, viewer. |
items[].owner_members[].user_id | string (uuid) | The ID of the user |
items[].predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
items[].updated_at | string (date-time) | When it was last changed. |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Create workspace
POST /api/v1/organizations/{organization_id}/workspaces
Creates a workspace in the organization; the caller becomes its owner. Send both name and
description (description may be null). Answers 409 until the organization's region is
set with set_region_organization.
Requires the organization member or owner role.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
organization_id | string (uuid) | ID of the organization |
| Field | Type | Description |
|---|---|---|
description | string or null | Required. Free-text description of the workspace; null when none is set. |
name | string | Required. The name of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/organizations/$ORGANIZATION_ID/workspaces" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "<description>", "name": "<name>"}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/organizations/<organization_id>/workspaces",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={"description": "<description>", "name": "<name>"},
)
response.raise_for_status()
print(response.json())
Response (201, 4xx, 5xx)
- Example
- Fields
- Errors
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
created_at | string (date-time) | When it was created. |
dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
description | string or null | Free-text description of the workspace; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
name | string | The name of the workspace |
organization_id | string (uuid) | The ID of the parent organization |
predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Get workspace
GET /api/v1/workspaces/{workspace_id}
Gets information about a workspace.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
created_at | string (date-time) | When it was created. |
dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
description | string or null | Free-text description of the workspace; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
name | string | The name of the workspace |
organization_id | string (uuid) | The ID of the parent organization |
predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Update workspace
PATCH /api/v1/workspaces/{workspace_id}
Updates the information for a workspace.
Answers 400 for a playground workspace and 409 for an archived one.
Requires the workspace owner role.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
| Field | Type | Description |
|---|---|---|
description | string or null | The description of the workspace |
name | string or null | The name of the workspace |
curl -X PATCH "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"description": "<description>", "name": "<name>"}'
import os
import requests
response = requests.patch(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={"description": "<description>", "name": "<name>"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
created_at | string (date-time) | When it was created. |
dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
description | string or null | Free-text description of the workspace; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
name | string | The name of the workspace |
organization_id | string (uuid) | The ID of the parent organization |
predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Archive workspace
POST /api/v1/workspaces/{workspace_id}/-archive
Archives a workspace: clears schedules and rejects further changes until unarchived. Answers 409 if the workspace is already archived or any run is still active, 400 for a playground.
Requires the workspace owner role.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/-archive" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/-archive",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
created_at | string (date-time) | When it was created. |
dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
description | string or null | Free-text description of the workspace; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
name | string | The name of the workspace |
organization_id | string (uuid) | The ID of the parent organization |
predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Deploy
POST /api/v1/workspaces/{workspace_id}/-deploy
Deploys a set of job definitions from a deployment manifest. Creates new jobs,
updates existing ones, and archives orphaned jobs (those previously deployed from
the same deployment_module but no longer present in the manifest).
Answers with one receipt per kind the manifest declares. Under job_receipt, succeeded
lists each job created, updated or archived with its outcome and skipped the unchanged
ones; a deploy is all or nothing, so failed is always empty.
When deployment_module is null, this is an ad-hoc deploy: jobs are only added or
updated, never archived. When deployment_module is __deployment__, the workspace
description is also updated from the manifest.
With dry_run, the changes are previewed without being saved; created and updated jobs then
carry the zero UUID as id and version 0.
Requires the developer role (or higher) in the workspace.
Request
- Parameters
- Body
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
| Field | Type | Description |
|---|---|---|
deployment_module | string or null | Deployment module the jobs come from, e.g. __deployment__ for a standard deploy. null makes an ad-hoc deploy, which never archives jobs. |
description | string or null | Workspace description, e.g. from the __deployment__ module docstring. Applied only when deployment_module is __deployment__. |
dry_run | boolean | Preview the changes without saving them. Created and updated jobs then carry the zero UUID as id and version 0. Default: false. |
job_definition_engine_version | integer | Required. Not used; send the value dlt produces. |
job_definition_hash | string | Required. Not used; send the value dlt produces. |
jobs | array of map of any | Required. Job definitions from the deployment manifest. |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/-deploy" \
-H "Authorization: Bearer $DLTHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"jobs": []
}'
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/-deploy",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
json={
"job_definition_engine_version": 0,
"job_definition_hash": "<job_definition_hash>",
"jobs": [],
},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"deployment_module": "<deployment_module>",
"job_receipt": {
"failed": [
{
"detail": "<detail>",
"ref": "<ref>"
}
],
"skipped": [
{
"job": {},
"outcome": "created",
"previous_version": {}
}
],
"succeeded": [
{
"job": {},
"outcome": "created",
"previous_version": {}
}
]
},
"warnings": ["<warnings>"]
}
| Field | Type | Description |
|---|---|---|
deployment_module | string or null | The deployment module the deploy was scoped to. |
job_receipt | object | What a deploy did to the workspace's jobs. |
job_receipt.failed | array of object | Always empty: a deploy is all or nothing, so a failure answers with an error instead. |
job_receipt.failed[].detail | string | Why it failed. |
job_receipt.failed[].ref | string | The item that failed, by its id or natural key. |
job_receipt.skipped | array of object | Jobs with no changes. |
job_receipt.skipped[].job | object | The job as it stands after the deploy. |
job_receipt.skipped[].job.created_at | string (date-time) | When it was created. |
job_receipt.skipped[].job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_receipt.skipped[].job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_receipt.skipped[].job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_receipt.skipped[].job.description | string or null | The description of the job |
job_receipt.skipped[].job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_receipt.skipped[].job.id | string (uuid) | Unique ID (a UUID). |
job_receipt.skipped[].job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_receipt.skipped[].job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_receipt.skipped[].job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
job_receipt.skipped[].job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_receipt.skipped[].job.job_definition | object | Job definition from the dlt deployment manifest. |
job_receipt.skipped[].job.job_definition_engine_version | integer | Version of the job definition format. |
job_receipt.skipped[].job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_receipt.skipped[].job.job_ref | string | Canonical job reference, unique per workspace |
job_receipt.skipped[].job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_receipt.skipped[].job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
job_receipt.skipped[].job.name | string or null | Display name for the job |
job_receipt.skipped[].job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
job_receipt.skipped[].job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_receipt.skipped[].job.profile | string | The profile the job runs under |
job_receipt.skipped[].job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
job_receipt.skipped[].job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
job_receipt.skipped[].job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_receipt.skipped[].job.updated_at | string (date-time) | When it was last changed. |
job_receipt.skipped[].job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_receipt.skipped[].job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
job_receipt.skipped[].outcome | string | What the deploy did to the job. One of: created, updated, archived, unchanged. |
job_receipt.skipped[].previous_version | object or null | The version an updated job had before the deploy. |
job_receipt.skipped[].previous_version.created_at | string (date-time) | When it was created. |
job_receipt.skipped[].previous_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_receipt.skipped[].previous_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_receipt.skipped[].previous_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_receipt.skipped[].previous_version.description | string or null | The description of the job |
job_receipt.skipped[].previous_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_receipt.skipped[].previous_version.id | string (uuid) | Unique ID (a UUID). |
job_receipt.skipped[].previous_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
job_receipt.skipped[].previous_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_receipt.skipped[].previous_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_receipt.skipped[].previous_version.job_definition | object | Job definition from the dlt deployment manifest. |
job_receipt.skipped[].previous_version.job_definition_engine_version | integer | Version of the job definition format. |
job_receipt.skipped[].previous_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_receipt.skipped[].previous_version.job_id | string (uuid) | The ID of the job the job version belongs to |
job_receipt.skipped[].previous_version.job_ref | string | Canonical job reference, unique per workspace |
job_receipt.skipped[].previous_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_receipt.skipped[].previous_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
job_receipt.skipped[].previous_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
job_receipt.skipped[].previous_version.name | string or null | Display name for the job |
job_receipt.skipped[].previous_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_receipt.skipped[].previous_version.profile | string | The profile the job runs under |
job_receipt.skipped[].previous_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
job_receipt.skipped[].previous_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_receipt.skipped[].previous_version.updated_at | string (date-time) | When it was last changed. |
job_receipt.skipped[].previous_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
job_receipt.skipped[].previous_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_receipt.succeeded | array of object | Jobs created, updated or archived. |
job_receipt.succeeded[].job | object | The job as it stands after the deploy. |
job_receipt.succeeded[].job.created_at | string (date-time) | When it was created. |
job_receipt.succeeded[].job.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_receipt.succeeded[].job.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_receipt.succeeded[].job.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_receipt.succeeded[].job.description | string or null | The description of the job |
job_receipt.succeeded[].job.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_receipt.succeeded[].job.id | string (uuid) | Unique ID (a UUID). |
job_receipt.succeeded[].job.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_receipt.succeeded[].job.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_receipt.succeeded[].job.is_archived | boolean | Whether the job is archived. Archived jobs cannot be run and their public URL stops working. Default: false. |
job_receipt.succeeded[].job.is_paused | boolean | Whether the job's scheduled runs are paused. The scheduler does not start it, including a scheduled run that was waiting for its upstream jobs; manual runs, runs started by a trigger request, and runs started by another job's success or failure still run. Only a job with next_scheduled_run_at can be paused, and a deploy that removes the schedule clears the pause. Default: false. |
job_receipt.succeeded[].job.job_definition | object | Job definition from the dlt deployment manifest. |
job_receipt.succeeded[].job.job_definition_engine_version | integer | Version of the job definition format. |
job_receipt.succeeded[].job.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_receipt.succeeded[].job.job_ref | string | Canonical job reference, unique per workspace |
job_receipt.succeeded[].job.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_receipt.succeeded[].job.job_url | string or null | The URL of the job in the web app for an interactive job; null otherwise. |
job_receipt.succeeded[].job.name | string or null | Display name for the job |
job_receipt.succeeded[].job.next_scheduled_run_at | string (date-time) or null | When the job is next scheduled to run; null if it has no schedule. |
job_receipt.succeeded[].job.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_receipt.succeeded[].job.profile | string | The profile the job runs under |
job_receipt.succeeded[].job.public_secret | string (uuid) or null | The secret in the job's public URL; null when the job is not published. |
job_receipt.succeeded[].job.public_url | string or null | The public URL where the job can be accessed without authentication; null when the job is not published. It does not work while the job is archived. |
job_receipt.succeeded[].job.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_receipt.succeeded[].job.updated_at | string (date-time) | When it was last changed. |
job_receipt.succeeded[].job.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
job_receipt.succeeded[].job.workspace_id | string (uuid) | The ID of the workspace the job belongs to |
job_receipt.succeeded[].outcome | string | What the deploy did to the job. One of: created, updated, archived, unchanged. |
job_receipt.succeeded[].previous_version | object or null | The version an updated job had before the deploy. |
job_receipt.succeeded[].previous_version.created_at | string (date-time) | When it was created. |
job_receipt.succeeded[].previous_version.created_by | string (uuid) | The organization_membership_id of the member who created the job. |
job_receipt.succeeded[].previous_version.default_trigger | string or null | The trigger fired when a run is started without naming one, computed from the job definition. |
job_receipt.succeeded[].previous_version.deployment_module | string or null | Deployment module the job was deployed from, e.g. __deployment__; null for a job deployed outside a module. |
job_receipt.succeeded[].previous_version.description | string or null | The description of the job |
job_receipt.succeeded[].previous_version.freshness | array of string or null | Freshness constraint strings (computed from job_definition) |
job_receipt.succeeded[].previous_version.id | string (uuid) | Unique ID (a UUID). |
job_receipt.succeeded[].previous_version.instance_size | string or null | Instance size this version runs on; null on a provider without instance sizing. One of: small, medium, large, xlarge. |
job_receipt.succeeded[].previous_version.interval_end | string (date-time) or null | Upper bound of the job's work window, from interval.end in its definition; null when there is no upper bound. The schedule stops once the next run would pass it. |
job_receipt.succeeded[].previous_version.interval_start | string (date-time) or null | Lower bound of the job's work window, from interval.start in its definition; null when the job has no bounded window. |
job_receipt.succeeded[].previous_version.job_definition | object | Job definition from the dlt deployment manifest. |
job_receipt.succeeded[].previous_version.job_definition_engine_version | integer | Version of the job definition format. |
job_receipt.succeeded[].previous_version.job_definition_hash | string | Hash of the job definition; a deploy compares it to detect changes. |
job_receipt.succeeded[].previous_version.job_id | string (uuid) | The ID of the job the job version belongs to |
job_receipt.succeeded[].previous_version.job_ref | string | Canonical job reference, unique per workspace |
job_receipt.succeeded[].previous_version.job_type | string | The type of the job: batch, interactive, or stream One of: batch, interactive, stream. |
job_receipt.succeeded[].previous_version.max_run_time_seconds | integer | Maximum allowed run duration in seconds for this job version |
job_receipt.succeeded[].previous_version.memory_mib | integer or null | Resolved memory in MiB; null when the version has no sized hardware. |
job_receipt.succeeded[].previous_version.name | string or null | Display name for the job |
job_receipt.succeeded[].previous_version.pipeline_name | string or null | Pipeline name this job operates on (computed from job_definition) |
job_receipt.succeeded[].previous_version.profile | string | The profile the job runs under |
job_receipt.succeeded[].previous_version.provider | string | Run provider for runs using this job version (e.g. 'tower', 'modal', 'local') One of: tower, modal, local. |
job_receipt.succeeded[].previous_version.triggers | array of string or null | Every trigger the job answers to, computed from its definition; selectors match against these. |
job_receipt.succeeded[].previous_version.updated_at | string (date-time) | When it was last changed. |
job_receipt.succeeded[].previous_version.vcpu | number or null | Resolved virtual CPU cores; null when the version has no sized hardware. |
job_receipt.succeeded[].previous_version.version | integer | Version number, starting at 1 and incremented by each update to the job: a job's current version, or a job version's own number. |
warnings | array of string | Always empty at present. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
Issue dataplane token
POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token
Issues a data plane token for this workspace, valid for 10 minutes. Send it as
Authorization: Bearer <token> to the services at the workspace's dataplane_url.
Viewers and developers can read files, logs and telemetry; owners can also read and change
workspace variables, even on an archived workspace. Cache the token and request a new one
before expires_at.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/-issue-dataplane-token" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/-issue-dataplane-token",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"expires_at": 0,
"token": "<token>"
}
| Field | Type | Description |
|---|---|---|
expires_at | integer | Unix timestamp (seconds) when the token expires. Clients should refresh before this moment. |
token | string | Data plane token; send it as Authorization: Bearer <token>. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.
Unarchive workspace
POST /api/v1/workspaces/{workspace_id}/-unarchive
Unarchives a workspace, restoring write access and recomputing schedules. Answers 409 if the workspace is not archived.
Requires the workspace owner role.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
curl -X POST "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/-unarchive" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.post(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/-unarchive",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"archived_at": "2026-01-01T00:00:00Z",
"created_at": "2026-01-01T00:00:00Z",
"dataplane_id": "<dataplane_id>",
"dataplane_url": "<dataplane_url>",
"description": "<description>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"is_playground": false,
"name": "<name>",
"organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"predefined_profiles": {},
"updated_at": "2026-01-01T00:00:00Z"
}
| Field | Type | Description |
|---|---|---|
archived_at | string (date-time) or null | When the workspace was archived; null when live. An archived workspace rejects all changes except unarchiving, though owners can still manage its workspace variables. |
created_at | string (date-time) | When it was created. |
dataplane_id | string | Identifier of the data plane that holds this workspace's user data. Matches the subdomain of the plane's public entrypoint. |
dataplane_url | string | Base URL of the workspace's data plane, https://<dataplane_id>.dlthub.com, where the Dataplane, Logs and Telemetry APIs are served. Call them with a token from POST /api/v1/workspaces/{workspace_id}/-issue-dataplane-token. |
description | string or null | Free-text description of the workspace; null when none is set. |
id | string (uuid) | Unique ID (a UUID). |
is_playground | boolean | Whether this is the user's auto-created personal playground workspace. A playground has a single member and cannot be updated, archived, shared, or given API keys. Default: false. |
name | string | The name of the workspace |
organization_id | string (uuid) | The ID of the parent organization |
predefined_profiles | map of string | Built-in profiles by data access: DATA_WRITE → prod (runs need developer or owner), DATA_READ → access (viewers may run). |
updated_at | string (date-time) | When it was last changed. |
400Bad Request401Unauthorized403Forbidden404Not Found409Conflict500Internal Server Error
Each error returns the error body.
List workspace members
GET /api/v1/workspaces/{workspace_id}/members
Lists a workspace's direct members as a paginated list, oldest first. Workspace API keys are
listed too, with kind=service_account; pass one or more kind values to filter.
Organization owners and members who reach the workspace only through its default member
role are not listed.
Requires the viewer role (or higher) in the workspace.
Request
- Parameters
- curl
- Python
Path parameters
| Name | Type | Description |
|---|---|---|
workspace_id | string (uuid) | ID of the workspace |
Query parameters
| Name | Type | Description |
|---|---|---|
kind | array of string or null | Exact match on kind. Repeat the parameter to match any of several values. One of: human, service_account, managed. |
sort | array of string or null | Keys to sort by, applied in the order given. Pairs positionally with order, which must have the same number of entries. One of: created_at, email. |
Pagination: limit, offset, order, cursor, see Lists and pagination
curl "https://api.dlthub.com/api/v1/workspaces/$WORKSPACE_ID/members" \
-H "Authorization: Bearer $DLTHUB_API_KEY"
import os
import requests
response = requests.get(
"https://api.dlthub.com/api/v1/workspaces/<workspace_id>/members",
headers={"Authorization": f"Bearer {os.environ['DLTHUB_API_KEY']}"},
)
response.raise_for_status()
print(response.json())
Response (200, 4xx, 5xx)
- Example
- Fields
- Errors
{
"items": [
{
"email": "<email>",
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "<name>",
"organization_membership_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"role": "owner",
"user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"limit": 0,
"next_cursor": "<next_cursor>",
"offset": 0,
"total": 0
}
| Field | Type | Description |
|---|---|---|
items | array of object | The rows of this page, in sort order. |
items[].email | string | The email of the user |
items[].id | string (uuid) | The ID of the workspace membership |
items[].name | string or null | Display name; null when the user has no name set. |
items[].organization_membership_id | string (uuid) | The ID of the member's organization membership, which created_by and triggered_by hold |
items[].role | string | The role of the user in the workspace One of: owner, developer, viewer. |
items[].user_id | string (uuid) | The ID of the user |
limit | integer | The page size this page was fetched with. |
next_cursor | string or null | Cursor for the page after this one; null on the last. |
offset | integer | How many rows were skipped before this page. |
total | integer | Rows matching the filters, reported up to 10001. |
400Bad Request401Unauthorized403Forbidden404Not Found500Internal Server Error
Each error returns the error body.