---
title: "Save a table or chart from an Ask Stuut answer as an artifact"
method: POST
path: "/v2/artifacts"
tags: ["artifacts"]
---

# Save a table or chart from an Ask Stuut answer as an artifact

`POST /v2/artifacts`

## Request

- Base URL: `https://api.stuut.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.stuut.ai/v2/artifacts`
- Auth: HTTP bearer

Copies the result and the chart spec or columns from the given message
part. The query behind it is not known here and is found later, so saving
never refuses for want of it. Saving a part again returns the existing
artifact with 200 instead of a duplicate. Returns 404 if the part is not a
table or chart in one of the caller's chats, and 409 at the per-user cap.
An omitted or blank title falls back to the question that produced the part.

## Request body

- SaveArtifactBody: Which chat part to save. The server copies everything else from the part.
  - `chatId` string, uuid, required
  - `messageId` string, uuid, required
  - `partOrder` integer, required
  - `title` string, nullable

## Response `200`

This part was already saved.

- ArtifactDetail: Summary plus the last result, in the same shape the chat renders. For a table: `{"columns": [...], "rows": [...], "totalRows": n}` (rows capped, `sql` blank). For a chart: `{"spec": <vega-lite with data.values>}`.
  - `id` string, uuid, required
  - `title` string, required
  - `kind` 'table' | 'chart', required: What an Ask Stuut artifact renders as.
  - `status` 'resolving' | 'fresh' | 'refreshing' | 'failed' | 'needs_reask', required: Refresh state of an Ask Stuut artifact. RESOLVING: just saved; a background job is looking up the SQL behind it, so whether this artifact can ever refresh is not known yet. FRESH: snapshot reflects the last successful run. REFRESHING: a rerun is in flight. FAILED: the last rerun errored for a transient reason; snapshot kept. NEEDS_REASK: no SQL could be found, or the saved SQL no longer runs (e.g. a model was renamed); the snapshot is kept and the user re-asks the question in a new chat. Refresh is offered only for FRESH, FAILED and REFRESHING.
  - `question` string, required
  - `totalRows` integer, nullable, required
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required
  - `lastRefreshedAt` string, date-time, nullable, required
  - `lastError` string, nullable, required
  - `sourceChatId` string, uuid, nullable, required
  - `sourceMessageId` string, uuid, nullable, required
  - `sourcePartOrder` integer, nullable, required
  - `snapshot` object, required

## Other responses

- `201`: Successful Response
- `422`: Validation Error

---

[API](https://skmtc.dev/stuut/apis/stuut-api.md) - [All operations](https://skmtc.dev/stuut/apis/stuut-api/llms.txt) - [OpenAPI document](https://skmtc.dev/stuut/apis/stuut-api/revisions/3b5ab941f918?raw)
