curl --request POST \
--url https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate', 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/offers/{id}/duplicate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
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://api.reply.io/v3/ai-sdr/offers/{id}/duplicate"
req, _ := http.NewRequest("POST", 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.post("https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": 4821,
"name": "Q3 Enterprise Outbound",
"companyName": "Acme Robotics",
"companyDescription": "AI-driven warehouse automation for mid-market logistics.",
"icp": "Director of Operations at logistics companies with 200+ warehouse staff",
"reasonForOutreach": "Q3 push into mid-market logistics — Acme just closed a marquee customer in this segment.",
"caseStudies": [
"Reduced order-pick errors 38% at NorthStar Logistics"
],
"painPoints": [
"Manual pick-pack errors driving customer churn",
"Labor cost rising 12% YoY"
],
"proofPoints": [
"Used by 4 of top 10 mid-market 3PLs"
],
"valuePropositions": [
"30% pick-rate improvement in 90 days"
],
"callToActions": [
"15-min demo this week?"
]
}{
"title": "Validation failed",
"status": 400,
"detail": "The request contains validation errors.",
"errors": [
{
"pointer": "/id",
"detail": "'id' must be a positive integer."
}
]
}{
"title": "Unauthorized",
"status": 401,
"detail": "Authentication credentials are missing or invalid."
}{
"title": "Forbidden",
"status": 403,
"detail": "Offer duplication is not enabled for your team",
"code": "offer.forbidden"
}{
"title": "Not Found",
"status": 404,
"detail": "Offer '4821' not found",
"code": "offer.notFound"
}{
"title": "Bad Gateway",
"status": 502,
"detail": "Upstream service returned an unexpected error",
"code": "offer.upstreamFailure"
}Duplicate an offer
ai-sdr:write scope (or a broader one that includes it).
Copy an offer so you can adapt a proven one to a new segment. The copy carries the same company context as the original.
curl --request POST \
--url https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate', 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/offers/{id}/duplicate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
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://api.reply.io/v3/ai-sdr/offers/{id}/duplicate"
req, _ := http.NewRequest("POST", 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.post("https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/offers/{id}/duplicate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": 4821,
"name": "Q3 Enterprise Outbound",
"companyName": "Acme Robotics",
"companyDescription": "AI-driven warehouse automation for mid-market logistics.",
"icp": "Director of Operations at logistics companies with 200+ warehouse staff",
"reasonForOutreach": "Q3 push into mid-market logistics — Acme just closed a marquee customer in this segment.",
"caseStudies": [
"Reduced order-pick errors 38% at NorthStar Logistics"
],
"painPoints": [
"Manual pick-pack errors driving customer churn",
"Labor cost rising 12% YoY"
],
"proofPoints": [
"Used by 4 of top 10 mid-market 3PLs"
],
"valuePropositions": [
"30% pick-rate improvement in 90 days"
],
"callToActions": [
"15-min demo this week?"
]
}{
"title": "Validation failed",
"status": 400,
"detail": "The request contains validation errors.",
"errors": [
{
"pointer": "/id",
"detail": "'id' must be a positive integer."
}
]
}{
"title": "Unauthorized",
"status": 401,
"detail": "Authentication credentials are missing or invalid."
}{
"title": "Forbidden",
"status": 403,
"detail": "Offer duplication is not enabled for your team",
"code": "offer.forbidden"
}{
"title": "Not Found",
"status": 404,
"detail": "Offer '4821' not found",
"code": "offer.notFound"
}{
"title": "Bad Gateway",
"status": 502,
"detail": "Upstream service returned an unexpected error",
"code": "offer.upstreamFailure"
}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
Id of the offer to duplicate
x >= 1Response
Offer duplicated successfully
Detailed representation of an offer — the bundle of company-context inputs the AI SDR uses to personalize outreach. Returned by get/create/update responses.
Unique identifier for the offer
Display name of the offer
The company being represented in outreach
Short description of what the company does
Ideal Customer Profile — who the offer is meant for
Free-form rationale shown to the AI SDR for why this outreach is being made
Case studies that demonstrate the company's value
Customer pain points this offer addresses
Proof points that back up the offer's claims
Value propositions presented in messaging
Call-to-action phrasings the AI SDR can use