Atualizar a lista de permissões do 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_bodyReferência da API
Atualizar a lista de permissões do Devin Desktop
Substitua programaticamente a lista de permissões do Devin Desktop da sua equipe: defina os UIDs de modelo e os marcadores permitidos, com uma verificação de ETag com base no estado atual.
PUT
/
api
/
v2alpha
/
models
Atualizar a lista de permissões do 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_bodyVisão geral
Substitui a lista de permissões da sua equipe, a mesma configuração que os administradores gerenciam nos controles da organização no Devin Desktop. O corpo da requisição representa o estado completo desejado: as duas listas substituem as que estão armazenadas. Para evitar sobrescrever uma alteração que você ainda não viu, a requisição deve incluir no cabeçalhoIf-Match o ETag de uma resposta de List Models. Se a lista de permissões, os modelos disponíveis ou os preços deles tiverem mudado desde essa resposta, a atualização será rejeitada com 412 e você deverá listar os modelos novamente.
Este endpoint está em alfa (
v2alpha). O formato da requisição e da resposta pode mudar.Autenticação
Envie uma chave de API no cabeçalhoAuthorization:
Authorization: Bearer <api-key>
cog_...). Além da permissão Use Devin Desktop exigida pelo List Models, a função do usuário de serviço precisa ter a permissão Windsurf admin (account.windsurf.admin), que já vem incluída na função nativa Account Admin. Um usuário de serviço sem essa permissão consegue listar modelos, mas recebe 403 neste endpoint.
Requisição
string
obrigatório
O cabeçalho
ETag de uma resposta de GET /api/v2alpha/models que reflete o estado atual. Obrigatório; * não é aceito.string[]
obrigatório
UIDs dos modelos que os usuários podem escolher, p. ex.
["claude-sonnet-4-5"]. Passe [] para permitir modelos apenas por marcador.string[]
obrigatório
Marcadores dos modelos que os usuários podem escolher, incluindo marcadores de provedor como
provider-anthropic ou provider-openai. Passe [] para permitir apenas os UIDs de modelos listados.Exemplo de requisição
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"]}'
Resposta
Em caso de sucesso, a resposta é igual à de List Models, já com a nova lista de permissões aplicada: todos os modelos com a respectiva flagallowed, os valores armazenados de allowed_model_uids e allowed_model_tags e um novo cabeçalho ETag.
Respostas de erro
Os erros são retornados no formato{"error": "<message>"}.
| Status | Causa |
|---|---|
400 | O corpo não é JSON, contém campos desconhecidos ou não inclui allowed_model_uids ou allowed_model_tags; ou o parâmetro de consulta filter foi definido (ele só é aceito por List Models) |
401 | Chave de API ausente ou inválida, ou uma chave de API legada do Windsurf (somente chaves de usuário de serviço cog_... do Devin são aceitas) |
403 | O usuário da chave não tem acesso ao Devin Desktop, ou a função dele não tem a permissão de Windsurf admin (account.windsurf.admin) |
412 | If-Match não corresponde ao ETag atual; liste os modelos novamente e tente outra vez |
428 | Cabeçalho If-Match ausente |
429 | Limite de requisições excedido; aguarde o tempo indicado no cabeçalho Retry-After antes de tentar novamente |

