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)

# Missions (every passport is issued for exactly one Mission)
stack.missions.open(intent_summary, agent_id=None, intent_services=None, ...)
stack.missions.start(agent_id=agent_id, mission={"intent_summary": "..."}, passport=None)
stack.missions.complete(mission_id)  # also revokes the Mission's passports
stack.missions.revoke(mission_id, reason="operator_initiated_clean")

# Passports
stack.passports.issue(agent_id, mission_ids=[mission_id], intent=None, services=None, ...)
stack.passports.mission(agent_id, intent, services, ...)  # context manager: Mission + passport, closed on exit
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, ..., passport_token=None)
stack.dropoffs.deposit(dropoff_id, data, agent_id, passport_token=None)
stack.dropoffs.collect(dropoff_id, agent_id, passport_token=None)

# 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)

Development

python -m pip install -e ".[dev]"
ruff check .
ruff format --check .
mypy src
python -m pytest -q

The package ships py.typed; mypy src runs in strict mode.

Metadata

Release files for getstack 4.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 4.0.0
File Size Uploaded Provenance
getstack-4.0.0.tar.gz 97.8 kB With provenance Details

Built distribution (wheel)

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

Total release size: 208.1 kB

Release files / getstack-4.0.0.tar.gz

Download URL getstack-4.0.0.tar.gz
Size 97.8 kB
Tags Source
SHA-256 checksum
How to use checksums
cf6c4dc224a316d2db4a3fc714e8a30d6bd739edc3604efcfb10629cc9766cf9
BLAKE2b-256 checksum
How to use checksums
bcfd2db784d958f8b2fbcf63cd4a2f516d7eb7eaa9970e2a13ec57028fe4faf4
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 Oct 16, 2026.

Transparency log

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

Download URL getstack-4.0.0-py3-none-any.whl
Size 110.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e44ae5175ba321d64405e2b41603379b599e8e14be2ee918f0423f9b61fbdb28
BLAKE2b-256 checksum
How to use checksums
3f9805fc5c591f47530a418324c81afaa30ab955cf62c70f65a6a71285d8f961
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 Oct 16, 2026.

Transparency log

Security for getstack 4.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-4.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 Oct 16, 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

4.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