# Billing

Source: https://dabadata.com/docs/billing/ (HTML) - https://dabadata.com/docs/billing/index.md (this page as markdown)

dabadata plans are paid per workspace, never per seat or per read. During the beta nothing is charged: plan changes are free and immediate. This page says how billing works once it is switched on - checkout, the customer portal, overages you opt into, and what happens when a payment fails - so the first invoice is never a surprise.

> **Note:** Beta - you are not charged. Billing is off on dabadata today. Usage is measured anyway (see [Usage metering](https://dabadata.com/docs/limits/index.md#usage)), so you can see now what you would pay later.

## During the beta

The workspace's owner changes the plan on **Usage & plan** in the console (or with [`POST /v1/workspaces/:id/plan`](https://dabadata.com/docs/api/index.md#workspace-plan)). It takes effect at once and costs nothing. Free and Starter are self-service; Pro and Scale are switched on by us on request. The workspace answers `billingMode: "off"`, and the billing routes answer `409` `{ "error": "billing_off" }`.

## Prices

|   | Free | Starter | Pro | Scale | Enterprise |
| --- | --- | --- | --- | --- | --- |
| Monthly | $0 | $9 | $29 | $99 | agreed with us |
| Annual (10 months for 12) | $0 | $90 | $290 | $990 | agreed with us |

What each plan includes is on [Plans and limits](https://dabadata.com/docs/limits/index.md#plans). Taxes (VAT, GST) are added by country at checkout. Enterprise is invoiced by us, not through checkout.

## Subscribing

With billing on, the owner picks a plan and a period on **Usage & plan**. The console asks for a checkout link and sends the owner to Stripe's payment page:

```bash
curl -X POST https://dabadata.com/v1/workspaces/ws_k3x9m2p7q4w8/billing/checkout \
  -H "Cookie: sid=..." -H "X-Requested-With: console" -H "Content-Type: application/json" \
  -d '{ "plan": "pro", "period": "annual" }'
# { "url": "https://checkout.stripe.com/c/pay/..." }
```

- The plan does not change when the link is made. It changes when Stripe tells us the subscription is paid, usually a few seconds after the payment page closes; the console comes back to **Usage & plan** and shows it.
- A workspace has one subscription. Once it has one, plan changes, cards, invoices and cancellation are in the **billing portal** ([`POST /v1/workspaces/:id/billing/portal`](https://dabadata.com/docs/api/index.md#billing-portal)), Stripe's page for exactly that.
- Moving to Free from **Usage & plan** cancels the subscription at the end of the period you paid for; the paid plan stays until then (`cancelAt` says when).

## Overages are opt-in

Every limit stays a hard cap at the plan's allowance unless the owner raises it: no usage, however high, is billed beyond the plan's price by surprise. With an active subscription the owner may raise five caps on **Usage & plan** ([`PATCH /v1/workspaces/:id/caps`](https://dabadata.com/docs/api/index.md#caps)); usage between the allowance and the raised cap is billed on the next invoice:

| Cap | Above the allowance | Counted as |
| --- | --- | --- |
| `connections` | $5 per 1,000 connections | The month's highest number of connections open at once, above the allowance. |
| `egressBytes` | $0.12 per GB | Bytes sent this calendar month above the allowance, in whole GB. |
| `dbBytes` | $0.30 per GB-month | The month's largest database size above the allowance, in whole GB. |
| `fileBytes` | $0.02 per GB-month | The month's largest file storage above the allowance, in whole GB. Free is always a hard cap. |
| `webhookDeliveries` | per block of 100,000 deliveries (price to be announced; nothing is billed during the beta) | [Webhook events](https://dabadata.com/docs/webhooks/index.md#limits) counted this calendar month above the allowance, in whole blocks of 100,000. At the cap events are held, not dropped. Free is always a hard cap. |

```json
{ "connections": 1500, "egressBytes": 161061273600 }
```

- Each value is at least the plan's allowance; `null` puts a cap back to the allowance. Bytes are binary (1 GB = 2^30 bytes).
- Usage past a raised cap is treated like usage past the allowance today: new connections are refused, and storage or egress over it refuses writes after 7 days (see [What happens at a limit](https://dabadata.com/docs/limits/index.md#at-the-limit)). It is never billed.
- Usage is counted once a night and sent to Stripe as it grows; each unit is billed once. Partial gigabytes are not billed.

## When a payment fails

1. The workspace's billing state becomes `past_due`. Nothing changes for your apps; Stripe retries the card and mails the owner.
2. After 7 days still unpaid, the workspace gets Free's connections, request rate, storage, egress and file storage limits (a soft cap): reads keep working, and writes are refused while storage or egress is over Free's allowance. Nothing is deleted or paused, and projects and members stay.
3. As soon as the invoice is paid (a new card in the billing portal), the plan's limits come back at once.

If the subscription ends (cancelled, or never paid after Stripe's retries), the workspace moves to Free and raised caps are cleared. Your data stays; a workspace over Free's allowances follows [the usual rules](https://dabadata.com/docs/limits/index.md#at-the-limit).

## Reading the billing state

Admins and the owner read it with [`GET /v1/workspaces/:id/billing`](https://dabadata.com/docs/api/index.md#billing-get):

```json
{
  "mode": "stripe", "plan": "pro", "period": "annual", "state": "active", "pastDueSince": null,
  "caps":      { "connections": 1500, "egressBytes": 161061273600, "dbBytes": 21474836480, "fileBytes": 107374182400 },
  "allowance": { "connections": 500,  "egressBytes": 107374182400, "dbBytes": 21474836480, "fileBytes": 107374182400 },
  "cancelAt": null, "softCapSince": null, "limits": { "plan": "pro", "connections": 1500, ... }
}
```

Plan changes, raised caps and billing state changes are written to the workspace's [audit log](https://dabadata.com/docs/accounts/index.md#audit); changes that come from Stripe have the actor `stripe`.
