OpenMeter OSS quickstart
August 11, 2026 ยท View on GitHub
Run a complete local OpenMeter stack, send a usage event, and query its metered value.
Prerequisites
- Docker with Compose
- Git
- one of:
- Bash and
curl - Node.js 22+ and npm for TypeScript
- Python 3.9+ and pip for Python
- Bash and
1. Start OpenMeter
git clone https://github.com/openmeterio/openmeter.git
cd openmeter/quickstart
docker compose up -d --wait
The API is available at http://localhost:48888. The Compose stack also starts
OpenMeter's workers and local Kafka, ClickHouse, PostgreSQL, Redis, and Svix
dependencies.
Note
This setup uses latest OpenMeter images and development-grade dependencies.
It is intended for local evaluation, not production.
2. Meter an event
The included configuration defines an api_requests_total meter that counts
events with type request. Choose a client; each example sends one event and
polls until its asynchronous processing completes.
Bash (curl)
curl -sS -o /dev/null -w '%{http_code}\n' \
-X POST http://localhost:48888/api/v1/events \
-H 'Content-Type: application/cloudevents+json' \
--data-raw '{
"specversion": "1.0",
"type": "request",
"id": "quickstart-curl-1",
"source": "quickstart",
"subject": "quickstart-curl",
"data": { "method": "GET", "route": "/hello" }
}'
response=
for attempt in 1 2 3 4 5 6 7 8 9 10; do
response=$(curl -fsS 'http://localhost:48888/api/v1/meters/api_requests_total/query?subject=quickstart-curl')
printf '%s' "$response" | grep -q '"value":1' && break
sleep 1
done
printf '%s\n' "$response"
The ingest prints 204; the query response contains
"subject":"quickstart-curl" and "value":1.
TypeScript SDK
Install the OpenMeter TypeScript SDK:
npm install @openmeter/sdk tsx
Save as quickstart.ts, then run npx tsx quickstart.ts:
import { OpenMeter } from '@openmeter/sdk'
const openmeter = new OpenMeter({ baseUrl: 'http://localhost:48888' })
const queryUsage = () =>
openmeter.meters.query('api_requests_total', {
subject: ['quickstart-typescript'],
})
async function main() {
await openmeter.events.ingest({
type: 'request',
id: 'quickstart-typescript-1',
source: 'quickstart',
subject: 'quickstart-typescript',
data: { method: 'GET', route: '/hello' },
})
let usage = await queryUsage()
for (let attempt = 1; usage.data[0]?.value !== 1 && attempt < 10; attempt++) {
await new Promise((resolve) => setTimeout(resolve, 1000))
usage = await queryUsage()
}
if (usage.data[0]?.value !== 1) {
throw new Error('usage was not processed in time')
}
console.log(usage.data[0].value)
}
main().catch((error) => {
console.error(error)
process.exitCode = 1
})
The script prints 1.
Python SDK
The Python SDK is in preview, so install it with pre-releases enabled:
python -m pip install --pre openmeter
Save as quickstart.py, then run python quickstart.py:
import time
from openmeter import Client
from openmeter.models import Event
with Client(endpoint="http://localhost:48888") as openmeter:
openmeter.events.ingest_event(
Event(
id="quickstart-python-1",
source="quickstart",
specversion="1.0",
type="request",
subject="quickstart-python",
data={"method": "GET", "route": "/hello"},
)
)
for _ in range(10):
usage = openmeter.meters.query_json(
"api_requests_total",
subject=["quickstart-python"],
)
if usage.data and usage.data[0].value == 1:
break
time.sleep(1)
else:
raise RuntimeError("usage was not processed in time")
print(usage.data[0].value)
The script prints 1.0.
3. Explore
Group usage by hour, method, and route:
curl 'http://localhost:48888/api/v1/meters/api_requests_total/query?windowSize=HOUR&groupBy=method&groupBy=route'
Then continue with:
- how meters and customer attribution work
- common AI, API, and compute metering examples
- entitlements and usage limits
- plans, pricing, and subscriptions
- the OSS API reference
- the Kubernetes deployment guide
Cleanup
Remove the quickstart containers and their data volumes:
docker compose down -v