rackspay 0.1.0
Payment infrastructure for AI agents — issue virtual cards, check budgets, and manage transactions.
License: MIT
Requires Python: >=3.8
Keywords: agents, ai, fintech, payments, racks, virtual-cards

# racks

Payment infrastructure for AI agents. Issue virtual cards, check budgets, and manage transactions — in three lines of Python.

```
pip install racks
```

## Quick Start

```python
from racks import Racks

client = Racks(api_key="your_api_key")

# Check budget
budget = client.budget.get()
print(f"Remaining: ${budget.remaining}")

# Issue a card
card = client.cards.create(
    agent_id="your_agent_id",
    amount=12.99,
    merchant="namecheap.com",
    reason="Domain registration for myproject.com",
)
print(card.number, card.cvv, card.expiry)
```

## Installation

```bash
pip install racks
```

Requires Python 3.8+. The only dependency is [httpx](https://www.python-httpx.org/).

## Usage

### Initialize the client

```python
from racks import Racks

client = Racks(api_key="your_api_key")

# Or as a context manager (auto-closes connections)
with Racks(api_key="your_api_key") as client:
    budget = client.budget.get()
```

### Check budget

```python
budget = client.budget.get()

print(budget.name)               # "My Agent"
print(budget.current_spend)      # 84.48
print(budget.monthly_limit)      # 500.00
print(budget.remaining)          # 415.52
print(budget.utilization)        # 16.9
print(budget.total_transactions) # 7
print(budget.can_transact)       # True
```

### Validate a transaction

Check if a purchase would be approved *without* issuing a card:

```python
result = client.budget.validate(amount=25.00, merchant="openai.com")

if result.would_approve:
    print("Good to go!")
else:
    print(f"Blocked: {result.reason} — {result.details}")
```

### Issue a virtual card

```python
card = client.cards.create(
    agent_id="your_agent_id",
    amount=12.99,
    merchant="namecheap.com",
    reason="Domain registration",
    intent="Register myproject.com for 1 year",  # optional
)

print(card.number)          # "4242 4242 4242 4242"
print(card.cvv)             # "123"
print(card.expiry)          # "12/28"
print(card.brand)           # "Visa"
print(card.issuing_bank)    # "STRIPE_ISSUING"
print(card.intent_verified) # True
```

### List transactions

```python
transactions = client.transactions.list(limit=10)

for txn in transactions:
    print(f"{txn.merchant}: ${txn.amount} ({txn.status})")
```

## Error Handling

Every API error maps to a specific exception:

```python
from racks import Racks, BudgetExceeded, MerchantNotPermitted, Unauthorized

client = Racks(api_key="your_api_key")

try:
    card = client.cards.create(
        agent_id="...",
        amount=999.99,
        merchant="example.com",
        reason="Big purchase",
    )
except BudgetExceeded as e:
    print(f"Not enough budget: {e}")
except MerchantNotPermitted as e:
    print(f"Store not allowed: {e}")
except Unauthorized:
    print("Bad API key")
```

### Exception hierarchy

| Exception | HTTP Status | When |
|---|---|---|
| `Unauthorized` | 401 | Invalid or missing API key |
| `BudgetExceeded` | 402 | Monthly or daily budget exceeded |
| `MerchantNotPermitted` | 403 | Merchant not in permitted stores |
| `IntentMismatch` | 403 | Declared intent doesn't match purchase |
| `NotFound` | 404 | Agent or resource not found |
| `RateLimitExceeded` | 429 | Too many requests |
| `ServiceUnavailable` | 503 | Stripe or backend down |
| `RacksError` | * | Base class for all errors |

## Configuration

```python
client = Racks(
    api_key="your_api_key",
    base_url="https://racks-server-v0.vercel.app",  # default
    timeout=30.0,                                     # seconds
)
```

### Environment variables

```bash
export RACKS_API_KEY="your_api_key"
export RACKS_AGENT_ID="your_agent_id"
```

```python
import os
from racks import Racks

client = Racks(api_key=os.environ["RACKS_API_KEY"])
```

## Full Example

```python
import os
from racks import Racks, BudgetExceeded, MerchantNotPermitted

api_key = os.environ["RACKS_API_KEY"]
agent_id = os.environ["RACKS_AGENT_ID"]

with Racks(api_key=api_key) as client:
    # Step 1: Check budget
    budget = client.budget.get()
    print(f"Budget: ${budget.remaining} remaining of ${budget.monthly_limit}")

    # Step 2: Validate the purchase
    check = client.budget.validate(amount=12.99, merchant="namecheap.com")
    if not check.would_approve:
        print(f"Can't buy: {check.details}")
        exit(1)

    # Step 3: Issue the card
    try:
        card = client.cards.create(
            agent_id=agent_id,
            amount=12.99,
            merchant="namecheap.com",
            reason="Domain registration for myproject.com",
        )
        print(f"Card issued: {card.number} | CVV: {card.cvv} | Exp: {card.expiry}")
    except BudgetExceeded:
        print("Budget exceeded")
    except MerchantNotPermitted:
        print("Merchant not allowed — add it in the dashboard first")

    # Step 4: Check transaction history
    for txn in client.transactions.list(limit=5):
        print(f"  {txn.merchant}: ${txn.amount} ({txn.status})")
```

## Testing

```bash
# Unit tests (no API key needed)
pip install pytest
pytest tests/ -v

# Live integration tests
RACKS_API_KEY=... RACKS_AGENT_ID=... pytest tests/ -v
```

## What is RACKS?

RACKS is the financial infrastructure for AI agents. It lets autonomous agents transact in the real economy using virtual cards — with budget controls, merchant permissions, and a full audit trail.

Learn more at [rackspay.com](https://rackspay.com).

## Support

Questions? Reach out at rakan@rackspay.com

## License

MIT