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)

Release files for getstack 1.4.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 1.4.0
File Size Uploaded
getstack-1.4.0.tar.gz 85.6 kB Details

Built distribution (wheel)

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

Total release size: 186.9 kB

Release files / getstack-1.4.0.tar.gz

Download URL getstack-1.4.0.tar.gz
Size 85.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9001e760ccb50dfc47251d6de8a88400c53a0822038ef7a5f9e25877669e7a0c
BLAKE2b-256 checksum
How to use checksums
1599355d32739ff9a35383c5447ebcf7c8336876d94f81f45377df4cb27d7a23
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 24, 2026.

Transparency log

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

Download URL getstack-1.4.0-py3-none-any.whl
Size 101.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
428b0859655d107f6d4a17afa84049cb074fcdb0fda7e934581bcd2640c28710
BLAKE2b-256 checksum
How to use checksums
1e7a51a0cd5fd816dc19a4930a133a9f5ef2ae75751576dcf7c081c20abc80b3
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 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.19.1

2 release files

0.19.0

2 release files

0.18.0

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

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