Create a single metric
curl -X POST 'https://api.growthbook.io/api/v1/metrics' \
-H 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.growthbook.io/api/v1/metrics"
payload = {
"datasourceId": "<string>",
"name": "<string>",
"owner": "<string>",
"description": "<string>",
"tags": ["<string>"],
"projects": ["<string>"],
"archived": True,
"behavior": {
"cap": 1,
"capValue": 1,
"conversionWindowStart": 123,
"conversionWindowEnd": 123,
"riskThresholdSuccess": 1,
"riskThresholdDanger": 1,
"minPercentChange": 1,
"maxPercentChange": 1,
"minSampleSize": 1,
"targetMDE": 1
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
datasourceId: '<string>',
name: '<string>',
owner: '<string>',
description: '<string>',
tags: ['<string>'],
projects: ['<string>'],
archived: true,
behavior: {
cap: 1,
capValue: 1,
conversionWindowStart: 123,
conversionWindowEnd: 123,
riskThresholdSuccess: 1,
riskThresholdDanger: 1,
minPercentChange: 1,
maxPercentChange: 1,
minSampleSize: 1,
targetMDE: 1
}
})
};
fetch('https://api.growthbook.io/api/v1/metrics', 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.growthbook.io/api/v1/metrics",
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([
'datasourceId' => '<string>',
'name' => '<string>',
'owner' => '<string>',
'description' => '<string>',
'tags' => [
'<string>'
],
'projects' => [
'<string>'
],
'archived' => true,
'behavior' => [
'cap' => 1,
'capValue' => 1,
'conversionWindowStart' => 123,
'conversionWindowEnd' => 123,
'riskThresholdSuccess' => 1,
'riskThresholdDanger' => 1,
'minPercentChange' => 1,
'maxPercentChange' => 1,
'minSampleSize' => 1,
'targetMDE' => 1
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.growthbook.io/api/v1/metrics"
payload := strings.NewReader("{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.growthbook.io/api/v1/metrics")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.growthbook.io/api/v1/metrics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}"
response = http.request(request)
puts response.read_body{
"metric": {
"id": "<string>",
"managedBy": "",
"dateCreated": "<string>",
"dateUpdated": "<string>",
"owner": "<string>",
"datasourceId": "<string>",
"name": "<string>",
"description": "<string>",
"type": "binomial",
"tags": [
"<string>"
],
"projects": [
"<string>"
],
"archived": true,
"behavior": {
"goal": "increase",
"windowSettings": {
"type": "none",
"delayValue": 123,
"delayUnit": "minutes",
"windowValue": 123,
"windowUnit": "minutes"
},
"riskThresholdSuccess": 123,
"riskThresholdDanger": 123,
"minPercentChange": 123,
"maxPercentChange": 123,
"minSampleSize": 123,
"targetMDE": 123,
"cappingSettings": {
"type": "none",
"value": 123,
"ignoreZeros": true
},
"cap": 123,
"capping": "absolute",
"capValue": 123,
"priorSettings": {
"override": true,
"proper": true,
"mean": 123,
"stddev": 123
},
"conversionWindowStart": 123,
"conversionWindowEnd": 123
},
"ownerEmail": "<string>",
"sql": {
"identifierTypes": [
"<string>"
],
"conversionSQL": "<string>",
"userAggregationSQL": "<string>",
"denominatorMetricId": "<string>"
},
"sqlBuilder": {
"identifierTypeColumns": [
{
"identifierType": "<string>",
"columnName": "<string>"
}
],
"tableName": "<string>",
"valueColumnName": "<string>",
"timestampColumnName": "<string>",
"conditions": [
{
"column": "<string>",
"operator": "<string>",
"value": "<string>"
}
]
},
"mixpanel": {
"eventName": "<string>",
"eventValue": "<string>",
"userAggregation": "<string>",
"conditions": [
{
"property": "<string>",
"operator": "<string>",
"value": "<string>"
}
]
}
}
}{
"confirmation": {
"id": "<string>",
"status": "pending",
"actions": [
{
"action": "feature.create",
"environments": [
"<string>"
]
}
],
"summary": "<string>",
"url": "<string>",
"expiresAt": "<string>",
"response": {
"status": 123,
"body": "<unknown>"
},
"note": "<string>"
},
"message": "<string>"
}Authorizations
If using Bearer auth, pass the Secret Key as the token:
curl https://api.growthbook.io/api/v1/features -H "Authorization: Bearer secret_abc123DEF456"
Body
ID for the DataSource
Short display name (e.g. Purchases per user). Put the definition in description.
Type of metric. See Metrics documentation
binomial, count, duration, revenue Where this metric must be managed from. If not set (empty string), it can be managed from anywhere. If set to "api", it can be managed via the API only.
, api The userId or email address of the owner. If an email address is provided, it will be used to look up the userId of the matching organization member. If an ID is provided, it will be validated as existing in the organization.
Markdown. Put context here, not in the name.
10000Tags for filtering and grouping. Use these instead of encoding groups in names.
List of project IDs for projects that can access this metric
Show child attributes
Show child attributes
Preferred way to define SQL. Only one of sql, sqlBuilder or mixpanel allowed, and at least one must be specified.
Show child attributes
Show child attributes
An alternative way to specify a SQL metric, rather than a full query. Using sql is preferred to sqlBuilder. Only one of sql, sqlBuilder or mixpanel allowed, and at least one must be specified.
Show child attributes
Show child attributes
Only use for MixPanel (non-SQL) Data Sources. Only one of sql, sqlBuilder or mixpanel allowed, and at least one must be specified.
Show child attributes
Show child attributes
Response
Resource created
Show child attributes
Show child attributes
Was this page helpful?
curl -X POST 'https://api.growthbook.io/api/v1/metrics' \
-H 'Authorization: Bearer YOUR_API_KEY'import requests
url = "https://api.growthbook.io/api/v1/metrics"
payload = {
"datasourceId": "<string>",
"name": "<string>",
"owner": "<string>",
"description": "<string>",
"tags": ["<string>"],
"projects": ["<string>"],
"archived": True,
"behavior": {
"cap": 1,
"capValue": 1,
"conversionWindowStart": 123,
"conversionWindowEnd": 123,
"riskThresholdSuccess": 1,
"riskThresholdDanger": 1,
"minPercentChange": 1,
"maxPercentChange": 1,
"minSampleSize": 1,
"targetMDE": 1
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
datasourceId: '<string>',
name: '<string>',
owner: '<string>',
description: '<string>',
tags: ['<string>'],
projects: ['<string>'],
archived: true,
behavior: {
cap: 1,
capValue: 1,
conversionWindowStart: 123,
conversionWindowEnd: 123,
riskThresholdSuccess: 1,
riskThresholdDanger: 1,
minPercentChange: 1,
maxPercentChange: 1,
minSampleSize: 1,
targetMDE: 1
}
})
};
fetch('https://api.growthbook.io/api/v1/metrics', 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.growthbook.io/api/v1/metrics",
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([
'datasourceId' => '<string>',
'name' => '<string>',
'owner' => '<string>',
'description' => '<string>',
'tags' => [
'<string>'
],
'projects' => [
'<string>'
],
'archived' => true,
'behavior' => [
'cap' => 1,
'capValue' => 1,
'conversionWindowStart' => 123,
'conversionWindowEnd' => 123,
'riskThresholdSuccess' => 1,
'riskThresholdDanger' => 1,
'minPercentChange' => 1,
'maxPercentChange' => 1,
'minSampleSize' => 1,
'targetMDE' => 1
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.growthbook.io/api/v1/metrics"
payload := strings.NewReader("{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.growthbook.io/api/v1/metrics")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.growthbook.io/api/v1/metrics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"datasourceId\": \"<string>\",\n \"name\": \"<string>\",\n \"owner\": \"<string>\",\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"projects\": [\n \"<string>\"\n ],\n \"archived\": true,\n \"behavior\": {\n \"cap\": 1,\n \"capValue\": 1,\n \"conversionWindowStart\": 123,\n \"conversionWindowEnd\": 123,\n \"riskThresholdSuccess\": 1,\n \"riskThresholdDanger\": 1,\n \"minPercentChange\": 1,\n \"maxPercentChange\": 1,\n \"minSampleSize\": 1,\n \"targetMDE\": 1\n }\n}"
response = http.request(request)
puts response.read_body{
"metric": {
"id": "<string>",
"managedBy": "",
"dateCreated": "<string>",
"dateUpdated": "<string>",
"owner": "<string>",
"datasourceId": "<string>",
"name": "<string>",
"description": "<string>",
"type": "binomial",
"tags": [
"<string>"
],
"projects": [
"<string>"
],
"archived": true,
"behavior": {
"goal": "increase",
"windowSettings": {
"type": "none",
"delayValue": 123,
"delayUnit": "minutes",
"windowValue": 123,
"windowUnit": "minutes"
},
"riskThresholdSuccess": 123,
"riskThresholdDanger": 123,
"minPercentChange": 123,
"maxPercentChange": 123,
"minSampleSize": 123,
"targetMDE": 123,
"cappingSettings": {
"type": "none",
"value": 123,
"ignoreZeros": true
},
"cap": 123,
"capping": "absolute",
"capValue": 123,
"priorSettings": {
"override": true,
"proper": true,
"mean": 123,
"stddev": 123
},
"conversionWindowStart": 123,
"conversionWindowEnd": 123
},
"ownerEmail": "<string>",
"sql": {
"identifierTypes": [
"<string>"
],
"conversionSQL": "<string>",
"userAggregationSQL": "<string>",
"denominatorMetricId": "<string>"
},
"sqlBuilder": {
"identifierTypeColumns": [
{
"identifierType": "<string>",
"columnName": "<string>"
}
],
"tableName": "<string>",
"valueColumnName": "<string>",
"timestampColumnName": "<string>",
"conditions": [
{
"column": "<string>",
"operator": "<string>",
"value": "<string>"
}
]
},
"mixpanel": {
"eventName": "<string>",
"eventValue": "<string>",
"userAggregation": "<string>",
"conditions": [
{
"property": "<string>",
"operator": "<string>",
"value": "<string>"
}
]
}
}
}{
"confirmation": {
"id": "<string>",
"status": "pending",
"actions": [
{
"action": "feature.create",
"environments": [
"<string>"
]
}
],
"summary": "<string>",
"url": "<string>",
"expiresAt": "<string>",
"response": {
"status": 123,
"body": "<unknown>"
},
"note": "<string>"
},
"message": "<string>"
}
