curl --request POST \
--url https://statsigapi.net/console/v1/metrics/metric_source \
--header 'Content-Type: application/json' \
--header 'STATSIG-API-KEY: <api-key>' \
--data '
{
"name": "<string>",
"sql": "<string>",
"timestampColumn": "<string>",
"idTypeMapping": [
{
"statsigUnitID": "<string>",
"column": "<string>"
}
],
"description": "<string>",
"tags": [
"<string>"
],
"timestampAsDay": true,
"tableName": "<string>",
"customFieldMapping": [
{
"key": "<string>",
"formula": "<string>"
}
],
"isReadOnly": true,
"owner": {
"ownerID": "user123",
"ownerType": "USER",
"ownerName": "John Doe",
"ownerEmail": "owner123@test.com"
},
"dryRun": true
}
'import requests
url = "https://statsigapi.net/console/v1/metrics/metric_source"
payload = {
"name": "<string>",
"sql": "<string>",
"timestampColumn": "<string>",
"idTypeMapping": [
{
"statsigUnitID": "<string>",
"column": "<string>"
}
],
"description": "<string>",
"tags": ["<string>"],
"timestampAsDay": True,
"tableName": "<string>",
"customFieldMapping": [
{
"key": "<string>",
"formula": "<string>"
}
],
"isReadOnly": True,
"owner": {
"ownerID": "user123",
"ownerType": "USER",
"ownerName": "John Doe",
"ownerEmail": "owner123@test.com"
},
"dryRun": True
}
headers = {
"STATSIG-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'STATSIG-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
sql: '<string>',
timestampColumn: '<string>',
idTypeMapping: [{statsigUnitID: '<string>', column: '<string>'}],
description: '<string>',
tags: ['<string>'],
timestampAsDay: true,
tableName: '<string>',
customFieldMapping: [{key: '<string>', formula: '<string>'}],
isReadOnly: true,
owner: {
ownerID: 'user123',
ownerType: 'USER',
ownerName: 'John Doe',
ownerEmail: 'owner123@test.com'
},
dryRun: true
})
};
fetch('https://statsigapi.net/console/v1/metrics/metric_source', 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://statsigapi.net/console/v1/metrics/metric_source",
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([
'name' => '<string>',
'sql' => '<string>',
'timestampColumn' => '<string>',
'idTypeMapping' => [
[
'statsigUnitID' => '<string>',
'column' => '<string>'
]
],
'description' => '<string>',
'tags' => [
'<string>'
],
'timestampAsDay' => true,
'tableName' => '<string>',
'customFieldMapping' => [
[
'key' => '<string>',
'formula' => '<string>'
]
],
'isReadOnly' => true,
'owner' => [
'ownerID' => 'user123',
'ownerType' => 'USER',
'ownerName' => 'John Doe',
'ownerEmail' => 'owner123@test.com'
],
'dryRun' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"STATSIG-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://statsigapi.net/console/v1/metrics/metric_source"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("STATSIG-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://statsigapi.net/console/v1/metrics/metric_source")
.header("STATSIG-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://statsigapi.net/console/v1/metrics/metric_source")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["STATSIG-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}"
response = http.request(request)
puts response.read_body{
"message": "Metric source created successfully.",
"data": {
"name": "test_metric_source2",
"description": "Test description for metric source",
"tags": [
"non_production"
],
"sql": "SELECT * FROM `shoppy-sales.logging.events`",
"timestampColumn": "ts",
"timestampAsDay": true,
"idTypeMapping": [
{
"statsigUnitID": "userID",
"column": "user_id"
}
],
"sourceType": "table",
"tableName": "shoppy-sales.logging.events"
}
}{
"status": 400,
"message": "Invalid request. Please check the request input and try again."
}{
"status": 401,
"message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
}Create Metric Source
curl --request POST \
--url https://statsigapi.net/console/v1/metrics/metric_source \
--header 'Content-Type: application/json' \
--header 'STATSIG-API-KEY: <api-key>' \
--data '
{
"name": "<string>",
"sql": "<string>",
"timestampColumn": "<string>",
"idTypeMapping": [
{
"statsigUnitID": "<string>",
"column": "<string>"
}
],
"description": "<string>",
"tags": [
"<string>"
],
"timestampAsDay": true,
"tableName": "<string>",
"customFieldMapping": [
{
"key": "<string>",
"formula": "<string>"
}
],
"isReadOnly": true,
"owner": {
"ownerID": "user123",
"ownerType": "USER",
"ownerName": "John Doe",
"ownerEmail": "owner123@test.com"
},
"dryRun": true
}
'import requests
url = "https://statsigapi.net/console/v1/metrics/metric_source"
payload = {
"name": "<string>",
"sql": "<string>",
"timestampColumn": "<string>",
"idTypeMapping": [
{
"statsigUnitID": "<string>",
"column": "<string>"
}
],
"description": "<string>",
"tags": ["<string>"],
"timestampAsDay": True,
"tableName": "<string>",
"customFieldMapping": [
{
"key": "<string>",
"formula": "<string>"
}
],
"isReadOnly": True,
"owner": {
"ownerID": "user123",
"ownerType": "USER",
"ownerName": "John Doe",
"ownerEmail": "owner123@test.com"
},
"dryRun": True
}
headers = {
"STATSIG-API-KEY": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'STATSIG-API-KEY': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
sql: '<string>',
timestampColumn: '<string>',
idTypeMapping: [{statsigUnitID: '<string>', column: '<string>'}],
description: '<string>',
tags: ['<string>'],
timestampAsDay: true,
tableName: '<string>',
customFieldMapping: [{key: '<string>', formula: '<string>'}],
isReadOnly: true,
owner: {
ownerID: 'user123',
ownerType: 'USER',
ownerName: 'John Doe',
ownerEmail: 'owner123@test.com'
},
dryRun: true
})
};
fetch('https://statsigapi.net/console/v1/metrics/metric_source', 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://statsigapi.net/console/v1/metrics/metric_source",
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([
'name' => '<string>',
'sql' => '<string>',
'timestampColumn' => '<string>',
'idTypeMapping' => [
[
'statsigUnitID' => '<string>',
'column' => '<string>'
]
],
'description' => '<string>',
'tags' => [
'<string>'
],
'timestampAsDay' => true,
'tableName' => '<string>',
'customFieldMapping' => [
[
'key' => '<string>',
'formula' => '<string>'
]
],
'isReadOnly' => true,
'owner' => [
'ownerID' => 'user123',
'ownerType' => 'USER',
'ownerName' => 'John Doe',
'ownerEmail' => 'owner123@test.com'
],
'dryRun' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"STATSIG-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://statsigapi.net/console/v1/metrics/metric_source"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("STATSIG-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://statsigapi.net/console/v1/metrics/metric_source")
.header("STATSIG-API-KEY", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://statsigapi.net/console/v1/metrics/metric_source")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["STATSIG-API-KEY"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"sql\": \"<string>\",\n \"timestampColumn\": \"<string>\",\n \"idTypeMapping\": [\n {\n \"statsigUnitID\": \"<string>\",\n \"column\": \"<string>\"\n }\n ],\n \"description\": \"<string>\",\n \"tags\": [\n \"<string>\"\n ],\n \"timestampAsDay\": true,\n \"tableName\": \"<string>\",\n \"customFieldMapping\": [\n {\n \"key\": \"<string>\",\n \"formula\": \"<string>\"\n }\n ],\n \"isReadOnly\": true,\n \"owner\": {\n \"ownerID\": \"user123\",\n \"ownerType\": \"USER\",\n \"ownerName\": \"John Doe\",\n \"ownerEmail\": \"owner123@test.com\"\n },\n \"dryRun\": true\n}"
response = http.request(request)
puts response.read_body{
"message": "Metric source created successfully.",
"data": {
"name": "test_metric_source2",
"description": "Test description for metric source",
"tags": [
"non_production"
],
"sql": "SELECT * FROM `shoppy-sales.logging.events`",
"timestampColumn": "ts",
"timestampAsDay": true,
"idTypeMapping": [
{
"statsigUnitID": "userID",
"column": "user_id"
}
],
"sourceType": "table",
"tableName": "shoppy-sales.logging.events"
}
}{
"status": 400,
"message": "Invalid request. Please check the request input and try again."
}{
"status": 401,
"message": "This endpoint only accepts an active CONSOLE key, but an invalid key was sent. Key: console-xxxXXXxxxXXXxxx"
}Authorizations
Headers
Optional header to respect review settings for mutation endpoints.
Body
The name of the metric source, serving as its primary identifier.
The SQL query or statement used to extract data from the metric source.
The name of the column containing timestamp data for the metric source.
Array defining the mapping between Statsig unit IDs and their respective source columns.
Show child attributes
Show child attributes
An optional description for the metric source, providing context and details about its purpose and usage.
Optional array of tags to categorize the metric source, facilitating easier organization and retrieval.
Indicates whether the timestamp should be treated as a day-level granularity.
The type of source, indicating whether it is a database table or a custom query.
table, query The name of the database table if the source type is "table".
Optional array defining mappings for custom fields using specific formulas.
Show child attributes
Show child attributes
Specifies if the source can only be edited via the Console API.
Schema for owner data including ID, type, name. Note that if Entity is created by CONSOLE API, owner will be undefined.
Show child attributes
Show child attributes
{
"ownerID": "user123",
"ownerType": "USER",
"ownerName": "John Doe",
"ownerEmail": "owner123@test.com"
}
Skips persisting the metric source (used to validate that inputs are correct)

