Actualizar la lista de modelos permitidos de Devin Desktop
curl --request PUT \
--url https://server.codeium.com/api/v2alpha/models \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: <if-match>' \
--data '
{
"allowed_model_uids": [
"<string>"
],
"allowed_model_tags": [
"<string>"
]
}
'import requests
url = "https://server.codeium.com/api/v2alpha/models"
payload = {
"allowed_model_uids": ["<string>"],
"allowed_model_tags": ["<string>"]
}
headers = {
"If-Match": "<if-match>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'If-Match': '<if-match>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({allowed_model_uids: ['<string>'], allowed_model_tags: ['<string>']})
};
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 => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'allowed_model_uids' => [
'<string>'
],
'allowed_model_tags' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"If-Match: <if-match>"
],
]);
$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://server.codeium.com/api/v2alpha/models"
payload := strings.NewReader("{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("If-Match", "<if-match>")
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.put("https://server.codeium.com/api/v2alpha/models")
.header("If-Match", "<if-match>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}")
.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::Put.new(url)
request["If-Match"] = '<if-match>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyReferencia de la API
Actualizar la lista de modelos permitidos de Devin Desktop
Reemplaza mediante programación la lista de modelos permitidos de Devin Desktop de tu equipo: define los UID de modelo y las etiquetas permitidos, con una comprobación de ETag contra el estado actual.
PUT
/
api
/
v2alpha
/
models
Actualizar la lista de modelos permitidos de Devin Desktop
curl --request PUT \
--url https://server.codeium.com/api/v2alpha/models \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'If-Match: <if-match>' \
--data '
{
"allowed_model_uids": [
"<string>"
],
"allowed_model_tags": [
"<string>"
]
}
'import requests
url = "https://server.codeium.com/api/v2alpha/models"
payload = {
"allowed_model_uids": ["<string>"],
"allowed_model_tags": ["<string>"]
}
headers = {
"If-Match": "<if-match>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'If-Match': '<if-match>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({allowed_model_uids: ['<string>'], allowed_model_tags: ['<string>']})
};
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 => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'allowed_model_uids' => [
'<string>'
],
'allowed_model_tags' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"If-Match: <if-match>"
],
]);
$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://server.codeium.com/api/v2alpha/models"
payload := strings.NewReader("{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("If-Match", "<if-match>")
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.put("https://server.codeium.com/api/v2alpha/models")
.header("If-Match", "<if-match>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}")
.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::Put.new(url)
request["If-Match"] = '<if-match>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"allowed_model_uids\": [\n \"<string>\"\n ],\n \"allowed_model_tags\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyDescripción general
Reemplaza la lista de modelos permitidos de tu equipo, la misma configuración que los Admin gestionan en los controles de la organización de Devin Desktop. El cuerpo de la solicitud representa el estado deseado completo: las dos listas sobrescriben las que estén almacenadas. Para no sobrescribir un cambio que no hayas visto, la solicitud debe incluir enIf-Match el ETag de una respuesta de List Models. Si la lista de permitidos, los modelos disponibles o sus precios han cambiado desde esa respuesta, la actualización se rechaza con un 412 y debes volver a listar los modelos.
Este endpoint está en fase alfa (
v2alpha). La estructura de la solicitud y de la respuesta puede cambiar.Autenticación
Envía una clave de API en el encabezadoAuthorization:
Authorization: Bearer <api-key>
cog_...). Además del permiso Use Devin Desktop que requiere List Models, el rol del usuario de servicio debe tener el permiso Windsurf admin (account.windsurf.admin), incluido en el rol integrado Account Admin. Un usuario de servicio sin este permiso puede listar modelos, pero recibe un 403 en este endpoint.
Solicitud
string
requerido
El encabezado
ETag de una respuesta de GET /api/v2alpha/models que refleja el estado actual. Obligatorio; no se acepta *.string[]
requerido
UID de los modelos que los usuarios pueden elegir, p. ej.,
["claude-sonnet-4-5"]. Pasa [] para permitir modelos solo por etiqueta.string[]
requerido
Etiquetas de los modelos que los usuarios pueden elegir, incluidas etiquetas de proveedor como
provider-anthropic o provider-openai. Pasa [] para permitir solo los UID de modelos indicados.Ejemplo de solicitud
ETAG=$(curl -s -D - -o /dev/null https://server.codeium.com/api/v2alpha/models \
-H "Authorization: Bearer $DEVIN_API_KEY" | awk 'tolower($1)=="etag:" {print $2}' | tr -d '\r')
curl -X PUT https://server.codeium.com/api/v2alpha/models \
-H "Authorization: Bearer $DEVIN_API_KEY" \
-H "If-Match: $ETAG" \
-H "Content-Type: application/json" \
-d '{"allowed_model_uids": ["claude-sonnet-4-5"], "allowed_model_tags": ["provider-anthropic"]}'
Respuesta
Si la operación se realiza correctamente, la respuesta es la misma que la de List Models, pero con la nueva lista de permitidos aplicada: cada modelo con su opciónallowed, los valores almacenados de allowed_model_uids y allowed_model_tags, y un nuevo encabezado ETag.
Respuestas de error
Los errores se devuelven con el formato{"error": "<message>"}.
| Estado | Causa |
|---|---|
400 | El cuerpo no es JSON, contiene campos desconocidos o le falta allowed_model_uids o allowed_model_tags; o se ha especificado el parámetro de consulta filter (solo lo acepta List Models) |
401 | Falta la clave de API o no es válida, o se ha usado una clave de API legacy de Windsurf (solo se aceptan claves de usuario de servicio cog_... de Devin) |
403 | El usuario de la clave no tiene acceso a Devin Desktop, o su rol no tiene el permiso de Windsurf admin (account.windsurf.admin) |
412 | If-Match no coincide con el ETag actual; vuelve a listar los modelos e inténtalo de nuevo |
428 | Falta el encabezado If-Match |
429 | Se superó el límite de tasa; espera el tiempo indicado en el encabezado Retry-After antes de volver a intentarlo |

