# Billing
Subscription, invoices and usage. Read only.
**Common tasks**
- [The current subscription](#get-organizations-organization-subscription)
**Only in the app:** Changing the plan, payment methods and invoices details.
**How it works in the app:** [help article](https://infranest.io/docs/subscription).
**Scopes:** Read with `billing.read`. See [Tokens and scopes](../tokens-and-scopes.md#scopes).
[Account credit](#account-credit) 1 · [Credit notes](#credit-notes) 1 · [Invoices](#invoices) 1 · [Referrals](#referrals) 1 · [Subscription](#subscription) 2
Every endpoint below takes a token in the `Authorization: Bearer` header and answers JSON. Errors use the shared format in [Errors](../errors.md). Base address: `https://api.infranest.io/api`.
## Account credit
### Get account credit {#get-organizations-organization-account-credit}
`GET` `/organizations/{organization}/account-credit`
**Scope:** `billing.read` · **Changes data:** no
Money InfraNest holds for you — for example after a downgrade or a refund — which comes off your next invoice. One balance per currency, in the currency’s smallest unit; empty when you have none. Read-only.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/account-credit" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
{
"credit": []
}
```
## Credit notes
### List credit notes {#get-organizations-organization-credit-notes}
`GET` `/organizations/{organization}/credit-notes`
**Scope:** `billing.read` · **Changes data:** no
Credit notes issued against your invoices, with the invoice each one credits, its amounts (negative, in the currency’s smallest unit), how it was settled and a PDF link. Read-only.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/credit-notes" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
[]
```
## Invoices
### List invoices {#get-organizations-organization-invoices}
`GET` `/organizations/{organization}/invoices`
**Scope:** `billing.read` · **Changes data:** no
Your most recent 100 invoices, newest first, with their status, totals, billing period and links to view or download each one. Read-only.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/invoices" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
[
{
"id": 6,
"number": "INF-2026-0100",
"status": "paid",
"currency": "eur",
"total": 4719,
"tax": 819,
"paid_at": "2026-01-02T00:00:00.000000Z",
"hosted_invoice_url": null,
"invoice_pdf": null,
"period_start": "2026-01-01T00:00:00.000000Z",
"period_end": "2026-01-31T23:59:59.000000Z",
"created_at": "2026-01-01T00:00:00.000000Z"
},
{
"id": 5,
"number": "INF-2025-0101",
"status": "paid",
"currency": "eur",
"total": 4719,
"tax": 819,
"paid_at": "2025-12-02T00:00:00.000000Z",
"hosted_invoice_url": null,
"invoice_pdf": null,
"period_start": "2025-12-01T00:00:00.000000Z",
"period_end": "2025-12-31T23:59:59.000000Z",
"created_at": "2025-12-01T00:00:00.000000Z"
}
]
```
## Referrals
### Get your referrals {#get-organizations-organization-referrals}
`GET` `/organizations/{organization}/referrals`
**Scope:** `billing.read` · **Changes data:** no
Your referral link, what it has earned and how much discount is left, and the workspaces that signed up with it — names partly hidden, with where each referral has got to. `enabled` is false when the referral programme is switched off. Read-only.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/referrals" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
{
"enabled": true,
"code": "northwind-cloud",
"link": "http://localhost/r/northwind-cloud",
"can_change": true,
"currency": "eur",
"stats": {
"signed_up": 5,
"paying": 3,
"rewards_this_year": 2,
"max_rewards_per_year": 12,
"earned": 12800,
"on_its_way": 1,
"remaining": 7000
},
"referrals": [
{
"id": 4,
"name": "Ve•••• Labs",
"joined_at": "2026-01-11T12:00:00+00:00",
"status": "pending",
"void_reason": null,
"credited_from": null,
"reward_amount": null,
"reward_currency": null,
"reward_remaining": null
},
{
"id": 3,
"name": "Ha•••• IT",
"joined_at": "2025-12-26T12:00:00+00:00",
"status": "qualifying",
"void_reason": null,
"credited_from": "2026-01-28T12:00:00+00:00",
"reward_amount": null,
"reward_currency": null,
"reward_remaining": null
}
]
}
```
## Subscription
### Get the subscription {#get-organizations-organization-subscription}
`GET` `/organizations/{organization}/subscription`
**Scope:** `billing.read` · **Changes data:** no
The organization’s subscription and plan, the plan whose limits currently apply, whether a free trial is still available and any discount in force. Read-only; returns 404 when there is no subscription.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/subscription" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
{
"id": 1,
"organization_id": 1,
"plan_id": 2,
"status": "active",
"provider": "stripe",
"provider_subscription_id": "sub_demo_northwind",
"trial_ends_at": null,
"current_period_start": "2026-01-01T00:00:00.000000Z",
"current_period_end": "2026-02-15T12:00:00.000000Z",
"canceled_at": null,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"cancel_at_period_end": false,
"stripe_price_id": null,
"currency": "eur",
"trial_reminder_sent_at": null,
"renewal_reminder_sent_at": null,
"card_expiry_reminder_sent_at": null,
"addons": [],
"card_on_file": false,
"trial_recap_sent_at": null,
"trial_last_call_sent_at": null,
"trial_first_steps_sent_at": null,
"trial_ended_at": null,
"trial_reactivation_sent_at": null,
"recap_period_start": null,
"renewal_recap_sent_for": null,
"discount_code": null,
"discount_percent": null,
"discount_amount_off": null,
"discount_duration": null,
"discount_starts_at": null,
"discount_ends_at": null,
"discount_label": null,
"plan": {
"id": 2,
"name": "Pro",
"slug": "pro",
"description": "For freelancers & solo devs — faster checks, cloud, API and automations.",
"limits": {
"api": true,
"rate": {
"manual_sync_per_hour": 30,
"domain_checks_per_hour": 100,
"monitor_checks_per_hour": 120,
"provider_api_per_minute": 300
},
"cloud": true,
"api.mcp": true,
"domains": 100,
"servers": 10,
"api.read": true,
"monitors": 50,
"webhooks": true,
"api.write": true,
"dns.drift": true,
"dns_zones": 100,
"drop_catch": true,
"automations": 25,
"data_import": true,
"dynamic_ips": 10,
"certificates": 100,
"status_pages": 3,
"team_members": 3,
"cloud.backups": true,
"cloud.volumes": true,
"dns.templates": true,
"organizations": 1,
"api.tokens_max": 5,
"cloud.firewalls": true,
"cloud.snapshots": true,
"watched_domains": 50,
"cloud.volumes_max": 10,
"external_monitors": 5,
"dropcatch.register": true,
"cloud.firewalls_max": 5,
"audit.retention_days": 30,
"domains.registration": true,
"monitor_min_interval": 60,
"monitoring.incidents": true,
"monitoring.maintenance": true,
"cloud.load_balancers_max": 0,
"monitoring.calendar_feed": true,
"monitoring.retention_days": 90,
"status_page_custom_domain": true,
"dns.history_retention_days": 90,
"automations.premium_actions": true,
"integrations.connections_max": 5
},
"price_monthly": 2250,
"price_yearly": 22800,
"active": true,
"created_at": "2026-01-15T12:00:00.000000Z",
"updated_at": "2026-01-15T12:00:00.000000Z",
"is_public": true,
"sort_order": 2,
"stripe_product_id": null,
"stripe_prices": null,
"prices": {
"eur": {
"yearly": 22800,
"monthly": 2250
}
},
"trial_days": 0,
"recommended": false,
"name_i18n": null,
"description_i18n": null,
"badge": null,
"tagline_i18n": {
"de": "Freelancer & Solo-Entwickler",
"en": "Freelancers & solo devs",
"fr": "Freelances & développeurs solo",
"nl": "Freelancers & solo-ontwikkelaars"
},
"highlights_i18n": {
"de": [
"Alles in Free",
"100 Domains"
],
"en": [
"Everything in Free",
"100 domains"
],
"fr": [
"Tout dans Free",
"100 domaines"
],
"nl": [
"Alles in Free",
"100 domeinen"
]
},
"contact_sales": false,
"contact_url": null
},
"effective_plan_id": 2,
"effective_plan_slug": "pro",
"trial_available": true,
"referral_welcome": null,
"suggested_promotion_code": null,
"discount": null
}
```
---
### List add-ons {#get-organizations-organization-subscription-addons}
`GET` `/organizations/{organization}/subscription/addons`
**Scope:** `billing.read` · **Changes data:** no
The add-ons on offer with their prices, each marked `owned` when the organization already has it. Read-only.
| Field | Type | Notes |
|---|---|---|
| `organization_id`
path · required | integer | Your organization's ID. |
**Errors:** [`unauthenticated`](../errors.md#unauthenticated), [`scope_missing`](../errors.md#scope_missing), [`wrong_organization`](../errors.md#wrong_organization), [`test_token_required`](../errors.md#test_token_required), [`test_token_sandbox_only`](../errors.md#test_token_sandbox_only), [`permission_denied`](../errors.md#permission_denied), [`not_found`](../errors.md#not_found), [`rate_limited`](../errors.md#rate_limited)
**Request**
```sh
curl "https://api.infranest.io/api/organizations/42/subscription/addons" \
-H "Authorization: Bearer $INFRANEST_TOKEN" \
-H "Accept: application/json"
```
**Response** · 200
```json
[]
```