Billing
The billing API lets you manage subscription plans, view invoices, track voucher usage, and handle payments. Payments are processed through Stripe. All endpoints require authentication and access to the specified client account.
Endpoints
| Method |
Endpoint |
Description |
| GET |
/billing/status |
Get billing status |
| GET |
/billing/usage |
Get voucher usage data |
| GET |
/billing/items |
List available plans and add-ons |
| GET |
/billing/orders |
Get current plan selection |
| PUT |
/billing/orders |
Update plan selection |
| GET |
/billing/documents |
List billing documents |
| GET |
/billing/documents/{id} |
Get a billing document |
| GET |
/billing/documents/{id}/pdf |
Download document PDF |
| POST |
/billing/documents/{id}/pay |
Pay a single document |
| POST |
/billing/pay |
Pay multiple documents |
| GET |
/billing/payment-methods |
List payment methods |
| POST |
/billing/payment-methods/setup |
Add a payment method |
| POST |
/billing/payment-methods/{id}/default |
Set default payment method |
| DELETE |
/billing/payment-methods/{id} |
Remove a payment method |
Status & Usage
Get Billing Status
GET /api/v2/billing/status
Returns the current billing status for a client account, including plan limits and payment method availability.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
{
"has_payment_method": true,
"status": "ACTIVE",
"can_process": true,
"vouchers_used": 45,
"vouchers_included": 100,
"over_limit": false
}
Status Values
| Value |
Description |
ACTIVE |
Account is active and can process normally |
NO_PLAN |
No billing plan selected |
OVER_USAGE |
Voucher usage exceeds plan limit |
PAYMENT_OVERDUE |
Outstanding payment is overdue |
Get Voucher Usage
GET /api/v2/billing/usage
Returns voucher usage counts over a time period, useful for charting and analytics.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
| granularity |
string |
No |
daily (default) or monthly |
| from_date |
date |
No |
Start date (ISO format). Defaults to first day of current month for daily, or 11 months ago for monthly |
| to_date |
date |
No |
End date (ISO format). Defaults to today |
Response
{
"from_date": "2026-04-01",
"to_date": "2026-04-30",
"total": 145,
"vouchers_included": 200,
"data": [
{
"period": "2026-04-01",
"count": 5
},
{
"period": "2026-04-02",
"count": 3
}
]
}
The vouchers_included field is null if the account has no active plan.
Error Responses
| Status |
Description |
| 400 |
Invalid granularity value, or from_date is after to_date |
| 403 |
No access to the client account |
Plans & Orders
List Available Items
GET /api/v2/billing/items
Returns all available billing items (plans and add-ons) for a client account.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Returns an array of item objects, each including a billing_metadata field with plan/add-on details.
Get Current Orders
GET /api/v2/billing/orders
Returns the currently selected plans and add-ons for a client account.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Returns an array of item collection entry objects, each containing item details with billing_metadata.
Update Orders
PUT /api/v2/billing/orders
Sets the billing plan and add-ons for a client account. Replaces the current selection.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Request Body
A single object or an array of objects:
| Field |
Type |
Required |
Description |
| item_id |
integer |
Yes |
The ID of the billing item |
| quantity |
integer |
No |
Quantity (defaults to 1) |
Example Request
[
{ "item_id": 10, "quantity": 1 },
{ "item_id": 15, "quantity": 2 }
]
Response
Returns the updated item collection entries with status 201 Created.
Error Responses
| Status |
Description |
| 400 |
Missing request body, invalid item ID, or item has no price defined |
| 403 |
No access to the client account |
Billing Documents
List Documents
GET /api/v2/billing/documents
Returns a paginated list of billing documents (invoices and credit notes).
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
| document_type |
string |
No |
Filter by type: ARInvoice, ARCreditNote |
| status |
string |
No |
Filter by status: OPEN, PAID, PART PAID |
| from_date |
date |
No |
Filter documents from this date |
| to_date |
date |
No |
Filter documents up to this date |
| page |
integer |
No |
Page number (default: 1) |
| per_page |
integer |
No |
Items per page (default: 50) |
Response
{
"data": [
{
"id": 42,
"document_type": "ARInvoice",
"document_number": "SB-2026-0042",
"document_date": "2026-04-01",
"due_date": "2026-04-15",
"document_status": "COMPLETED",
"payment_status": "OPEN",
"gross_total": 1250.00,
"open_amount": 1250.00,
"currency_code": "NOK",
"pdf_url": "https://..."
}
],
"meta": {
"page": 1,
"pages": 3,
"per_page": 50,
"records": 125
}
}
The pdf_url field is null if no PDF is available for the document.
Get Document
GET /api/v2/billing/documents/{id}
Returns a single billing document.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Returns a single document object (same shape as the list response items).
Error Responses
| Status |
Description |
| 403 |
No access to the client account |
| 404 |
Document not found |
Download Document PDF
GET /api/v2/billing/documents/{id}/pdf
Redirects to a presigned URL for downloading the document PDF.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Returns a 302 Found redirect to the presigned S3 download URL.
Error Responses
| Status |
Description |
| 403 |
No access to the client account |
| 404 |
Document not found or PDF not available |
Pay a Document
POST /api/v2/billing/documents/{id}/pay
Initiates payment for a single billing document. If a saved payment method exists, the charge is processed directly. Otherwise, a Stripe checkout URL is returned for redirect.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Request Body
| Field |
Type |
Required |
Description |
| success_url |
string |
Yes |
URL to redirect to after successful payment |
| cancel_url |
string |
Yes |
URL to redirect to if payment is cancelled |
Example Request
{
"success_url": "https://app.snapbooks.no/billing/success",
"cancel_url": "https://app.snapbooks.no/billing"
}
Response (Direct Charge)
{
"status": "processing",
"payment_request_id": 123,
"amount": 1250.00,
"currency": "NOK"
}
Response (Redirect Required)
{
"status": "pending_redirect",
"payment_request_id": 123,
"amount": 1250.00,
"currency": "NOK",
"checkout_url": "https://checkout.stripe.com/..."
}
Pay Multiple Documents
Creates a checkout session for paying one or more billing documents in a single transaction.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Request Body
| Field |
Type |
Required |
Description |
| document_ids |
array |
Yes |
Array of document IDs to pay |
| success_url |
string |
Yes |
URL to redirect to after successful payment |
| cancel_url |
string |
Yes |
URL to redirect to if payment is cancelled |
Example Request
{
"document_ids": [42, 43],
"success_url": "https://app.snapbooks.no/billing/success",
"cancel_url": "https://app.snapbooks.no/billing"
}
Response
{
"checkout_url": "https://checkout.stripe.com/...",
"total_amount": 2500.00,
"payment_request_id": 789
}
Error Responses
| Status |
Description |
| 400 |
Missing or empty document_ids, missing URLs, or payment provider not configured |
| 403 |
No access to the client account |
Payment Methods
List Payment Methods
GET /api/v2/billing/payment-methods
Returns saved payment methods (cards) for a client account.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
[
{
"id": "pm_1234567890",
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2025,
"is_default": true
}
]
Returns an empty array if no payment methods are saved.
Add Payment Method
POST /api/v2/billing/payment-methods/setup
Creates a Stripe checkout session for securely adding a new payment method.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Request Body
| Field |
Type |
Required |
Description |
| success_url |
string |
Yes |
URL to redirect to after card is saved |
| cancel_url |
string |
Yes |
URL to redirect to if setup is cancelled |
Response
{
"checkout_url": "https://checkout.stripe.com/..."
}
Redirect the user to checkout_url to complete the card setup.
Error Responses
| Status |
Description |
| 400 |
Missing URLs or payment provider not configured |
| 403 |
No access to the client account |
Set Default Payment Method
POST /api/v2/billing/payment-methods/{payment_method_id}/default
Sets a payment method as the default for the client account.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Error Responses
| Status |
Description |
| 400 |
Operation failed |
| 403 |
Payment method does not belong to the client account |
Remove Payment Method
DELETE /api/v2/billing/payment-methods/{payment_method_id}
Removes a saved payment method from the client account.
Query Parameters
| Parameter |
Type |
Required |
Description |
| client_account_id |
integer |
Yes |
The client account ID |
Response
Error Responses
| Status |
Description |
| 400 |
Failed to detach payment method from Stripe |
| 403 |
Payment method does not belong to the client account |
Attributes
Billing Document
| Attribute |
Type |
Description |
| id |
integer |
Unique identifier (read-only) |
| document_type |
string |
Document type: ARInvoice or ARCreditNote |
| document_number |
string |
Human-readable document number |
| document_date |
date |
Date the document was issued |
| due_date |
date |
Payment due date |
| document_status |
string |
Processing status |
| payment_status |
string |
Payment status: OPEN, PAID, PART PAID |
| gross_total |
decimal |
Total amount including tax |
| open_amount |
decimal |
Remaining unpaid amount |
| currency_code |
string |
Currency code (e.g. NOK) |
| pdf_url |
string |
Presigned URL for PDF download (null if unavailable) |
Payment Method
| Attribute |
Type |
Description |
| id |
string |
Stripe payment method ID |
| brand |
string |
Card brand (e.g. visa, mastercard) |
| last4 |
string |
Last four digits of the card |
| exp_month |
integer |
Card expiration month |
| exp_year |
integer |
Card expiration year |
| is_default |
boolean |
Whether this is the default payment method |