+Sample Response
+
+```json
+{
+ "enabled": true,
+ "counts": {},
+ "omitted": ["string"]
}
```
@@ -897,6 +942,24 @@ epilot message searchThreadsV2 \
-d '{
"inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
"q": "subject:\"Request for solar panel price\" AND _tags:INBOX",
+ "view": {
+ "folder": "inbox",
+ "mailbox": "organization",
+ "labels": ["string"],
+ "purposes": ["string"],
+ "filters": ["unread"],
+ "from": ["string"],
+ "to": ["string"],
+ "assigned_to": ["string"],
+ "include_unassigned": true,
+ "date_from_days_ago": 0,
+ "date_to_days_ago": 0,
+ "email_filter": ["string"],
+ "text": "string",
+ "thread_ids": ["string"],
+ "pinned_by": "string"
+ },
+ "user_groups": ["string"],
"fields": ["_id", "_title", "first_name", "account", "!account.*._files", "**._product"],
"from": 0,
"size": 10,
@@ -960,9 +1023,36 @@ Return all thread id's that match a criteria
**Sample Call**
+```bash
+epilot message searchIds
+```
+
+With request body:
+
```bash
epilot message searchIds \
- -d '{"q":"subject:\"Request for solar panel price\" AND _tags:INBOX"}'
+ -d '{
+ "view": {
+ "folder": "inbox",
+ "mailbox": "organization",
+ "labels": ["string"],
+ "purposes": ["string"],
+ "filters": ["unread"],
+ "from": ["string"],
+ "to": ["string"],
+ "assigned_to": ["string"],
+ "include_unassigned": true,
+ "date_from_days_ago": 0,
+ "date_to_days_ago": 0,
+ "email_filter": ["string"],
+ "text": "string",
+ "thread_ids": ["string"],
+ "pinned_by": "string"
+ },
+ "user_groups": ["string"],
+ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
+ "q": "subject:\"Request for solar panel price\" AND _tags:INBOX"
+}'
```
Using stdin pipe:
@@ -991,6 +1081,51 @@ epilot message searchIds --jsonata 'results[0]'
---
+### `getAssigneeWorkload`
+
+Return the open-thread workload for a set of user ids.
+
+`POST /v2/message/threads:workload`
+
+**Request Body** (required)
+
+**Sample Call**
+
+```bash
+epilot message getAssigneeWorkload \
+ -d '{"user_ids":["11000902","11001053"]}'
+```
+
+Using stdin pipe:
+
+```bash
+cat body.json | epilot message getAssigneeWorkload
+```
+
+With JSONata filter:
+
+```bash
+epilot message getAssigneeWorkload --jsonata 'workloads'
+```
+
+
+Sample Response
+
+```json
+{
+ "workloads": [
+ {
+ "user_id": "11000902",
+ "open_threads": 2
+ }
+ ]
+}
+```
+
+
+
+---
+
### `updateThread`
Modify thread metadata
@@ -1028,6 +1163,7 @@ epilot message updateThread --jsonata '$'
"latest_message": {
"message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>",
"sender": "206801",
+ "updated_by": "206801",
"subject": "Request for solar panel price",
"html": "We at ABC GmbH would like to request a price quote for the solar panel.
",
"text": "We at ABC GmbH would like to request a price quote for the solar panel.",
@@ -1068,6 +1204,7 @@ epilot message updateThread --jsonata '$'
"latest_trash_message": {
"message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>",
"sender": "206801",
+ "updated_by": "206801",
"subject": "Request for solar panel price",
"html": "We at ABC GmbH would like to request a price quote for the solar panel.
",
"text": "We at ABC GmbH would like to request a price quote for the solar panel.",
@@ -1292,12 +1429,24 @@ epilot message getThreadTimeline -p id=123e4567-e89b-12d3-a456-426614174000 --js
{
"events": [
{
+ "id": "string",
"data": {
"type": "THREAD_DONE",
"user_id": "123",
"organization_id": "456"
},
- "timestamp": "2024-01-01T00:00:00.000Z"
+ "timestamp": "2024-01-01T00:00:00.000Z",
+ "message_id": "string",
+ "source": "user",
+ "automated": true,
+ "actor": {
+ "user_id": "string",
+ "email": "string"
+ },
+ "automation": {
+ "id": "string",
+ "name": "string"
+ }
}
]
}
@@ -1373,6 +1522,218 @@ epilot message untrashThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonat
---
+### `spamThread`
+
+Mark a thread as spam
+
+`POST /v1/message/threads/{id}/spam`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `id` | path | string | Yes | Thread ID |
+
+**Sample Call**
+
+```bash
+epilot message spamThread \
+ -p id=123e4567-e89b-12d3-a456-426614174000
+```
+
+Using positional args for path parameters:
+
+```bash
+epilot message spamThread 123e4567-e89b-12d3-a456-426614174000
+```
+
+With JSONata filter:
+
+```bash
+epilot message spamThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$'
+```
+
+---
+
+### `unspamThread`
+
+Remove spam marking from a thread
+
+`POST /v1/message/threads/{id}/unspam`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `id` | path | string | Yes | Thread ID |
+
+**Sample Call**
+
+```bash
+epilot message unspamThread \
+ -p id=123e4567-e89b-12d3-a456-426614174000
+```
+
+Using positional args for path parameters:
+
+```bash
+epilot message unspamThread 123e4567-e89b-12d3-a456-426614174000
+```
+
+With JSONata filter:
+
+```bash
+epilot message unspamThread -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$'
+```
+
+---
+
+### `spamMessage`
+
+Mark a single message as spam. Also marks the parent thread as spam if all messages in the thread are spam.
+
+`POST /v1/message/messages/{id}/spam`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `id` | path | string | Yes | Message ID |
+
+**Sample Call**
+
+```bash
+epilot message spamMessage \
+ -p id=123e4567-e89b-12d3-a456-426614174000
+```
+
+Using positional args for path parameters:
+
+```bash
+epilot message spamMessage 123e4567-e89b-12d3-a456-426614174000
+```
+
+With JSONata filter:
+
+```bash
+epilot message spamMessage -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$'
+```
+
+---
+
+### `unspamMessage`
+
+Remove spam marking from a single message. Also removes spam from the parent thread if no other messages are spam.
+
+`POST /v1/message/messages/{id}/unspam`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `id` | path | string | Yes | Message ID |
+
+**Sample Call**
+
+```bash
+epilot message unspamMessage \
+ -p id=123e4567-e89b-12d3-a456-426614174000
+```
+
+Using positional args for path parameters:
+
+```bash
+epilot message unspamMessage 123e4567-e89b-12d3-a456-426614174000
+```
+
+With JSONata filter:
+
+```bash
+epilot message unspamMessage -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata '$'
+```
+
+---
+
+### `bulkMoveThreads`
+
+Move many threads to a different inbox
+
+`POST /v1/message/threads/bulk:move`
+
+**Request Body** (required)
+
+**Sample Call**
+
+```bash
+epilot message bulkMoveThreads
+```
+
+With request body:
+
+```bash
+epilot message bulkMoveThreads \
+ -d '{
+ "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"],
+ "assign_to": ["206801"],
+ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
+ "scopes": ["organization", "user"]
+}'
+```
+
+Using stdin pipe:
+
+```bash
+cat body.json | epilot message bulkMoveThreads
+```
+
+With JSONata filter:
+
+```bash
+epilot message bulkMoveThreads --jsonata '$'
+```
+
+---
+
+### `bulkAssignThreads`
+
+Assign many threads
+
+`POST /v1/message/threads/bulk:assign`
+
+**Request Body** (required)
+
+**Sample Call**
+
+```bash
+epilot message bulkAssignThreads
+```
+
+With request body:
+
+```bash
+epilot message bulkAssignThreads \
+ -d '{
+ "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"],
+ "assign_to": ["206801"],
+ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
+ "scopes": ["organization", "user"]
+}'
+```
+
+Using stdin pipe:
+
+```bash
+cat body.json | epilot message bulkAssignThreads
+```
+
+With JSONata filter:
+
+```bash
+epilot message bulkAssignThreads --jsonata '$'
+```
+
+---
+
### `threadBulkActionsRead`
Perform a bulk action of marking an array of thread ids as read
@@ -1383,9 +1744,20 @@ Perform a bulk action of marking an array of thread ids as read
**Sample Call**
+```bash
+epilot message threadBulkActionsRead
+```
+
+With request body:
+
```bash
epilot message threadBulkActionsRead \
- -d '{"ids":["6b299eda-4018-4554-8965-c4b5598e6531"],"scopes":["organization","user"]}'
+ -d '{
+ "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"],
+ "assign_to": ["206801"],
+ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
+ "scopes": ["organization", "user"]
+}'
```
Using stdin pipe:
@@ -1412,9 +1784,20 @@ Perform a bulk action of marking an array of thread ids as unread
**Sample Call**
+```bash
+epilot message threadBulkActionsUnread
+```
+
+With request body:
+
```bash
epilot message threadBulkActionsUnread \
- -d '{"ids":["6b299eda-4018-4554-8965-c4b5598e6531"],"scopes":["organization","user"]}'
+ -d '{
+ "ids": ["6b299eda-4018-4554-8965-c4b5598e6531"],
+ "assign_to": ["206801"],
+ "inbox_id": "3f34ce73-089c-4d45-a5ee-c161234e41c3",
+ "scopes": ["organization", "user"]
+}'
```
Using stdin pipe:
@@ -1837,6 +2220,7 @@ Unassign thread from entities
| Name | In | Type | Required | Description |
| ---- | -- | ---- | -------- | ----------- |
| `id` | path | string | Yes | Thread ID |
+| `unlink_mapped_entities` | query | boolean | No | When true, also removes unassigned entities from mapped_entities on related source entities |
**Request Body** (required)
@@ -2059,6 +2443,7 @@ epilot message createDraft --jsonata '$'
"_updated_at": "2021-02-10T09:14:31.990Z",
"message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>",
"sender": "206801",
+ "updated_by": "206801",
"subject": "Request for solar panel price",
"html": "We at ABC GmbH would like to request a price quote for the solar panel.
",
"text": "We at ABC GmbH would like to request a price quote for the solar panel.",
@@ -2112,7 +2497,8 @@ epilot message createDraft --jsonata '$'
"may_be_signature_attachment": true,
"cid": "fb222496-a1a5-4639-94f2-07b5e35e4068",
"inline": false,
- "send_as_link": false
+ "send_as_link": false,
+ "save_to_entity": true
}
]
},
@@ -2162,6 +2548,7 @@ epilot message sendDraft --jsonata '$'
"_updated_at": "2021-02-10T09:14:31.990Z",
"message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>",
"sender": "206801",
+ "updated_by": "206801",
"subject": "Request for solar panel price",
"html": "We at ABC GmbH would like to request a price quote for the solar panel.
",
"text": "We at ABC GmbH would like to request a price quote for the solar panel.",
@@ -2215,7 +2602,8 @@ epilot message sendDraft --jsonata '$'
"may_be_signature_attachment": true,
"cid": "fb222496-a1a5-4639-94f2-07b5e35e4068",
"inline": false,
- "send_as_link": false
+ "send_as_link": false,
+ "save_to_entity": true
}
]
},
@@ -2280,6 +2668,7 @@ epilot message getMessageV2 -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata
"_updated_at": "2021-02-10T09:14:31.990Z",
"message_id": "<0102017b97a502f8-a67f01c2-68cc-4928-b91b-45853f34e259-000000@eu-west-1.amazonses.com>",
"sender": "206801",
+ "updated_by": "206801",
"subject": "Request for solar panel price",
"html": "We at ABC GmbH would like to request a price quote for the solar panel.
",
"text": "We at ABC GmbH would like to request a price quote for the solar panel.",
@@ -2333,7 +2722,8 @@ epilot message getMessageV2 -p id=4d74976d-fb64-47fd-85e2-65eea140f5eb --jsonata
"may_be_signature_attachment": true,
"cid": "fb222496-a1a5-4639-94f2-07b5e35e4068",
"inline": false,
- "send_as_link": false
+ "send_as_link": false,
+ "save_to_entity": true
}
]
},
diff --git a/docs/cli/commands/metering.md b/docs/cli/commands/metering.md
index 8b1be534..5504834c 100644
--- a/docs/cli/commands/metering.md
+++ b/docs/cli/commands/metering.md
@@ -8,6 +8,8 @@ description: "epilot CLI commands for the Metering API: quick start, common flag
- **Base URL:** `https://metering.sls.epilot.io`
- **API Docs:** [https://docs.epilot.io/api/metering](https://docs.epilot.io/api/metering)
+The Metering API manages smart meter data, meter counters, and meter readings for epilot customers and administrators.
+
## Quick Start
```bash
@@ -39,31 +41,44 @@ epilot metering getCustomerMeters
## Operations
**ECP**
-- [`getCustomerMeters`](#getcustomermeters) — Retrieves all meters related to a customer.
-- [`getMetersByContractId`](#getmetersbycontractid) — Retrieves all meters related to a contract.
-- [`getMeter`](#getmeter) — Retrieves the details of a meter.
-- [`updateMeter`](#updatemeter) — Updates the details of a meter.
-- [`getMeterCounters`](#getmetercounters) — Retrieves all counters for a given meter.
-- [`getCounterDetails`](#getcounterdetails) — Retrieves the details of a meter counter.
-- [`createPortalMeterReadings`](#createportalmeterreadings) — Inserts multiple meter readings at once for a given meter. Limited to 2 readings per request.
+- [`getCustomerMeters`](#getcustomermeters) — Retrieves all meters associated with the authenticated portal customer.
+- [`getMetersByContractId`](#getmetersbycontractid) — Retrieves all meters associated with a given contract entity.
+- [`getMeter`](#getmeter) — Retrieves the full details of a specific meter by ID, including related entities and available journey actions.
+- [`updateMeter`](#updatemeter) — Partially updates the details of a meter entity by ID.
+- [`getMeterCounters`](#getmetercounters) — Retrieves all meter counters associated with a given meter.
+- [`getCounterDetails`](#getcounterdetails) — Retrieves the full details of a single meter counter by its ID.
+- [`createPortalMeterReadings`](#createportalmeterreadings) — Inserts multiple meter readings at once for a given meter via the end customer portal.
**ECP Admin**
- [`createMeterReading`](#createmeterreading) — Inserts a new meter reading.
- [`createMeterReadings`](#createmeterreadings) — Inserts multiple meter readings at once. Limited to 100 readings per request.
-- [`batchWriteMeterReadings`](#batchwritemeterreadings) — Upserts/Deletes multiple meter readings at once. Limited to 100 readings per request.
-- [`createMeterReadingFromSubmission`](#createmeterreadingfromsubmission) — Creates a reading from a journey submission.
-- [`getAllowedReadingForMeter`](#getallowedreadingformeter) — Get allowed reading for the given meter
-- [`createReadingWithMeter`](#createreadingwithmeter) — Creates a reading along with a meter.
+- [`batchWriteMeterReadings`](#batchwritemeterreadings) — Upserts or deletes multiple meter readings at once. Limited to 100 readings per request.
+- [`pruneMeterReadings`](#prunemeterreadings) — Deletes every reading of a meter whose `external_id` is NOT in the provided keep list — in a single request.
+- [`createMeterReadingFromSubmission`](#createmeterreadingfromsubmission) — Creates meter readings from a journey submission payload.
+- [`getAllowedReadingForMeter`](#getallowedreadingformeter) — Returns the allowed min/max reading range for each counter of the given meter.
+- [`createReadingWithMeter`](#createreadingwithmeter) — Creates a meter reading along with meter lookup or creation by MA-LO ID and OBIS number.
- [`getReadingsByInterval`](#getreadingsbyinterval) — Retrieves all readings specified in an interval.
-- [`updateMeterReading`](#updatemeterreading) — Updates a meter reading.
-- [`deleteMeterReading`](#deletemeterreading) — Deletes a meter reading.
+- [`updateMeterReading`](#updatemeterreading) — Updates an existing meter reading identified by meter ID, counter ID, and timestamp.
+- [`deleteMeterReading`](#deletemeterreading) — Permanently deletes a meter reading identified by meter ID, counter ID, and timestamp.
+
+**Metering**
+- [`getReadingChangesets`](#getreadingchangesets) — GET /v1/metering/reading/{meter_id}/{counter_id}/changesets
+- [`applyReadingChangeset`](#applyreadingchangeset) — Applies the proposed reading value to ClickHouse and removes the pending changeset.
+- [`dismissReadingChangeset`](#dismissreadingchangeset) — Removes the pending changeset without applying it. The reading value remains unchanged.
+- [`updateReadingChangeset`](#updatereadingchangeset) — Updates the proposed value of a pending changeset without going through the normal write path.
### `getCustomerMeters`
-Retrieves all meters related to a customer.
+Retrieves all meters associated with the authenticated portal customer.
`GET /v1/metering/meter`
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `include_pending_changesets` | query | boolean | No | When true, the response includes a `pending_changesets` field with the list of pending reading changesets alongside the confirmed readings. |
+
**Sample Call**
```bash
@@ -109,7 +124,7 @@ epilot metering getCustomerMeters --jsonata 'data'
],
"used_for": "Domestic Usage",
"manufacturer": "Energy One",
- "calibration_date": "2022-10-10T00:00:00.000Z",
+ "calibration_date": "2022-10-10",
"contract": {
"$relation": [
{
@@ -141,7 +156,7 @@ epilot metering getCustomerMeters --jsonata 'data'
}
]
},
- "last_reading": "2022-10-10T00:00:00.000Z",
+ "last_reading": "2022-10-10",
"current_consumption": 100.5
}
]
@@ -154,7 +169,7 @@ epilot metering getCustomerMeters --jsonata 'data'
### `getMetersByContractId`
-Retrieves all meters related to a contract.
+Retrieves all meters associated with a given contract entity.
`GET /v1/metering/contract/meters/{contract_id}`
@@ -216,7 +231,7 @@ epilot metering getMetersByContractId -p contract_id=123e4567-e89b-12d3-a456-426
],
"used_for": "Domestic Usage",
"manufacturer": "Energy One",
- "calibration_date": "2022-10-10T00:00:00.000Z",
+ "calibration_date": "2022-10-10",
"contract": {
"$relation": [
{
@@ -244,7 +259,7 @@ epilot metering getMetersByContractId -p contract_id=123e4567-e89b-12d3-a456-426
### `getMeter`
-Retrieves the details of a meter.
+Retrieves the full details of a specific meter by ID, including related entities and available journey actions.
`GET /v1/metering/meter/{id}`
@@ -306,7 +321,7 @@ epilot metering getMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'd
],
"used_for": "Domestic Usage",
"manufacturer": "Energy One",
- "calibration_date": "2022-10-10T00:00:00.000Z",
+ "calibration_date": "2022-10-10",
"contract": {
"$relation": [
{
@@ -359,7 +374,7 @@ epilot metering getMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'd
### `updateMeter`
-Updates the details of a meter.
+Partially updates the details of a meter entity by ID.
`PATCH /v1/metering/meter/{id}`
@@ -429,7 +444,7 @@ epilot metering updateMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata
],
"used_for": "Domestic Usage",
"manufacturer": "Energy One",
- "calibration_date": "2022-10-10T00:00:00.000Z",
+ "calibration_date": "2022-10-10",
"contract": {
"$relation": [
{
@@ -456,7 +471,7 @@ epilot metering updateMeter -p id=123e4567-e89b-12d3-a456-426614174000 --jsonata
### `getMeterCounters`
-Retrieves all counters for a given meter.
+Retrieves all meter counters associated with a given meter.
`GET /v1/metering/counter`
@@ -498,9 +513,9 @@ epilot metering getMeterCounters -p meter_id=123e4567-e89b-12d3-a456-42661417400
"transformer_ratio": 70,
"unit": "string",
"forecast_reading_value": 270,
- "forecast_as_of": "2022-12-10T00:00:00.000Z",
+ "forecast_as_of": "2022-12-10",
"current_consumption": 240,
- "last_reading": "2022-10-10T00:00:00.000Z",
+ "last_reading": "2022-10-10",
"conversion_factor": 3,
"tariff_type": "ht"
}
@@ -514,7 +529,7 @@ epilot metering getMeterCounters -p meter_id=123e4567-e89b-12d3-a456-42661417400
### `getCounterDetails`
-Retrieves the details of a meter counter.
+Retrieves the full details of a single meter counter by its ID.
`GET /v1/metering/counter/{counter_id}`
@@ -561,9 +576,9 @@ epilot metering getCounterDetails -p counter_id=123e4567-e89b-12d3-a456-42661417
"transformer_ratio": 70,
"unit": "string",
"forecast_reading_value": 270,
- "forecast_as_of": "2022-12-10T00:00:00.000Z",
+ "forecast_as_of": "2022-12-10",
"current_consumption": 240,
- "last_reading": "2022-10-10T00:00:00.000Z",
+ "last_reading": "2022-10-10",
"conversion_factor": 3,
"tariff_type": "ht"
}
@@ -580,6 +595,12 @@ Inserts a new meter reading.
`POST /v1/metering/reading`
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. |
+
**Request Body** (required)
**Sample Call**
@@ -599,7 +620,7 @@ epilot metering createMeterReading \
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -637,7 +658,7 @@ epilot metering createMeterReading --jsonata 'data'
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -671,6 +692,10 @@ Inserts multiple meter readings at once. Limited to 100 readings per request.
| `skip_validation` | query | boolean | No | When set to true, all validations will be skipped and the system will allow the reading to be created.
If set to false or not provided, the system performs the following validations:
Validation Rule |
+| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. |
+| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the
+written readings. Defaults to true, preserving portal/journey behaviour (readings with
+source ECP or journ |
**Request Body** (required)
@@ -693,7 +718,7 @@ epilot metering createMeterReadings \
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -734,7 +759,7 @@ epilot metering createMeterReadings --jsonata 'data'
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -756,7 +781,7 @@ epilot metering createMeterReadings --jsonata 'data'
### `createPortalMeterReadings`
-Inserts multiple meter readings at once for a given meter. Limited to 2 readings per request.
+Inserts multiple meter readings at once for a given meter via the end customer portal.
`POST /v1/metering/readings/{meter_id}`
@@ -765,6 +790,7 @@ Inserts multiple meter readings at once for a given meter. Limited to 2 readings
| Name | In | Type | Required | Description |
| ---- | -- | ---- | -------- | ----------- |
| `meter_id` | path | string | Yes | The ID of the meter. |
+| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. |
**Request Body** (required)
@@ -789,7 +815,7 @@ epilot metering createPortalMeterReadings \
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -836,7 +862,7 @@ epilot metering createPortalMeterReadings -p meter_id=123e4567-e89b-12d3-a456-42
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -858,7 +884,7 @@ epilot metering createPortalMeterReadings -p meter_id=123e4567-e89b-12d3-a456-42
### `batchWriteMeterReadings`
-Upserts/Deletes multiple meter readings at once. Limited to 100 readings per request.
+Upserts or deletes multiple meter readings at once. Limited to 100 readings per request.
`POST /v2/metering/readings`
@@ -871,6 +897,10 @@ Upserts/Deletes multiple meter readings at once. Limited to 100 readings per req
If set to false or not provided, the system performs the following validations:
Validation Rule |
| `activity_id` | query | string (ulid) | No | Activity to include in event feed |
+| `direct` | query | boolean | No | When true, bypasses changeset interception and writes directly to ClickHouse. Used by trusted integrations (e.g., ERP sync) to confirm changes and auto-clear matching pending changesets. |
+| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the
+written readings. Defaults to true, preserving portal/journey behaviour (readings with
+source ECP or journ |
**Request Body** (required)
@@ -888,24 +918,24 @@ epilot metering batchWriteMeterReadings \
"identifiers": ["string"],
"readings": [
{
- "value": 240,
- "read_by": "John Doe",
- "reason": "",
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
- "source": "ECP",
- "status": "valid",
+ "timestamp": "2022-10-10T10:00:00Z",
"external_id": "string",
- "remark": "Customer reported unusual consumption",
"metadata": {
"registration_id": "1234567890",
"business_unit": "ABC"
},
+ "operation": "create",
+ "value": 240,
+ "source": "ECP",
+ "read_by": "John Doe",
+ "reason": "",
+ "status": "valid",
+ "remark": "Customer reported unusual consumption",
"note": "string",
- "unit": "string",
- "operation": "create"
+ "unit": "string"
}
]
}'
@@ -936,7 +966,7 @@ epilot metering batchWriteMeterReadings --jsonata 'data'
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -956,9 +986,74 @@ epilot metering batchWriteMeterReadings --jsonata 'data'
---
+### `pruneMeterReadings`
+
+Deletes every reading of a meter whose `external_id` is NOT in the provided keep list — in a single request.
+
+`POST /v2/metering/readings/prune`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `async` | query | boolean | No | Don't wait for the deletions to become visible in GetReadings API. Useful for large prunes |
+| `activity_id` | query | string (ulid) | No | Activity to include in event feed |
+| `create_ticket` | query | boolean | No | Controls whether a manual-intervention ("Übermittlung Zählerstand") ticket is created for the
+written readings. Defaults to true, preserving portal/journey behaviour (readings with
+source ECP or journ |
+| `dry_run` | query | boolean | No | When true, computes and returns the deleted/kept counts without deleting anything. |
+
+**Request Body** (required)
+
+**Sample Call**
+
+```bash
+epilot metering pruneMeterReadings
+```
+
+With request body:
+
+```bash
+epilot metering pruneMeterReadings \
+ -d '{
+ "meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
+ "counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
+ "source": "ECP",
+ "keep_external_ids": ["erp-reading-1", "erp-reading-2"]
+}'
+```
+
+Using stdin pipe:
+
+```bash
+cat body.json | epilot metering pruneMeterReadings
+```
+
+With JSONata filter:
+
+```bash
+epilot metering pruneMeterReadings --jsonata 'data'
+```
+
+
+Sample Response
+
+```json
+{
+ "data": {
+ "deleted_count": 42,
+ "kept_count": 12
+ }
+}
+```
+
+
+
+---
+
### `createMeterReadingFromSubmission`
-Creates a reading from a journey submission.
+Creates meter readings from a journey submission payload.
`POST /v1/metering/reading/submission`
@@ -1034,7 +1129,7 @@ epilot metering createMeterReadingFromSubmission --jsonata 'message'
### `getAllowedReadingForMeter`
-Get allowed reading for the given meter
+Returns the allowed min/max reading range for each counter of the given meter.
`GET /v1/metering/allowed/reading/{meter_id}`
@@ -1085,7 +1180,7 @@ epilot metering getAllowedReadingForMeter -p meter_id=123e4567-e89b-12d3-a456-42
### `createReadingWithMeter`
-Creates a reading along with a meter.
+Creates a meter reading along with meter lookup or creation by MA-LO ID and OBIS number.
`POST /v1/metering/reading/with-meter`
@@ -1140,7 +1235,7 @@ epilot metering createReadingWithMeter --jsonata 'data'
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -1182,6 +1277,7 @@ If this value is provided as -1, then it returns all results at once.
If this value is provided as "cumulative", then actual re |
| `sort` | query | "asc" \| "desc" | No | If this value is provided as "asc", then the results will be sorted by the timestamp field in ascending order.
If this value is provided as "desc", then the results will be sorted by the timestamp fie |
+| `include_pending_changesets` | query | boolean | No | When true, the response includes a `pending_changesets` field with the list of pending reading changesets alongside the confirmed readings. |
**Sample Call**
@@ -1217,7 +1313,7 @@ epilot metering getReadingsByInterval -p meter_id=123e4567-e89b-12d3-a456-426614
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -1241,7 +1337,7 @@ epilot metering getReadingsByInterval -p meter_id=123e4567-e89b-12d3-a456-426614
### `updateMeterReading`
-Updates a meter reading.
+Updates an existing meter reading identified by meter ID, counter ID, and timestamp.
`PUT /v1/metering/reading/{meter_id}/{counter_id}`
@@ -1278,7 +1374,7 @@ epilot metering updateMeterReading \
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -1320,7 +1416,7 @@ epilot metering updateMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174
"meter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"counter_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"direction": "feed-in",
- "timestamp": "2022-10-10T00:00:00.000Z",
+ "timestamp": "2022-10-10",
"source": "ECP",
"status": "valid",
"external_id": "string",
@@ -1341,7 +1437,7 @@ epilot metering updateMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174
### `deleteMeterReading`
-Deletes a meter reading.
+Permanently deletes a meter reading identified by meter ID, counter ID, and timestamp.
`DELETE /v1/metering/reading/{meter_id}/{counter_id}`
@@ -1390,3 +1486,402 @@ epilot metering deleteMeterReading -p meter_id=123e4567-e89b-12d3-a456-426614174
---
+
+### `getReadingChangesets`
+
+`GET /v1/metering/reading/{meter_id}/{counter_id}/changesets`
+
+**Parameters**
+
+| Name | In | Type | Required | Description |
+| ---- | -- | ---- | -------- | ----------- |
+| `meter_id` | path | string | Yes | The ID of the meter. |
+| `counter_id` | path | string | Yes | The ID of the counter. |
+
+**Sample Call**
+
+```bash
+epilot metering getReadingChangesets \
+ -p meter_id=123e4567-e89b-12d3-a456-426614174000 \
+ -p counter_id=123e4567-e89b-12d3-a456-426614174000
+```
+
+Using positional args for path parameters:
+
+```bash
+epilot metering getReadingChangesets 123e4567-e89b-12d3-a456-426614174000 123e4567-e89b-12d3-a456-426614174000
+```
+
+With JSONata filter:
+
+```bash
+epilot metering getReadingChangesets -p meter_id=123e4567-e89b-12d3-a456-426614174000 -p counter_id=123e4567-e89b-12d3-a456-426614174000 --jsonata 'changesets'
+```
+
+