curl --request POST \
--url https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"feedback": "Make the angles shorter and drop case-study mentions."
}
'import requests
url = "https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate"
payload = { "feedback": "Make the angles shorter and drop case-study mentions." }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({feedback: 'Make the angles shorter and drop case-study mentions.'})
};
fetch('https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate', 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.reply.io/v3/ai-sdr/playbooks/{id}/regenerate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'feedback' => 'Make the angles shorter and drop case-study mentions.'
]),
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.reply.io/v3/ai-sdr/playbooks/{id}/regenerate"
payload := strings.NewReader("{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}"
response = http.request(request)
puts response.read_body{
"id": "t-7",
"name": "Outbound playbook v2",
"description": "Tone and pacing for cold outreach",
"body": "## Voice\nFriendly, concise, never desperate.\n\n## Pacing\nTwo touches per week max.",
"type": "team",
"lastUpdatedAt": "2026-05-10T14:32:11Z",
"authorUserId": 4821,
"isAiGenerated": false,
"sourceOfferId": null,
"styleFiles": [
{
"id": 12345,
"fileName": "tone-guide.pdf"
}
]
}Regenerate a playbook
Coming soon. This endpoint will be available by late October 2026.
ai-sdr:write scope (or a broader one that includes it).
Have the AI SDR rewrite a playbook’s body from your feedback. The playbook is updated in place, so every sequence that uses it picks up the new version. Works on organization and team playbooks; global playbooks are read-only.
curl --request POST \
--url https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"feedback": "Make the angles shorter and drop case-study mentions."
}
'import requests
url = "https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate"
payload = { "feedback": "Make the angles shorter and drop case-study mentions." }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({feedback: 'Make the angles shorter and drop case-study mentions.'})
};
fetch('https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate', 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.reply.io/v3/ai-sdr/playbooks/{id}/regenerate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'feedback' => 'Make the angles shorter and drop case-study mentions.'
]),
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.reply.io/v3/ai-sdr/playbooks/{id}/regenerate"
payload := strings.NewReader("{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/playbooks/{id}/regenerate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"feedback\": \"Make the angles shorter and drop case-study mentions.\"\n}"
response = http.request(request)
puts response.read_body{
"id": "t-7",
"name": "Outbound playbook v2",
"description": "Tone and pacing for cold outreach",
"body": "## Voice\nFriendly, concise, never desperate.\n\n## Pacing\nTwo touches per week max.",
"type": "team",
"lastUpdatedAt": "2026-05-10T14:32:11Z",
"authorUserId": 4821,
"isAiGenerated": false,
"sourceOfferId": null,
"styleFiles": [
{
"id": 12345,
"fileName": "tone-guide.pdf"
}
]
}Authorizations
Authenticate every request with a Bearer token. Pass your Reply API key in the
Authorization header:
Authorization: Bearer <your-api-key>
Get your API key from the Reply dashboard: Settings → API Key.
Path Parameters
Composite playbook id (g-N for global, o-N for organization, t-N for team)
Body
Instructions the AI SDR applies when rewriting the playbook.
What to change, in plain language (e.g. "Make the angles shorter and drop case-study mentions").
1 - 2000Response
Playbook regenerated
Detailed representation of a playbook, returned by get/create/update responses.
Composite identifier formatted as {prefix}-{numericId} where the prefix encodes the playbook scope:
g for global, o for organization, t for team (e.g. g-1, o-42, t-7).
Display name of the playbook
Short description of the playbook's purpose
Full playbook body — typically Markdown or plain text instructions the AI SDR follows when this playbook is applied.
Visibility scope of the playbook. Set on create and immutable thereafter.
global, organization, team Timestamp of the last modification
User ID of the playbook author. null for global playbooks and when the original author is no longer a team member.
Whether the playbook was generated by the AI SDR from an offer.
Id of the offer the playbook was generated from. null for playbooks that were not AI-generated.
Style files attached to the playbook. Managed via the /style-files sub-resource — uploads are immediate, deletes are immediate; the field is read-only on the playbook payload.
Show child attributes
Show child attributes