curl --request PATCH \
--url https://api.reply.io/v3/ai-sdr/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Q4 Enterprise Outbound",
"reasonForOutreach": "Refocused on mid-market after Q3 results."
}
'import requests
url = "https://api.reply.io/v3/ai-sdr/offers/{id}"
payload = {
"name": "Q4 Enterprise Outbound",
"reasonForOutreach": "Refocused on mid-market after Q3 results."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Q4 Enterprise Outbound',
reasonForOutreach: 'Refocused on mid-market after Q3 results.'
})
};
fetch('https://api.reply.io/v3/ai-sdr/offers/{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.reply.io/v3/ai-sdr/offers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Q4 Enterprise Outbound',
'reasonForOutreach' => 'Refocused on mid-market after Q3 results.'
]),
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/offers/{id}"
payload := strings.NewReader("{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.reply.io/v3/ai-sdr/offers/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/offers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}"
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?"
]
}Update an offer
ai-sdr:write scope (or a broader one that includes it).
Use this endpoint when you need to change part of an existing offer without resending all of it. Send only the fields you want to change — at least one must be present, and every field you leave out keeps its current value. A list field you do send replaces the whole list, so include every entry you want to keep; each list accepts up to 10 non-empty entries of at most 1000 characters, and any text you send may reference only the template variables your account recognizes. The full updated offer is returned. The AI SDR feature must be enabled for your team.
curl --request PATCH \
--url https://api.reply.io/v3/ai-sdr/offers/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Q4 Enterprise Outbound",
"reasonForOutreach": "Refocused on mid-market after Q3 results."
}
'import requests
url = "https://api.reply.io/v3/ai-sdr/offers/{id}"
payload = {
"name": "Q4 Enterprise Outbound",
"reasonForOutreach": "Refocused on mid-market after Q3 results."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Q4 Enterprise Outbound',
reasonForOutreach: 'Refocused on mid-market after Q3 results.'
})
};
fetch('https://api.reply.io/v3/ai-sdr/offers/{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.reply.io/v3/ai-sdr/offers/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Q4 Enterprise Outbound',
'reasonForOutreach' => 'Refocused on mid-market after Q3 results.'
]),
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/offers/{id}"
payload := strings.NewReader("{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://api.reply.io/v3/ai-sdr/offers/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/ai-sdr/offers/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Q4 Enterprise Outbound\",\n \"reasonForOutreach\": \"Refocused on mid-market after Q3 results.\"\n}"
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?"
]
}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
Offer id
x >= 1Body
Partial update for an offer. Send only the fields you want to change; absent fields retain their current value. At least one field must be present.
All array fields, if present, fully replace the current value (no item-level merge).
Updated display name (non-empty)
1 - 200200300010001000101 - 1000101 - 1000101 - 1000101 - 1000101 - 1000Response
Offer updated 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