Merge Contact Data
curl --request PATCH \
--url https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {},
"ttlSeconds": 3888030
}
'import requests
url = "https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data"
payload = {
"data": {},
"ttlSeconds": 3888030
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({data: {}, ttlSeconds: 3888030})
};
fetch('https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data', 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.usesimple.ai/api/v1/contacts/{phoneNumber}/data",
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([
'data' => [
],
'ttlSeconds' => 3888030
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.usesimple.ai/api/v1/contacts/{phoneNumber}/data"
payload := strings.NewReader("{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.usesimple.ai/api/v1/contacts/{phoneNumber}/data")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}"
response = http.request(request)
puts response.read_body{
"phoneNumber": "<string>",
"data": {},
"revision": 2,
"ttlSeconds": 123,
"expiresAt": "2023-11-07T05:31:56Z"
}{
"status": "error",
"success": false,
"error": "<string>",
"errors": [
"<string>"
]
}{
"status": "error",
"success": false,
"error": "<string>",
"errors": [
"<string>"
]
}Contacts
Merge Stored Contact Data with the API
Shallow-merge selected fields into the data stored for a contact phone number without replacing the contact’s complete state.
PATCH
/
contacts
/
{phoneNumber}
/
data
Merge Contact Data
curl --request PATCH \
--url https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {},
"ttlSeconds": 3888030
}
'import requests
url = "https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data"
payload = {
"data": {},
"ttlSeconds": 3888030
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({data: {}, ttlSeconds: 3888030})
};
fetch('https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data', 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.usesimple.ai/api/v1/contacts/{phoneNumber}/data",
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([
'data' => [
],
'ttlSeconds' => 3888030
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.usesimple.ai/api/v1/contacts/{phoneNumber}/data"
payload := strings.NewReader("{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.usesimple.ai/api/v1/contacts/{phoneNumber}/data")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.usesimple.ai/api/v1/contacts/{phoneNumber}/data")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {},\n \"ttlSeconds\": 3888030\n}"
response = http.request(request)
puts response.read_body{
"phoneNumber": "<string>",
"data": {},
"revision": 2,
"ttlSeconds": 123,
"expiresAt": "2023-11-07T05:31:56Z"
}{
"status": "error",
"success": false,
"error": "<string>",
"errors": [
"<string>"
]
}{
"status": "error",
"success": false,
"error": "<string>",
"errors": [
"<string>"
]
}See the integrations overview for ways to connect external systems with Simple AI.
Use this endpoint when an external system needs to update only part of the state stored against a caller’s phone number. PATCH merges top-level fields into the existing object without replacing unrelated fields.
Set a field to
For example, if the stored object is
The serialized
null to delete that field. If no data exists yet, the patch starts with an empty object. A PATCH without ttlSeconds preserves the existing expiration; provide a new value to replace it.
The data is scoped to your organization and the phone number. A previously unknown number gets a contact automatically. US numbers can be formatted or sent as digits. Non-US numbers must include the + country code. URL-encode the + when it appears in the path.
Callers that do not have a phone number can be keyed by any other identifier, such as a chat or SIP identifier, of up to 128 characters. Simple stores those identifiers as provided and returns them unchanged in phoneNumber.
curl -X PATCH 'https://api.usesimple.ai/api/v1/contacts/14155550100/data' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"data": {
"routingStatus": "completed",
"five9ConversationId": null
}
}'
{"five9ConversationId":"conv-48291","routingStatus":"queued"}, the request above leaves {"routingStatus":"completed"}.
The response contains the normalized phone number, the merged object, its revision, and expiration metadata:
{
"phoneNumber": "+14155550100",
"data": {
"routingStatus": "completed"
},
"revision": 2,
"ttlSeconds": null,
"expiresAt": null
}
data object may be at most 64 KiB. When supplied, ttlSeconds must be an integer from 60 seconds through 90 days. Without an explicit TTL, a record has no expiry by default or keeps its current expiry when patching an existing record.
The endpoint returns 401 when authentication fails and 422 when the caller identifier or request body is invalid.Authorizations
Path Parameters
The caller's phone number or other caller identifier. US numbers may be formatted or sent as digits; non-US numbers must include the + country code. Non-phone identifiers (for example chat or SIP identifiers) are accepted verbatim, up to 128 characters.
Body
application/json
Response
Contact data merged.
The normalized phone number in E.164 format, or the caller identifier as provided when it is not a phone number.
The stored JSON object.
The revision number of this value.
Required range:
x >= 1Remaining TTL in seconds, or null when the record has no expiry.
Expiration timestamp in UTC, or null when the record has no expiry.
Last modified on September 3, 2026