Counters
Track utility meter readings for your properties
What are counters?
Counters allow you to track utility meter readings for your properties: electricity, water, gas, heating, and other utilities. Each counter stores its serial number, initial reading, and a history of all readings.
Key features
- Linked to expense types (electricity, water, gas, etc.)
- Document attachments for meters and readings (photos, PDFs, up to 20 MB)
- Full history of readings with dates
- Automatic validation: new readings must be greater or equal to previous
- Support for multi-zone electricity tariffs (single, two-zone, three-zone)
Electricity Tariff Zones
For electricity counters, you can select different tariff types depending on your meter capabilities.
| Tariff Type | Zones | Description |
|---|---|---|
| single-zone | 1 zone | Standard meter with single reading. Default for all expense types. |
| two-zone | T1 (Day (T1)), T2 (Night (T2)) | Day/night meter. Enter both zones, total calculated automatically. |
| three-zone | T1 (Peak (T1)), T2 (Half-peak (T2)), T3 (Night (T3)) | Peak/half-peak/night meter. All zones required. |
Important
Multi-zone tariffs are only available for expense types that support them (e.g., electricity). When adding a reading for a multi-zone counter, you must enter values for all zones.
How to create a counter?
Go to your property
Open the property page where you want to add a counter.
Open Counters section
Click "Counters" in the property menu to see existing counters or add a new one.
Fill in the counter details
Select the expense type, enter the serial number, initial reading value, and optionally upload a photo of the meter.
Adding readings
After creating a counter, you can add readings to track consumption over time.
Validation rules
New readings must be greater than or equal to the previous reading. The system will not accept lower values to ensure data integrity.
Attach documents
Upload photos of the meter display or PDF documents with each reading for proof and reference.
Track dates
Always enter the exact date when the reading was taken for accurate consumption tracking.
Regular updates
Add readings regularly (monthly) to track consumption patterns and detect issues early.
Adjustments and Corrections
Sometimes meter readings need to be corrected due to meter rollback, replacement, or utility provider adjustments.
Consumption
Normal readings. New value must be greater than or equal to the previous reading.
Adjustment
Correction readings. Use when meter was replaced, rolled back, or adjusted by utility provider.
When to use adjustments?
- Meter replacement - new meter starts from lower value
- Meter rollback after reaching maximum value
- Utility provider correction after recalculation
- Error correction in previously entered reading
Important
Adjustment readings are stored as negative values and are excluded from automatic expense charge calculations. They cannot be linked to expense charges.
Readings Linked to Expense Charges
When an expense charge is created based on counter readings, the system automatically links the reading to the charge for tracking and data integrity.
Reading is not linked to any expense charge. Can be edited or deleted by Owner/Representative.
Reading is linked to an expense charge. Cannot be edited or deleted to ensure data integrity. Only administrators can modify linked readings.
Automatic Linking
When creating an expense charge for a counter-based expense, the system automatically finds and links the latest unlinked reading.
Linking Rules
| Reading Type | Can Be Linked | Reason |
|---|---|---|
| Regular consumption | Yes | Normal readings represent actual consumption |
| Adjustment/Correction | No | Negative values cannot represent billable consumption |
| Initial reading | No | Initial readings are starting points, not consumption |
Creating Expense Charges
When creating an expense charge for a counter-based expense, you select an existing counter reading instead of entering values directly. This ensures data integrity and proper tracking.
Add counter reading
First, add a new counter reading with the current meter value.
Create expense charge
Go to the expense and create a new charge. Select the reading from the dropdown list.
Automatic calculation
The system automatically calculates consumption based on the difference between the selected reading and the previous one.
No unlinked readings?
If there are no unlinked readings available, you cannot create a charge. First add a new counter reading, then return to create the charge.
Creating Charges via API
# 1. Get available unlinked readings:
GET /api/v1/properties/{propertyId}/expenses/{expenseId}/unlinked-readings
# Response:
{
"has_counters": true,
"has_unlinked_readings": true,
"counters": [
{
"counter_id": 5,
"serial_number": "ABC-123456",
"unlinked_readings": [
{
"id": 12,
"date": "2026-01-15",
"value": "1500.00",
"previous_value": "1350.00",
"consumption": "150.0000"
}
]
}
]
}
# 2. Create charge with selected reading:
POST /api/v1/properties/{propertyId}/expenses/{expenseId}/charges
{
"charge_date": "2026-01-21",
"period_start": "2025-12-01",
"period_end": "2025-12-31",
"counter_value_ids": [12]
}
Access rights
Different property participants have different permissions for counters and readings.
Counter permissions
| Action | Who can do this |
|---|---|
| View counters | All property participants |
| Create counters | All property participants |
| Edit counters | All property participants |
| Delete counters | Owner and Representative only |
Reading permissions
| Action | Who can do this |
|---|---|
| View readings | All property participants |
| Add readings | All property participants |
| Edit readings | Owner and Representative only |
| Delete readings | Owner and Representative only |
Property roles
- Owner (PROPERTY_LANDLORD): Full access to all operations
- Representative (PROPERTY_LANDLORD_AGENT): Can edit and delete counters and readings
- Other participants: Can view, create counters and add new readings
Counter Status
Counters can be activated or deactivated depending on whether they are currently in use.
Counter is in use. New readings can be added and counter will be used for automatic expense charge calculations.
Counter is deactivated. It remains in the system for historical records but is not used for new calculations.
When to deactivate a counter?
- Meter has been replaced with a new one
- Meter is temporarily out of service
- Meter is no longer relevant for the property
Important
Inactive counters are excluded from automatic expense charge calculations. If you need to use a counter again, simply activate it.
Counter Deletion
To maintain data integrity, counters with linked expense charges cannot be deleted.
Can be deleted
Counter has no readings linked to expense charges. All history will be permanently removed.
Cannot be deleted
Counter has readings that are linked to expense charges. Deactivate the counter instead to preserve historical data.
Alternative to deletion
If you cannot delete a counter, deactivate it instead. Deactivated counters remain in the system for reference but are not used in new calculations.
REST API
All API endpoints require JWT authentication.
Service layer note
Counters API
GET /api/v1/properties/{propertyId}/counters # List counters for property
POST /api/v1/properties/{propertyId}/counters # Create counter
GET /api/v1/properties/{propertyId}/counters/{id} # Counter details with readings
PUT /api/v1/properties/{propertyId}/counters/{id} # Update counter
DELETE /api/v1/properties/{propertyId}/counters/{id} # Delete counter (if no linked charges)
POST /api/v1/properties/{propertyId}/counters/{id}/toggle # Toggle active/inactive status
Readings API
POST /api/v1/properties/{propertyId}/counters/{counterId}/values # Add reading
PUT /api/v1/properties/{propertyId}/counters/{counterId}/values/{id} # Edit reading
DELETE /api/v1/properties/{propertyId}/counters/{counterId}/values/{id} # Delete reading
Counter Documents
POST /properties/{propertyId}/counters/{id}/documents/upload # Upload document (multipart/form-data)
POST /properties/{propertyId}/counters/{id}/documents/{documentId}/delete # Delete document
Reading Documents
POST /properties/{propertyId}/counters/{id}/values/{valueId}/documents/upload # Upload document (multipart/form-data)
POST /properties/{propertyId}/counters/{id}/values/{valueId}/documents/{documentId}/delete # Delete document
File limits
Maximum file size: 20 MB. Supported formats: JPEG, PNG, GIF, WebP, HEIC, PDF. Multiple files can be attached to each counter or reading.
Example: Create counter
POST /api/v1/properties/1/counters
Content-Type: application/json
Authorization: Bearer <token>
{
"expense_type_id": 1,
"serial_number": "ABC-123456",
"tariff_type": "TWO_ZONE",
"initial_value": "100.500",
"initial_value_t1": "60.300",
"initial_value_t2": "40.200",
"initial_value_date": "2026-01-01"
}
Example: Add reading
POST /api/v1/properties/1/counters/5/values
Content-Type: application/json
Authorization: Bearer <token>
# Single-zone counter (regular consumption):
{ "value": "1350.75", "date": "2026-01-07" }
# Multi-zone counter (total auto-calculated):
{
"value_t1": "150.300",
"value_t2": "80.200",
"date": "2026-01-07"
}
# Adjustment reading (correction):
{
"value": "50.000",
"date": "2026-01-07",
"is_adjustment": true
}
Counter Documents: Upload
POST /properties/1/counters/5/documents/upload
Content-Type: multipart/form-data
documents[] — file (jpg, jpeg, png, gif, webp, heic, pdf), max 20 MB
comment — string (optional)
# Response:
{ "success": true, "uploaded": 1 }
Reading Documents: Upload
POST /properties/1/counters/5/values/12/documents/upload
Content-Type: multipart/form-data
documents[] — file (jpg, jpeg, png, gif, webp, heic, pdf), max 20 MB
comment — string (optional)
# Response:
{ "success": true, "uploaded": 2 }
Example Response
{
"id": 12,
"value": "230.500",
"value_t1": "150.300",
"value_t2": "80.200",
"value_t3": null,
"date": "2026-01-07",
"is_initial": false,
"is_adjustment": false,
"has_linked_charge": true,
"expense_charge_id": 45,
"can_edit": false,
"can_delete": false,
"documents_count": 2,
"created_at": "2026-01-07T10:30:00+00:00"
}
Related sections
Swagger / OpenAPI
Full API documentation is available in Swagger UI: /api/v1/doc