List Devin Desktop Models and Pricing
curl --request GET \
--url https://server.codeium.com/api/v2alpha/models \
--header 'Authorization: Bearer <token>'import requests
url = "https://server.codeium.com/api/v2alpha/models"
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/models', 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/models",
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/models"
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/models")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://server.codeium.com/api/v2alpha/models")
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{
"models": [
{
"uid": "<string>",
"name": "<string>",
"allowed": true,
"pricing_dimensions": [
{
"label": "<string>",
"unit": "<string>",
"value": 123,
"denominator": "<string>",
"info": "<string>"
}
]
}
],
"allowed_model_uids": [
"<string>"
],
"allowed_model_tags": [
"<string>"
]
}API Reference
List Devin Desktop Models and Pricing
List the Devin Desktop models available to your account with their UIDs, names, prices, whether your team allows each one, and the team’s model allowlist.
GET
/
api
/
v2alpha
/
models
List Devin Desktop Models and Pricing
curl --request GET \
--url https://server.codeium.com/api/v2alpha/models \
--header 'Authorization: Bearer <token>'import requests
url = "https://server.codeium.com/api/v2alpha/models"
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/models', 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/models",
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/models"
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/models")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://server.codeium.com/api/v2alpha/models")
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{
"models": [
{
"uid": "<string>",
"name": "<string>",
"allowed": true,
"pricing_dimensions": [
{
"label": "<string>",
"unit": "<string>",
"value": 123,
"denominator": "<string>",
"info": "<string>"
}
]
}
],
"allowed_model_uids": [
"<string>"
],
"allowed_model_tags": [
"<string>"
]
}Overview
Returns the models available to the calling account, with the prices that account is actually charged, whether your team currently allows each one, and the team’s stored model allowlist. Use it as a programmatic source of truth for model pricing instead of copying prices from the models page, and as the read side of the Update Model Allowlist API. Prices depend on the caller’s plan and billing model, so two teams can get different values for the same model.This endpoint is in alpha (
v2alpha). The response shape may change.Authentication
Pass an API key in theAuthorization header:
Authorization: Bearer <api-key>
cog_...). The service user’s role must include the Use Devin Desktop permission, and Devin Desktop access must be enabled for the account.
Request
string
Leave unset to list every model allowed by your plan and billing model, ignoring team-level restrictions. Each model’s
allowed field tells you whether your team’s restrictions currently allow it.Set to allowlist to list only the models your team’s model allowlist, organization controls, and group restrictions allow, so the list matches what users see in the Devin Desktop model picker.string
An
ETag from an earlier response. Returns 304 Not Modified with no body when the response has not changed since.Example Request
curl https://server.codeium.com/api/v2alpha/models \
-H "Authorization: Bearer $DEVIN_API_KEY"
curl "https://server.codeium.com/api/v2alpha/models?filter=allowlist" \
-H "Authorization: Bearer $DEVIN_API_KEY"
Response
The response carries anETag header that changes whenever anything in the unfiltered response changes: the available models, their names and prices, their allowed flags, or the allowlist fields. Pass it as If-Match to the Update Model Allowlist API; it is the same regardless of filter.
object[]
Models available to the caller. Disabled models are not included.
Show properties
Show properties
string
Stable model identifier, e.g.
claude-sonnet-4-5.string
Display name shown in the model picker.
boolean
Whether your team’s model allowlist, organization controls, and group restrictions currently let users pick this model. Always
true with filter=allowlist.object[]
Prices charged to the caller for this model. Empty for models with no charge.
Show properties
Show properties
string
What is being priced, in snake_case:
input, output, cached_input, cache_read, or cache_write for token pricing; for prices in a non-currency unit, the quantity being priced, e.g. message for per-message pricing. Fusion models also list their sidekick’s prices with a sidekick_ prefix, e.g. sidekick_input or sidekick_message.string
The unit
value is expressed in, in snake_case, e.g. usd, acus, or credits.number
The price in
unit, per denominator.string
The quantity the price applies to, e.g.
1M tokens or message.string
Optional note about the price, e.g.
Higher effort consumes more tokens.string[]
Model UIDs on your team’s allowlist, as stored. Empty when the team allows models by tag only.
string[]
Model tags on your team’s allowlist, as stored, including provider tags such as
provider-anthropic. A model is allowed when its UID is listed or it carries a listed tag.Example Response
The models and prices below only illustrate the response shape. Call the endpoint for your actual prices.{
"models": [
{
"uid": "claude-sonnet-4-5",
"name": "Claude Sonnet 4.5",
"allowed": true,
"pricing_dimensions": [
{ "label": "input", "unit": "usd", "value": 3, "denominator": "1M tokens" },
{ "label": "cached_input", "unit": "usd", "value": 0.3, "denominator": "1M tokens" },
{ "label": "output", "unit": "usd", "value": 15, "denominator": "1M tokens" }
]
},
{
"uid": "example-model",
"name": "Example Model",
"allowed": false,
"pricing_dimensions": [
{ "label": "message", "unit": "acus", "value": 0.5, "denominator": "message" }
]
}
],
"allowed_model_uids": ["claude-sonnet-4-5"],
"allowed_model_tags": ["provider-anthropic"]
}
Error Responses
Errors are returned as{"error": "<message>"}.
| Status | Cause |
|---|---|
400 | filter is set to a value other than allowlist |
401 | Missing or invalid API key, or a legacy Windsurf API key (only Devin cog_... service user keys are accepted) |
403 | The key’s user doesn’t have Devin Desktop access |
429 | Rate limit exceeded; wait for the Retry-After header before retrying |

