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
StackgenError— base typeHttpError— HTTP failure (statusCodewhen available)TimeoutError— poll/wait exceededtimeout_secondsNotAllowlistedError— operation not included in this SDK release
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:
- Python, TypeScript:
STACKGEN_WORKSPACE_ID, thenSTACKGEN_PROJECT, thenSTACKGEN_ORG_ID - Go:
STACKGEN_WORKSPACE_ID, thenORG_ID, thenSTACKGEN_ORG_ID, thenSTACKGEN_PROJECT
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:
-
Python emits
DeprecationWarningfor the old names. Filter it:import warnings warnings.filterwarnings("ignore", category=DeprecationWarning, module="stackgen")or run with
-W ignore::DeprecationWarning. Old environment variables do not warn. - TypeScript marks old names
@deprecated. Editors strike them through andeslint-plugin-deprecationcan flag them; nothing is logged at runtime. - Go marks old names
// Deprecated:.staticcheckreports them asSA1019; add//lint:ignore SA1019 migratingon the line to silence one use.
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.