# Billing & Credits — Locus Build

> Companion guide to [`SKILL.md`](./SKILL.md). Covers credit-based billing, pricing, payment flow, and delinquency handling.

## When To Load

Load this file only for balance checks, payment flows, `402 Insufficient Credits`, renewals, or delinquency handling.

## Table of Contents

- [Pricing Model](#pricing-model)
- [Credit Balance Check](#credit-balance-check)
- [Making a Payment](#making-a-payment)
- [Handling 402 Insufficient Credits](#handling-402-insufficient-credits)
- [Billing Webhooks](#billing-webhooks)
- [Delinquency Timeline](#delinquency-timeline)

## Pricing Model

| Item | Price | Notes |
|------|-------|-------|
| Every service | **$0.25/month** each | Includes containers and addons (Postgres, Redis) |
| Initial credits | **$1.00** | Added automatically when workspace is created (covers first 4 services) |

Every service and addon costs $0.25/month, deducted from the workspace credit balance on creation and renewed monthly. New workspaces start with $1.00 in credits, which covers the first 4 services.

## Credit Balance Check

Before creating services, check if the workspace has sufficient credits:

```bash
curl -s -H "Authorization: Bearer $TOKEN" \
  https://api.buildwithlocus.com/v1/billing/balance | jq
```

Response:
```json
{
  "creditBalance": 1.00,
  "totalServices": 2,
  "monthlyTotal": 0.50,
  "billingCycleDay": 15,
  "nextBillingDate": "2026-04-15",
  "status": "active"
}
```

| Field | Description |
|-------|-------------|
| `creditBalance` | Current credit balance in USD |
| `totalServices` | Number of active billable services |
| `monthlyTotal` | Total monthly charge ($0.25 x services) |
| `status` | `active`, `delinquent`, or `suspended` |

## Making a Payment

Payments are made via stablecoins through [paywithlocus.com](https://paywithlocus.com). The API proxies the payment:

```bash
curl -s -X POST https://api.buildwithlocus.com/v1/billing/add-credits \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5.00,
    "apiKey": "claw_your_pay_api_key"
  }'
```

Response (immediate success):
```json
{
  "status": "success",
  "creditBalance": 6.00,
  "paymentId": "pay_abc123"
}
```

Response (pending approval):
```json
{
  "status": "pending_approval",
  "paymentId": "pay_abc123",
  "approvalUrl": "https://paywithlocus.com/approve/pay_abc123",
  "message": "Payment pending. Credits will be added once confirmed. Poll GET /v1/billing/balance to check."
}
```

If the payment requires approval, direct the user to the `approvalUrl`. Poll `GET /v1/billing/balance` until `creditBalance` increases.

## Handling 402 Insufficient Credits

When a service or addon creation returns `402`, the workspace is out of credits:

```json
{
  "error": "Insufficient credits",
  "creditBalance": 0.00,
  "requiredAmount": 0.25
}
```

**Agent workflow:**
1. Inform the user their workspace needs credits
2. Show current balance: `GET /v1/billing/balance`
3. Direct them to add credits via `POST /v1/billing/add-credits` or at [paywithlocus.com](https://paywithlocus.com)
4. Once credits are added, retry the service creation

## Billing Endpoints

| Action | Endpoint | Notes |
|--------|----------|-------|
| **Get balance** | `GET /v1/billing/balance` | Credit balance + billing summary |
| **Add credits** | `POST /v1/billing/add-credits` | `{amount, apiKey}` — proxy to paywithlocus.com |
| **MPP top-up** | `POST https://mpp.buildwithlocus.com/v1/billing/mpp-top-up` | `{amount, tempoAddress?}` — credit top-up via Tempo MPP payment. Requires `X-Mpp-Payment` header or `X-Service-Token` for service-authenticated calls |
| **x402 top-up** | `POST /v1/billing/x402-top-up` | `{amount}` — credit top-up via x402 USDC payment (Polygon or Base). Payment negotiated via x402 protocol headers |
| **x402 fund wallet** | `POST /v1/billing/x402-fund` | `{amount, targetWalletAddress}` — fund an existing workspace by linked wallet address. Does not return a workspace JWT |
| **Transaction history** | `GET /v1/billing/transactions` | `?limit=50` — credit/debit ledger |
| **Billable services** | `GET /v1/billing/services` | Services with rate breakdown |

For sign-up flows (MPP, x402, API key), see [onboarding.md](./onboarding.md).

## Billing Webhooks

Subscribe to billing events to monitor payment status and delinquency:

| Event | Trigger |
|-------|---------|
| `billing.reminder` | 7 days and 1 day before billing due |
| `billing.failed` | Monthly charge failed (insufficient credits) |
| `billing.delinquent` | Workspace is overdue (days 1-6) |
| `billing.final_warning` | 7 days overdue — suspension imminent |
| `billing.payment_received` | Credits added to workspace |

## Delinquency Timeline

| Day | Action |
|-----|--------|
| -7 | `billing.reminder` webhook (daysUntilDue: 7) |
| -1 | `billing.reminder` webhook (daysUntilDue: 1) |
| 0 | Monthly charge attempted. If fails: `billing.failed` webhook |
| 1-6 | `billing.delinquent` webhook daily (daysOverdue: N) |
| 7 | `billing.final_warning` webhook, then workspace suspended |

After suspension, services stop receiving traffic. Add credits and the workspace is restored to `active` status automatically.
