Frequently asked questions

Answers for Aiden, SRE, DevOps, and Context Graph integrations using the StackGen SDK. For step-by-step samples see the Aiden guide and code samples.


Package installation and versioning

Which packages should I install?

Language Install Import
Python pip install stackgen-sdk==0.4.0 from stackgen import StackgenClient, StackgenConfig
TypeScript / Node 18+ npm install stackgen-sdk@0.4.0 import { StackgenClient, StackgenConfig } from "stackgen-sdk"
Go (invite-only) go get github.com/appcd-dev/stackgen-sdk/clients/go@v0.4.0 stackgen "github.com/appcd-dev/stackgen-sdk/clients/go"

The PyPI/npm distribution name is stackgen-sdk; the Python import name is stackgen. Prefer the Go facade (stackgen.NewClient) over the generated client under clients/go/generated.

Go is invite-only while the SDK repository is private. Ask StackGen for GitHub access before go get; anonymous pulls fail. Python and TypeScript remain on public PyPI and npm.

Go today covers webhook → report, agent chat + SSE, workspaces, integrations, and Vault. Ask wait helpers, SRE investigate, chat subscriptions, audit export, and workflow builder remain on Python/TypeScript for now; more Go journeys are coming.

How should I pin versions in CI?

Always pin an exact release in pipelines (== for pip, @ for npm). The SDK exposes a curated allowlist of HTTP operations per release — upgrading without reading the Product map can surface NotAllowlistedError for calls that are not yet in your pinned version.

How do I try a release candidate?

Every merge to main publishes a new RC so you can preview the next SDK before it becomes the default install.

pip install stackgen-sdk==0.4.0rc1
npm install stackgen-sdk@0.4.0-rc.1
# or the moving npm preview pointer
npm install stackgen-sdk@next

Plain pip install stackgen-sdk and npm install stackgen-sdk stay on the last stable release. Use pip install --pre stackgen-sdk only when you want pip to consider pre-releases. See the Changelog for what the preview includes.

What is included in the current release (v0.1.5)?

See Product map → Public API surface for the full list.


Authentication and token management

What credentials do I need?

Field Example Used for
base_url https://app.stackgen.com Mothership host — no /guild suffix
workspace_id Workspace UUID Sent as orgId on Aiden routes (formerly org_id)
api_token stackgen_… Sessions, artifacts, Ask, SRE reads/writes
webhook_token sg_aios_… Only POST /webhooks/trigger

SRE calls use the API token and base_url only (no webhook token, no separate SRE secret in this SDK).

Why two tokens for webhook automation?

Least privilege for CI secrets:

Store them in separate secret managers or CI variables when possible.

Can I use environment variables?

Optional convenience for the three core fields:

Env var Config field
STACKGEN_URL base_url
STACKGEN_TOKEN api_token
STACKGEN_WORKSPACE_ID workspace_id (older STACKGEN_PROJECT / STACKGEN_ORG_ID still work)
STACKGEN_LOG_LEVEL log_level / logLevel (debug, info, warn, error, silent)

Use StackgenConfig.from_env() (Python) or StackgenConfig.fromEnv() (TypeScript), then set webhook_token, poll timeouts, and artifact paths in code. For production pipelines, prefer explicit StackgenConfig so every run is self-describing in logs.

webhook_token is not loaded from a default env var — pass it explicitly when using webhook helpers.

How do I enable SDK logs?

The SDK stays quiet by default (library-friendly). Turn levels on when debugging:

export STACKGEN_LOG_LEVEL=debug   # or info / warn / error

Python uses the stdlib logger named stackgen (children like stackgen.http). You can also call configure_logging("debug") or set log_level= on StackgenConfig. TypeScript accepts logLevel / a custom logger on config.

At debug you see each HTTP attempt (URLs with tokens redacted). Retries and subscribe reconnects log at warn. Failures log at error before the SDK raises.

Where do I get tokens and the workspace UUID?

Create API tokens and webhook tokens in the StackGen UI for your workspace. The workspace UUID is the workspace_id / workspaceId value (sent as orgId on Aiden API calls). If you see 401/403 from Aiden routes, verify the token type matches the operation (webhook vs API) and that workspace_id matches the workspace where the workflow is registered.


Webhook configuration

What must exist in Aiden before I call the SDK?

  1. A workflow registered in Aiden (for example incident-triage for alert triage).
  2. A webhook mapped to that workflow, with a sg_aios_… token issued for CI or your alerting tool.

The SDK can create agents and workflows in code (Create a workflow). Webhook tokens and mappings still come from Aiden after a webhook resource exists; for day-2 triggers you need a registered webhook pointing at the workflow you published.

What payload should I send?

The trigger POST accepts plain text or JSON (your alert body):

P1 | checkout-api error rate above SLO

Or structured JSON from Datadog, Grafana, or an internal alert bus. The SDK sends Content-Type: text/plain with the bytes you provide; match what your webhook expects when testing with curl.

What does the trigger response include?

On success the mothership returns JSON including at least:

Field Meaning
webhook_id Webhook identifier
invocation_id Invocation row id for run polling
run_id Temporal dispatch workflow run id (older builds)
session_id Session workspace — may appear on the acknowledgement body on newer motherships
trace_id Execution trace — may appear on the body or after polling

The HTTP status of that acknowledgement defaults to 202 Accepted. When you create the webhook you can set response_status to 200, 201, 202, or 204, plus optional response_headers, so providers that reject 202 (for example Linear) stay happy while Aiden still processes asynchronously. See Webhook acknowledgement (Linear-style).

Dual-path contract: If session_id is on the acknowledgement body, the SDK uses it immediately. If not, run_webhook_and_download_report polls GET /webhooks/{webhook_id}/runs/{invocation_id} until session_id is set. The same sequence is in the webhook session artifact script.

How do I stop a webhook from starting work for every delivery?

Set filter_cel on the webhook — a CEL boolean expression over body (decoded JSON) and headers (sanitized, lowercase). A delivery that evaluates to false still gets the configured acknowledgement, but starts no run, writes no invocation row, and spends no AI-query quota. Clear it with an explicit empty string on update_webhook / updateWebhook; leaving the field out of an update keeps the current condition. Try a draft condition against sample JSON and headers with preview_webhook_filter / previewWebhookFilter before you save it — preview never saves data or starts work. See Webhook condition (filter_cel).

For split workers (queue + scheduler), use stateless methods on client.aiden: trigger_webhook, get_webhook_run, wait_for_webhook_session, download_session_artifact. See Async webhook CI.

Can Datadog or Grafana call the webhook directly?

Yes — that is the common SRE pattern: the observability tool POSTs to the webhook URL with the sg_aios_… token. Use the SDK when your CI job (Jenkins, GitHub Actions, custom runner) needs to trigger triage and wait for session-report.md in one script.

What about app-forward webhooks?

The wait/download journey targets Aiden session artifacts. App-forward or non-session webhook flows are outside the SDK’s run_webhook_and_download_report helper — use lower-level API calls or the StackGen UI for those paths.


End-to-end integration examples

Alert → triage report (webhook path)

Typical SRE pipeline:

  1. CI or alert router receives P1 | checkout-api error rate above SLO.
  2. Script calls run_webhook_and_download_report(payload).
  3. Pipeline uploads session-report.md to the ticket, Slack, or object storage.

Sample: Webhook → session → artifact

Natural language → triage report (Ask path)

When you only have an API token:

  1. Pin workflow: entity_refs=[{"name": "incident-triage", "type": "workflow"}].
  2. Call run_ask_and_download_artifact(message=…).
  3. Consume session-report.md from output_path.

Sample: Ask → artifact

Trigger only — handle download elsewhere

Use Webhook → session only when another system owns artifact retrieval or you only need session_id for logging.

SRE alerts and investigations

List firing alerts, refresh the inbox, or start an investigation — API token only. Prefer investigate_alert_and_wait so the SDK polls until the RCA is ready.

Python

client.sre.pull_alerts_and_wait(source="grafana")
alerts = client.sre.list_alerts(status="active", q="checkout CPU")
rows = alerts.get("alerts") or alerts.get("items") or []
inv = client.sre.investigate_alert_and_wait(rows[0]["id"])
# optional guild_session_id for Aiden artifacts

TypeScript

await client.sre.pullAlertsAndWait("grafana");
const alerts = await client.sre.listAlerts({ status: "active", q: "checkout CPU" });
const rows = ((alerts as { alerts?: Array<{ id: string }> }).alerts) ?? [];
const inv = await client.sre.investigateAlertAndWait(rows[0].id);

Sample: SRE → investigate alert · Pull alerts · Triage alerts

DevOps Ops Inbox

Sync tickets, wait for triage, approve a request, and discover workflows from recent ticket history on client.devops.

Sample: Sync Ops Inbox · Approve request · Discover workflows

Context Graph

Probe health, read the schema catalog and record types, sync connectors, and search graph tools on client.contextGraph / client.context_graph. Override the edge prefix with contextGraphUrl / context_graph_url for local or port-forward runs (default ${STACKGEN_URL}/context-graph).

Sample: Context Graph inventory

See Usage → Namespaces.

Runnable CLI scripts

Full flag-based examples live under Code samples (Python and TypeScript toggles on each journey page).


Expected inputs and outputs

Webhook journey (run_webhook_and_download_report)

   
Input Alert string or JSON file contents; config with webhook_token, api_token, workspace_id, optional artifact_name, output_path, timeout_seconds
Output webhook_id, invocation_id, session_id, artifacts (listed metadata), output_path (local file)

Ask journey (run_ask_and_download_artifact)

   
Input message; entity_refs (recommended in CI); optional inputs when workflow needs extra fields; API token only
Output trace_id, run_id, session_id, plan, candidates, artifacts, output_path

Ask start / wait (step-by-step)

Step API Key response fields
Start start_ask / startAsk trace_id, session_id, optional inputs_required
Poll wait_for_execution / waitForExecution execution.status, trace_settled, session_id
Artifact listSessionArtifacts + download File bytes at output_path
Subscribe wait waitForSubscribeComplete ok when the run finishes (SSE with reconnect)

Samples: Ask → execution, Ask → session artifacts · Ask → debug ZIP

Queue / scheduler (non-blocking)

Workers that must return immediately (submit on one process, poll from another) should not call run_ask_and_download_artifact or wait_for_execution on the submit path.

Step API Blocks?
Start start_ask / start_workflow_run no — persist session_id + trace_id
Follow-up get_run_status(session_id=…, trace_id=…, ready_artifact="session-report.md") no — one shot
Download download_session_artifact when ready no

get_run_status / getRunStatus is the stateless “what’s the status of run X?” primitive for a separate scheduler. Locks, stale detection, and retries stay in your application code.

Sample: Async Ask worker

SRE namespace

Method Input Output
list_alerts() Optional query params Alert list (JSON)
get_alert(id) Alert id Alert detail
investigate_alert(id, body?) Alert id, optional body Investigation start payload
list_investigations() Optional filters Investigation list
get_investigation(id) Investigation id Investigation detail

Default artifact

Most triage workflows publish session-report.md — markdown RCA/summary. Override with artifact_name / artifactName; matching is case-insensitive.


Error handling and retry behavior

What errors can the SDK raise?

Error When
StackgenError Business failures — bad trigger body, missing session_id, Ask inputs_required, execution ended in error, unexpected JSON
HttpError HTTP failure with statusCode when available — wrong token, wrong workspace_id, 404 workflow
TimeoutError Poll exceeded timeout_seconds while waiting for session artifact, Ask execution, or similar
NotAllowlistedError Method not in this SDK release (e.g. Vault)
ValueError Missing required config such as webhook_token on webhook helpers

What is retried automatically?

How do timeouts work?

Config fields:

Field Default Purpose
poll_interval_seconds 5 Sleep between poll ticks
timeout_seconds 1800 (30 min) Max wait for artifact or Ask execution

Raise TimeoutError when exceeded. Increase timeout_seconds for long-running triage workflows; decrease in fast-fail CI smoke tests.

Ask-specific failures


Report retrieval and consumption

How does the SDK get session-report.md?

After session_id is known:

  1. Poll listSessionArtifacts until the named artifact appears.
  2. Download via downloadSessionArtifact to output_path.

High-level helpers combine trigger/Ask + wait + download in one call.

If the workflow did not write an artifact file, call export_session(session_id, parts="report") and read the report part content from the JSON manifest.

Where is the file written?

Default output_path is session-report.md in the process working directory. Set per run:

Python

StackgenConfig(..., output_path="./artifacts/incident-123/report.md")

TypeScript

new StackgenConfig({ ..., outputPath: "./artifacts/incident-123/report.md" });

How should SRE teams consume the report?

Common patterns:

Can I list artifacts without downloading?

Yes — use session helpers or listSessionArtifacts when you need metadata only, or when multiple artifacts exist (logs bundle, structured JSON, etc.). The default journey targets one named artifact.


Operational considerations and limitations

Polling and subscribe waits

Most status helpers use HTTP polling (CI-friendly). For Ask and webhook runs you can also call wait_for_subscribe_complete / waitForSubscribeComplete, which opens the execution subscribe stream (SSE) and reconnects on drop or quiet stalls inside your timeout. Use the StackGen UI when you want a live human-facing trace view.

To render reply text and tool calls in your own chat UI, use stream_execution_events / streamExecutionEvents instead of waiting for completion. See Stream agent chat.

Curated API surface

The SDK wraps a subset of StackGen HTTP APIs. Calls outside the allowlist fail fast with NotAllowlistedError. Regenerate or upgrade the SDK when new operations are added to the product OpenAPI spec. Download the current allowlisted surface as stackgen.openapi.yaml.

Mothership and workflow prerequisites

Idempotency and duplicate runs

Each successful webhook POST starts a new workflow invocation. Do not blindly retry failed POSTs without an idempotency strategy. GET polls and downloads are safe to retry.

Exception: terminate_session / terminateSession is idempotent on the Aiden API (no running workflows returns 200; cancellation intent is persisted before Temporal). The SDK retries that call through a shared idempotent mutation policy (retry_idempotent_op / retryIdempotentOp) on transient 5xx/429/network errors. Subscribe waits use a separate reconnect policy (SUBSCRIBE_RECONNECT_MAX) for dropped SSE streams. Webhook and workflow start POSTs are not covered by either policy.

Long-running and concurrent workflows

Default 30-minute timeout suits typical triage. Very large investigations may need a higher timeout_seconds. Parallel CI jobs each get their own session_id; there is no global queue limit enforced by the SDK.

Secrets hygiene

Vault

Prefer client.aiden.upsert_integration_with_secrets / upsertIntegrationWithSecrets when provisioning an integration from a vendor token. Pass a plain secrets map; the SDK resolves Vault metadata keys, stores the secret, and binds secret_ref_ids. Override with vault_category / vault_subcategory when needed. For a granular path, use client.vault.get_supported_metadata, store_secret / store_github_secret (and grafana / kafka / generic helpers), then upsert_integration with secret_ref_ids, and get_secret / delete_secret. Soft-ignore 404 on delete stays in your teardown code, not in the SDK.

Getting help