Update playbook
curl --request PUT \
--url https://api.devin.ai/v1/playbooks/{playbook_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body": "<string>",
"title": "<string>",
"macro": "<string>"
}
'import requests
url = "https://api.devin.ai/v1/playbooks/{playbook_id}"
payload = {
"body": "<string>",
"title": "<string>",
"macro": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({body: JSON.stringify('<string>'), title: '<string>', macro: '<string>'})
};
fetch('https://api.devin.ai/v1/playbooks/{playbook_id}', 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.devin.ai/v1/playbooks/{playbook_id}",
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([
'body' => '<string>',
'title' => '<string>',
'macro' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.devin.ai/v1/playbooks/{playbook_id}"
payload := strings.NewReader("{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
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://api.devin.ai/v1/playbooks/{playbook_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devin.ai/v1/playbooks/{playbook_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Playbooks Endpoints
Update Playbook
Update an existing team playbook
PUT
/
v1
/
playbooks
/
{playbook_id}
Update playbook
curl --request PUT \
--url https://api.devin.ai/v1/playbooks/{playbook_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"body": "<string>",
"title": "<string>",
"macro": "<string>"
}
'import requests
url = "https://api.devin.ai/v1/playbooks/{playbook_id}"
payload = {
"body": "<string>",
"title": "<string>",
"macro": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({body: JSON.stringify('<string>'), title: '<string>', macro: '<string>'})
};
fetch('https://api.devin.ai/v1/playbooks/{playbook_id}', 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.devin.ai/v1/playbooks/{playbook_id}",
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([
'body' => '<string>',
'title' => '<string>',
'macro' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://api.devin.ai/v1/playbooks/{playbook_id}"
payload := strings.NewReader("{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
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://api.devin.ai/v1/playbooks/{playbook_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devin.ai/v1/playbooks/{playbook_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"body\": \"<string>\",\n \"title\": \"<string>\",\n \"macro\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Playbooks are moving to Skills. In an account that has moved, this request writes the playbook’s skill instead: a create adds a skill, an update changes it, a delete removes it. Create and edit skills on the Customize page. New accounts will start with Skills and have no Playbooks, from October 24, 2026. See Playbooks are moving to Skills.
Authorizations
Personal API Key (apk_user_*) or Service API Key (apk_*)
Path Parameters
Body
application/json
Response
Successful Response
Response for successful playbook update.

