curl --request POST \
--url https://api.reply.io/v3/custom-fields \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"entityType": "contact",
"metadata": "<string>",
"orgWide": false,
"aiDefinition": {
"promptText": "Summarize what {{Company}} does in one sentence"
}
}
'import requests
url = "https://api.reply.io/v3/custom-fields"
payload = {
"title": "<string>",
"entityType": "contact",
"metadata": "<string>",
"orgWide": False,
"aiDefinition": { "promptText": "Summarize what {{Company}} does in one sentence" }
}
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({
title: '<string>',
entityType: 'contact',
metadata: '<string>',
orgWide: false,
aiDefinition: {promptText: 'Summarize what {{Company}} does in one sentence'}
})
};
fetch('https://api.reply.io/v3/custom-fields', 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/custom-fields",
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([
'title' => '<string>',
'entityType' => 'contact',
'metadata' => '<string>',
'orgWide' => false,
'aiDefinition' => [
'promptText' => 'Summarize what {{Company}} does in one sentence'
]
]),
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/custom-fields"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\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/custom-fields")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/custom-fields")
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 \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"title": "<string>",
"fieldType": "text",
"entityType": "contact",
"metadata": "<string>",
"orgWide": true,
"fieldSource": "regular",
"aiDefinition": {
"promptText": "Summarize what {{Company}} does in one sentence",
"variableKeys": [
"Company"
],
"createdAt": "2026-09-15T12:00:00Z",
"updatedAt": "2026-09-15T12:30:00Z"
},
"promptActions": [
{
"promptActionId": 12,
"promptActionName": "Qualify inbound"
}
]
}Create a custom field
contacts:write scope (or a broader one that includes it).
Track something on contacts or accounts that Reply doesn’t capture by default. Provide a title and a text or number field type; set entityType to account for a field that lives on accounts.
curl --request POST \
--url https://api.reply.io/v3/custom-fields \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"entityType": "contact",
"metadata": "<string>",
"orgWide": false,
"aiDefinition": {
"promptText": "Summarize what {{Company}} does in one sentence"
}
}
'import requests
url = "https://api.reply.io/v3/custom-fields"
payload = {
"title": "<string>",
"entityType": "contact",
"metadata": "<string>",
"orgWide": False,
"aiDefinition": { "promptText": "Summarize what {{Company}} does in one sentence" }
}
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({
title: '<string>',
entityType: 'contact',
metadata: '<string>',
orgWide: false,
aiDefinition: {promptText: 'Summarize what {{Company}} does in one sentence'}
})
};
fetch('https://api.reply.io/v3/custom-fields', 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/custom-fields",
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([
'title' => '<string>',
'entityType' => 'contact',
'metadata' => '<string>',
'orgWide' => false,
'aiDefinition' => [
'promptText' => 'Summarize what {{Company}} does in one sentence'
]
]),
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/custom-fields"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\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/custom-fields")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.reply.io/v3/custom-fields")
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 \"title\": \"<string>\",\n \"entityType\": \"contact\",\n \"metadata\": \"<string>\",\n \"orgWide\": false,\n \"aiDefinition\": {\n \"promptText\": \"Summarize what {{Company}} does in one sentence\"\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"title": "<string>",
"fieldType": "text",
"entityType": "contact",
"metadata": "<string>",
"orgWide": true,
"fieldSource": "regular",
"aiDefinition": {
"promptText": "Summarize what {{Company}} does in one sentence",
"variableKeys": [
"Company"
],
"createdAt": "2026-09-15T12:00:00Z",
"updatedAt": "2026-09-15T12:30:00Z"
},
"promptActions": [
{
"promptActionId": 12,
"promptActionName": "Qualify inbound"
}
]
}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.
Body
Custom field name
90Custom field type
text, number The entity the field belongs to. Omit it for a contact field. An account field cannot carry an aiDefinition.
contact, account Optional metadata for the field (e.g., dropdown options)
Whether the field should be shared across the organization
Makes the field an AI custom field, filled by running this prompt against a contact. Omit it for a field you fill yourself.
Show child attributes
Show child attributes
{
"promptText": "Summarize what {{Company}} does in one sentence"
}
Response
Custom field created successfully
A user-defined field for storing additional data on contacts.
Custom field ID
Custom field name
Custom field type
text, number The entity the field belongs to. A contact field holds a value on each contact, an account field on each account.
contact, account Optional metadata for the field (e.g., dropdown options)
Whether the field is shared across the organization
What fills the field. regular is one you fill yourself, ai one that carries its own prompt in aiDefinition, and promptAction one written by the Prompt Actions listed in promptActions. Only an ai field can be previewed or enriched; only a field that is not ai can be mapped to a Prompt Action output.
regular, ai, promptAction The prompt that fills the field. Present only when fieldSource is ai; null otherwise.
Show child attributes
Show child attributes
{
"promptText": "Summarize what {{Company}} does in one sentence",
"variableKeys": ["Company"],
"createdAt": "2026-09-15T12:00:00Z",
"updatedAt": "2026-09-15T12:30:00Z"
}
The Prompt Actions that write into this field. Empty unless fieldSource is promptAction.
Show child attributes
Show child attributes