REST API: Catalog
Per-tenant private flow packages. List, publish, install, change visibility, delete.
All endpoints under /api/v1/catalog. All require ScaiKey OIDC (the dev-token path doesn't reach the catalog).
GET /v1/catalog#
List packages visible to the caller.
Visibility:
tenant-scoped packages — anyone withscaicore:viewin the tenant sees them.groups-scoped packages — only members of one of thevisibility_group_idssee them.- The author of a package always sees their own packages regardless of visibility.
- Super admins see all packages across all tenants.
Response:
[
{
"package_id": "customer-support",
"name": "Customer Support",
"description": "Triage + KB + HITL",
"version": "0.2.0",
"author_id": "usr_alice",
"author_email": "alice@acme.example",
"visibility": "tenant",
"visibility_group_ids": [],
"created_at": "2026-04-01...",
"updated_at": "2026-04-29..."
}
]
scaicore:view.
POST /v1/catalog/publish#
Publish a flow as a new catalog package (or bump the version of an existing one).
Body — by flow id (preferred; the server fetches the latest content):
{
"package_id": "customer-support",
"name": "Customer Support",
"description": "Triage + KB + HITL",
"version": "0.2.0",
"readme": "# Customer Support\n\n...",
"flow_id": "flow_abc123"
}
Body — by inline content (for unsaved flows):
{
"package_id": "customer-support",
"name": "Customer Support",
"version": "0.2.0",
"content": { /* full FlowGraph */ }
}
Behavior:
- Compiles the flow to YAML server-side. If compile fails, returns 400 with the compile error — no half-published package.
- Bundles
flow.json+manifest.yaml+package.json+ optionalREADME.mdinto a deterministic.scaipkg. - Writes to object storage at
catalog/{tenant_id}/{package_id}/v{version}.scaipkg. - Upserts the
CatalogPackagerow pointing at the latest version.
If you republish with the same version string, the patch number auto-bumps (0.1.0 → 0.1.1). To pin a deliberate version, provide a new value.
Response: 201 Created with the CatalogPackageSummary.
scaicore:manage + deploy ACL on the source flow (if flow_id provided).
GET /v1/catalog/{package_id}/install#
Install a package — returns the flow JSON with a fresh id and "Copy of {name}" label, ready for the caller to save as their own flow.
Response:
{
"flow": { /* full FlowGraph with fresh id + "Copy of..." name */ },
"metadata": {
"package_id": "customer-support",
"name": "Customer Support",
"version": "0.2.0",
"author_email": "alice@acme.example"
}
}
The returned flow has a freshly minted id, so saving it creates a new flow row rather than overwriting the package author's original. Other content (nodes, edges, config) is verbatim.
scaicore:view + visibility check.
PATCH /v1/catalog/{package_id}/visibility#
Change a package's visibility.
Body:
{
"visibility": "groups",
"visibility_group_ids": ["group_acme_eng", "group_acme_ops"]
}
Only the author or a tenant admin / super admin can change visibility.
Response: updated CatalogPackageSummary.
DELETE /v1/catalog/{package_id}#
Soft-delete the package. 204 No Content.
The underlying object-storage .scaipkg files are kept for audit; only the CatalogPackage row is marked deleted.
Author / tenant admin / super admin.