> For the complete documentation index, see [llms.txt](https://docs.oomus.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.oomus.org/api-reference/billing.md).

# Billing

Billing endpoints, accounting ledger, modules, and plan management.

**Base URL:** `https://api.oomus.health` **Authentication:** All endpoints require `Authorization: Bearer <TOKEN>`

***

## GET /billing/balance

Returns the balance, plan, and quotas of the authenticated account.

**200 OK response:**

```json
{
  "account_id": "prog_01HXYZ123",
  "plan": "regional_ops",
  "plan_display_name": "Regional Command",
  "balance_fcfa": 45000,
  "monthly_subscription_fcfa": 75000,
  "quota": {
    "identities_total": 100000,
    "identities_used": 23450,
    "identities_remaining": 76550,
    "sms_total": 250000,
    "sms_used": 12300,
    "sms_remaining": 237700,
    "whatsapp_total": 100000,
    "whatsapp_used": 4500,
    "whatsapp_remaining": 95500,
    "verifications_total": 50000,
    "storage_gb_total": 50
  },
  "quota_reset_date": "2026-06-01T00:00:00Z",
  "currency": "XOF"
}
```

| Field                       | Type    | Description                                   |
| --------------------------- | ------- | --------------------------------------------- |
| `balance_fcfa`              | integer | Available credit                              |
| `quota.identities_total`    | integer | Monthly quota (Studio + DHIS2 cards combined) |
| `quota.sms_total`           | integer | Monthly SMS quota                             |
| `quota.whatsapp_total`      | integer | Monthly WhatsApp quota                        |
| `quota.verifications_total` | integer | Monthly verification quota                    |

***

## GET /billing/transactions

Returns the account transaction history.

**Query parameters:**

| Parameter | Type    | Description                     |
| --------- | ------- | ------------------------------- |
| `limit`   | integer | Number of results (default: 50) |
| `offset`  | integer | Offset for pagination           |

**200 OK response:**

```json
[
  {
    "id": "txn_01HXYZ111",
    "tx_type": "debit",
    "amount": -16000,
    "description": "Generation of 2000 cards — DKR-VAC campaign (1800 billed @ 8 FCFA, 200 within the quota)",
    "card_count": 2000,
    "reference": "JOB:job_01|INV:a3f4c2...",
    "created_at": "2026-05-14T14:30:00Z"
  }
]
```

***

## GET /billing/ledger

Complete accounting ledger — all transactions with their associated invoices and audit flag.

**Query parameters:**

| Parameter | Type    | Description                     |
| --------- | ------- | ------------------------------- |
| `limit`   | integer | Number of entries (default: 50) |
| `offset`  | integer | Offset for pagination           |
| `tx_type` | string  | Filter by transaction type      |

**200 OK response:**

```json
{
  "programme_id": "prog_01HXYZ",
  "total_entries": 12,
  "debits_with_invoice": 10,
  "debits_without_invoice": 2,
  "entries": [
    {
      "id": "txn_01HXYZ111",
      "description": "PVC order 100 Standard cards",
      "amount": -35000,
      "tx_type": "debit",
      "is_debit": true,
      "invoice_id": "a3f4c2d1-...",
      "audited": true,
      "invoice": {
        "invoice_number": "INV-PVC-202605-AB1234",
        "status": "paid",
        "total_fcfa": 35000,
        "issued_at": "2026-05-14T14:30:00Z",
        "invoice_type": "pvc_order",
        "signature_hash": "sha256:abc123..."
      },
      "created_at": "2026-05-14T14:30:00Z"
    }
  ]
}
```

| Field                    | Type    | Description                                            |
| ------------------------ | ------- | ------------------------------------------------------ |
| `debits_with_invoice`    | integer | Debits linked to a formal invoice                      |
| `debits_without_invoice` | integer | Debits without invoice (credits, top-ups)              |
| `audited`                | boolean | `true` if an invoice is associated or if it's a credit |
| `invoice.signature_hash` | string  | SHA-256 of invoice integrity                           |

***

## GET /billing/my-usage

Actual monthly usage (identities, SMS, WhatsApp) from records `EngineUsageRecord`.

**200 OK response:**

```json
{
  "period": "2026-05",
  "identities_used": 23450,
  "studio_cards": 18200,
  "dhis2_cards": 5250,
  "sms_sent": 12300,
  "whatsapp_sent": 4500,
  "storage_gb_used": 3.2
}
```

***

## GET /billing/my-modules

Active program modules — merge of modules included in the plan and manually activated modules.

**200 OK response:**

```json
[
  {
    "key": "sms_gateway",
    "label": "Omnichannel SMS Distribution",
    "included_in_plan": true,
    "plan": "regional_ops",
    "monthly_cost": 0,
    "is_active": true
  },
  {
    "key": "ai_fraud_detection",
    "label": "Anomaly Detection & Compliance",
    "included_in_plan": false,
    "monthly_cost": 60000,
    "is_active": true,
    "activated_at": "2026-04-01T00:00:00Z"
  }
]
```

| Field              | Type    | Description                                                                           |
| ------------------ | ------- | ------------------------------------------------------------------------------------- |
| `included_in_plan` | boolean | `true` if the module is included in the subscription, `false` if purchased separately |
| `monthly_cost`     | integer | 0 if included in the plan, otherwise monthly cost in FCFA                             |

***

## GET /billing/my-quota

Detailed monthly quotas (cards, SMS, WhatsApp).

***

## GET /billing/quota-plans

Available plans with quotas and pricing. Returns the 4 active plans.

**200 OK response:**

```json
[
  {
    "plan": "starter",
    "display_name": "Essential",
    "monthly_subscription_fcfa": 25000,
    "studio_print_quota": 10000,
    "sms_quota": 50000,
    "whatsapp_quota": 10000,
    "verifications_quota": 5000,
    "storage_gb": 10
  },
  {
    "plan": "regional_ops",
    "display_name": "Regional Command",
    "monthly_subscription_fcfa": 75000,
    "studio_print_quota": 100000,
    "sms_quota": 250000,
    "whatsapp_quota": 100000,
    "verifications_quota": 50000,
    "storage_gb": 50
  },
  {
    "plan": "national_campaign",
    "display_name": "National Infrastructure",
    "monthly_subscription_fcfa": 250000,
    "studio_print_quota": 1000000,
    "sms_quota": 3000000,
    "whatsapp_quota": 1000000,
    "verifications_quota": 500000,
    "storage_gb": 500
  },
  {
    "plan": "sovereign_enterprise",
    "display_name": "Sovereign Cloud",
    "monthly_subscription_fcfa": 750000,
    "studio_print_quota": -1,
    "sms_quota": -1,
    "whatsapp_quota": -1,
    "verifications_quota": -1,
    "storage_gb": -1
  }
]
```

> `-1` means unlimited. Admin-configurable prices via `PUT /billing/quota-plans/{plan}`.

***

## PUT /billing/quota-plans/{plan}

\[Admin] Configure a plan's quotas and prices. Effective immediately for all new operations.

**Request body:**

```json
{
  "monthly_subscription_fcfa": 75000,
  "studio_print_quota": 100000,
  "sp_price_per_card": 10,
  "sp_dhis2_price": 10,
  "sp_quality_surcharge": 3
}
```

***

## POST /billing/change-plan

Changes the account plan. Charges the full monthly price of the target plan, automatically activates included modules, generates a signed invoice.

**Request body:**

```json
{ "plan_alias": "national_campaign" }
```

**200 OK response:**

```json
{
  "previous_plan": "regional_ops",
  "new_plan": "national_campaign",
  "effective_date": "2026-05-15T10:00:00Z",
  "modules_activated": ["ai_fraud_detection", "sovereign_wallet", "mpi_registry"],
  "invoice_number": "INV-SUB-202605-XY1234"
}
```

***

## GET /billing/premium-modules

Catalog of all available premium modules.

***

## GET /billing/premium-modules/active

Modules activated for the current program (plan + manual add-ons).

***

## POST /billing/premium-modules/activate

Activates a premium module. Automatically generates a debit + a formal invoice.

**Request body:**

```json
{ "module_key": "advanced_analytics" }
```

**Errors:**

| Code  | Description           |
| ----- | --------------------- |
| `400` | Unknown module        |
| `402` | Insufficient balance  |
| `409` | Module already active |

***

## GET /billing/engine-usage

Usage by engine (Studio Print vs Campaign Delivery).

***

## GET /billing/v2/invoices

List of formal invoices issued for the program.

**200 OK response:**

```json
[
  {
    "id": "inv_01HXYZ",
    "invoice_number": "INV-GEN-202605-AB1234",
    "invoice_type": "generation",
    "status": "paid",
    "total_fcfa": 16000,
    "issued_at": "2026-05-14T14:30:00Z",
    "signature_hash": "sha256:abc123..."
  }
]
```

Invoice types: `subscription` · `module_activation` · `pvc_order` · `generation` · `platform_creation`

***

## GET /billing/v2/invoices/{id}/pdf

Downloads the PDF of a formal invoice (authenticated). Returns `application/pdf`.

***

## Next steps

* [Plans & Features](/getting-started/plans-and-pricing.md) — Plan comparison
* [Authentication](/api-reference/authentication.md) — Token management
* [Campaigns & Jobs](/api-reference/campaigns-and-jobs.md) — Use your quota


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.oomus.org/api-reference/billing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
