# Billing and Credits

> How credit-based billing works, pricing, and managing costs

Struere uses a credit-based billing system. Credits are consumed when no direct provider key or OpenRouter key is configured — the platform routes LLM calls through its own OpenRouter key and meters usage per-token at provider rates with a 25% markup. Organizations that bring their own API keys (direct provider keys or an OpenRouter key) bypass platform billing entirely.

## Credit System

Credits are stored as **microdollars** (1 USD = 1,000,000 microdollars). This integer-based representation avoids floating-point precision issues across all balance calculations and transaction records.

Each organization has a single `creditBalances` record tracking the current balance, plus a `creditTransactions` ledger that records every credit movement:

| Transaction Type | Description |
|------------------|-------------|
| `purchase` | Credits added via Polar checkout |
| `addition` | Manual credit addition by an org admin |
| `deduction` | Automated deduction after an LLM call or billable action |
| `adjustment` | Manual balance correction by an org admin |

## Purchasing Credits

Credits are purchased through Polar checkout. The minimum purchase is **$1.00**.

1. Navigate to **Settings > Billing** in the dashboard
2. Enter the amount and click **Add Credits**
3. Complete checkout on Polar
4. Credits are added to your organization balance automatically via webhook

Polar sends an `order.updated` webhook when a payment completes. The platform converts the Polar amount (cents) to microdollars and creates a `purchase` transaction. Duplicate orders are detected by `polarOrderId` to prevent double-crediting.

## Pricing

All prices reflect provider base rates with a **25% platform markup**. Prices are per 1 million tokens.

### Anthropic

| Model | Input / 1M tokens | Output / 1M tokens |
|-------|--------------------|---------------------|
| `claude-haiku-4-5` | $1.10 | $5.50 |
| `claude-sonnet-4` | $3.30 | $16.50 |
| `claude-sonnet-4-5` | $3.30 | $16.50 |
| `claude-sonnet-4-6` | $3.30 | $16.50 |
| `claude-opus-4` | $16.50 | $82.50 |
| `claude-opus-4-5` | $5.50 | $27.50 |
| `claude-opus-4-6` | $5.50 | $27.50 |

### OpenAI

| Model | Input / 1M tokens | Output / 1M tokens |
|-------|--------------------|---------------------|
| `gpt-4o-mini` | $0.165 | $0.66 |
| `gpt-4o` | $2.75 | $11.00 |
| `gpt-4.1-nano` | $0.11 | $0.44 |
| `gpt-4.1-mini` | $0.44 | $1.76 |
| `gpt-4.1` | $2.20 | $8.80 |
| `gpt-5-nano` | $0.055 | $0.44 |
| `gpt-5-mini` | $0.275 | $2.20 |
| `gpt-5` | $1.375 | $11.00 |
| `gpt-5.1` | $1.375 | $11.00 |
| `gpt-5.2` | $1.925 | $15.40 |
| `o1` | $16.50 | $66.00 |
| `o1-mini` | $1.21 | $4.84 |
| `o1-pro` | $165.00 | $660.00 |
| `o3` | $2.20 | $8.80 |
| `o3-mini` | $1.21 | $4.84 |
| `o3-pro` | $22.00 | $88.00 |
| `o4-mini` | $1.21 | $4.84 |

### Google

| Model | Input / 1M tokens | Output / 1M tokens |
|-------|--------------------|---------------------|
| `gemini-2.0-flash` | $0.11 | $0.44 |
| `gemini-2.5-flash` | $0.33 | $2.75 |
| `gemini-2.5-pro` | $1.375 | $11.00 |

### xAI

| Model | Input / 1M tokens | Output / 1M tokens |
|-------|--------------------|---------------------|
| `grok-3` | $3.30 | $16.50 |
| `grok-3-mini` | $0.33 | $0.55 |
| `grok-4-0709` | $3.30 | $16.50 |
| `grok-4-1-fast` | $0.22 | $0.55 |
| `grok-4-1-fast-reasoning` | $0.22 | $0.55 |
| `grok-4-1-fast-non-reasoning` | $0.22 | $0.55 |
| `grok-4-fast-reasoning` | $0.22 | $0.55 |
| `grok-4-fast-non-reasoning` | $0.22 | $0.55 |
| `grok-code-fast-1` | $0.22 | $1.65 |

The default model is `openai/gpt-5-mini` at $0.275 input / $2.20 output per million tokens. Models not in the pricing table fall back to the default model pricing.

See [Model Configuration](/reference/model-configuration) for provider setup and model selection details.

## Credit Billing Flow

Credits are deducted directly after each LLM execution completes. The flow is:

```
Step 1: LLM execution
    │
    │  Run the agent's LLM loop (up to 10 iterations
    │  of tool calls). Token usage is tracked.
    │
    ▼
Step 2: Deduct credits (atomic Convex mutation)
    │
    │  After the LLM returns, calculate the actual cost
    │  from real token counts. Call deductCredits to
    │  subtract the cost from the organization's balance
    │  and insert a deduction transaction.
    │
    ▼
Step 3: Reconciliation (every 1 hour)
    │
    │  A cron job processes pending transactions and
    │  updates the cached balance on the creditBalances
    │  record.
    │
    ▼
Balance is up to date
```

### Cost Calculation

The cost is calculated from actual token usage after the LLM call completes:

```
cost = (inputTokens * inputRate + outputTokens * outputRate) / 1,000,000
```

The result is stored in microdollars on the execution record and deducted from the organization balance via `deductCredits`.

## What Consumes Credits

### Agent Chat (API, Webhook, Widget)

Every agent chat request that uses platform credits (no direct or OpenRouter key configured) is billed. The cost is calculated from actual token usage:

```
cost = (inputTokens * inputRate + outputTokens * outputRate) / 1,000,000
```

The result is stored in microdollars on the execution record and deducted from the organization balance.

### Studio Sessions

[Studio](/platform/studio) sessions deduct credits per message when using platform credits. Each message's token usage is tracked on the session and deducted via the same billing pipeline. Sessions using a direct provider key or OpenRouter key track token usage for analytics but skip credit deduction.

### Eval Runs

[Evaluations](/platform/evals) consume credits in two ways:

- **Agent tokens** from running each eval case through the agent
- **Judge tokens** from the LLM judge evaluating assertions

Both agent and judge token costs are calculated and deducted through the standard billing pipeline.

### WhatsApp Messages

Outbound WhatsApp messages sent through the platform incur per-message costs based on the Meta pricing category. Credits are deducted when the message status transitions to `sent`.

### Email

Outbound emails sent through the platform incur a per-message credit deduction.

## Bring Your Own Keys

Organizations can configure their own API keys to bypass platform billing entirely.

### How It Works

1. Navigate to **Settings > Providers** in the dashboard
2. Add a **direct provider key** (e.g., Anthropic, OpenAI, Google, xAI) or an **OpenRouter key**
3. Click **Test Connection** to verify the key works

When an agent runs, the platform resolves the API key using a 3-tier fallback:

1. **Direct provider key** -- If a key is configured for the model's provider, that key is used. No credits consumed.
2. **OpenRouter key** -- If an OpenRouter key is configured, all LLM calls are routed through OpenRouter. No credits consumed.
3. **Platform credits** -- If no keys are found, the platform uses its own OpenRouter key and deducts credits.

Token usage is always tracked on the execution record regardless of which key is used.

Keys are stored encrypted in the `providerConfigs` table. The API never returns the full key — only a masked version (first 4 and last 4 characters).

## Manual Credit Management

Organization admins can manage credits directly from the dashboard:

### Add Credits

Add a specific amount of credits to the organization balance. Creates an `addition` transaction with the admin's user ID recorded as `createdBy`.

### Adjust Balance

Set the balance to an exact value. The platform calculates the difference and creates an `adjustment` transaction. This is useful for corrections or promotional credits.

Both operations require organization admin privileges and are recorded in the transaction ledger with full audit trail.

## Database Schema

### creditBalances

| Field | Type | Description |
|-------|------|-------------|
| `organizationId` | ID | One balance record per organization |
| `balance` | number | Current balance in microdollars |
| `reservedCredits` | number (optional) | Sum of all active reservations in microdollars |
| `updatedAt` | number | Last reconciliation timestamp |

### creditTransactions

| Field | Type | Description |
|-------|------|-------------|
| `organizationId` | ID | Owning organization |
| `type` | enum | `purchase`, `addition`, `deduction`, `adjustment` |
| `amount` | number | Transaction amount in microdollars |
| `balanceAfter` | number (optional) | Balance after reconciliation (undefined while pending) |
| `description` | string | Human-readable description |
| `executionId` | ID (optional) | Linked execution for deductions |
| `createdBy` | ID (optional) | User who initiated manual transactions |
| `metadata` | object (optional) | Additional data (e.g., `polarOrderId`) |
| `createdAt` | number | Transaction timestamp |
