Billing & Usage¶
The billing system tracks resource usage at hourly granularity per project and product, generates monthly invoices, and manages payment methods through Stripe.
Endpoints¶
| Method | Path | Description |
|---|---|---|
GET | /billing/usage?organization_id=<uuid> | Get usage data for a period |
GET | /subscriptions | List subscriptions |
GET | /subscriptions/{id} | Show a subscription |
PATCH | /organizations/{id} | Update organization name / billing address |
GET | /invoices | List invoices |
GET | /invoices/{id} | Show invoice with line items |
GET | /organizations/{id}/invoices | List EasyBill invoices |
GET | /organizations/{id}/invoices/{invoice_id} | Show EasyBill invoice |
GET | /organizations/{id}/invoices/download?invoice_id=<id> | Download invoice PDF |
GET | /organizations/{id}/payment_methods | List payment methods |
POST | /organizations/{id}/payment_methods/create_and_attach | Attach a Stripe payment method |
PUT | /organizations/{id}/payment_methods/{payment_method_id}/set_default | Set default payment method |
DELETE | /organizations/{id}/payment_methods/{payment_method_id} | Remove a payment method |
Usage data¶
GET /billing/usage?organization_id=<uuid>&from=2026-01-01T00:00:00Z&to=2026-01-31T23:59:59Z
Authorization: Bearer <token>
Returns resource consumption broken down by project and product for the requested window. Use this to build cost forecasts and chargeback reports.
Subscriptions¶
Subscriptions link a product to a project with a start (and optional end) date. Hourly usage entries are recorded against active subscriptions.
Subscription fields:
| Field | Description |
|---|---|
id | Subscription UUID |
organization_id | Organization UUID |
project_id | Project UUID (nullable — org-level subscriptions have none) |
product_id | Product UUID |
start_date | ISO 8601 datetime the subscription began |
end_date | ISO 8601 datetime the subscription ended; null if active |
Organization billing address¶
The organization's name and billing address feed EasyBill invoicing (VAT handling, invoice header). Update them with:
PATCH /organizations/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"organization": {
"address": {
"street": "Musterstraße 1",
"city": "Hamburg",
"zip_code": "20095",
"country": "DE"
}
}
}
Address fields: first_name, name, email, street, city, state, zip_code, country — see the Address schema in the interactive reference.
country is an ISO 3166-1 alpha-2 code, uppercase (DE, AT, CH, …), or null. On write, hq accepts an alpha-2 code in any case or a known country name in English or German (for the EU/EFTA/UK/US set) and normalizes it to uppercase alpha-2; anything else is rejected with 422 Unprocessable Content. This endpoint returns a bare Rails errors.details hash — no message text and no errors/request_id envelope:
An unrecognised country always reports "error": "inclusion" (the value you sent is echoed back in "value"); build any user-facing message client-side from that code rather than relying on server text.
This is a deliberate deviation from the standard ErrorEnvelope shape used by the rest of the API.
An empty string ("") normalizes to null, clearing the country.
Partial address updates merge — omit keys you don't change
address updates merge into the existing address rather than replacing it wholesale. Send only the keys you intend to change; omit the rest. Do not send "" for a field you want to leave untouched — for most address fields (unlike country) an empty string is written literally and blanks that field. To update just the city, for example, send { "organization": { "address": { "city": "Hamburg" } } } with no other address keys.
Invoices¶
The platform generates two invoice representations:
Internal invoices (/invoices) reflect the platform's usage metering:
Fields: period, total (Money object: {cents, currency_iso}), and items (array of line items with product, project, unit price, and unit).
EasyBill invoices (/organizations/{id}/invoices) are the legally binding invoices delivered via the EasyBill integration. Download a PDF:
Returns application/pdf.
Payment methods¶
Payment methods are Stripe payment instruments attached to an organization.
Payment method fields:
| Field | Description |
|---|---|
id | Internal UUID |
payment_type | card, sepa_debit, etc. |
default | Whether this is the default payment method |
brand | Card brand (e.g. visa); null for non-card methods |
last4 | Last four digits of the card number |
exp_month / exp_year | Card expiry |
iban | IBAN (SEPA debit only) |
Attach a payment method¶
Use the Stripe.js PaymentElement in the dashboard to collect card details and generate a Stripe paymentMethodId, then attach it:
POST /organizations/{id}/payment_methods/create_and_attach
Authorization: Bearer <token>
Content-Type: application/json
{ "payment_method_id": "pm_..." }
Create a Stripe payment intent (for setup flow)¶
Returns { "client_secret": "seti_...secret_..." } for use with Stripe.js confirmSetup.
Authorization¶
Billing read operations require the billing:read permission. Update operations (setting default, removing a payment method) require billing:update. See RBAC Presets for which roles carry these permissions.