Artifacts
Read the Documents, Mockups, Images and Videos the agent wrote in a chat session. List them to get their ids, then read one, by its id or its slug, for its content. Artifacts stay readable after the session ends, and reading them never wakes a sandbox.
| Method | Path | Description |
|---|---|---|
| GET | /api/projects/{projectId}/chat-sessions/{sessionId}/artifacts | List the session's artifacts, most recently changed first. Rows only: a body or a file url comes from reading one. |
| POST | /api/projects/{projectId}/chat-sessions/{sessionId}/artifacts | Copy a file of the project's workspace Files, or each file directly in a folder, onto a Backlog session as its own artifacts. Markdown, HTML, images and videos only; a slug the session already has gets a new version. |
| GET | /api/projects/{projectId}/chat-sessions/{sessionId}/artifacts/{artifactId} | Read one artifact of the session, by its id or its slug, such as testing-checklist, qa-report or review: a markdown or html one carries its body, an image or a video a presigned url, its media type and its size. |
| POST | /api/prototypes/render | Render a prototype from its prototype.json, content.css and content.js, attached as three files, and save it to a Chat Session's artifacts (projectId and sessionId) or a workspace's Files (workspaceId). A failed check answers 422 with the issues in details and saves nothing. A session token saves only to its own session, Sensei only to Files. |
Kinds
kind | In the app | Where the content is |
|---|---|---|
markdown | Document | Markdown text in body. |
html | Mockup | A self-contained HTML page in body. |
image | Image | A file behind url, with its mediaType and byteSize. |
video | Video | A file behind url, with its mediaType and byteSize. |
The field a kind does not use comes back null.
List artifacts
GET .../chat-sessions/{sessionId}/artifacts lists a session's artifacts, most recently changed first, without their content.
curl -s "https://app.kosuke.ai/api/projects/$PROJECT_ID/chat-sessions/$SESSION_ID/artifacts" \
-H "Authorization: Bearer $KOSUKE_API_KEY"
{
"data": {
"artifacts": [
{
"id": "e2c79a10-5b4d-4f8e-a3c6-91d0b7f2e845",
"slug": "checkout-investigation",
"title": "Why checkout fails on Safari",
"kind": "markdown",
"version": 2,
"createdAt": "2026-09-30T08:02:13.415Z",
"updatedAt": "2026-09-30T08:47:55.902Z"
}
]
}
}
slug names the artifact within its session. When the agent writes the same slug again, it replaces the artifact and version goes up by one. A report that declares its own version in the page, such as the QA Report and the review report, gets that version instead. Only the current version is kept. The CLI command is kosuke sessions artifacts list <projectId> <sessionId>.
Read one artifact
GET .../chat-sessions/{sessionId}/artifacts/{artifactId} returns the artifact with its content. A Document or a Mockup carries its text:
{
"data": {
"id": "e2c79a10-5b4d-4f8e-a3c6-91d0b7f2e845",
"slug": "checkout-investigation",
"title": "Why checkout fails on Safari",
"kind": "markdown",
"version": 2,
"createdAt": "2026-09-30T08:02:13.415Z",
"updatedAt": "2026-09-30T08:47:55.902Z",
"body": "# Why checkout fails on Safari\n\nThe payment form posts before…",
"url": null,
"mediaType": null,
"byteSize": null,
"expiredAt": null
}
}
An Image or a Video carries a download URL instead:
{
"data": {
"id": "7d3f0b62-c18e-4a95-b2d7-4e6a8c1f09b3",
"slug": "settings-dark-mode",
"title": "Settings page in dark mode",
"kind": "image",
"version": 1,
"createdAt": "2026-09-30T09:21:40.118Z",
"updatedAt": "2026-09-30T09:21:40.118Z",
"body": null,
"url": "https://…",
"mediaType": "image/png",
"byteSize": 184233,
"expiredAt": null
}
}
The download URL works for 24 hours. Read the artifact again for a fresh one. Request an artifact through its own session, because any other session answers 404. The CLI command is kosuke sessions artifacts get <projectId> <sessionId> <artifactId>.
Every metadata GET, including shared previews and Cron Run artifacts, returns expiredAt: null while live, or an ISO timestamp after expiry. An expired video still answers 200, with url: null and its metadata intact.
GET /api/projects/{projectId}/chat-sessions/{sessionId}/artifacts/{artifactId}/download downloads the source or media bytes. An expired video answers 410 (GONE) with Video expired on <date>: videos are kept 30 days.; a missing media object answers 404. The same applies to session, workspace Cron and personal Cron downloads.
Who can read them
Any member of the workspace can read the artifacts of any session in it. A share link also opens a session's artifacts to people outside the workspace, as Previews describes.
The agent writes artifacts during a turn. To get one, ask for it in a message, such as "Write your findings up as a document."
Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | The project, session or artifact does not exist, the artifact belongs to another session, or its download object is missing. |
| 410 | GONE | The downloaded video has expired. Metadata GET still answers 200. |
Responses and errors has the full table.