Actionbox Python SDK
Actionbox gives backend services a durable, server-authoritative way to ask a human for a decision and continue when that decision is available. This package is the typed Python client for creating, resolving, and waiting on Actions, plus managing source-scoped heartbeat Watches.
Documentation
Requirements
- Python 3.11 or newer
- An Actionbox Source API key, supplied through
ACTIONBOX_API_KEY
Keep API keys and Watch capability URLs on trusted servers, workers, or CI jobs. Do not put this SDK or its credentials in browser code.
Install
pip install actionbox-sdk
The distribution is named actionbox-sdk so it does not conflict with the
Actionbox CLI distribution on PyPI. The Python import remains actionbox.
import os
from actionbox import Actionbox
with Actionbox(os.environ["ACTIONBOX_API_KEY"]) as client:
decision = client.ask(
title="Deploy to production?",
options=["Approve", "Reject"],
callback_url="https://ci.example.com/actionbox",
)
print(decision)
The SDK uses the hosted production API at https://api.actionbox.cloud by
default. Customer integrations should use that default and only pass
base_url in maintainer-controlled test environments.
ask(..., wait=False) returns an Action; Action.wait() polls the server and leaves the Action open when the local timeout expires. The concise single-choice API returns the selected option ID as a string.
Typed interactions and responses
The SDK exports typed interaction and response contracts that match the REST API. Use an explicit typed interaction with create or ask when the human response is more than a single choice:
from actionbox import Actionbox, BooleanInteraction
with Actionbox(os.environ["ACTIONBOX_API_KEY"]) as client:
action = client.create(
title="Deploy configuration",
interaction=BooleanInteraction(
type="boolean",
label="Deploy now?",
true_label="Deploy",
false_label="Hold",
),
)
resolved = client.resolve(
action.id,
response={"type": "boolean", "value": True},
reason="Approved by release manager",
)
print(resolved.response) # {"type": "boolean", "value": True}
The available interaction types are boolean, single_choice, multi_choice, text, integer, number, rating, and form. Form fields use the same typed field shapes and are returned as {"type": "form", "values": {...}}. Create inputs also accept bounded developer context blocks and an explicit typed on_expire fallback; omitting it returns expired without inventing a response.
resolve supports concise single-choice syntax and generic typed input:
client.resolve(action.id, "approve") # single-choice shorthand
client.resolve(action.id, {"response": {"type": "text", "value": "ship"}})
client.actions.resolve(action.id, response={"type": "number", "value": 4.5})
Action.interaction and Action.response expose the canonical typed wire values. options, option_id, ask(..., options=[...]), and string decision results are first-class single-choice conveniences.
Optional decision context
Keep simple Actions unchanged. For higher-impact reviews, use a helper that builds the same generic structured context accepted by the REST API:
from actionbox import deployment_decision_context
action = client.create(
title="Deploy 2.18.0?",
decision_class="production_deployment",
decision_context=deployment_decision_context(
reason="Release passed staging.",
proposed_change="Deploy 2.18.0 to production.",
risk_level="high",
reversibility="reversible",
rollback_plan="Restore the previous image.",
),
)
The generic, refund, database-change, and access-request helpers emit this same wire shape; they do not create server-side template types.
Agent framework integrations
The OpenAI Agents SDK and LangGraph keep their own paused run state; Actionbox supplies the durable human request and typed response. The repository includes tested examples for both patterns:
- OpenAI Agents: map
result.interruptionsto Actions, apply each decision toresult.to_state(), then resume the original agent. - LangGraph: create Actions after interrupts surface to the graph driver, then
resume the same checkpoint and
thread_idwithCommand(resume=...).
See integrations/agent_frameworks/ in the Actionbox repository. No additional
Actionbox endpoint or framework-owned state migration is required.
Execution outcomes
After carrying out an approved operation, report its real result from the resolved Action snapshot:
outcome = resolved.report_outcome(
"success",
duration_ms=48_312,
rollback=False,
)
The SDK sends the Action's exact version and fingerprint. Exact retries are safe; Actionbox rejects a conflicting second outcome.
Agent Runs
Group an agent task and its Actions without managing another framework:
run = client.runs.start(
external_id="checkout-fix-42",
agent_name="codex",
title="Fix checkout deadlock",
stall_after_seconds=900,
)
run.progress(stage="tests", checkpoint="test-184")
action = client.create(title="Approve staging migration", run_id=run.id)
run.complete()
The SDK handles progress sequence numbers. Runs are optional; standalone
Actions continue to work exactly as before. When stall_after_seconds is set,
unchanged status/stage/checkpoint updates do not reset the timer. Actionbox
creates one ordinary Action if progress stalls and resolves it when progress
changes or the Run completes; waiting pauses the timer.
Heartbeat Watches
Source credentials can create and list Watches scoped to that Source. The raw heartbeat URL is returned only by creation:
from actionbox import Actionbox, send_heartbeat
with Actionbox(os.environ["ACTIONBOX_API_KEY"]) as client:
watch = client.watches.create(
source_id="src_…",
name="Nightly backup",
schedule_type="interval",
interval_seconds=3600,
grace_seconds=60,
signal_method="post",
)
send_heartbeat(watch.heartbeat_url, "start")
Use send_heartbeat for ping, start, success, or fail; it always sends
POST. signal_method="post" prevents link previewers and security scanners
from accidentally recording a heartbeat with GET. The
source-scoped resource also exposes client.watches.pause(id),
resume(id), rotate_token(id), and archive(id); only create/rotate return
a raw URL. Store capability URLs in a secret manager; Watch details and
exports never return them.
License
MIT. See LICENSE.
Metadata
Release files for actionbox-sdk 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| actionbox_sdk-0.1.8.tar.gz | 18.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| actionbox_sdk-0.1.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.9 kB
Release files / actionbox_sdk-0.1.8.tar.gz
| Download URL | actionbox_sdk-0.1.8.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
05de6142555471fc7991f02042c0f18dde5e0e0d3e040f27a843b128fa3347cf
|
|
BLAKE2b-256 checksum How to use checksums |
d13363918f6754e3a186cd5489b5e92761f989de973d430354b6d3f3282ad602
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.8.11
|
Release files / actionbox_sdk-0.1.8-py3-none-any.whl
| Download URL | actionbox_sdk-0.1.8-py3-none-any.whl |
|---|---|
| Size | 12.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
684317f392c19cc482cdd3f5d4473c95d3593a0c8761ef0bf8d77432d3cd3a3d
|
|
BLAKE2b-256 checksum How to use checksums |
a82dc1a961b833f02df9036ec4583dfa734452d85894ef71f406d43f9ff30271
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.8.11
|
Security for actionbox-sdk 0.1.8
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.