Skip to content

Artifacts

Artifacts API

Artifacts are files produced by or attached to conversations, workflow executions, and the org library. This page covers the endpoints behind the Apps feature — pinning an artifact so it appears as an App, unpinning, renaming, reordering, and the app-manifest approval flow. For the full artifact surface (publish, list, get, download, share, promote, send-to-kb) see the Apps guide and the hutly artifact CLI reference, which cover the same endpoints end to end.

“Apps” are pinned HTML artifacts. Pinning is what puts an artifact there; unpinning removes it without deleting the artifact.

Pin an Artifact

PUT /orgs/{organizationId}/artifacts/{artifactId}/pin

Only HTML artifacts can be pinned. This endpoint does not check or change approval state — pinning never implicitly approves a declared scope. If the artifact declares an app manifest that isn’t approved yet, call the app-manifest approval endpoint separately (the hutly artifact pin CLI and the UI enforce this by refusing to pin an unapproved app until you approve its scope).

Response:

{
  "artifact": { "artifactId": "art_456", "name": "Lead Intake", "pinnedAt": "2026-07-13T00:00:00Z", "...": "..." }
}

Unpin an Artifact

DELETE /orgs/{organizationId}/artifacts/{artifactId}/pin

Removes the artifact from Apps. The artifact and its versions are untouched — it stays in the library.

Response:

{ "success": true }

Rename an Artifact

PUT /orgs/{organizationId}/artifacts/{artifactId}

Renames the artifact’s display name only — the artifactId, filename, and all versions are unchanged, so every existing reference (routing, shares, canvas pushes) stays valid.

Request Body:

{ "name": "Lead Intake" }

name is required, trimmed, and must be 1–500 characters after trimming.

Response:

{
  "artifact": { "artifactId": "art_456", "name": "Lead Intake", "...": "..." }
}

Reorder Pinned Artifacts (Apps)

POST /orgs/{organizationId}/artifacts/pins/reorder

Sets the manual display order of the org’s pinned Apps. Send the full list of pinned artifact IDs in the desired order; each is assigned its index as its position. IDs that aren’t pinned or don’t belong to the org are ignored.

Request Body:

{ "orderedArtifactIds": ["art_456", "art_789", "art_123"] }

Response:

{ "success": true }

App Manifest

An artifact built as a Hutly app declares the workflows and tables it uses in hutly.manifest.ts. That declared scope must be approved before window.hutly calls from the running app succeed.

Get the App Manifest

GET /orgs/{organizationId}/artifacts/{artifactId}/app-manifest

Returns the manifest declared in the artifact’s HTML alongside the currently approved manifest (if any), for the artifact’s current version (or a specific ?versionId= query param).

Response:

{
  "declared": {
    "workflows": ["create-lead"],
    "tables": [{ "table": "leads", "access": "write" }]
  },
  "declaredSha256": "a1b2c3...",
  "declaredError": null,
  "approved": null
}

declared is null for a plain HTML artifact with no manifest. declaredError distinguishes the two null cases: it stays null for a genuine non-app, but carries the typed code (app_manifest_invalid_json / app_manifest_invalid_shape) when the artifact does embed a manifest that fails to parse — so a caller can refuse a broken app rather than treat it as a plain artifact and pin it. approved is null until an admin approves this version’s declared scope.

Approve the App Manifest

PUT /orgs/{organizationId}/artifacts/{artifactId}/app-manifest

Required Capability: apps.manage

Approves the artifact version’s declared scope — re-extracted from the artifact’s HTML server-side, never trusted from the request body — and records which workflows/tables it grants. Every declared workflow must exist and be runnable, and every declared table must exist, or the request fails with 400.

Request Body (optional):

{ "versionId": "ver_789" }

Defaults to the artifact’s current version when versionId is omitted.

Response: Returns the ApprovedAppManifest:

{
  "versionId": "ver_789",
  "artifactId": "art_456",
  "organizationId": "org-123",
  "manifest": {
    "workflows": ["create-lead"],
    "tables": [{ "table": "leads", "access": "write" }]
  },
  "manifestSha256": "a1b2c3...",
  "workflowBindings": { "create-lead": "wf_001" },
  "approvedBy": "user-456",
  "approvedAt": "2026-07-13T00:00:00Z"
}
Approval is scoped to one specific artifact version. Publishing a new version resets the approval state — the new version needs its own approval, even if a prior version was approved.

Roles

Pin, unpin, rename, and reorder require the artifacts.use capability (any member who can use artifacts). Approving an app manifest requires the apps.manage capability.