curl --request PATCH \
--url https://api.creem.io/v1/meters/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "Image generations (v2)",
"aggregation": "sum",
"aggregation_property": "tokens"
}
'import requests
url = "https://api.creem.io/v1/meters/{id}"
payload = {
"name": "Image generations (v2)",
"aggregation": "sum",
"aggregation_property": "tokens"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Image generations (v2)',
aggregation: 'sum',
aggregation_property: 'tokens'
})
};
fetch('https://api.creem.io/v1/meters/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.creem.io/v1/meters/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Image generations (v2)',
'aggregation' => 'sum',
'aggregation_property' => 'tokens'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.creem.io/v1/meters/{id}"
payload := strings.NewReader("{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.creem.io/v1/meters/{id}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.creem.io/v1/meters/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}"
response = http.request(request)
puts response.read_body{
"id": "mtr_abc123",
"store_id": "sto_abc123",
"name": "Image generations",
"event_name": "image.generated",
"aggregation": "sum",
"aggregation_property": "tokens",
"filter": {
"conjunction": "and",
"clauses": [
{
"property": "tier",
"operator": "equals",
"value": "pro"
}
]
},
"unit_label": "images",
"status": "active",
"created_at": "<string>",
"updated_at": "<string>"
}{
"error": {
"type": "invalid_request_error",
"code": "meter_name_taken",
"message": "A meter named \"Image generations\" already exists in this store",
"request_id": "req_abc123def456",
"param": "events[3].customer_id",
"details": {
"archived_holder": true,
"archived_holder_id": "mtr_abc123"
}
}
}{
"error": {
"type": "invalid_request_error",
"code": "meter_name_taken",
"message": "A meter named \"Image generations\" already exists in this store",
"request_id": "req_abc123def456",
"param": "events[3].customer_id",
"details": {
"archived_holder": true,
"archived_holder_id": "mtr_abc123"
}
}
}Update a meter
Rename a meter and/or revise its definition. A rename is always allowed — the name is a label no aggregate depends on — but it must stay unique within the store (409 meter_name_taken). Definition changes (filter, aggregation, aggregation_property) are only accepted while the meter has processed no usage and has no associated purchase; otherwise the request is rejected with 409, because editing the definition would silently rewrite what already-recorded usage means. Send aggregation_property as null to clear it; omit it to leave it unchanged.
curl --request PATCH \
--url https://api.creem.io/v1/meters/{id} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "Image generations (v2)",
"aggregation": "sum",
"aggregation_property": "tokens"
}
'import requests
url = "https://api.creem.io/v1/meters/{id}"
payload = {
"name": "Image generations (v2)",
"aggregation": "sum",
"aggregation_property": "tokens"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Image generations (v2)',
aggregation: 'sum',
aggregation_property: 'tokens'
})
};
fetch('https://api.creem.io/v1/meters/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.creem.io/v1/meters/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Image generations (v2)',
'aggregation' => 'sum',
'aggregation_property' => 'tokens'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.creem.io/v1/meters/{id}"
payload := strings.NewReader("{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.creem.io/v1/meters/{id}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.creem.io/v1/meters/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Image generations (v2)\",\n \"aggregation\": \"sum\",\n \"aggregation_property\": \"tokens\"\n}"
response = http.request(request)
puts response.read_body{
"id": "mtr_abc123",
"store_id": "sto_abc123",
"name": "Image generations",
"event_name": "image.generated",
"aggregation": "sum",
"aggregation_property": "tokens",
"filter": {
"conjunction": "and",
"clauses": [
{
"property": "tier",
"operator": "equals",
"value": "pro"
}
]
},
"unit_label": "images",
"status": "active",
"created_at": "<string>",
"updated_at": "<string>"
}{
"error": {
"type": "invalid_request_error",
"code": "meter_name_taken",
"message": "A meter named \"Image generations\" already exists in this store",
"request_id": "req_abc123def456",
"param": "events[3].customer_id",
"details": {
"archived_holder": true,
"archived_holder_id": "mtr_abc123"
}
}
}{
"error": {
"type": "invalid_request_error",
"code": "meter_name_taken",
"message": "A meter named \"Image generations\" already exists in this store",
"request_id": "req_abc123def456",
"param": "events[3].customer_id",
"details": {
"archived_holder": true,
"archived_holder_id": "mtr_abc123"
}
}
}Authorizations
API key for authentication. You can find your API key in the Creem dashboard under Settings > API Keys.
Path Parameters
Body
New meter name. Renaming is allowed even after the meter has processed usage — the name is a label, not part of the definition. Must stay unique within the store. Omit to leave unchanged; null is rejected.
"Image generations (v2)"
New aggregation. Part of the meter definition, so it is only editable while the meter has processed no usage and has no associated purchase. Omit to leave unchanged; null is rejected.
count, sum, average, min, max, unique "sum"
New aggregation property. Omit to leave unchanged; send null to clear it (only valid when the resulting aggregation is "count").
"tokens"
New filter. Part of the meter definition (see aggregation). Omit to leave unchanged; null is rejected — to remove a filter, send one with an empty clauses array.
Show child attributes
Show child attributes
Response
Meter updated
Meter ID
"mtr_abc123"
Store ID
"sto_abc123"
Meter name
"Image generations"
Usage event name the meter consumes
"image.generated"
Aggregation applied to matching events
count, sum, average, min, max, unique "sum"
Property the aggregation reduces; null for "count"
"tokens"
The meter filter; always present (empty clauses = match all)
Show child attributes
Show child attributes
Display unit
"images"
Whether the meter is active or archived
active, archived "active"
Creation timestamp (ISO 8601)
Last update timestamp (ISO 8601)