Skip to content

Studio (HTML artifacts)

Studio is where the agent builds live HTML dashboards ("artifacts") from a conversation. Artifacts are versioned, can be refreshed against their data sources, duplicated, restored, and shared through permanent links.

Endpoints

MethodPathPurpose
POST/microservices/agent/artifact-chat/Build or edit a page with the agent
GET/microservices/artifacts/My artifacts
GET/microservices/artifacts/{artifact_id}/Artifact metadata
PATCH/microservices/artifacts/{artifact_id}/Rename an artifact
DELETE/microservices/artifacts/{artifact_id}/Delete an artifact
GET/microservices/artifacts/{artifact_id}/delete-impact/What deleting an artifact removes
GET/microservices/artifacts/{artifact_id}/versions/Version history
POST/microservices/artifacts/{artifact_id}/render-url/Get an embeddable URL
POST/microservices/artifacts/{artifact_id}/refresh/Refresh the page's data
POST/microservices/artifacts/{artifact_id}/restore/Restore a version
POST/microservices/artifacts/{artifact_id}/duplicate/Duplicate an artifact
GET/artifacts/links/My permanent links
POST/artifacts/links/Create a permanent link
DELETE/artifacts/links/{uid}/Revoke a permanent link

POST /microservices/agent/artifact-chat/

Build or edit a page with the agent

The same contract as POST /microservices/agent/chat/ (see Chat AI), bound to the data sources you select and, when editing, to one artifact:

  • file_uids — up to 5 uploaded spreadsheets/CSVs from My Data;
  • source_refs — up to 3 registered SQL connections (ds:<id>);
  • artifact_id — an artifact you created, to edit instead of building new;
  • mode: ask — a read-only conversation about a published page (the page's state and visible rows may be sent so "the number top-left" is answerable).

The skill is pinned to the artifact builder; the agent can only build against the selected sources. A successful build/update returns dashboard_id in the reply — the artifact id to render. Use one conversation_id per source set.

Auth: Session token · In the app: Studio → chat

Query parameters

FieldTypeRequiredDescription
timeoutintegernoDefault: 600.

Request body (application/json)

FieldTypeRequiredDescription
conversation_idstringyes
messagestringyes
file_uidsstring (uuid)[]no
source_refsstring[]no
artifact_idstringno
modestring ("build", "ask")noDefault: "build".
chat_session_idintegerno
reasoning_effortstringno
json
{
  "conversation_id": "8a7b6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
  "message": "Build a sales dashboard with revenue by region and a monthly trend.",
  "source_refs": [
    "ds:7"
  ]
}

Response 200 — The agent's reply; dashboard_id identifies the built artifact.

FieldTypeDescription
statusstringcompletedanswer holds the reply. queued — the turn is queued behind another one; the reply will arrive on the ws/chat/{conversation_id} socket. missing_param, clarification, interrupted — the agent needs input; the question is in message.
answerstringThe reply (Markdown).
messagestringThe agent's question when it needs input.
turn_idstring
queue_positioninteger
mgidstringPresent when the turn produced a dashboard chart (fetch it with GET /microservices/dashboard-data/?mgid=).
dashboard_idstringPresent when the turn published a Studio artifact.
generated_files_urlsstring[]Media URLs of files the turn produced (documents, images). Sign them to download.
json
{
  "status": "completed",
  "turn_id": "7c1f0c1e-2b8f-4a6e-9c0a-1e4b6f2d3a55",
  "answer": "Q3 revenue grew **12.4% year over year**, driven by the enterprise segment (+19%) …\n",
  "generated_files_urls": []
}

Response 400 — Too many sources, unknown file, or invalid mode.

Response 403 — Artifact or source not yours.

Example

bash
curl -X POST "https://api.example.com/microservices/agent/artifact-chat/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"conversation_id":"8a7b6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d","message":"Build a sales dashboard with revenue by region and a monthly trend.","source_refs":["ds:7"]}'

GET /microservices/artifacts/

My artifacts

Auth: Session token · In the app: Studio gallery

Response 200 — Artifacts, newest first (service response).

FieldTypeDescription
artifactsobject[]
artifacts[].artifact_idstring
artifacts[].titlestring
artifacts[].kindstringdashboard, report, …
artifacts[].versionintegerLatest version number.
artifacts[].created_atstring (date-time)
artifacts[].updated_atstring (date-time)
artifacts[].dataset_namesstring[]
artifacts[].sourcesobjectThe data behind the page, keyed by source ref (file:<uid> for uploaded spreadsheets, ds:<id> for registered connections).
artifacts[].change_notestring
artifacts[].created_byobject
artifacts[].created_by.user_idstring
artifacts[].created_by.usernamestring
artifacts[].created_by.organization_namestring

Response 503 — Studio service not configured.

Example

bash
curl -X GET "https://api.example.com/microservices/artifacts/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /microservices/artifacts/{artifact_id}/

Artifact metadata

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Response 200 — Metadata (no HTML).

FieldTypeDescription
artifact_idstring
titlestring
kindstringdashboard, report, …
versionintegerLatest version number.
created_atstring (date-time)
updated_atstring (date-time)
dataset_namesstring[]
sourcesobjectThe data behind the page, keyed by source ref (file:<uid> for uploaded spreadsheets, ds:<id> for registered connections).
change_notestring
created_byobject
created_by.user_idstring
created_by.usernamestring
created_by.organization_namestring
json
{
  "artifact_id": "art_7f6e5d4c",
  "title": "Sales dashboard",
  "kind": "dashboard",
  "version": 3,
  "created_at": "2026-09-10T09:00:00Z",
  "updated_at": "2026-09-21T14:12:00Z",
  "dataset_names": [
    "orders",
    "customers"
  ],
  "sources": {
    "ds:7": {
      "type": "sql",
      "source_ref": "ds:7",
      "name": "Warehouse (read-only)"
    }
  },
  "change_note": "Added region filter",
  "created_by": {
    "user_id": "42",
    "username": "jane",
    "organization_name": "Acme"
  }
}

Response 403 — Not the creator.

Response 404 — Unknown artifact.

Example

bash
curl -X GET "https://api.example.com/microservices/artifacts/art_7f6e5d4c/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

PATCH /microservices/artifacts/{artifact_id}/

Rename an artifact

Recorded as a new version; the chat thread and board tiles that carry the name follow.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Request body (application/json)

FieldTypeRequiredDescription
titlestringyes

Response 200 — Renamed.

FieldTypeDescription
artifact_idstring
titlestring
versioninteger

Example

bash
curl -X PATCH "https://api.example.com/microservices/artifacts/<artifact_id>/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

DELETE /microservices/artifacts/{artifact_id}/

Delete an artifact

Deletes the artifact with every version, plus the board tiles that show it and the conversations bound to it (with their files and charts). Boards themselves are kept.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Response 200 — Deleted, with counts.

FieldTypeDescription
artifact_idstring
deletedboolean
sessionsinteger
tilesinteger
boardsinteger
filesinteger
errorsstring[]
versionsinteger
queriesinteger

Example

bash
curl -X DELETE "https://api.example.com/microservices/artifacts/<artifact_id>/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /microservices/artifacts/{artifact_id}/delete-impact/

What deleting an artifact removes

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Response 200 — Impact report (sessions, tiles, files).

Example

bash
curl -X GET "https://api.example.com/microservices/artifacts/<artifact_id>/delete-impact/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

GET /microservices/artifacts/{artifact_id}/versions/

Version history

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Response 200 — Versions.

FieldTypeDescription
artifact_idstring
versionsobject[]
versions[].versioninteger
versions[].titlestring
versions[].change_notestring
versions[].created_atstring (date-time)

Example

bash
curl -X GET "https://api.example.com/microservices/artifacts/<artifact_id>/versions/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /microservices/artifacts/{artifact_id}/render-url/

Get an embeddable URL

Mints a short-lived viewer token and returns the URL to load in an <iframe> (/artifacts/{id}/render/?token=…&version=…). Optionally pin a version and pass a small state object (≤ 2 KB, e.g. the selected filter) that the page receives on load.

Auth: Session token · In the app: Studio viewer; dashboard tiles of kind html_artifact

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Request body (application/json, optional)

FieldTypeRequiredDescription
versionintegerno
stateobjectno

Response 200 — URL and token.

FieldTypeDescription
artifact_idstring
versioninteger
titlestring
kindstring
urlstring (uri)
tokenstring
json
{
  "artifact_id": "art_7f6e5d4c",
  "version": 3,
  "title": "Sales dashboard",
  "kind": "dashboard",
  "url": "https://api.example.com/artifacts/art_7f6e5d4c/render/?token=eyJ…&version=3",
  "token": "eyJ…"
}

Response 400 — Bad version or state.

Example

bash
curl -X POST "https://api.example.com/microservices/artifacts/<artifact_id>/render-url/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /microservices/artifacts/{artifact_id}/refresh/

Refresh the page's data

Retires every cached query result for the artifact so the next render shows current data. Reload the page afterwards.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Response 200 — Refreshed (service response).

Example

bash
curl -X POST "https://api.example.com/microservices/artifacts/<artifact_id>/refresh/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /microservices/artifacts/{artifact_id}/restore/

Restore a version

Makes version N the latest again as a new version that copies it; nothing is rewritten.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Request body (application/json)

FieldTypeRequiredDescription
versionintegeryes

Response 200 — Restored (service response with the new version).

Response 400version not an integer.

Example

bash
curl -X POST "https://api.example.com/microservices/artifacts/<artifact_id>/restore/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

POST /microservices/artifacts/{artifact_id}/duplicate/

Duplicate an artifact

A new artifact of yours copying the latest version (own id, own history, version 1).

Auth: Session token

Path parameters

FieldTypeRequiredDescription
artifact_idstringyes

Request body (application/json, optional)

FieldTypeRequiredDescription
titlestringno

Response 200 — The new artifact (service response).

FieldTypeDescription
artifact_idstring
titlestring
kindstringdashboard, report, …
versionintegerLatest version number.
created_atstring (date-time)
updated_atstring (date-time)
dataset_namesstring[]
sourcesobjectThe data behind the page, keyed by source ref (file:<uid> for uploaded spreadsheets, ds:<id> for registered connections).
change_notestring
created_byobject
created_by.user_idstring
created_by.usernamestring
created_by.organization_namestring
json
{
  "artifact_id": "art_7f6e5d4c",
  "title": "Sales dashboard",
  "kind": "dashboard",
  "version": 3,
  "created_at": "2026-09-10T09:00:00Z",
  "updated_at": "2026-09-21T14:12:00Z",
  "dataset_names": [
    "orders",
    "customers"
  ],
  "sources": {
    "ds:7": {
      "type": "sql",
      "source_ref": "ds:7",
      "name": "Warehouse (read-only)"
    }
  },
  "change_note": "Added region filter",
  "created_by": {
    "user_id": "42",
    "username": "jane",
    "organization_name": "Acme"
  }
}

Example

bash
curl -X POST "https://api.example.com/microservices/artifacts/<artifact_id>/duplicate/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

My permanent links

Auth: Session token · In the app: My Data → Artifacts → Get link / Permanent links

Response 200 — Live links.

Array of:

FieldTypeDescription
uidstring (uuid)
urlstringMedia-relative URL with ?link=<token>; prefix with the API host.
media_pathstring
namestring
artifact_uidstring, nullableThe generated-file uid, when minted from one.
created_atstring (date-time)
last_accessed_atstring (date-time), nullable
access_countinteger

Example

bash
curl -X GET "https://api.example.com/artifacts/links/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

Create a permanent link

Mints a public link to one of your generated files, by artifact_uid (from GET /artifacts/) or by media_path. Idempotent — the same file returns the same link. The link is public and never expires; revoke it with DELETE.

Auth: Session token

Request body (application/json)

FieldTypeRequiredDescription
artifact_uidstring (uuid)no
media_pathstringno
json
{
  "artifact_uid": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
}

Response 201 — The link.

FieldTypeDescription
uidstring (uuid)
urlstringMedia-relative URL with ?link=<token>; prefix with the API host.
media_pathstring
namestring
artifact_uidstring, nullableThe generated-file uid, when minted from one.
created_atstring (date-time)
last_accessed_atstring (date-time), nullable
access_countinteger
json
{
  "uid": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
  "url": "/media/Acme/file_writer/jane/pdf/board-pack.pdf?link=Zk9Qm2Lp8Xc4Vb7N",
  "media_path": "Acme/file_writer/jane/pdf/board-pack.pdf",
  "name": "board-pack.pdf",
  "artifact_uid": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
  "created_at": "2026-09-22T09:00:00Z",
  "last_accessed_at": null,
  "access_count": 0
}

Response 400 — Neither id nor path, or the file cannot be linked.

json
{
  "detail": "Authentication credentials were not provided."
}

Response 404 — Unknown artifact.

Example

bash
curl -X POST "https://api.example.com/artifacts/links/" \
  -H "Authorization: Token $FINBLADE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"artifact_uid":"0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}'

Revoke a permanent link

The URL stops working on the next request.

Auth: Session token

Path parameters

FieldTypeRequiredDescription
uidstring (uuid)yes

Response 204 — Revoked.

Response 404 — Not your link.

Example

bash
curl -X DELETE "https://api.example.com/artifacts/links/<uid>/" \
  -H "Authorization: Token $FINBLADE_TOKEN"

Finblade documentation