curl -X POST "https://api-meter.metrifox.com/usage/events" \
-H "x-api-key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"customer_key": "cust-6d11ca90",
"feature_key": "monthly_active_users",
"quantity": 1,
"event_id": "evt_mau_001",
"properties": { "user_id": "usr_42" }
}'from metrifox_sdk import MetrifoxClient
import time
client = MetrifoxClient(api_key="your_api_key")
# Basic usage recording
response = client.usages.record_usage({
"customer_key": "cust-6d11ca90",
"event_name": "candidate.sourced",
"quantity": 2,
"event_id": "evt_12345", # required idempotency key
"timestamp": int(time.time() * 1000) # recommended
})
# Usage recording with all optional fields
response = client.usages.record_usage({
"customer_key": "cust-6d11ca90",
"event_name": "premium.feature",
"quantity": 3,
"credit_used": 10,
"event_id": "evt_external_789",
"timestamp": 1703246400000,
"metadata": {
"feature_type": "advanced",
"user_tier": "premium"
}
})
import { init } from "metrifox-js";
const metrifoxClient = init({
apiKey: process.env.METRIFOX_API_KEY
});
// Basic usage recording
await metrifoxClient.usages.recordUsage({
customerKey: "cust-6d11ca90",
eventName: "candidate.sourced",
quantity: 2,
eventId: "evt_12345", // required idempotency key
timestamp: Date.now() // recommended
});
// Usage recording with all optional fields
await metrifoxClient.usages.recordUsage({
customerKey: "cust-6d11ca90",
eventName: "premium.feature",
quantity: 3,
creditUsed: 10,
eventId: "evt_external_789",
timestamp: 1703246400000,
metadata: {
feature_type: "advanced",
user_tier: "premium"
}
});
require 'metrifox-sdk'
# Initialize with configuration
METRIFOX_SDK = MetrifoxSDK.init({ api_key: "your-api-key" })
# Basic usage recording
response = METRIFOX_SDK.usages.record_usage({
customer_key: "cust-6d11ca90",
event_name: "candidate.sourced",
quantity: 2,
event_id: "evt_12345", # required idempotency key
timestamp: (Time.now.to_f * 1000).to_i # recommended
})
# Usage recording with all optional fields
response = METRIFOX_SDK.usages.record_usage({
customer_key: "cust-6d11ca90",
event_name: "premium.feature",
quantity: 3,
credit_used: 10,
event_id: "evt_external_789",
timestamp: 1703246400000,
metadata: {
feature_type: "advanced",
user_tier: "premium"
}
})
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-meter.metrifox.com/usage/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customer_key' => 'cust-6d11ca90',
'event_name' => 'candidate.sourced',
'quantity' => 2,
'event_id' => 'evt_12345',
'timestamp' => 1703073600000,
'metadata' => [
'source' => 'linkedin',
'job_title' => 'Software Engineer'
]
]),
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-meter.metrifox.com/usage/events"
payload := strings.NewReader("{\n \"customer_key\": \"cust-6d11ca90\",\n \"event_name\": \"candidate.sourced\",\n \"quantity\": 2,\n \"event_id\": \"evt_12345\",\n \"timestamp\": 1703073600000,\n \"metadata\": {\n \"source\": \"linkedin\",\n \"job_title\": \"Software Engineer\"\n }\n}")
req, _ := http.NewRequest("POST", 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.post("https://api-meter.metrifox.com/usage/events")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer_key\": \"cust-6d11ca90\",\n \"event_name\": \"candidate.sourced\",\n \"quantity\": 2,\n \"event_id\": \"evt_12345\",\n \"timestamp\": 1703073600000,\n \"metadata\": {\n \"source\": \"linkedin\",\n \"job_title\": \"Software Engineer\"\n }\n}")
.asString();{
"data": {
"customer_key": "cust-mit7k5v8obzs",
"quantity": 1,
"feature_key": "feature_job_posts"
},
"message": "Event received"
}{
"message": "Validation failed",
"errors": {
"customer_key": [
"is required"
],
"event_name": [
"either event_name or feature_key is required"
],
"event_id": [
"is required"
],
"quantity": [
"must be a positive number"
]
}
}{
"message": "Unauthorized"
}{
"message": "Customer not found"
}{
"message": "Validation failed",
"errors": {
"quantity": [
"must be greater than 0"
]
}
}Record a Usage Event
Records a usage event for a specific customer and feature. This endpoint is used to track feature usage for billing and quota management purposes.
curl -X POST "https://api-meter.metrifox.com/usage/events" \
-H "x-api-key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"customer_key": "cust-6d11ca90",
"feature_key": "monthly_active_users",
"quantity": 1,
"event_id": "evt_mau_001",
"properties": { "user_id": "usr_42" }
}'from metrifox_sdk import MetrifoxClient
import time
client = MetrifoxClient(api_key="your_api_key")
# Basic usage recording
response = client.usages.record_usage({
"customer_key": "cust-6d11ca90",
"event_name": "candidate.sourced",
"quantity": 2,
"event_id": "evt_12345", # required idempotency key
"timestamp": int(time.time() * 1000) # recommended
})
# Usage recording with all optional fields
response = client.usages.record_usage({
"customer_key": "cust-6d11ca90",
"event_name": "premium.feature",
"quantity": 3,
"credit_used": 10,
"event_id": "evt_external_789",
"timestamp": 1703246400000,
"metadata": {
"feature_type": "advanced",
"user_tier": "premium"
}
})
import { init } from "metrifox-js";
const metrifoxClient = init({
apiKey: process.env.METRIFOX_API_KEY
});
// Basic usage recording
await metrifoxClient.usages.recordUsage({
customerKey: "cust-6d11ca90",
eventName: "candidate.sourced",
quantity: 2,
eventId: "evt_12345", // required idempotency key
timestamp: Date.now() // recommended
});
// Usage recording with all optional fields
await metrifoxClient.usages.recordUsage({
customerKey: "cust-6d11ca90",
eventName: "premium.feature",
quantity: 3,
creditUsed: 10,
eventId: "evt_external_789",
timestamp: 1703246400000,
metadata: {
feature_type: "advanced",
user_tier: "premium"
}
});
require 'metrifox-sdk'
# Initialize with configuration
METRIFOX_SDK = MetrifoxSDK.init({ api_key: "your-api-key" })
# Basic usage recording
response = METRIFOX_SDK.usages.record_usage({
customer_key: "cust-6d11ca90",
event_name: "candidate.sourced",
quantity: 2,
event_id: "evt_12345", # required idempotency key
timestamp: (Time.now.to_f * 1000).to_i # recommended
})
# Usage recording with all optional fields
response = METRIFOX_SDK.usages.record_usage({
customer_key: "cust-6d11ca90",
event_name: "premium.feature",
quantity: 3,
credit_used: 10,
event_id: "evt_external_789",
timestamp: 1703246400000,
metadata: {
feature_type: "advanced",
user_tier: "premium"
}
})
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-meter.metrifox.com/usage/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'customer_key' => 'cust-6d11ca90',
'event_name' => 'candidate.sourced',
'quantity' => 2,
'event_id' => 'evt_12345',
'timestamp' => 1703073600000,
'metadata' => [
'source' => 'linkedin',
'job_title' => 'Software Engineer'
]
]),
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-meter.metrifox.com/usage/events"
payload := strings.NewReader("{\n \"customer_key\": \"cust-6d11ca90\",\n \"event_name\": \"candidate.sourced\",\n \"quantity\": 2,\n \"event_id\": \"evt_12345\",\n \"timestamp\": 1703073600000,\n \"metadata\": {\n \"source\": \"linkedin\",\n \"job_title\": \"Software Engineer\"\n }\n}")
req, _ := http.NewRequest("POST", 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.post("https://api-meter.metrifox.com/usage/events")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"customer_key\": \"cust-6d11ca90\",\n \"event_name\": \"candidate.sourced\",\n \"quantity\": 2,\n \"event_id\": \"evt_12345\",\n \"timestamp\": 1703073600000,\n \"metadata\": {\n \"source\": \"linkedin\",\n \"job_title\": \"Software Engineer\"\n }\n}")
.asString();{
"data": {
"customer_key": "cust-mit7k5v8obzs",
"quantity": 1,
"feature_key": "feature_job_posts"
},
"message": "Event received"
}{
"message": "Validation failed",
"errors": {
"customer_key": [
"is required"
],
"event_name": [
"either event_name or feature_key is required"
],
"event_id": [
"is required"
],
"quantity": [
"must be a positive number"
]
}
}{
"message": "Unauthorized"
}{
"message": "Customer not found"
}{
"message": "Validation failed",
"errors": {
"quantity": [
"must be greater than 0"
]
}
}Usage endpoints are served from https://api-meter.metrifox.com. Other API calls stay on https://api.metrifox.com.Important Notes:
event_id(required) is required for idempotency: You generate a unique UUID per real event. This prevents duplicates if sent multiple times. Metrifox will always send back a 200 response if the event is consumable but will record it only once per event_id.feature_key(this is required if there is no event_name): The unique key of the metered feature (from dashboard).event_name(optional if feature_key is already provided): One of the event names configured on the feature (e.g., “api_request” or “image_generated”)- Include a
timestamp(ms) when possible to aid ordering/debugging. properties(required forCOUNT_UNIQUEfeatures): The values of the feature’s aggregation properties for this event, e.g.{ "account_id": "acct_1" }. Send the values as strings — they are compared exactly and as strings, so1and"1"are the same value but1.0is a different one.nullcounts as omitting the property, and is rejected. Optional otherwise —SUMandCOUNTfeatures ignore it.
COUNT_UNIQUE feature records one unit the first time a value is seen in the period, and nothing
for repeats. An event that omits a configured property is rejected. On persistent-use features,
send the same property values with a negative quantity to release the value. See
Understanding Features for the full behaviour.{
"data": {
"customer_key": "cust-mit7k5v8obzs",
"quantity": 1,
"feature_key": "feature_job_posts"
},
"message": "Event received"
}
Authorizations
Body
The unique customer identifier in your application
Required idempotency key for this event. Must be unique per event.
The name of the event as set up in the Metrifox platform. Either event_name or feature_key is required.
Feature key associated with this usage event. Either event_name or feature_key is required.
The quantity of usage. Defaults to 1 if not provided
Optional credits used for this event
Unix timestamp (in milliseconds) when the event occurred. Defaults to current time if not provided. Supplying this improves ordering and debugging.
The values of the feature's aggregation properties for this event. Required for features whose aggregation method is count_unique, which counts one unit the first time a value is seen in the period; an event that omits a configured property, or sends it as null, is rejected. Values are compared exactly and as strings: ACC_1 and acc_1 are two different values, while 1 and "1" are the same one. Send identifiers as strings — a value sent as 1 by one client and 1.0 by another would otherwise count twice. Ignored by sum and count features.
Show child attributes
Show child attributes
Optional metadata to attach to the event

