Frequently asked questions
Answers for Guild (Aiden) automation and SRE 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.1.5 |
from stackgen import StackgenClient, StackgenConfig |
| TypeScript / Node 18+ | npm install stackgen-sdk@0.1.5 |
import { StackgenClient, StackgenConfig } from "stackgen-sdk" |
| Go | Module github.com/appcd-dev/stackgen-sdk/clients/go |
Generated client under clients/go/generated |
The PyPI/npm distribution name is stackgen-sdk; the Python import name is stackgen.
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.
What is included in the current release (v0.1.5)?
- Aiden — webhook trigger, Ask Guild, session artifacts, high-level
run_webhook_and_download_reportandrun_ask_and_download_artifactjourneys - SRE — list/get alerts, start investigations, list/get investigations
- Vault — not included (
NotAllowlistedErrorif called)
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 |
org_id |
Project UUID | Sent as orgId on Aiden routes |
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:
- Webhook token — permission to start automation (ring the doorbell).
- API token — permission to read sessions, poll executions, and download artifacts.
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_PROJECT |
org_id |
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.
Where do I get tokens and the project UUID?
Create API tokens and webhook tokens in the StackGen UI for your project. The project UUID
is the org_id / orgId value on Aiden API calls. If you see 401/403 from Guild routes,
verify the token type matches the operation (webhook vs API) and that org_id matches the
project where the workflow is registered.
Webhook configuration
What must exist in Guild before I call the SDK?
- A workflow registered in Aiden (for example
incident-triagefor alert triage). - 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 202 body on newer motherships |
trace_id |
Execution trace — may appear on the 202 body or after polling |
Dual-path contract: If session_id is on the 202 response, 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 (same as Guild’s
reference script).
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 Guild 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:
- CI or alert router receives
P1 | checkout-api error rate above SLO. - Script calls
run_webhook_and_download_report(payload). - Pipeline uploads
session-report.mdto the ticket, Slack, or object storage.
Sample: Webhook → session → artifact
Natural language → triage report (Ask path)
When you only have an API token:
- Pin workflow:
entity_refs=[{"name": "incident-triage", "type": "workflow"}]. - Call
run_ask_and_download_artifact(message=…). - Consume
session-report.mdfromoutput_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, fetch detail, or start an investigation — API token only.
investigate_alert returns immediately; poll get_investigation until status is terminal.
Python
alerts = client.sre.list_alerts(status="active", q="checkout CPU")
alert_id = alerts["items"][0]["id"]
started = client.sre.investigate_alert(alert_id)
inv = client.sre.get_investigation(started["investigation"]["id"])
# poll until inv["status"] is terminal; optional guild_session_id for Aiden artifacts
TypeScript
const alerts = await client.sre.listAlerts({ status: "active", q: "checkout CPU" });
const items = (alerts as { items: Array<{ id: string }> }).items;
const started = await client.sre.investigateAlert(items[0].id);
const investigation = (started as { investigation: { id: string } }).investigation;
const inv = await client.sre.getInvestigation(investigation.id);
// poll until inv.status is terminal; optional guild_session_id for Aiden artifacts
Sample: SRE → investigate alert · Automation surface
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, org_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 |
Sample: Ask → execution
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 org_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?
- GET requests (poll, list artifacts, download): retry up to 3 attempts on
429,502,503,504and transient network errors, with exponential backoff (capped at 8 seconds between attempts). - POST webhook trigger: not auto-retried — a retry could start duplicate workflow runs. Implement idempotency in your caller if you must retry triggers.
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
inputs_requiredin start response — workflow needs more structuredinputs; fix the message or passinputs={...}. One-shot helpers raiseStackgenError.execution.status=errorafter poll — workflow failed; inspect trace in StackGen UI; SDK raises on the download helper path.
Report retrieval and consumption
How does the SDK get session-report.md?
After session_id is known:
- Poll
listSessionArtifactsuntil the named artifact appears. - Download via
downloadSessionArtifacttooutput_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:
- Attach the markdown file to PagerDuty, Jira, or ServiceNow.
- Upload to S3/GCS for audit retention.
- Parse sections (summary, timeline, recommendations) in a downstream linter — the SDK delivers raw file bytes; parsing is application-specific.
- Link
session_idin your ticket so operators can open the live session in StackGen UI.
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 only — no live streaming
The SDK uses HTTP polling (suitable for CI and locked-down networks). There is no SSE or websocket progress stream in this release. Use the StackGen UI for live trace viewing.
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
- Workflow and webhook must already exist on the target project.
base_urlmust be the mothership root (e.g.https://app.stackgen.com), not a path under/guild.org_idmust match the project where the workflow is registered.
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.
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
- Never commit tokens; use CI secret stores.
- Rotate API and webhook tokens independently.
- Scope webhook tokens to the minimum webhook entry points required.
Vault
client.vault is reserved but not implemented in v0.1.5. Use platform secret management
for CI credentials until Vault methods ship in a future release.