Artifacts
Export workspace files as durable, indexed artifacts that outlive the sandbox.
An artifact is a durable, indexed output copied from a sandbox workspace to object storage. Export is always explicit — nothing is saved automatically — and artifacts survive after the sandbox is destroyed.
The Artifact object
| Field | Type | Description |
|---|---|---|
id | string | Artifact ID, prefixed art_ |
orgId | string | Owning organization, prefixed org_ |
projectId | string | Owning project, prefixed prj_ |
sandboxId | string | Source sandbox, prefixed sbx_ |
name | string | Display name |
sourcePath | string | Workspace path it was copied from, when recorded |
objectKey | string | Object storage key |
sizeBytes | integer | Size in bytes |
contentType | string | MIME type, when detected |
createdAt | string | ISO 8601 creation timestamp |
deletedAt | string | ISO 8601 deletion timestamp, once deleted |
Create an artifact
POST /v1/sandboxes/{sandboxId}/artifacts — requires scopes
artifact:create and file:read. Accepts an
Idempotency-Key header.
Copies a file from the live sandbox workspace into object storage. The sandbox must still be alive — export anything you need before killing it.
| Field | Type | Required | Constraints |
|---|---|---|---|
path | string | Yes | Must resolve inside /workspace |
name | string | No | Display name; defaults from the path |
curl -X POST https://api.crownest.dev/v1/sandboxes/sbx_abc123/artifacts \
-H "Authorization: Bearer $CROWNEST_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4c8a1d7e-export-01" \
-d '{ "path": "/workspace/model.bin", "name": "model" }'Returns 201 with the artifact:
{
"artifact": {
"id": "art_abc123",
"orgId": "org_abc123",
"projectId": "prj_abc123",
"sandboxId": "sbx_abc123",
"name": "model",
"sourcePath": "/workspace/model.bin",
"objectKey": "org_abc123/art_abc123",
"sizeBytes": 5242880,
"contentType": "application/octet-stream",
"createdAt": "2026-06-11T13:00:00.000Z"
}
}Errors: invalid_request, forbidden, not_found, file_not_found,
path_outside_workspace, sandbox_destroyed.
[!TIP] You can also export artifacts automatically when a command finishes by passing
collectto the run endpoint. See Commands.
List artifacts
GET /v1/sandboxes/{sandboxId}/artifacts — requires scope
artifact:read.
Returns a paginated list of the
sandbox's artifacts, newest first. Standard limit and cursor
parameters apply.
curl https://api.crownest.dev/v1/sandboxes/sbx_abc123/artifacts \
-H "Authorization: Bearer $CROWNEST_API_KEY"{
"data": [
{
"id": "art_abc123",
"name": "model",
"sizeBytes": 5242880,
"createdAt": "2026-06-11T13:00:00.000Z"
}
],
"hasMore": false
}Get an artifact
GET /v1/artifacts/{artifactId} — requires scope artifact:read.
Returns one artifact by ID. This works after the source sandbox is destroyed.
curl https://api.crownest.dev/v1/artifacts/art_abc123 \
-H "Authorization: Bearer $CROWNEST_API_KEY"Returns 200 with { "artifact": { ... } }. Errors: forbidden,
not_found.
Get a download URL
POST /v1/artifacts/{artifactId}/download-url — requires scope
artifact:read.
Returns instructions for downloading the artifact's content.
curl -X POST https://api.crownest.dev/v1/artifacts/art_abc123/download-url \
-H "Authorization: Bearer $CROWNEST_API_KEY"{
"url": "https://api.crownest.dev/v1/...",
"method": "GET",
"headers": { "Authorization": "Bearer cn_live_..." },
"authMode": "api_key"
}With authMode of api_key, send the returned headers (your API key)
on the GET request to the URL.
Delete an artifact
DELETE /v1/artifacts/{artifactId} — requires scope artifact:delete.
Deletes the artifact's content and marks the record deleted. The operation is idempotent by state — deleting an already-deleted artifact returns the deleted record.
curl -X DELETE https://api.crownest.dev/v1/artifacts/art_abc123 \
-H "Authorization: Bearer $CROWNEST_API_KEY"Returns 200 with { "artifact": { ... } } including deletedAt.
Errors: forbidden, not_found.