# Brix API v1

Brix is an AI money assistant for college students. The API lets a Brix user read their subscriptions, free trials, reminders, single-use cards (masked), school refunds and practice portfolio, mark charges to cancel, and schedule reminders, with a personal key they create and can revoke.

- Base URL: `https://www.usebrix.app/api/v1`
- OpenAPI 3.1 spec: https://www.usebrix.app/api/v1/openapi.json
- Human docs: https://www.usebrix.app/developers
- Source: https://github.com/Timeless-Dave/brix

## Quickstart

1. Sign in to Brix and open Developers → API keys. Name the key, choose only the scopes you need, and copy it (it's shown once).
2. Store it server-side as `BRIX_API_KEY`. Never ship it in a web page, app bundle or public repo.
3. Make your first call:

```bash
curl https://www.usebrix.app/api/v1/me \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

JavaScript:

```js
const res = await fetch("https://www.usebrix.app/api/v1/charges/upcoming?days=7", {
  headers: { Authorization: `Bearer ${process.env.BRIX_API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data } = await res.json();
for (const c of data)
  console.log(`${c.merchant}: $${c.amount} on ${c.next_date}`);
```

Python:

```python
import os, requests

r = requests.post(
    "https://www.usebrix.app/api/v1/reminders",
    headers={"Authorization": f"Bearer {os.environ['BRIX_API_KEY']}"},
    json={"merchant": "Spotify", "when": "2 days before"},
    timeout=10,
)
r.raise_for_status()
print(r.json()["remind_at"])
```

## Authentication and scopes

Send `Authorization: Bearer brix_sk_…`. Brix stores only a SHA-256 hash of the key. Up to 5 active keys per user. A missing scope returns `403 insufficient_scope`.

| Scope | Allows |
|---|---|
| `charges:read` | Read charges, upcoming charges, and the spending summary. |
| `charges:write` | Add trials and mark charges to cancel or active. |
| `reminders:read` | List reminders. |
| `reminders:write` | Create and delete reminders. |
| `cards:read` | List single-use cards (masked; never card numbers). |
| `news:read` | Read subscription news about your merchants. |
| `refunds:read` | Read school refunds and their plans. |
| `practice:read` | Read the practice portfolio (virtual money): value, positions, rules, orders. |

## Conventions

- JSON in and out, `snake_case` fields, amounts in USD as decimal numbers, dates as `YYYY-MM-DD`.
- Lists: `{ "object": "list", "data": [...] }`.
- Rate limit: 120 requests per minute per key, with `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `Retry-After` on 429.
- `POST /trials` accepts an `Idempotency-Key` header.
- Responses carry `Brix-Version: 2026-10-24`. Fields are only ever added within `/v1`.
- Every response has an `X-Request-Id`, also inside error bodies.

## Errors

```json
{
  "error": {
    "type": "insufficient_scope",
    "message": "This key is missing the `charges:write` scope.",
    "request_id": "req_4f1c9a0b2e7d4c3a8b19"
  }
}
```

| Status | Type | Meaning |
|---|---|---|
| 400 | `invalid_request` | A parameter or body field is missing or invalid. |
| 401 | `authentication_failed` | The key is missing, malformed, unknown, or revoked. |
| 403 | `insufficient_scope` | The key doesn't have the scope this endpoint needs. |
| 404 | `not_found` | No charge or reminder with that ID belongs to this user. |
| 409 | `conflict` | The change conflicts with the current state, e.g. a sent reminder. |
| 413 | `request_too_large` | The body is larger than 64 KB. |
| 429 | `rate_limited` | More than 120 requests in a minute. Wait for `Retry-After`. |
| 502 | `upstream_unavailable` | A provider such as the news service didn't respond. |
| 500 | `api_error` | Something failed on our side. Retry; share the request ID if it continues. |

## Endpoints

### GET /v1/me

**Check your key.** Returns the key you authenticated with and its scopes. Works with any scope; use it to verify setup.

Scope: any valid key

```bash
curl "https://www.usebrix.app/api/v1/me" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/charges

**List charges.** Every subscription and trial Brix knows about, sorted by next expected date.

Scope: `charges:read`

```bash
curl "https://www.usebrix.app/api/v1/charges?status=active" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/charges/upcoming

**Upcoming charges.** Active subscriptions and trials expected within the next `days` days (default 14, max 90).

Scope: `charges:read`

```bash
curl "https://www.usebrix.app/api/v1/charges/upcoming?days=7" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/charges/{id}

**Get a charge.** One charge by ID.

Scope: `charges:read`

```bash
curl "https://www.usebrix.app/api/v1/charges/ch_123" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### PATCH /v1/charges/{id}

**Mark to cancel / reactivate.** Set `status` to `to_cancel` to mark a charge for cancellation, or `active` to undo it. Brix never cancels at the merchant; the response includes the merchant's cancel link when known.

Scope: `charges:write`

```bash
curl -X PATCH "https://www.usebrix.app/api/v1/charges/ch_123" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"to_cancel"}'
```

### POST /v1/trials

**Add a free trial.** Track a free trial so Brix reminds you before it bills. Send an `Idempotency-Key` header to make retries safe.

Scope: `charges:write`

```bash
curl -X POST "https://www.usebrix.app/api/v1/trials" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Idempotency-Key: trial-notion-nov" \
  -H "Content-Type: application/json" \
  -d '{"merchant":"Notion AI","end_date":"2026-11-15","amount":10}'
```

### GET /v1/summary

**Spending summary.** Monthly subscription total, counts, the next 14 days, and the estimated amount avoided this month.

Scope: `charges:read`

```bash
curl "https://www.usebrix.app/api/v1/summary" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/reminders

**List reminders.** Scheduled and sent reminders, earliest first.

Scope: `reminders:read`

```bash
curl "https://www.usebrix.app/api/v1/reminders" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### POST /v1/reminders

**Create a reminder.** Remind the user about a charge. Identify it by `charge_id` or `merchant`. `when` accepts a future `YYYY-MM-DD`, an ISO timestamp, or `N days before`. Delivery is WhatsApp when the user enabled it, otherwise in the app.

Scope: `reminders:write`

```bash
curl -X POST "https://www.usebrix.app/api/v1/reminders" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"merchant":"Spotify","when":"2 days before"}'
```

### DELETE /v1/reminders/{id}

**Delete a reminder.** Removes a reminder that hasn't been sent yet.

Scope: `reminders:write`

```bash
curl -X DELETE "https://www.usebrix.app/api/v1/reminders/manual:…" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/cards

**List cards.** Single-use cards created in Brix. Only the last four digits are returned. Creating cards is not available through the API; it requires confirmation in the app.

Scope: `cards:read`

```bash
curl "https://www.usebrix.app/api/v1/cards" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/news

**Merchant news.** Recent articles about pricing or renewal changes at the user's top merchants. Articles don't confirm a change to the user's own plan.

Scope: `news:read`

```bash
curl "https://www.usebrix.app/api/v1/news" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/refunds

**List refunds.** School refunds (aid left after tuition) Brix detected or the user added, with any saved plan. `loan_amount` is the borrowed part; federal Direct Loan money can be returned within 120 days without interest.

Scope: `refunds:read`

```bash
curl "https://www.usebrix.app/api/v1/refunds" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

### GET /v1/practice

**Practice portfolio.** The user's paper-trading portfolio: virtual cash, positions at live prices, gain compared with the S&P 500 (VOO), auto-invest rules, and recent orders. No real money is involved. `null` when the user hasn't started one.

Scope: `practice:read`

```bash
curl "https://www.usebrix.app/api/v1/practice" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

## What the API doesn't do

- Create cards (needs the user's confirmation in the app), link banks (Plaid's secure screen in the app), chat with the assistant, cancel at the merchant, or act for other people (keys are personal; no OAuth yet).

## Data and safety

Bank charges are Plaid sandbox data and cards are Lithic sandbox cards that can't spend real money. Treat a key like a password; revoke a leaked key on the Developers page in the app.
