Tenant Billing¶
The Tenant Billing API supports Ratio Utility Billing Systems (RUBS) and property-management-system (PMS) integrated billing. It allocates master-metered utility costs across individual tenant units. All endpoints require authentication and are prefixed with /billing.
POST /billing/config¶
Create a billing configuration for a property. A billing config defines how utility costs are allocated to tenants.
| Auth required | Yes |
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
property_id |
string | Yes | Property ID |
method |
string | Yes | Allocation method: sqft, occupant_count, unit_count, custom_weight |
utility_types |
array | Yes | Utility types to bill: ["electric"], ["electric", "gas", "water"], etc. |
common_area_percent |
number | No | Percentage of total cost allocated to common areas (default: 0). Range: 0-50 |
admin_fee_percent |
number | No | Administrative fee added to each tenant's bill (default: 0). Range: 0-15 |
billing_day |
integer | No | Day of month to generate bills (default: 1). Range: 1-28 |
is_active |
boolean | No | Whether this config is active (default: true) |
Example Request¶
curl -X POST https://app.meterbase.io/api/v1/billing/config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"property_id": "prop_abc123",
"method": "sqft",
"utility_types": ["electric", "water"],
"common_area_percent": 15,
"admin_fee_percent": 5,
"billing_day": 1
}'
Example Response¶
201 Created
{
"id": "bcfg_001",
"property_id": "prop_abc123",
"method": "sqft",
"utility_types": ["electric", "water"],
"common_area_percent": 15,
"admin_fee_percent": 5,
"billing_day": 1,
"is_active": true,
"created_at": "2026-03-25T14:00:00Z"
}
Error Cases¶
| Status | Detail | Cause |
|---|---|---|
404 |
"Property not found" |
Invalid property_id |
422 |
"common_area_percent must be between 0 and 50" |
Value out of range |
400 |
"Active billing config already exists for this property" |
Duplicate active config |
GET /billing/config/{property_id}¶
Get all billing configurations for a property.
| Auth required | Yes |
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
property_id |
string | Property ID |
Example Request¶
Example Response¶
200 OK
[
{
"id": "bcfg_001",
"property_id": "prop_abc123",
"method": "sqft",
"utility_types": ["electric", "water"],
"common_area_percent": 15,
"admin_fee_percent": 5,
"billing_day": 1,
"is_active": true,
"created_at": "2026-03-25T14:00:00Z"
}
]
POST /billing/calculate-rubs¶
Manually trigger a RUBS calculation for a billing period. You provide the master bill total and the list of units with their allocation factors.
| Auth required | Yes |
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
property_id |
string | Yes | Property ID |
billing_config_id |
string | Yes | Billing config ID |
billing_period_start |
string | Yes | Period start date (YYYY-MM-DD) |
billing_period_end |
string | Yes | Period end date (YYYY-MM-DD) |
total_amount |
number | Yes | Total master-meter bill amount in USD |
utility_type |
string | Yes | Utility type: electric, gas, water, sewer, trash |
units |
array | Yes | Array of unit objects (see below) |
Unit Object:
| Field | Type | Required | Description |
|---|---|---|---|
unit_id |
string | Yes | Unique unit identifier (e.g., "101", "A-201") |
tenant_name |
string | Yes | Tenant name |
sqft |
number | Conditional | Required if method is sqft |
occupant_count |
integer | Conditional | Required if method is occupant_count |
custom_weight |
number | Conditional | Required if method is custom_weight (0-100) |
is_vacant |
boolean | No | If true, cost is absorbed by the property (default: false) |
Example Request¶
curl -X POST https://app.meterbase.io/api/v1/billing/calculate-rubs \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"property_id": "prop_abc123",
"billing_config_id": "bcfg_001",
"billing_period_start": "2026-03-01",
"billing_period_end": "2026-03-31",
"total_amount": 3247.85,
"utility_type": "electric",
"units": [
{
"unit_id": "101",
"tenant_name": "Alice Johnson",
"sqft": 750,
"is_vacant": false
},
{
"unit_id": "102",
"tenant_name": "Bob Smith",
"sqft": 900,
"is_vacant": false
},
{
"unit_id": "103",
"tenant_name": "",
"sqft": 650,
"is_vacant": true
},
{
"unit_id": "104",
"tenant_name": "Carol Davis",
"sqft": 1100,
"is_vacant": false
}
]
}'
Example Response¶
200 OK
{
"id": "rubs_calc_001",
"property_id": "prop_abc123",
"billing_config_id": "bcfg_001",
"billing_period_start": "2026-03-01",
"billing_period_end": "2026-03-31",
"utility_type": "electric",
"total_amount": 3247.85,
"common_area_deduction": 487.18,
"billable_amount": 2760.67,
"admin_fee_rate": 0.05,
"method": "sqft",
"unit_bills": [
{
"unit_id": "101",
"tenant_name": "Alice Johnson",
"sqft": 750,
"allocation_percent": 27.27,
"base_charge": 752.91,
"admin_fee": 37.65,
"total_charge": 790.56,
"is_vacant": false
},
{
"unit_id": "102",
"tenant_name": "Bob Smith",
"sqft": 900,
"allocation_percent": 32.73,
"base_charge": 903.49,
"admin_fee": 45.17,
"total_charge": 948.66,
"is_vacant": false
},
{
"unit_id": "103",
"tenant_name": "",
"sqft": 650,
"allocation_percent": 0.0,
"base_charge": 0.0,
"admin_fee": 0.0,
"total_charge": 0.0,
"is_vacant": true
},
{
"unit_id": "104",
"tenant_name": "Carol Davis",
"sqft": 1100,
"allocation_percent": 40.0,
"base_charge": 1104.27,
"admin_fee": 55.21,
"total_charge": 1159.48,
"is_vacant": false
}
],
"vacant_absorption": 652.44,
"calculated_at": "2026-03-25T14:30:00Z"
}
Vacant Unit Handling
Units marked as is_vacant: true are excluded from the allocation. Their share is absorbed by the property owner and shown in the vacant_absorption field.
Error Cases¶
| Status | Detail | Cause |
|---|---|---|
404 |
"Property not found" |
Invalid property_id |
404 |
"Billing config not found" |
Invalid billing_config_id |
422 |
"units array must not be empty" |
No units provided |
422 |
"sqft required for sqft allocation method" |
Missing required allocation field |
POST /billing/calculate-from-pms¶
Trigger a RUBS calculation using tenant data pulled directly from a connected property management system (PMS). This eliminates the need to manually supply the units array.
| Auth required | Yes |
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
property_id |
string | Yes | Property ID (must have PMS integration configured) |
billing_config_id |
string | Yes | Billing config ID |
billing_period_start |
string | Yes | Period start date (YYYY-MM-DD) |
billing_period_end |
string | Yes | Period end date (YYYY-MM-DD) |
total_amount |
number | Yes | Total master-meter bill amount in USD |
utility_type |
string | Yes | Utility type: electric, gas, water, sewer, trash |
Example Request¶
curl -X POST https://app.meterbase.io/api/v1/billing/calculate-from-pms \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"property_id": "prop_abc123",
"billing_config_id": "bcfg_001",
"billing_period_start": "2026-03-01",
"billing_period_end": "2026-03-31",
"total_amount": 3247.85,
"utility_type": "electric"
}'
Example Response¶
200 OK
The response schema is identical to POST /billing/calculate-rubs. The units array is populated automatically from the PMS.
PMS Integration Flow
- The system queries the connected PMS for current tenant and unit data.
- Unit sizes, occupancy, and vacancy are pulled in real time.
- The RUBS calculation runs using the billing config's allocation method.
- Results are returned and stored in billing history.
Error Cases¶
| Status | Detail | Cause |
|---|---|---|
404 |
"Property not found" |
Invalid property_id |
400 |
"No PMS integration configured for this property" |
Property has no connected PMS |
502 |
"Failed to fetch tenant data from PMS" |
PMS API error |
GET /billing/history/{property_id}¶
Retrieve billing period history for a property, showing all past RUBS calculations.
| Auth required | Yes |
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
property_id |
string | Property ID |
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number |
per_page |
integer | 20 |
Items per page (max 100) |
Example Request¶
curl "https://app.meterbase.io/api/v1/billing/history/prop_abc123?per_page=5" \
-H "Authorization: Bearer $TOKEN"
Example Response¶
200 OK
{
"items": [
{
"id": "rubs_calc_001",
"property_id": "prop_abc123",
"billing_period_start": "2026-03-01",
"billing_period_end": "2026-03-31",
"utility_type": "electric",
"total_amount": 3247.85,
"units_billed": 3,
"units_vacant": 1,
"method": "sqft",
"calculated_at": "2026-03-25T14:30:00Z"
},
{
"id": "rubs_calc_002",
"property_id": "prop_abc123",
"billing_period_start": "2026-02-01",
"billing_period_end": "2026-02-28",
"utility_type": "electric",
"total_amount": 2980.50,
"units_billed": 4,
"units_vacant": 0,
"method": "sqft",
"calculated_at": "2026-02-28T10:00:00Z"
}
],
"total": 2,
"page": 1,
"per_page": 5,
"pages": 1
}
Error Cases¶
| Status | Detail | Cause |
|---|---|---|
404 |
"Property not found" |
Invalid property ID |