Artifacts
An Artifact is a file an Agent deliberately delivers from a Turn. Use one when an application must discover and download a finished output; workspace files that were never published remain private mutable Sandbox state.
From private file to Artifact
The save_artifacts Tool accepts workspace-relative paths. It resolves every
path under /workspace, reads every file, and validates the whole batch before
uploading bytes. One call accepts at most 10 paths, each file can be at most 10
MiB, and the complete batch can be at most 25 MiB. A Session can hold at most
100 active Artifacts.
After validation, the Tool uploads the files to private object storage and atomically records the batch metadata. A stored Artifact has a platform ID, filename, media type, byte size, creation time, and ownership fields. Partial uploads and later deletions enter the durable cleanup path rather than becoming public files.
Publish and download an Artifact
import { BlazingAgents } from "@blazing-agents/sdk";
const client = new BlazingAgents({
apiKey: process.env.BLAZING_AGENTS_API_KEY!,
});
const sandbox = await client.sandboxes.create({ name: "Output Sandbox" });
const agent = await client.agents.create({
name: "Artifact Writer",
sandboxId: sandbox.id,
tools: ["file_operation_sandbox"],
});
const expected = "# Release checklist\n\n- Ship docs\n";
const turn = await client.chat({
agentId: agent.id,
message: {
id: crypto.randomUUID(),
role: "user",
parts: [{ type: "text", text: `Write release.md with exactly ${JSON.stringify(expected)}, then publish it.` }],
},
});
const sessionId = await turn.sessionId;
for await (const _chunk of turn.toUIMessageStream()) {
// Drain the Turn so publication and Session persistence finish.
}
const page = await client.artifacts.list(agent.id, { sessionId });
const artifact = page.data.find(({ filename }) => filename === "release.md");
if (!artifact) throw new Error("release.md was not published");
const response = await client.artifacts.download(agent.id, artifact.artifactId);
if ((await response.text()) !== expected) throw new Error("bytes differ");The final assertion verifies that the downloaded bytes match the file the Agent created and published.
Ownership and discovery
Every Artifact belongs to one tenant, Agent, and stateful Session. It inherits
the Session's Attribution userId and metadata; Attribution supports
filtering and reporting, not access control.
A Task run creates its own fresh
Session when execution starts. Artifacts that the run publishes belong to that
Session, and the Task run exposes its sessionId after the Session is attached.
Retrieve the run with client.tasks.getRun() or client.tasks.listRuns(), then
pass its non-null sessionId to
client.artifacts.list(agentId, { sessionId }) to discover only that run's
Artifacts.
Artifact lists are scoped to an Agent, ordered newest first, and cursor
paginated. They can be filtered by sessionId or userId; deleted records are
excluded unless includeDeleted: true is set. Each item includes the ownership
fields, filename, media type, byte size, timestamps, and tombstone state.
Download returns the raw bytes in a Response. The server supplies
Content-Type, Content-Length, an attachment Content-Disposition, and
X-Content-Type-Options: nosniff; the SDK does not convert the body.
Immutability and deletion
Artifact content is immutable. To replace an output, publish a new Artifact.
Deleting one atomically tombstones its product record and records cleanup of
its private bytes. Normal lists no longer return it; lists with
includeDeleted: true return it with deletedAt. Get, download, or repeated
delete of that tombstone returns 410 Gone; an unknown or out-of-scope ID
returns 404 Not Found. Existing Session transcripts are not rewritten.
Production considerations
- Enforce the per-file, per-call, and per-Session limits before designing large-output workflows. See Artifact service limits.
- Treat Agent-controlled filenames, media types, and bytes as untrusted even though download headers force attachment behavior.
- Keep API keys on your backend. Tenant credentials can access all Artifacts
in the tenant;
userIdis not authorization. - Define retention in your application and delete outputs when their private bytes are no longer needed.
- Do not construct object-storage paths or assume Artifacts have public URLs. List and download them through the authenticated SDK or REST API.
Related guides
Reference
- Files and outputs overview
- Artifact list, download, and delete: TypeScript SDK and REST API
- Sessions and Turns
- Tenancy and end-user Attribution
- Sandboxes and file operations