Using the StackGen SDK

Install a language package, construct a client with an explicit config, then call product namespaces (aiden, sre, vault).

Aiden automation (webhooks, Ask, sessions, artifacts): read the full guide with glossary and step-by-step samples in the Aiden guide.

Prefer explicit StackgenConfig in application code. Do not rely on a large set of environment variables for production runs.

Shared credentials

Field / env Purpose
base_url / STACKGEN_URL Mothership URL with no path suffix (e.g. https://app.stackgen.com)
api_token / STACKGEN_TOKEN API token (stackgen_…)
workspace_id / STACKGEN_WORKSPACE_ID Workspace UUID, sent as orgId on Aiden routes. org_id, STACKGEN_PROJECT and STACKGEN_ORG_ID still work (see Renamed in 0.5.0).

Webhook trigger credentials (webhook_token) are config fields, not default env vars — pass them when you call webhook helpers.

Python

pip install stackgen-sdk==0.3.0
from pathlib import Path
from stackgen import StackgenClient, StackgenConfig

client = StackgenClient(
    StackgenConfig(
        base_url="https://app.stackgen.com",
        api_token="stackgen_…",
        workspace_id="<workspace-uuid>",
        webhook_token="sg_aios_…",  # only needed for webhook journeys
    )
)

# Aiden: trigger webhook → wait → download session-report.md
result = client.aiden.run_webhook_and_download_report(
    Path("alert.json").read_text(encoding="utf-8")
)
print(result.session_id, result.output_path)

# Aiden: Ask → poll execution → download artifact (API token only)
ask = client.aiden.run_ask_and_download_artifact(
    message="Run triage for checkout CPU alert",
    entity_refs=[{"name": "incident-triage", "type": "workflow"}],
    artifact_name="session-report.md",
)
print(ask.trace_id, ask.session_id, ask.output_path)

# Aiden: create schedule, trigger now, wait on SSE
sched = client.aiden.create_schedule({
    "name": "ops-hourly",
    "target_type": "agent",
    "target_name": "my-oncall-agent",
    "expression": "0 * * * *",
    "action": "Hourly health check",
    "enabled": True,
})
client.aiden.trigger_schedule(sched["id"])
# After you have a trace_id from the run:
# client.aiden.wait_for_subscribe_complete(trace_id)
# client.aiden.resolve_approval(approval_id, {"decision": "approve"})

# Aiden: mid-turn Ask follow-up (action may be "steer")
from stackgen import is_steer_response

follow = client.aiden.start_ask("Also check the last deploy", session_id="ops-thread-1")
if is_steer_response(follow):
    client.aiden.wait_for_subscribe_complete(follow["trace_id"])

# After any finished Ask: list + download every session artifact
# for art in client.aiden.list_session_artifacts(session_id):
#     client.aiden.download_session_artifact(session_id, art["name"], f"./out/{art['name']}")

# Aiden: chat subscription CRUD (Slack/Teams routing for an installed app)
# Aiden resolves endpoint_path from the app discovery manifest.
sub = client.aiden.create_chat_subscription({
    "name": "ops-chat",
    "app_name": "sre",
    "target_type": "app",
    "target_name": "sre",
    "trigger_types": ["mention"],
    "enabled": True,
})
client.aiden.delete_chat_subscription(sub["id"])

# SRE
client.sre.pull_alerts_and_wait(source="grafana")
alerts = client.sre.list_alerts(status="active")
inv = client.sre.investigate_alert_and_wait(alerts["alerts"][0]["id"])

# DevOps Ops Inbox
client.devops.sync_requests()
req = client.devops.fetch_and_wait("CORE-981")
finished = client.devops.approve_and_wait(req["id"])

Optional convenience — load only the three default env vars, then set the rest in code:

from dataclasses import replace
from stackgen import StackgenClient, StackgenConfig

client = StackgenClient(
    replace(
        StackgenConfig.from_env(),  # STACKGEN_URL, STACKGEN_TOKEN, STACKGEN_WORKSPACE_ID
        webhook_token="sg_aios_…",
    )
)

Import name is stackgen (distribution name is stackgen-sdk).

TypeScript / JavaScript

npm install stackgen-sdk@0.3.0
import { readFileSync } from "node:fs";
import { StackgenClient, StackgenConfig, isSteerResponse } from "stackgen-sdk";

const client = new StackgenClient(
  new StackgenConfig({
    baseUrl: "https://app.stackgen.com",
    apiToken: "stackgen_…",
    workspaceId: "<workspace-uuid>",
    webhookToken: "sg_aios_…", // only needed for webhook journeys
  }),
);

const result = await client.aiden.runWebhookAndDownloadReport(
  readFileSync("alert.json", "utf8"),
);
console.log(result.sessionId, result.outputPath);

const ask = await client.aiden.runAskAndDownloadArtifact({
  message: "Run triage for checkout CPU alert",
  entityRefs: [{ name: "incident-triage", type: "workflow" }],
  artifactName: "session-report.md",
});

const sched = await client.aiden.createSchedule({
  name: "ops-hourly",
  target_type: "agent",
  target_name: "my-oncall-agent",
  expression: "0 * * * *",
  action: "Hourly health check",
  enabled: true,
});
await client.aiden.triggerSchedule(String(sched.id));

const follow = await client.aiden.startAsk("Also check the last deploy", {
  sessionId: "ops-thread-1",
});
if (isSteerResponse(follow)) {
  await client.aiden.waitForSubscribeComplete(String(follow.trace_id));
}

// After any finished Ask: list + download every session artifact
// const arts = await client.aiden.listSessionArtifacts(sessionId);
// for (const a of arts) {
//   await client.aiden.downloadSessionArtifact(sessionId, String(a.name), `./out/${a.name}`);
// }

const sub = await client.aiden.createChatSubscription({
  name: "ops-chat",
  app_name: "sre",
  target_type: "app",
  target_name: "sre",
  trigger_types: ["mention"],
  enabled: true,
});
await client.aiden.deleteChatSubscription(String(sub.id));
// await client.aiden.waitForSubscribeComplete(traceId);
// await client.aiden.resolveApproval(approvalId, { decision: "approve" });

console.log(ask.traceId, ask.sessionId, ask.outputPath);

const alerts = await client.sre.listAlerts();

Optional convenience — load only the three default env vars, then set the rest in code:

const base = StackgenConfig.fromEnv(); // STACKGEN_URL, STACKGEN_TOKEN, STACKGEN_WORKSPACE_ID
const client = new StackgenClient(
  new StackgenConfig({
    baseUrl: base.baseUrl,
    apiToken: base.apiToken,
    workspaceId: base.workspaceId,
    webhookToken: "sg_aios_…",
  }),
);

Requires Node.js 18+. Network methods are async.

Go

Invite-only. The Go module ships from this private repository. Request GitHub access from StackGen before go get; Python and TypeScript stay on public PyPI and npm.

go get github.com/appcd-dev/stackgen-sdk/clients/go@v0.4.0
import (
    "context"
    "fmt"
    "os"
    "time"

    stackgen "github.com/appcd-dev/stackgen-sdk/clients/go"
    "github.com/appcd-dev/stackgen-sdk/clients/go/aiden"
)

client, err := stackgen.NewClient(stackgen.Config{
    BaseURL:      "https://app.stackgen.com",
    APIToken:     "stackgen_…",
    WorkspaceID:  "<workspace-uuid>",
    WebhookToken: "sg_aios_…", // only needed for webhook journeys
    OutputPath:   "session-report.md",
})
if err != nil { panic(err) }

ctx, cancel := context.WithTimeout(context.Background(), 30*time.Minute)
defer cancel()

// Webhook → wait → download session-report.md
result, err := client.Aiden.RunWebhookAndDownloadReport(ctx, "P1 | checkout-api error rate above SLO")
if err != nil { panic(err) }
fmt.Println(result.SessionID, result.OutputPath)

// Agent chat + SSE (Grafana plugin / backend host)
run, err := client.Aiden.StartAgentChat(ctx, "grafana-assistant", aiden.StartChatRequest{
    Message: "List available data sources without changing anything.",
})
if err != nil { panic(err) }
err = client.Aiden.SubscribeExecution(ctx, run.TraceID, func(event aiden.ExecutionEvent) error {
    if !event.Subagent && event.Type == "TEXT_MESSAGE_CONTENT" {
        fmt.Print(event.Text("Content", "content"))
    }
    return nil
})

Optional convenience: stackgen.NewClientFromEnv() reads STACKGEN_URL, STACKGEN_TOKEN, and STACKGEN_WORKSPACE_ID (plus WEBHOOK_TOKEN when set). ORG_ID, STACKGEN_ORG_ID and STACKGEN_PROJECT still work as fallbacks.

Go today covers webhook → report, agent chat + SSE, workspaces (client.Workspaces), integrations, and Vault helpers. Ask wait helpers, SRE investigate, chat subscriptions, audit export, and workflow builder remain on Python/TypeScript for now. More Go journeys are coming. See Aiden chat from a Go backend and Webhook → session → artifact.

Namespaces

Namespace Use
client.aiden / client.Aiden Webhooks, Ask, sessions, artifact download, export, terminate, agent chat
client.workspaces / client.Workspaces Workspace list / create / get / delete, members, AppStacks
client.sre / client.SRE Alerts and investigations (pull_alerts_and_wait, investigate_alert_and_wait)
client.devops / client.DevOps Ops Inbox (sync_requests, approve_and_wait, discovery)
client.vault / client.Vault Secrets (store_secret, category helpers, delete_secret, …)
client.contextGraph / client.context_graph / client.ContextGraph Workspace graph, connectors, syncs, and tool search

Errors

GET poll/download retries on 429 and any 5xx.

Renamed in 0.5.0

The SDK now uses the same names as the StackGen UI. The old names keep working in every 0.x release and will be removed in the next major version. Nothing changes on the wire: requests still use the same API paths and fields (for example orgId, /model-providers, knowledge_base_id).

Old name New name
Python StackgenConfig(org_id=…) StackgenConfig(workspace_id=…)
TypeScript new StackgenConfig({ orgId }) / config.orgId { workspaceId } / config.workspaceId
Go Config.OrgID (also on aiden, sre, devops, vault configs) Config.WorkspaceID
STACKGEN_PROJECT, STACKGEN_ORG_ID (Go also ORG_ID) STACKGEN_WORKSPACE_ID
client.orgs / client.Orgs client.workspaces / client.Workspaces (the same object)
Python stackgen.orgs.OrgsNamespace, TS OrgsNamespace, Go package orgs stackgen.workspaces.WorkspacesNamespace, WorkspacesNamespace, Go package workspaces
OrgUserAssignment WorkspaceUserAssignment
Python client.workspaces.get(org_id=…) (also delete, assign_users, remove_user) workspace_id=…
aiden.create_knowledge_base / createKnowledgeBase aiden.create_knowledge_hub / createKnowledgeHub
aiden.delete_knowledge_base(knowledge_base_id) / deleteKnowledgeBase aiden.delete_knowledge_hub(knowledge_hub_id) / deleteKnowledgeHub
aiden.models (ModelRegistry) aiden.llm (LLMRegistry), the same object
Go Aiden.DeleteModelProvider Aiden.DeleteLLMProvider
Example flag --org-id --workspace-id

Setting both names. workspace_id and org_id (or STACKGEN_WORKSPACE_ID and an older variable) set to different values is an error: Python raises ValueError, TypeScript throws, and Go Validate() / NewClient return an error that matches httpx.ErrWorkspaceConflict. Setting the same value twice is fine.

Environment variable order. The first non-empty value wins:

Knowledge hub ids. Knowledge helpers accept knowledge_hub_id (TypeScript also knowledgeHubId) in filters and in the create_knowledge_document body, and send it as knowledge_base_id. Responses keep knowledge_base_id and add knowledge_hub_id with the same value.

Silencing the deprecation warnings while you migrate:

Versions

Pin releases in CI (pip install stackgen-sdk==0.1.5, npm install stackgen-sdk@0.1.5). See the Product map for the API surface in each release.

For webhook triggers, Ask, waiting for session_id, and downloading session-report.md, see the Aiden guide (glossary + Python/TypeScript examples).

For Ask + SRE side by side, see Automation surface. For investigate-from-alert, see SRE → investigate alert. For the Ops Inbox, see DevOps → sync Ops Inbox.

See FAQ for installation, authentication, webhook setup, error handling, report consumption, and operational limits.