Skip to main content

getstack

Python SDK for STACK — trust infrastructure for AI agents.

Install

pip install getstack

Quick start

Sign in once on your machine — the SDK reads credentials from ~/.stack/credentials.json automatically:

npx -y @getstackrun/cli auth login
import hashlib
import json
from getstack.errors import StackError


def run_fleet_mission_example(stack, request, provider_url="https://slack.com/api/chat.postMessage"):
    started = stack.missions.start(request)
    repeated = stack.missions.start(request)
    assert repeated["mission_id"] == started["mission_id"]
    operation_id = hashlib.sha256(json.dumps([started["mission_id"], "support-update"]).encode()).hexdigest()
    response = stack.proxy.request("slack", provider_url, "POST",
        body={"channel": "C123", "text": "Support update"},
        passport_token=started["passport"]["token"], authority_request_id=operation_id)
    assert response.status == 200
    try:
        stack.proxy.request("slack", provider_url, "POST", body={"channel": "OTHER", "text": "Support update"},
            passport_token=started["passport"]["token"], authority_request_id=operation_id + "_denied")
    except StackError as error:
        assert error.status_code == 403
    else:
        raise AssertionError("Expected channel restriction")
    before = stack.missions.get(started["mission_id"])
    renewed = stack.missions.renew(started["mission_id"])
    after = stack.missions.get(renewed["mission_id"])
    assert renewed["mission_id"] == started["mission_id"]
    assert after["fleet"]["limits"] == before["fleet"]["limits"]
    assert after["fleet"]["usage"] == before["fleet"]["usage"]
    completed = stack.missions.complete(started["mission_id"], output={"done": True})
    assert completed["terminal_state"] == "completed_successful"
    stopped = stack.missions.start({**request, "idempotency_key": request["idempotency_key"] + "-stop"})
    stack.missions.revoke(stopped["mission_id"], reason="operator_initiated_clean")
    try:
        stack.missions.renew(stopped["mission_id"])
    except StackError:
        pass
    else:
        raise AssertionError("Expected revoked Mission")
    return {"mission_id": started["mission_id"], "operation_id": operation_id, "completed": True, "revoked": True}

Authentication

Four sources, resolved in priority order:

# 1. Explicit auth strategy
stack = Stack.from_oauth(client_id="...", client_secret="", access_token="...", refresh_token="...")
stack = Stack.from_session(session_token="...")

# 2. agent_id (Phase 2 — recommended for production runtimes)
stack = Stack(agent_id="agt_xxx")

# 3. api_key (legacy sk_live_*; for CI without a browser)
stack = Stack(api_key="sk_live_...")
# or set STACK_API_KEY in the environment

# 4. ~/.stack/credentials.json (Phase 1 — `stack-cli auth login` writes it)
stack = Stack()

See /docs/security/stack-auth for the full auth model and /docs/security/agent-keys for the per-agent keypair story.

Renew a Mission's Passport

renewed = stack.missions.renew(mission_id)
passport_token = renewed["passport"]["token"]

Renewal keeps the same Mission, permission and recorded usage. Its deadline and limits still apply. Start a new Mission for the next job.

Services

# Agents
stack.agents.register(name, description=None, accountability_mode="enforced")
stack.agents.get(agent_id)
stack.agents.list()
stack.agents.update(agent_id, **fields)
stack.agents.unblock(agent_id)

# Passports
stack.passports.issue(agent_id, intent=None, services=None, ...)
stack.passports.verify(token)
stack.passports.revoke(jti, reason=None)
stack.passports.checkpoint(jti, services_used, actions_count, ...)
stack.passports.checkout(jti, services_used, actions_count, ...)
stack.passports.report(jti)

# Credentials
stack.credentials.get(provider)
stack.credentials.get_by_connection(connection_id)

# Services
stack.services.list()
stack.services.connect_custom(name, credential, ...)
stack.services.verify(connection_id)
stack.services.disconnect(connection_id)

# Reviews
stack.reviews.list(status="flagged")
stack.reviews.decide(checkout_id, decision, notes=None, block_future=False)

# Drop-offs
stack.dropoffs.create(from_agent_id, to_agent_id, schema, ...)
stack.dropoffs.deposit(dropoff_id, data, agent_id)
stack.dropoffs.collect(dropoff_id, agent_id)

# Notifications
stack.notifications.list()
stack.notifications.create(channel_type, destination, ...)
stack.notifications.delete(channel_id)

# Audit
stack.audit.list(page=1, limit=50, action=None, agent_id=None)

Metadata

Release files for getstack 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for getstack 2.0.0
File Size Uploaded Provenance
getstack-2.0.0.tar.gz 87.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for getstack 2.0.0
File Interpreter ABI Platform
getstack-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 189.6 kB

Release files / getstack-2.0.0.tar.gz

Download URL getstack-2.0.0.tar.gz
Size 87.0 kB
Tags Source
SHA-256 checksum
How to use checksums
30f845f5e665fb50f16a53bebc6d83083606316eeb87479148fd1786ab651c65
BLAKE2b-256 checksum
How to use checksums
ad4349169569ee389ae48b13b073156da8e2107507e515a1dfa400d235130aa0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / getstack-2.0.0-py3-none-any.whl

Download URL getstack-2.0.0-py3-none-any.whl
Size 102.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cf4516359c4e1160bf72b5df0407fb7911597affc153ea97ddcd0e6dd167cb79
BLAKE2b-256 checksum
How to use checksums
cbbef623e30d3f27729f524101b817d644263b151154a24197ad9cc61644dda0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Security for getstack 2.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for getstack-2.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page