File size: 3,407 Bytes
6380833 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | # Quickstart
## Prerequisites
- Docker (with Compose)
- curl
- jq
Clone the repository:
```sh
git clone git@github.com:openmeterio/openmeter.git
cd openmeter/quickstart
```
## 1. Launch OpenMeter
Launch OpenMeter and its dependencies via:
```sh
docker compose up -d
```
## 2. Ingest usage event(s)
Ingest usage events in [CloudEvents](https://cloudevents.io/) format:
```sh
curl -X POST http://localhost:48888/api/v1/events \
-H 'Content-Type: application/cloudevents+json' \
--data-raw '
{
"specversion" : "1.0",
"type": "request",
"id": "00001",
"time": "2026-07-07T00:00:00.001Z",
"source": "service-0",
"subject": "customer-1",
"data": {
"method": "GET",
"route": "/hello",
"duration_ms": 10
}
}
'
```
Note how ID is different:
```sh
curl -X POST http://localhost:48888/api/v1/events \
-H 'Content-Type: application/cloudevents+json' \
--data-raw '
{
"specversion" : "1.0",
"type": "request",
"id": "00002",
"time": "2026-07-07T00:00:00.001Z",
"source": "service-0",
"subject": "customer-1",
"data": {
"method": "GET",
"route": "/hello",
"duration_ms": 20
}
}
'
```
Note how ID and time are different:
```sh
curl -X POST http://localhost:48888/api/v1/events \
-H 'Content-Type: application/cloudevents+json' \
--data-raw '
{
"specversion" : "1.0",
"type": "request",
"id": "00003",
"time": "2026-07-08T00:00:00.001Z",
"source": "service-0",
"subject": "customer-1",
"data": {
"method": "GET",
"route": "/hello",
"duration_ms": 30
}
}
'
```
## 3. Query Usage
Query the usage hourly:
```sh
curl 'http://localhost:48888/api/v1/meters/api_requests_total/query?windowSize=HOUR&groupBy=method&groupBy=route' | jq
```
```json
{
"windowSize": "HOUR",
"data": [
{
"value": 2,
"windowStart": "2026-07-07T00:00:00Z",
"windowEnd": "2026-07-07T01:00:00Z",
"subject": null,
"groupBy": {
"method": "GET",
"route": "/hello"
}
},
{
"value": 1,
"windowStart": "2026-07-08T00:00:00Z",
"windowEnd": "2026-07-08T01:00:00Z",
"subject": null,
"groupBy": {
"method": "GET",
"route": "/hello"
}
}
]
}
```
Query the total usage for `customer-1`:
```sh
curl 'http://localhost:48888/api/v1/meters/api_requests_total/query?subject=customer-1' | jq
```
```json
{
"data": [
{
"value": 3,
"windowStart": "2026-07-07T00:00:00Z",
"windowEnd": "2026-07-08T00:01:00Z",
"subject": "customer-1",
"groupBy": {}
}
]
}
```
## 4. Configure additional meter(s) _(optional)_
In this example we will meter LLM token usage, groupped by AI model and prompt type.
You can think about it how OpenAI [charges](https://openai.com/pricing) by tokens for ChatGPT.
Configure how OpenMeter should process your usage events in this new `tokens_total` meter.
```yaml
# ...
meters:
# Sample meter to count LLM Token Usage
- slug: tokens_total
description: AI Token Usage
eventType: prompt # Filter events by type
aggregation: SUM
valueProperty: $.tokens # JSONPath to parse usage value
groupBy:
model: $.model # AI model used: gpt4-turbo, etc.
type: $.type # Prompt type: input, output, system
```
## Cleanup
Once you are done, stop any running instances:
```sh
docker compose down -v
```
|