Metadata-Version: 2.4
Name: api-sandbox
Version: 0.1.6
Summary: CLI for API sandboxes. Test your APIs in a sandbox env.
Author-email: Subbu Athikunte <subramani.a@digitalapi.ai>
License-Expression: LicenseRef-Proprietary
Project-URL: Homepage, https://www.digitalapi.ai/
Project-URL: Documentation, https://github.com/digitalapicraft/api-sandbox/tree/main/docs
Project-URL: Repository, https://github.com/digitalapicraft/api-sandbox
Keywords: api,sandbox,cli,openapi,simulation
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Utilities
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: cryptography>=46.0
Requires-Dist: fastapi>=0.115
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.8
Requires-Dist: psycopg[binary]>=3.3
Requires-Dist: pyyaml>=6.0
Requires-Dist: typer>=0.12
Requires-Dist: uvicorn>=0.30
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: mypy>=1.11; extra == "dev"
Requires-Dist: pytest>=8.3; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: twine>=6.1; extra == "dev"
Provides-Extra: release
Requires-Dist: build>=1.2; extra == "release"
Requires-Dist: twine>=6.1; extra == "release"

# `api-sandbox`

Create a sandbox from your OpenAPI spec.

Use `api-sandbox` when you need to:

- give partners a stable test endpoint
- require API key or bearer authentication in the sandbox
- test state changes, timers, and webhooks
- inspect traces when an integration fails

## Install

Recommended:

```bash
pipx install api-sandbox
```

Homebrew:

```bash
brew tap digitalapicraft/api-sandbox-cli https://github.com/digitalapicraft/api-sandbox-cli && brew install api-sandbox
```

If you already manage your own virtual environment:

```bash
python -m pip install api-sandbox
```

Requirements:

- Python `3.12+`

Verify the install:

```bash
sdb --help
```

For the hosted customer path, export your control-plane token before the first hosted command:

```bash
export API_SANDBOX_TOKEN=<REAL_CONTROL_PLANE_TOKEN>
```

The first interactive hosted command offers to create the default `customer` profile pointed at `https://api.sandbox.digitalapi.ai`.

## Choose a guide

| If you want to... | Start here |
| --- | --- |
| Publish a sandbox from a spec | [Publisher quickstart](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/publisher-quickstart.md) |
| Connect to a sandbox as a consumer | [Consumer quickstart](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/consumer-quickstart.md) |
| Test stateful flows, timers, and webhooks | [Simulation runbook](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/simulation.md) |
| See the end-to-end flow first | [Overview](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/product-explainer.md) |

## Publish your first sandbox

This example creates bearer auth once, then publishes a sandbox in one command and returns a `connect_url`.

```bash
sdb auth create-profile payments-sim \
  --mode simulated \
  --scheme BearerAuth=bearer

sdb policy create refunds-only

sdb --output json publish ./payments.yaml \
  --sandbox bank-sim \
  --auth-profile payments-sim \
  --policy-pack refunds-only
```

After publish succeeds, copy `publish.connection.connect_url` from the JSON response. That is the consumer entry point.

Hosted control-plane commands fail fast if no control-plane token source is configured.

## Protect endpoints with auth and scopes

Use an auth profile to define how consumers authenticate in the sandbox. Use a policy pack to enforce scopes.

For example, this flow creates bearer auth and a scope-aware release:

```bash
sdb auth create-profile payments-sim \
  --mode simulated \
  --scheme BearerAuth=bearer

sdb policy create refunds-only

sdb --output json publish ./payments.yaml \
  --sandbox bank-sim \
  --auth-profile payments-sim \
  --policy-pack refunds-only
```

Consumers can then:

- discover the auth configuration from the sandbox alias
- issue scoped credentials
- exchange a bearer token
- call protected endpoints with the saved session

## Connect as a consumer

This example creates an app, issues client credentials, connects once, logs in, and sends a request.

```bash
sdb auth create-app bank-sim partner-app \
  --alias latest \
  --auth-profile payments-sim \
  --scheme BearerAuth

sdb auth issue-client partner-app \
  --sandbox bank-sim \
  --scope refunds.read

sdb connect <CONNECT_URL>

printf '%s\n' "<CLIENT_SECRET>" | sdb auth login \
  --client-id <CLIENT_ID> \
  --client-secret-stdin \
  --scope refunds.read

sdb sandbox request GET /refunds/ref_123
```

Consumer discovery, login, and request commands use the same hosted product URL: `https://api.sandbox.digitalapi.ai`.

Use these commands to inspect or clear saved sessions:

```bash
sdb connection show
sdb auth session list
sdb --yes auth session clear --expired
```

## Test stateful integrations

Use simulation mode when the response should change over time.

Common cases:

- banking flows such as deposits, credits, refunds, and disputes
- commerce flows such as order creation, shipment updates, and cancellations
- SaaS workflows such as tenant provisioning, entitlement changes, and delayed jobs
- webhook-based integrations that need repeatable event delivery
- negative-path testing for retries, failures, and time-based transitions

Simulation mode lets you:

- seed known state for a sandbox
- apply named scenarios
- capture and restore snapshots
- advance the sandbox clock explicitly
- trigger deterministic timers
- verify emitted webhook events

### Example: credit an account and verify a webhook

This example creates a simulation sandbox, applies a scenario, advances time, and checks the emitted event.

```bash
sdb sandbox create banking-sim --api "Retail Banking API" --mode simulation

sdb simulation create-pack retail-banking-sim \
  --kind scenario_v1 \
  --seed 'getAccount@{"account_id":"{account_id}","balance":100,"status":"pending"}' \
  --scenario '{"scenario_id":"credit-ladder","name":"Credit ladder","state_patches":[{"path":"/accounts/{account_id}","body":{"status":"credited","balance":250}}]}'

sdb release create banking-sim \
  --spec "Retail Banking API@2026-04-18" \
  --simulation-pack retail-banking-sim

sdb release list --sandbox banking-sim
sdb release promote banking-sim --alias latest --release <SIM_RELEASE_ID>

sdb simulation snapshot create banking-sim --name pre-credit

sdb simulation webhook create banking-sim \
  --destination capture://partner-a \
  --event account.updated.demo

sdb simulation scenario apply banking-sim \
  --scenario credit-ladder \
  --binding account_id=acc_123 \
  --binding run_id=demo

sdb simulation timer list banking-sim
sdb simulation clock advance banking-sim --to 2026-04-18T20:00:00Z
sdb simulation event list --sandbox banking-sim --type account.updated.demo
```

Use snapshots and reset to rerun the same flow:

```bash
sdb simulation snapshot list banking-sim
sdb --yes sandbox reset banking-sim
```

## Inspect requests and failures

Use traces to see what a consumer sent and how the sandbox handled the request.

```bash
sdb trace tail bank-sim --limit 10
sdb trace list --sandbox bank-sim
sdb trace get <TRACE_ID>
sdb trace replay <TRACE_ID>
```

This is useful when you need to:

- confirm the request path and method
- check whether auth or scope enforcement blocked the request
- replay a failing request against the sandbox

## More guides

- [Install + first hosted use](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/public-cli-install.md)
- [Publisher quickstart](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/publisher-quickstart.md)
- [Consumer quickstart](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/consumer-quickstart.md)
- [Publisher runbook](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/publisher.md)
- [Consumer runbook](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/consumer.md)
- [Simulation runbook](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/simulation.md)
- [Troubleshooting](https://github.com/digitalapicraft/api-sandbox/blob/main/docs/runbooks/troubleshooting.md)

## Video walkthrough

- [Watch on YouTube](https://youtu.be/40O5IWPn2aI)
