Skip to main content
Artifacts are workspace-scoped files owned by the gateway. The protocol exposes metadata through JSON-RPC and moves large file bytes through WebSocket binary frames. Use this API whenever a client needs to upload a local file to a gateway, list files attached to a thread, preview a generated file, download a remote artifact to the client machine, or bind an existing artifact to a new turn.

Methods

MethodParamsResultPurpose
artifact/capabilitiesArtifactCapabilitiesParamsArtifactCapabilitiesResponseRead upload/download limits and chunk sizes for a workspace.
artifact/listArtifactListParamsArtifactListResponseList workspace artifacts with optional scope filters.
artifact/list/threadArtifactListForThreadParamsArtifactListResponseList artifacts for one materialized thread. Requires thread_id.
artifact/list/turnArtifactListForTurnParamsArtifactListResponseList artifacts for one turn. Requires turn_id.
artifact/list/messageArtifactListForMessageParamsArtifactListResponseList artifacts for one message. Requires message_id.
artifact/getArtifactGetParamsArtifactGetResponseLoad one artifact summary.
artifact/readArtifactReadParamsArtifactReadResponseRead a small range of an artifact or projection as base64 JSON.
artifact/bindArtifactBindParamsArtifactBindResponseAttach an existing artifact/version to thread, turn, message, item, tool, or task lineage.
artifact/deleteArtifactDeleteParamsArtifactDeleteResponseSoft-delete an artifact.
artifact/restoreArtifactRestoreParamsArtifactRestoreResponseRestore a soft-deleted artifact.
artifact/upload/startArtifactUploadStartParamsArtifactUploadStartResponseStart a client-to-gateway upload session.
artifact/upload/finishArtifactUploadFinishParamsArtifactUploadFinishResponseValidate and persist a completed upload.
artifact/upload/abortArtifactUploadAbortParamsArtifactUploadAbortResponseAbort an upload session and remove temp bytes.
artifact/download/startArtifactDownloadStartParamsArtifactDownloadStartResponseStart a gateway-to-client download session.
artifact/download/chunkArtifactDownloadChunkParamsArtifactDownloadChunkResponseRequest a binary download chunk.
artifact/download/finishArtifactDownloadFinishParamsArtifactDownloadFinishResponseFinish a download session.
artifact/download/abortArtifactDownloadAbortParamsArtifactDownloadAbortResponseAbort a download session.
Artifact payloads use snake_case field names.

Artifact Summary

Most list and get responses return ArtifactSummary.
{
  "artifact": {
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "display_name": "screenshot.png",
    "kind": "image",
    "mime_type": "image/png",
    "size_bytes": 73422,
    "sha256": "9f86d081884c7d659a2feaa0c55ad015...",
    "status": "ready",
    "preview": {
      "projection_kind": "thumbnail",
      "status": "ready",
      "artifact_id": "art_000000000000000001",
      "version_id": "av_000000000000000001",
      "blob_id": "abl_000000000000000001",
      "mime_type": "image/png",
      "size_bytes": 12345,
      "sha256": "4bf5122f344554c53bde2ebb8cd2b7e3..."
    }
  },
  "workspace_id": "ws_000000000000000001",
  "primary_thread_id": "thr_000000000000000001",
  "created_by_kind": "user",
  "created_at": 1777900000,
  "updated_at": 1777900000,
  "bindings": [
    {
      "binding_id": "abn_000000000000000001",
      "workspace_id": "ws_000000000000000001",
      "thread_id": "thr_000000000000000001",
      "turn_id": "trn_000000000000000001",
      "message_id": "msg_000000000000000001",
      "binding_kind": "user_input",
      "direction": "input",
      "role": "user",
      "created_at": 1777900000
    }
  ],
  "metadata": {}
}
Important enum values:
TypeValues
ArtifactKindfile, text, image, audio, video, pdf, spreadsheet, archive, json, generated_image, screenshot, workspace_file, directory_manifest, unknown
ArtifactStatusready, pending, quarantined, deleted, missing_external_source, failed
ArtifactCreatedByKinduser, agent, tool, task, system, import, external_agent
ArtifactBindingKinduser_input, agent_output, tool_output, task_result, context_attachment, derived_from, preview, manual_attach, draft_upload
ArtifactBindingDirectioninput, output, context, derived
ArtifactProjectionKindplain_text, thumbnail, json_summary, pdf_text
ArtifactProjectionStatuspending, ready, failed, stale

Capabilities

Ask the gateway for limits before starting upload or download UI.
{
  "jsonrpc": "2.0",
  "id": "aaaaaaaaaaaaaaaaaaaaa",
  "method": "artifact/capabilities",
  "params": {
    "workspace_id": "ws_000000000000000001"
  }
}
Response:
{
  "upload": {
    "required_for_local_paths": true,
    "recommended_chunk_size_bytes": 262144,
    "max_chunk_size_bytes": 1048576,
    "max_file_size_bytes": 52428800,
    "max_files_per_turn": 32
  },
  "download": {
    "recommended_chunk_size_bytes": 262144,
    "max_chunk_size_bytes": 1048576,
    "max_concurrent_downloads": 2
  }
}
required_for_local_paths means clients should upload local files to the gateway before referring to them in a turn. This is required for remote gateways and is the safe default for local gateways too.

Agent Artifact Tools

Agent-created user-visible files use model-facing tools, not client JSON-RPC methods. The tools are registered inside an agent turn when artifact registration is enabled, then made visible by turn preflight or by request_tools with the artifact domain. artifact_prepare reserves a safe staging path before the file exists. It does not create an artifact.
{
  "displayName": "report.pdf",
  "kind": "document",
  "mimeType": "application/pdf",
  "description": "Final report for the user"
}
Response:
{
  "outputPath": "/gateway/runtime/artifact-output/ws_.../thr_.../trn_.../report.pdf",
  "outputDir": "/gateway/runtime/artifact-output/ws_.../thr_.../trn_...",
  "expiresAt": "2026-05-17T12:00:00Z",
  "displayName": "report.pdf"
}
outputPath is inside PIONEER_ARTIFACT_OUTPUT_DIR. It is a temporary gateway path that can be passed to shell, browser, renderer, MCP, or skill tools. It is not a durable artifact id and must not be treated as a client-visible file location. artifact_register imports a completed regular file into the workspace artifact store and binds it to the current turn.
{
  "path": "/gateway/runtime/artifact-output/ws_.../thr_.../trn_.../report.pdf",
  "displayName": "report.pdf",
  "kind": "document",
  "mimeType": "application/pdf",
  "description": "Final report for the user",
  "preparedOutputPath": "/gateway/runtime/artifact-output/ws_.../thr_.../trn_.../report.pdf"
}
Response:
{
  "artifactId": "art_000000000000000001",
  "versionId": "av_000000000000000001",
  "displayName": "report.pdf",
  "kind": "pdf",
  "mimeType": "application/pdf",
  "sizeBytes": 922337,
  "sha256": "9f86d081884c7d659a2feaa0c55ad015..."
}
Common artifact_register errors include: the file does not exist, the path is outside the allowed workspace or staging roots, the path escapes through a symlink, the path is not a regular file, the file is too large, the workspace quota would be exceeded, or the file was already removed from staging. If the final assistant message mentions PIONEER_ARTIFACT_OUTPUT_DIR or a private gateway path instead of a registered artifact, the gateway can ask the agent to retry registration once. If registration still does not happen, the turn fails instead of presenting a private path as the result.

artifact_read

artifact_read is the model-facing read tool for artifact continuity. It is different from the client JSON-RPC method artifact/read. The model sees artifact refs in recent history or recalled thread context as metadata. If it needs actual file content, it requests the hidden artifact domain and then calls artifact_read for the specific artifact ids it needs. The gateway resolves workspace, thread, turn, and authorization from the active agent turn; the model does not pass workspace_id. Typical arguments are camelCase because this is a model tool contract:
{
  "artifactId": "art_000000000000000001",
  "versionId": "av_000000000000000001",
  "projectionKind": "plain_text",
  "offset": 0,
  "maxBytes": 65536
}
For text-like artifacts or ready text projections, the tool can return text. For images and other binary content, the gateway can return an attachment shape suitable for the provider request path. The model should read only the artifact it needs, not every artifact reference in the prompt. Artifact refs do not make artifact_read visible by themselves. They tell the model what can be requested. The capability becomes callable only after normal tool visibility rules reveal the artifact domain.

Listing Artifacts

Use artifact/list/thread for the thread artifacts panel.
{
  "jsonrpc": "2.0",
  "id": "bbbbbbbbbbbbbbbbbbbbb",
  "method": "artifact/list/thread",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "thread_id": "thr_000000000000000001",
    "include_deleted": false,
    "limit": 100
  }
}
Response:
{
  "items": [
    {
      "artifact": {
        "artifact_id": "art_000000000000000001",
        "version_id": "av_000000000000000001",
        "display_name": "report.pdf",
        "kind": "pdf",
        "mime_type": "application/pdf",
        "size_bytes": 922337,
        "status": "ready"
      },
      "workspace_id": "ws_000000000000000001",
      "primary_thread_id": "thr_000000000000000001",
      "created_by_kind": "agent",
      "created_at": 1777900000,
      "updated_at": 1777900000,
      "bindings": []
    }
  ],
  "next_cursor": null
}
Do not call artifact/list/thread for a draft thread that has not been materialized. The gateway validates that the thread exists and belongs to the workspace.

Reading Small Content

artifact/read is for previews, small text, and ranged reads. It returns base64 inside a JSON response and is capped by the gateway’s JSON read limit.
{
  "jsonrpc": "2.0",
  "id": "ccccccccccccccccccccc",
  "method": "artifact/read",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "projection_kind": "thumbnail",
    "offset": 0,
    "max_bytes": 524288
  }
}
Response:
{
  "artifact": {
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "display_name": "screenshot.png",
    "kind": "image",
    "mime_type": "image/png",
    "size_bytes": 73422,
    "sha256": "9f86d081884c7d659a2feaa0c55ad015...",
    "status": "ready"
  },
  "offset": 0,
  "len": 12345,
  "total_size_bytes": 12345,
  "sha256": "4bf5122f344554c53bde2ebb8cd2b7e3...",
  "content_base64": "iVBORw0KGgoAAAANSUhEUg...",
  "truncated": false
}
For full-size files, use the download flow.

Upload Flow

Start an upload session:
{
  "jsonrpc": "2.0",
  "id": "ddddddddddddddddddddd",
  "method": "artifact/upload/start",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "thread_id": "thr_000000000000000001",
    "planned_turn_id": "trn_000000000000000001",
    "client_attachment_id": "client-file-1",
    "file_name": "photo.webp",
    "mime_type": "image/webp",
    "size_bytes": 68211,
    "sha256": "b770ac0a8cc7b54e090de88a8c6e5b73...",
    "source_kind": "user_composer"
  }
}
Response:
{
  "upload_id": "upl_000000000000000001",
  "recommended_chunk_size_bytes": 262144,
  "max_chunk_size_bytes": 1048576,
  "max_size_bytes": 52428800,
  "expires_at_unix": 1777903600
}
After artifact/upload/start, send chunks as binary WebSocket frames on the same authenticated connection.

Upload Binary Chunk Frame

BytesContent
0..4Magic bytes: ARTU
4..8Big-endian u32 header length.
next header_lenUTF-8 JSON ArtifactUploadChunkHeader.
remaining bytesRaw file chunk bytes.
Header:
{
  "workspace_id": "ws_000000000000000001",
  "upload_id": "upl_000000000000000001",
  "offset": 0,
  "len": 68211,
  "chunk_sha256": "optional-lower-hex-chunk-sha256"
}
The gateway acknowledges accepted chunks with artifact/upload/chunk_ack:
{
  "jsonrpc": "2.0",
  "method": "artifact/upload/chunk_ack",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "upload_id": "upl_000000000000000001",
    "offset": 0,
    "len": 68211,
    "received_bytes": 68211,
    "next_offset": 68211
  }
}
Use next_offset as the authoritative resume point. Finish the upload:
{
  "jsonrpc": "2.0",
  "id": "eeeeeeeeeeeeeeeeeeeee",
  "method": "artifact/upload/finish",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "upload_id": "upl_000000000000000001"
  }
}
Response:
{
  "upload_id": "upl_000000000000000001",
  "artifact": {
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "display_name": "photo.webp",
    "kind": "image",
    "mime_type": "image/webp",
    "size_bytes": 68211,
    "sha256": "b770ac0a8cc7b54e090de88a8c6e5b73...",
    "status": "ready"
  }
}
If the user cancels, call artifact/upload/abort.

Download Flow

Start a download session:
{
  "jsonrpc": "2.0",
  "id": "fffffffffffffffffffff",
  "method": "artifact/download/start",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "preferred_chunk_size_bytes": 262144
  }
}
Response:
{
  "download_id": "dwn_000000000000000001",
  "artifact": {
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "display_name": "photo.webp",
    "kind": "image",
    "mime_type": "image/webp",
    "size_bytes": 68211,
    "sha256": "b770ac0a8cc7b54e090de88a8c6e5b73...",
    "status": "ready"
  },
  "file_name": "photo.webp",
  "size_bytes": 68211,
  "sha256": "b770ac0a8cc7b54e090de88a8c6e5b73...",
  "recommended_chunk_size_bytes": 262144,
  "max_chunk_size_bytes": 1048576,
  "expires_at_unix": 1777903600
}
Request a chunk:
{
  "jsonrpc": "2.0",
  "id": "ggggggggggggggggggggg",
  "method": "artifact/download/chunk",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "download_id": "dwn_000000000000000001",
    "offset": 0,
    "len": 68211
  }
}
The JSON response confirms the request:
{
  "download_id": "dwn_000000000000000001",
  "offset": 0,
  "len": 68211,
  "queued": true
}
The bytes arrive as a binary WebSocket frame.

Download Binary Chunk Frame

BytesContent
0..4Magic bytes: ARTD
4..8Big-endian u32 header length.
next header_lenUTF-8 JSON ArtifactDownloadChunkHeader.
remaining bytesRaw file chunk bytes.
Header:
{
  "workspace_id": "ws_000000000000000001",
  "download_id": "dwn_000000000000000001",
  "artifact_id": "art_000000000000000001",
  "version_id": "av_000000000000000001",
  "offset": 0,
  "len": 68211,
  "total_size_bytes": 68211,
  "chunk_sha256": "lower-hex-chunk-sha256",
  "final_chunk": true
}
After all chunks have been verified and written locally, call artifact/download/finish. If the user cancels, call artifact/download/abort.

Binding Existing Artifacts

Use artifact/bind when a client or gateway flow needs to associate an existing artifact with a new message, turn, tool call, or task result.
{
  "jsonrpc": "2.0",
  "id": "hhhhhhhhhhhhhhhhhhhhh",
  "method": "artifact/bind",
  "params": {
    "workspace_id": "ws_000000000000000001",
    "artifact_id": "art_000000000000000001",
    "version_id": "av_000000000000000001",
    "thread_id": "thr_000000000000000001",
    "turn_id": "trn_000000000000000001",
    "message_id": "msg_000000000000000001",
    "binding_kind": "manual_attach",
    "direction": "input",
    "role": "user",
    "item_index": 0
  }
}
Response:
{
  "binding": {
    "binding_id": "abn_000000000000000001",
    "workspace_id": "ws_000000000000000001",
    "thread_id": "thr_000000000000000001",
    "turn_id": "trn_000000000000000001",
    "message_id": "msg_000000000000000001",
    "binding_kind": "manual_attach",
    "direction": "input",
    "item_index": 0,
    "role": "user",
    "created_at": 1777900000
  }
}

Notifications

EventParamsMeaning
artifact/createdArtifactCreatedNotificationAn artifact was created and is ready to display.
artifact/updatedArtifactUpdatedNotificationArtifact metadata or current version changed.
artifact/deletedArtifactDeletedNotificationArtifact was soft-deleted.
thread/artifacts/changedThreadArtifactsChangedNotificationA thread-level artifacts list should be refreshed.
artifact/projection/updatedArtifactProjectionUpdatedNotificationA projection, such as a thumbnail, changed state.
artifact/upload/chunk_ackArtifactUploadChunkAckNotificationA binary upload chunk was accepted.
artifact/upload/progressArtifactUploadProgressNotificationOptional aggregate upload progress notification.
artifact/download/progressArtifactDownloadProgressNotificationOptional aggregate download progress notification.
Clients should refresh thread artifact lists on thread/artifacts/changed, not only on artifact/created, because one artifact may gain new bindings or metadata without creating a new artifact id.

Client Rules

  • Always include workspace_id.
  • Do not list artifacts for draft threads that have not been created on the gateway.
  • Use artifact/read only for small ranges or projections; use download sessions for full files.
  • Verify sha256 for completed uploads, download chunks, and final downloaded files.
  • Treat desktop paths and gateway paths as different machines unless you know the gateway is local.
  • Store local preview/download caches as disposable client state.
  • Use generated schemas from /schemas for exact validation.