curl --request GET \
--url https://server.codeium.com/api/v2alpha/analytics/output \
--header 'Authorization: Bearer <token>'import requests
url = "https://server.codeium.com/api/v2alpha/analytics/output"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://server.codeium.com/api/v2alpha/analytics/output', 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://server.codeium.com/api/v2alpha/analytics/output",
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://server.codeium.com/api/v2alpha/analytics/output"
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://server.codeium.com/api/v2alpha/analytics/output")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://server.codeium.com/api/v2alpha/analytics/output")
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{
"data": [
{
"timestamp": "2026-06-15",
"source": "CASCADE_CLIENT",
"loc_inserted": 18420,
"loc_deleted": 3105
},
{
"timestamp": "2026-06-15",
"source": "CHISEL",
"loc_inserted": 92310,
"loc_deleted": 11874
}
],
"pagination": {
"next_page_cursor": null
},
"metadata": {
"data_freshness": "2026-06-16T03:00:00Z",
"query_time_ms": 1311,
"team_id": "team_abc123"
}
}Get Agent Output (Lines of Code)
Query lines of code inserted and deleted by the agent and accepted by your team in Devin Desktop and the Devin CLI, with filtering, grouping, and pagination.
curl --request GET \
--url https://server.codeium.com/api/v2alpha/analytics/output \
--header 'Authorization: Bearer <token>'import requests
url = "https://server.codeium.com/api/v2alpha/analytics/output"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://server.codeium.com/api/v2alpha/analytics/output', 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://server.codeium.com/api/v2alpha/analytics/output",
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://server.codeium.com/api/v2alpha/analytics/output"
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://server.codeium.com/api/v2alpha/analytics/output")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://server.codeium.com/api/v2alpha/analytics/output")
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{
"data": [
{
"timestamp": "2026-06-15",
"source": "CASCADE_CLIENT",
"loc_inserted": 18420,
"loc_deleted": 3105
},
{
"timestamp": "2026-06-15",
"source": "CHISEL",
"loc_inserted": 92310,
"loc_deleted": 11874
}
],
"pagination": {
"next_page_cursor": null
},
"metadata": {
"data_freshness": "2026-06-16T03:00:00Z",
"query_time_ms": 1311,
"team_id": "team_abc123"
}
}Authentication
This endpoint uses Bearer token authentication. Include your token in theAuthorization header:
Authorization: Bearer <your_token>
Metrics
Themetric query parameter is required and takes a comma-separated list of the metrics to return.
Each requested metric appears as an integer field on every row:
| Metric | Description |
|---|---|
loc_inserted | Lines inserted by the agent that the user accepted |
loc_deleted | Lines deleted by the agent that the user accepted |
?metric=loc_inserted,loc_deleted returns both; ?metric=loc_inserted returns only
loc_inserted. Requests without metric, or naming an unknown metric, fail with 400.
Lines are counted when a user accepts an agent edit in Devin Desktop or the
Devin CLI, from any model. The product parameter is also required and currently accepts only
agent.
Grouping and Granularity
Usegranularity and group_by to control the shape of returned data:
- No granularity or grouping — returns a single aggregated row for the entire date range
granularity=daily— each row includes atimestampinYYYY-MM-DDformatgranularity=monthly— each row includes atimestampinYYYY-MMformatgroup_by=user— each row includes auser_idanduser_emailgroup_by=session— each row includes asession_id(the Devin Desktop conversation or CLI session the lines were accepted in)group_by=model_uid— each row includes amodel_uidgroup_by=ide— each row includes anidegroup_by=ide,ide_version— each row includesideandide_version(grouping byide_versionrequiresideto also be included)group_by=os— each row includes anos, such asdarwin(macOS),windows, orlinuxgroup_by=source— each row includes asource:CASCADE_CLIENTfor lines accepted in Devin Desktop,CHISELfor lines accepted in the Devin CLI (including the CLI running as an agent inside other editors)
group_by=user,source,model_uid. The same models,
group_id, and user_id filters as Get Consumption
apply.
Pagination
Results are paginated with a default page size of 1,000 rows (max 10,000). When more results are available, the response includes anext_page_cursor in the pagination object. Pass it as the page_cursor query
parameter to fetch the next page, with the same metric list as the original request. Cursors are bound
to the endpoint and metrics that issued them; a cursor from /consumption, or one issued for a different
metric list, is rejected with 400.
Page cursors expire after 24 hours. A follow-up page request does not count as a new query against your rate limit.
Rate Limits
This endpoint is rate-limited to 10 requests per hour per team. If you exceed this limit, the server returns429 Too Many Requests with a Retry-After header.
Paginating an earlier query (following a next_page_cursor) does not count against this limit —
only the initial query for each report does. The low limit reflects that this endpoint is for
periodic reporting, not real-time usage monitoring.Authorizations
A service key with Analytics Read permission, passed as a Bearer token in the Authorization header.
Create a service key in your team settings under the "Service Keys" section.
Query Parameters
Comma-separated list of output metrics to return; each appears as a field on every row. Supported metrics:
loc_inserted— lines inserted by the agent that the user acceptedloc_deleted— lines deleted by the agent that the user accepted
Start of the date range (inclusive) in YYYY-MM-DD format.
End of the date range (inclusive) in YYYY-MM-DD format. The range must not exceed 90 days.
Product to query output for.
agent Time granularity for grouping results. When specified, each row includes a timestamp field.
If omitted, results are aggregated across the entire date range.
daily, monthly Comma-separated list of dimensions to group results by. Supported dimensions:
user— includesuser_idanduser_emailin each rowsession— includessession_idin each rowmodel_uid— includesmodel_uidin each rowide— includesidein each rowide_version— includeside_versionin each row; requiresideto also be includedos— includesosin each rowsource— includessourcein each row (CASCADE_CLIENTfor Devin Desktop,CHISELfor the Devin CLI)
Comma-separated list of model UIDs to filter results to.
Filter results to users in a specific group. The service key must have access to this group. Not supported with Devin service user API keys.
Filter results to a specific user (auth UID).
Maximum number of rows to return per page.
1 <= x <= 10000Opaque cursor from a previous response's pagination.next_page_cursor to fetch the next page. Pass the same metric list as the request that issued it; cursors issued by other endpoints or for a different metric list are rejected.

