curl --request GET \
--url https://api.dumgum.com/cs/v1/content_creation/statistics/project \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.dumgum.com/cs/v1/content_creation/statistics/project"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.dumgum.com/cs/v1/content_creation/statistics/project', 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.dumgum.com/cs/v1/content_creation/statistics/project",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.dumgum.com/cs/v1/content_creation/statistics/project"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.dumgum.com/cs/v1/content_creation/statistics/project")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dumgum.com/cs/v1/content_creation/statistics/project")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"rows": [
{
"date": "<string>",
"metrics": {
"answerMessageCount": 123,
"answerHumanCount": 123,
"answerHumanCost": "<string>",
"answerAiCount": 123,
"answerAiCost": "<string>",
"messageDroppedCount": 123,
"answerActionCount": 123,
"cost": "<string>",
"answerFreeCount": 123,
"photoAnalysisCount": 123,
"webSearchCount": 123,
"webSearchCost": "<string>",
"icebreakerSuggestionCount": 123,
"followupSuggestionCount": 123
}
}
],
"total": {
"answerMessageCount": 123,
"answerHumanCount": 123,
"answerHumanCost": "<string>",
"answerAiCount": 123,
"answerAiCost": "<string>",
"messageDroppedCount": 123,
"answerActionCount": 123,
"cost": "<string>",
"answerFreeCount": 123,
"photoAnalysisCount": 123,
"webSearchCount": 123,
"webSearchCost": "<string>",
"icebreakerSuggestionCount": 123,
"followupSuggestionCount": 123
}
}Project Statistics
Usage and cost for a single project, bucketed by day or by calendar month over the date range you ask for.
Figures are recomputed every 15 minutes from closed billing records, so the current day stays partial until it ends (UTC) and may still move slightly afterwards.
startDate and endDate are both inclusive, and days are counted in UTC — a range of 2026-07-01 to 2026-07-31 covers the whole of July.
curl --request GET \
--url https://api.dumgum.com/cs/v1/content_creation/statistics/project \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.dumgum.com/cs/v1/content_creation/statistics/project"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.dumgum.com/cs/v1/content_creation/statistics/project', 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.dumgum.com/cs/v1/content_creation/statistics/project",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.dumgum.com/cs/v1/content_creation/statistics/project"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.dumgum.com/cs/v1/content_creation/statistics/project")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dumgum.com/cs/v1/content_creation/statistics/project")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"rows": [
{
"date": "<string>",
"metrics": {
"answerMessageCount": 123,
"answerHumanCount": 123,
"answerHumanCost": "<string>",
"answerAiCount": 123,
"answerAiCost": "<string>",
"messageDroppedCount": 123,
"answerActionCount": 123,
"cost": "<string>",
"answerFreeCount": 123,
"photoAnalysisCount": 123,
"webSearchCount": 123,
"webSearchCost": "<string>",
"icebreakerSuggestionCount": 123,
"followupSuggestionCount": 123
}
}
],
"total": {
"answerMessageCount": 123,
"answerHumanCount": 123,
"answerHumanCost": "<string>",
"answerAiCount": 123,
"answerAiCost": "<string>",
"messageDroppedCount": 123,
"answerActionCount": 123,
"cost": "<string>",
"answerFreeCount": 123,
"photoAnalysisCount": 123,
"webSearchCount": 123,
"webSearchCost": "<string>",
"icebreakerSuggestionCount": 123,
"followupSuggestionCount": 123
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is an access key.
Example: Authorization: Bearer sk-proj-XXXXXXXXX
Query Parameters
The project to report on. When you authenticate with an access key, this must be the project that key belongs to.
First day to include, as YYYY-MM-DD (UTC). Inclusive.
Last day to include, as YYYY-MM-DD (UTC). Inclusive.
Size of each bucket in rows: one row per day, or one row per calendar month.
DAILY, MONTHLY Response
OK
Usage and cost for a project over the requested range, split into buckets plus a grand total.
Every amount is in your account currency, as a decimal string so no precision is lost when you parse it.
One entry per bucket that recorded activity, most recent first. Buckets with no activity at all are omitted.
Hide child attributes
Hide child attributes
The bucket, as YYYY-MM-DD. With groupBy=MONTHLY this is the first day of that month.
"2026-07-14"
What the project used and what it cost, over one bucket or over the whole requested range.
Counts are integers. Amounts are in your account currency, as plain decimal strings (21.25, 0.0) so no precision is lost when you parse them.
Hide child attributes
Hide child attributes
How many of your users' messages the answers of this bucket replied to.
"1420"
Answers written by a human operator, in HUMAN reply mode.
"12"
What those human-written answers cost you.
"0.3"
Answers generated by the model, in AI reply mode.
"838"
What those AI answers cost you.
"20.95"
Generation requests that ended without a reply — dropped by a guardrail, or with nothing to answer. Not billed.
"7"
Answers carrying an action rather than a text reply (ACTION_* types: pokes, picture requests, profile reports, …).
"23"
Everything billed on the answers of this bucket — AI and human replies, plus any Smart Fetch performed while writing them. This is the figure to use for a project's answer spend.
Photo Analyses and suggestion requests are billed outside of answers, so they are not part of this amount. They appear here as counts (photoAnalysisCount, icebreakerSuggestionCount, followupSuggestionCount) — multiply them by your per-unit price to get their spend.
"21.25"
Answers that were not billed — mostly the follow-up messages of a multi-message reply, which is billed once on the first answer.
"134"
Photo Analyses run on pictures your users sent. Billed outside of answers — see cost.
"58"
Smart Fetch lookups performed while writing answers.
"16"
What those Smart Fetch lookups cost you. Already included in cost.
"0.8"
Icebreaker suggestions requested — a suggestion call on a conversation with no history. Billed outside of answers.
"31"
Follow-up suggestions requested — a suggestion call on a conversation that already has messages. Billed outside of answers.
"44"
The same metrics summed over every returned bucket, so you don't have to add up rows yourself.
Hide child attributes
Hide child attributes
How many of your users' messages the answers of this bucket replied to.
"1420"
Answers written by a human operator, in HUMAN reply mode.
"12"
What those human-written answers cost you.
"0.3"
Answers generated by the model, in AI reply mode.
"838"
What those AI answers cost you.
"20.95"
Generation requests that ended without a reply — dropped by a guardrail, or with nothing to answer. Not billed.
"7"
Answers carrying an action rather than a text reply (ACTION_* types: pokes, picture requests, profile reports, …).
"23"
Everything billed on the answers of this bucket — AI and human replies, plus any Smart Fetch performed while writing them. This is the figure to use for a project's answer spend.
Photo Analyses and suggestion requests are billed outside of answers, so they are not part of this amount. They appear here as counts (photoAnalysisCount, icebreakerSuggestionCount, followupSuggestionCount) — multiply them by your per-unit price to get their spend.
"21.25"
Answers that were not billed — mostly the follow-up messages of a multi-message reply, which is billed once on the first answer.
"134"
Photo Analyses run on pictures your users sent. Billed outside of answers — see cost.
"58"
Smart Fetch lookups performed while writing answers.
"16"
What those Smart Fetch lookups cost you. Already included in cost.
"0.8"
Icebreaker suggestions requested — a suggestion call on a conversation with no history. Billed outside of answers.
"31"
Follow-up suggestions requested — a suggestion call on a conversation that already has messages. Billed outside of answers.
"44"