Home Library Counters

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?

1

Go to your property

Open the property page where you want to add a counter.

2

Open Counters section

Click "Counters" in the property menu to see existing counters or add a new one.

3

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.

Unlinked

Reading is not linked to any expense charge. Can be edited or deleted by Owner/Representative.

Linked

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.

1

Add counter reading

First, add a new counter reading with the current meter value.

2

Create expense charge

Go to the expense and create a new charge. Select the reading from the dropdown list.

3

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.

Active

Counter is in use. New readings can be added and counter will be used for automatic expense charge calculations.

Inactive

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