API Reference
API Reference
The full interactive API reference is hosted alongside the NovaBilling API server.
Base URL
http://localhost:3000/api
Webhooks are received at:
http://localhost:3000/api/webhooks/{provider}
Authentication
All API endpoints require authentication. NovaBilling uses two authentication methods:
| Method | Header | Used For |
|---|---|---|
| JWT Bearer | Authorization: Bearer <jwt_token> | Tenant management (/auth/*, /tenants/*) |
| API Key | Authorization: Bearer sk_live_... | Data operations (/customers/*, /plans/*, etc.) |
See Authentication for details on obtaining tokens and API keys.
Response Format
All successful responses return JSON. List endpoints include pagination metadata:
{
"data": [...],
"meta": {
"total": 150,
"page": 1,
"limit": 20,
"totalPages": 8
}
}
Rate Limiting
All endpoints are rate-limited to 100 requests per minute per tenant. Exceeding this returns a 429 Too Many Requests response.
Auth
Public endpoints for tenant registration, login, and password management.
| Method | Endpoint | Description |
|---|---|---|
POST | /auth/register | Register a new tenant — provisions isolated database, generates API key, returns JWT tokens |
POST | /auth/login | Login with email and password — returns access and refresh tokens |
POST | /auth/refresh | Exchange a refresh token for a new access/refresh token pair |
POST | /auth/forgot-password | Request a password reset email (always returns success to prevent enumeration) |
POST | /auth/reset-password | Set a new password using the reset token received via email |
Register
curl -X POST http://localhost:3000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@company.com",
"password": "securePassword123",
"companyName": "Acme Corp"
}'
Login
curl -X POST http://localhost:3000/api/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "john@company.com", "password": "securePassword123" }'
Tenants
Manage your tenant profile, API keys, SMTP settings, and usage statistics. Authenticated via JWT.
| Method | Endpoint | Description |
|---|---|---|
GET | /tenants/me | Get current tenant info |
PATCH | /tenants/me | Update tenant profile and settings |
GET | /tenants/me/usage | Get tenant usage statistics |
POST | /tenants/me/api-keys | Generate a new API key |
GET | /tenants/me/api-keys | List all API keys |
DELETE | /tenants/me/api-keys/:id | Revoke an API key |
POST | /tenants/me/smtp/test | Test SMTP configuration with a test email |
Customers
CRUD operations for customers plus relationship queries for their subscriptions, invoices, and payments.
| Method | Endpoint | Description |
|---|---|---|
GET | /customers | List customers (paginated, searchable) |
GET | /customers/:id | Get customer by ID |
POST | /customers | Create a new customer |
PATCH | /customers/:id | Update a customer |
DELETE | /customers/:id | Delete a customer (fails if active subscriptions exist) |
GET | /customers/:id/subscriptions | List customer's subscriptions |
GET | /customers/:id/invoices | List customer's invoices |
GET | /customers/:id/payments | List customer's payments |
Create Customer
curl -X POST http://localhost:3000/api/customers \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"externalId": "cust_123",
"name": "Jane Smith",
"email": "jane@example.com",
"country": "US",
"currency": "USD"
}'
const customer = await client.customers.create({
externalId: "cust_123",
name: "Jane Smith",
email: "jane@example.com",
country: "US",
currency: "USD",
});
customer = client.customers.create(
external_id="cust_123",
name="Jane Smith",
email="jane@example.com",
country="US",
currency="USD",
)
Plans
Manage billing plans with pricing, features, and billing configuration.
| Method | Endpoint | Description |
|---|---|---|
GET | /plans | List all plans |
GET | /plans/:id | Get plan by ID |
POST | /plans | Create a new plan |
PATCH | /plans/:id | Update a plan |
DELETE | /plans/:id | Delete a plan |
POST | /plans/:id/prices | Add a price to a plan |
PATCH | /plans/:id/prices/:priceId | Update a plan price |
DELETE | /plans/:id/prices/:priceId | Delete a plan price |
Create Plan
curl -X POST http://localhost:3000/api/plans \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Plan",
"code": "pro",
"description": "For growing teams",
"billingInterval": "MONTHLY",
"features": ["Unlimited users", "Priority support"],
"prices": [{ "currency": "USD", "amount": 49.99 }]
}'
const plan = await client.plans.create({
name: "Pro Plan",
code: "pro",
billingInterval: "MONTHLY",
prices: [{ currency: "USD", amount: 49.99 }],
});
plan = client.plans.create(
name="Pro Plan",
code="pro",
billing_interval="MONTHLY",
prices=[{"currency": "USD", "amount": 49.99}],
)
Subscriptions
Create and manage customer subscriptions with support for cancellation, pausing, resuming, and mid-cycle plan changes with proration.
| Method | Endpoint | Description |
|---|---|---|
GET | /subscriptions | List subscriptions (filterable by status, planId) |
GET | /subscriptions/:id | Get subscription by ID |
POST | /subscriptions | Create a new subscription |
PATCH | /subscriptions/:id | Update subscription metadata |
POST | /subscriptions/:id/cancel | Cancel (immediate or end-of-period) |
POST | /subscriptions/:id/pause | Pause a subscription |
POST | /subscriptions/:id/resume | Resume a paused subscription |
POST | /subscriptions/:id/change-plan | Change plan (with proration) |
Cancel Subscription
# Immediate cancellation (issues pro-rated credit note)
curl -X POST http://localhost:3000/api/subscriptions/:id/cancel \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "cancelAt": "now" }'
# Cancel at period end
curl -X POST http://localhost:3000/api/subscriptions/:id/cancel \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "cancelAt": "period_end" }'
Invoices
Full invoice lifecycle: create, finalize, void, mark paid, generate checkout URLs, send emails, and download PDFs.
| Method | Endpoint | Description |
|---|---|---|
GET | /invoices | List invoices (filterable by status) |
GET | /invoices/:id | Get invoice by ID |
POST | /invoices | Create a new invoice |
POST | /invoices/:id/finalize | Finalize a draft invoice |
POST | /invoices/:id/void | Void an invoice |
POST | /invoices/:id/mark-paid | Manually mark invoice as paid |
POST | /invoices/:id/checkout | Generate a payment checkout URL |
POST | /invoices/:id/send-email | Send invoice to customer via email |
GET | /invoices/:id/pdf | Download invoice as PDF |
Payments
View payment history and process refunds.
| Method | Endpoint | Description |
|---|---|---|
GET | /payments | List payments (filterable by status, provider) |
GET | /payments/:id | Get payment by ID |
POST | /payments/:id/refund | Refund a payment (full or partial) |
Refund Payment
curl -X POST http://localhost:3000/api/payments/:id/refund \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "amount": 25.00, "reason": "Customer request" }'
Payment Providers
Configure and manage payment provider integrations (Stripe, Paystack, Flutterwave, M-Pesa).
| Method | Endpoint | Description |
|---|---|---|
GET | /payment-providers | List configured providers |
GET | /payment-providers/:id | Get provider by ID |
POST | /payment-providers | Configure a new provider |
PATCH | /payment-providers/:id | Update provider settings |
DELETE | /payment-providers/:id | Remove a provider |
POST | /payment-providers/:id/test | Test provider connection |
Billable Metrics
Define event-based usage metrics for usage-based billing.
| Method | Endpoint | Description |
|---|---|---|
GET | /billable-metrics | List all billable metrics |
GET | /billable-metrics/:id | Get metric by ID |
POST | /billable-metrics | Create a billable metric |
PATCH | /billable-metrics/:id | Update a billable metric |
DELETE | /billable-metrics/:id | Delete a billable metric |
Aggregation Types: COUNT, SUM, MAX, UNIQUE_COUNT, LATEST, WEIGHTED_SUM
Create Billable Metric
curl -X POST http://localhost:3000/api/billable-metrics \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "API Calls",
"code": "api_calls",
"aggregationType": "COUNT",
"recurring": false,
"filters": [
{ "key": "region", "values": ["us-east", "us-west", "eu"] }
]
}'
Usage Events
Ingest usage events for metered billing. Supports single and batch ingestion with idempotency.
| Method | Endpoint | Description |
|---|---|---|
POST | /events | Ingest a single usage event |
POST | /events/batch | Ingest a batch of usage events |
GET | /events/:id | Get event by ID |
GET | /events/subscription/:subscriptionId | List events for a subscription |
Ingest Event
curl -X POST http://localhost:3000/api/events \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"transactionId": "txn_unique_123",
"subscriptionId": "sub_abc",
"code": "api_calls",
"timestamp": "2026-02-12T10:00:00Z",
"properties": { "region": "us-east", "bytes": 1024 }
}'
Charges
Define pricing models attached to plans and billable metrics.
| Method | Endpoint | Description |
|---|---|---|
GET | /charges | List all charges |
GET | /charges/:id | Get charge by ID |
GET | /charges/plan/:planId | List charges for a specific plan |
POST | /charges | Create a charge |
PATCH | /charges/:id | Update a charge |
DELETE | /charges/:id | Delete a charge |
Charge Models: STANDARD, GRADUATED, VOLUME, PACKAGE, PERCENTAGE
Create Graduated Charge
curl -X POST http://localhost:3000/api/charges \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"planId": "plan_abc",
"billableMetricId": "bm_api_calls",
"chargeModel": "GRADUATED",
"billingTiming": "IN_ARREARS",
"graduatedRanges": [
{ "fromValue": 0, "toValue": 1000, "perUnitAmount": 0, "flatAmount": 0 },
{ "fromValue": 1001, "toValue": 10000, "perUnitAmount": 0.01, "flatAmount": 0 },
{ "fromValue": 10001, "perUnitAmount": 0.005, "flatAmount": 0 }
]
}'
Coupons
Create and manage discount coupons that can be applied to customers or subscriptions.
| Method | Endpoint | Description |
|---|---|---|
GET | /coupons | List coupons (filterable by isActive) |
GET | /coupons/:id | Get coupon by ID |
POST | /coupons | Create a coupon |
PATCH | /coupons/:id | Update a coupon |
DELETE | /coupons/:id | Delete a coupon |
POST | /coupons/apply | Apply coupon to a customer |
DELETE | /coupons/applied/:id | Remove an applied coupon |
Add-Ons
One-time or recurring add-on charges that can be applied to customer subscriptions.
| Method | Endpoint | Description |
|---|---|---|
GET | /add-ons | List add-ons |
GET | /add-ons/:id | Get add-on by ID |
POST | /add-ons | Create an add-on |
PATCH | /add-ons/:id | Update an add-on |
DELETE | /add-ons/:id | Delete an add-on |
POST | /add-ons/apply | Apply add-on to a customer |
GET | /add-ons/applied/list | List applied add-ons |
DELETE | /add-ons/applied/:id | Remove an applied add-on |
Credit Notes
Issue credit notes against invoices for refunds, adjustments, or order changes.
| Method | Endpoint | Description |
|---|---|---|
GET | /credit-notes | List credit notes (filterable by customerId, invoiceId, status) |
GET | /credit-notes/:id | Get credit note by ID |
POST | /credit-notes | Create a credit note |
PATCH | /credit-notes/:id | Update a draft credit note |
POST | /credit-notes/:id/finalize | Finalize a credit note |
POST | /credit-notes/:id/void | Void a credit note |
Reasons: DUPLICATE, PRODUCT_UNSATISFACTORY, ORDER_CHANGE, OTHER
Wallets / Prepaid Credits
Manage customer prepaid credit wallets with top-ups, voiding, and automatic invoice deduction.
| Method | Endpoint | Description |
|---|---|---|
POST | /wallets | Create a wallet for a customer |
GET | /wallets | List wallets (filterable by customerId, status) |
GET | /wallets/:id | Get wallet by ID |
PATCH | /wallets/:id | Update wallet (name, expiration) |
DELETE | /wallets/:id | Terminate a wallet (voids remaining credits) |
POST | /wallets/transactions | Top up or void credits |
GET | /wallets/:id/transactions | List wallet transactions |
Create Wallet
curl -X POST http://localhost:3000/api/wallets \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"customerId": "cust_abc",
"name": "Main Wallet",
"currency": "USD",
"rateAmount": 1.0,
"paidCredits": 100,
"grantedCredits": 10,
"expirationAt": "2027-01-01T00:00:00Z"
}'
Top Up Credits
curl -X POST http://localhost:3000/api/wallets/transactions \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"walletId": "wallet_abc",
"paidCredits": 50,
"grantedCredits": 5
}'
Analytics
Revenue, subscription, customer, and payment analytics with optional date range filtering.
| Method | Endpoint | Description |
|---|---|---|
GET | /analytics/revenue | Revenue analytics (totalRevenue, MRR) |
GET | /analytics/subscriptions | Subscription breakdown (active, canceled, etc.) |
GET | /analytics/customers | Customer analytics (total, new, churned) |
GET | /analytics/payments | Payment analytics (success rate, volume) |
All analytics endpoints accept optional dateFrom and dateTo query parameters for date-range filtering.
Customer Portal
Public-facing endpoints for customer self-service billing (authenticated via API key).
| Method | Endpoint | Description |
|---|---|---|
GET | /portal/customers/:externalId/billing | Customer billing overview |
GET | /portal/customers/:externalId/subscriptions | List customer subscriptions |
GET | /portal/customers/:externalId/invoices | List customer invoices |
POST | /portal/customers/:externalId/invoices/:invoiceId/checkout | Create checkout for an invoice |
GET | /portal/customers/:externalId/payments | List customer payments |
Webhooks (Inbound)
Endpoints that receive payment provider webhook notifications. These are public and use provider-specific signature verification.
| Method | Endpoint | Description |
|---|---|---|
POST | /webhooks/stripe | Stripe webhook receiver |
POST | /webhooks/paystack | Paystack webhook receiver |
POST | /webhooks/flutterwave | Flutterwave webhook receiver |
POST | /webhooks/mpesa | M-Pesa webhook receiver |
OpenAPI Spec
The raw OpenAPI 3.0 specification is available at:
GET http://localhost:3000/api/openapi.json