curl --request PATCH \
--url https://api.instaview.sk/contacts/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phoneNumber": "+421901234567",
"gdprExpiryDate": "2026-11-16",
"status": "IN_PROCESS",
"jobIds": [
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174001"
],
"metadata": {
"source": "LinkedIn",
"referredBy": "John Smith"
},
"fields": {
"order_number": "SO-40129",
"renewal_date": null
},
"gender": "female",
"cvText": "Jane Doe\nSoftware Engineer\nExperience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}
'import requests
url = "https://api.instaview.sk/contacts/{id}"
payload = {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phoneNumber": "+421901234567",
"gdprExpiryDate": "2026-11-16",
"status": "IN_PROCESS",
"jobIds": ["123e4567-e89b-12d3-a456-426614174000", "987e6543-e21b-12d3-a456-426614174001"],
"metadata": {
"source": "LinkedIn",
"referredBy": "John Smith"
},
"fields": {
"order_number": "SO-40129",
"renewal_date": None
},
"gender": "female",
"cvText": "Jane Doe
Software Engineer
Experience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}
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({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phoneNumber: '+421901234567',
gdprExpiryDate: '2026-11-16',
status: 'IN_PROCESS',
jobIds: ['123e4567-e89b-12d3-a456-426614174000', '987e6543-e21b-12d3-a456-426614174001'],
metadata: {source: 'LinkedIn', referredBy: 'John Smith'},
fields: {order_number: 'SO-40129', renewal_date: null},
gender: 'female',
cvText: 'Jane Doe\nSoftware Engineer\nExperience: ...',
workHistory: [
{
companyName: 'Google',
candidatePosition: 'Software Engineer',
referencePhone: '+1987654321',
id: '123e4567-e89b-12d3-a456-426614174000',
referenceName: 'Jane Smith',
startDate: '2020-01-01',
endDate: '2022-12-31'
}
]
})
};
fetch('https://api.instaview.sk/contacts/{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.instaview.sk/contacts/{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([
'firstName' => 'John',
'lastName' => 'Doe',
'email' => 'john.doe@example.com',
'phoneNumber' => '+421901234567',
'gdprExpiryDate' => '2026-11-16',
'status' => 'IN_PROCESS',
'jobIds' => [
'123e4567-e89b-12d3-a456-426614174000',
'987e6543-e21b-12d3-a456-426614174001'
],
'metadata' => [
'source' => 'LinkedIn',
'referredBy' => 'John Smith'
],
'fields' => [
'order_number' => 'SO-40129',
'renewal_date' => null
],
'gender' => 'female',
'cvText' => 'Jane Doe
Software Engineer
Experience: ...',
'workHistory' => [
[
'companyName' => 'Google',
'candidatePosition' => 'Software Engineer',
'referencePhone' => '+1987654321',
'id' => '123e4567-e89b-12d3-a456-426614174000',
'referenceName' => 'Jane Smith',
'startDate' => '2020-01-01',
'endDate' => '2022-12-31'
]
]
]),
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.instaview.sk/contacts/{id}"
payload := strings.NewReader("{\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\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.instaview.sk/contacts/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.instaview.sk/contacts/{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 \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "123e4567-e89b-12d3-a456-426614174000",
"firstName": "John",
"lastName": "Doe",
"status": "APPLIED",
"fields": {
"order_number": "SO-40128",
"is_vip": true,
"renewal_date": "2026-04-01"
},
"createdAt": "2025-11-20T10:30:00Z",
"updatedAt": "2025-11-20T10:30:00Z",
"jobId": "987e6543-e21b-12d3-a456-426614174000",
"jobIds": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"email": "john.doe@example.com",
"phoneNumber": "+421915123456",
"gdprExpiryDate": "2026-11-16",
"overallRating": 85,
"metadata": {
"source": "LinkedIn",
"externalId": "CAND-12345"
},
"analysisCount": 2,
"interviewCount": 3,
"links": {
"analyses": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/analyses",
"interviews": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/conversations"
},
"gender": "female",
"anonymizedCvText": "[NAME]\nSoftware Engineer\nExperience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}Update Contact
Updates a contact that belongs to the API key’s company. Only basic profile, reachability and status fields are supported.
curl --request PATCH \
--url https://api.instaview.sk/contacts/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phoneNumber": "+421901234567",
"gdprExpiryDate": "2026-11-16",
"status": "IN_PROCESS",
"jobIds": [
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174001"
],
"metadata": {
"source": "LinkedIn",
"referredBy": "John Smith"
},
"fields": {
"order_number": "SO-40129",
"renewal_date": null
},
"gender": "female",
"cvText": "Jane Doe\nSoftware Engineer\nExperience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}
'import requests
url = "https://api.instaview.sk/contacts/{id}"
payload = {
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phoneNumber": "+421901234567",
"gdprExpiryDate": "2026-11-16",
"status": "IN_PROCESS",
"jobIds": ["123e4567-e89b-12d3-a456-426614174000", "987e6543-e21b-12d3-a456-426614174001"],
"metadata": {
"source": "LinkedIn",
"referredBy": "John Smith"
},
"fields": {
"order_number": "SO-40129",
"renewal_date": None
},
"gender": "female",
"cvText": "Jane Doe
Software Engineer
Experience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}
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({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phoneNumber: '+421901234567',
gdprExpiryDate: '2026-11-16',
status: 'IN_PROCESS',
jobIds: ['123e4567-e89b-12d3-a456-426614174000', '987e6543-e21b-12d3-a456-426614174001'],
metadata: {source: 'LinkedIn', referredBy: 'John Smith'},
fields: {order_number: 'SO-40129', renewal_date: null},
gender: 'female',
cvText: 'Jane Doe\nSoftware Engineer\nExperience: ...',
workHistory: [
{
companyName: 'Google',
candidatePosition: 'Software Engineer',
referencePhone: '+1987654321',
id: '123e4567-e89b-12d3-a456-426614174000',
referenceName: 'Jane Smith',
startDate: '2020-01-01',
endDate: '2022-12-31'
}
]
})
};
fetch('https://api.instaview.sk/contacts/{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.instaview.sk/contacts/{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([
'firstName' => 'John',
'lastName' => 'Doe',
'email' => 'john.doe@example.com',
'phoneNumber' => '+421901234567',
'gdprExpiryDate' => '2026-11-16',
'status' => 'IN_PROCESS',
'jobIds' => [
'123e4567-e89b-12d3-a456-426614174000',
'987e6543-e21b-12d3-a456-426614174001'
],
'metadata' => [
'source' => 'LinkedIn',
'referredBy' => 'John Smith'
],
'fields' => [
'order_number' => 'SO-40129',
'renewal_date' => null
],
'gender' => 'female',
'cvText' => 'Jane Doe
Software Engineer
Experience: ...',
'workHistory' => [
[
'companyName' => 'Google',
'candidatePosition' => 'Software Engineer',
'referencePhone' => '+1987654321',
'id' => '123e4567-e89b-12d3-a456-426614174000',
'referenceName' => 'Jane Smith',
'startDate' => '2020-01-01',
'endDate' => '2022-12-31'
]
]
]),
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.instaview.sk/contacts/{id}"
payload := strings.NewReader("{\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\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.instaview.sk/contacts/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.instaview.sk/contacts/{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 \"firstName\": \"John\",\n \"lastName\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"phoneNumber\": \"+421901234567\",\n \"gdprExpiryDate\": \"2026-11-16\",\n \"status\": \"IN_PROCESS\",\n \"jobIds\": [\n \"123e4567-e89b-12d3-a456-426614174000\",\n \"987e6543-e21b-12d3-a456-426614174001\"\n ],\n \"metadata\": {\n \"source\": \"LinkedIn\",\n \"referredBy\": \"John Smith\"\n },\n \"fields\": {\n \"order_number\": \"SO-40129\",\n \"renewal_date\": null\n },\n \"gender\": \"female\",\n \"cvText\": \"Jane Doe\\nSoftware Engineer\\nExperience: ...\",\n \"workHistory\": [\n {\n \"companyName\": \"Google\",\n \"candidatePosition\": \"Software Engineer\",\n \"referencePhone\": \"+1987654321\",\n \"id\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"referenceName\": \"Jane Smith\",\n \"startDate\": \"2020-01-01\",\n \"endDate\": \"2022-12-31\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "123e4567-e89b-12d3-a456-426614174000",
"firstName": "John",
"lastName": "Doe",
"status": "APPLIED",
"fields": {
"order_number": "SO-40128",
"is_vip": true,
"renewal_date": "2026-04-01"
},
"createdAt": "2025-11-20T10:30:00Z",
"updatedAt": "2025-11-20T10:30:00Z",
"jobId": "987e6543-e21b-12d3-a456-426614174000",
"jobIds": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"email": "john.doe@example.com",
"phoneNumber": "+421915123456",
"gdprExpiryDate": "2026-11-16",
"overallRating": 85,
"metadata": {
"source": "LinkedIn",
"externalId": "CAND-12345"
},
"analysisCount": 2,
"interviewCount": 3,
"links": {
"analyses": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/analyses",
"interviews": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/conversations"
},
"gender": "female",
"anonymizedCvText": "[NAME]\nSoftware Engineer\nExperience: ...",
"workHistory": [
{
"companyName": "Google",
"candidatePosition": "Software Engineer",
"referencePhone": "+1987654321",
"id": "123e4567-e89b-12d3-a456-426614174000",
"referenceName": "Jane Smith",
"startDate": "2020-01-01",
"endDate": "2022-12-31"
}
]
}PATCH /candidates/{id} is a permanent alias of this endpoint and keeps working unchanged, with the same scopes and the same response. See Resource names.Overview
A partial update, so you send the fields you want to change and nothing more. Use it to correct a phone number, move someone’s status, change their job assignments, or attach metadata.Use Cases
- Status updates: move a contact through your own process
- Reachability: change email, phone number or name
- Gender override: set or clear it for accurate addressing on the call
- Job assignments: attach, replace or clear them
- Metadata: add or change your own opaque key-value pairs — not the same thing as contact fields
- Refinement: fill the record in as you learn more
Partial Updates
You can update any combination of fields:// Update only status
PATCH /contacts/{id}
{
"status": "IN_PROCESS"
}
// Update how to reach them
PATCH /contacts/{id}
{
"email": "newemail@example.com",
"phoneNumber": "+1987654321"
}
// Assign to multiple jobs
PATCH /contacts/{id}
{
"jobIds": ["job-uuid-1", "job-uuid-2", "job-uuid-3"]
}
// Remove all job assignments
PATCH /contacts/{id}
{
"jobIds": []
}
// Set gender explicitly
PATCH /contacts/{id}
{
"gender": "female"
}
// Clear gender (revert to auto-detection)
PATCH /contacts/{id}
{
"gender": null
}
// Replace the work history
PATCH /contacts/{id}
{
"workHistory": [
{
"companyName": "Tech Corp",
"candidatePosition": "Senior Software Engineer",
"referenceName": "Jane Smith",
"referencePhone": "+1234567890",
"startDate": "2020-01-01"
}
]
}
metadata is not readable by an agent. It is your own scratch space — free-form,
unvalidated, and never placed in a prompt. If you want a value an agent can say, it has to
be a contact field: catalogued, typed, and addressable as {{contact.<key>}}. See
Update Contact.metadata never disturbs the contact’s fields. The two are stored separately, so
replacing metadata wholesale cannot reach the catalogued values: they survive the write
untouched, and the response shows them back to you under fields. A routine sync of your own
payload cannot erase a value an agent depends on.It does not work as a back door either. Nothing on the metadata path checks a value against
its field’s type, enum or reserved-key rules, and nothing reads a contact field out of it —
whatever you put there stays your own scratch space. fields below is the validated door, on
this endpoint and on POST /contacts, and it answers
422 naming the key when a value does not fit.Updating Field Values
Sendfields to change a contact’s catalogued values in the same request as anything else:
PATCH /contacts/{id}
{ "status": "contacted", "fields": { "order_number": "SO-40129" } }
fields merges; metadata replaces. A key you omit keeps its value, and an explicit
null clears one. The two behave differently in the same request body on purpose:
metadata is one opaque document you own, fields are individually catalogued values.// Change one value, leave every other alone
PATCH /contacts/{id}
{ "fields": { "order_number": "SO-40129" } }
// Clear one
PATCH /contacts/{id}
{ "fields": { "renewal_date": null } }
"fields": null is not a wipe — it reads as “no values in this request” and is a no-op.
Clearing is per key, which is what stops a partial update from blanking a contact by accident.
Values are validated against the catalog
Every value is checked against its field’s declared type, and an unknown key is refused. Both answer422 naming the key — never a silent drop, because a caller who believes it wrote a
value it did not is the worse outcome. 422 rather than 400: the request is well formed, it
is the catalog that rejects its contents.
Validation runs in the same transaction as the contact update, so a rejection applies
nothing — not the status, not the metadata, not the other values.
| The field is | Accepted | Refused |
|---|---|---|
string | any text (trimmed) | an object |
number | 42, "42", "-7.5" | "twelve", "12abc" |
bool | true, "true", "yes", "1" and negatives | "maybe" |
date | "2026-04-20", any parseable date | "not a date" |
enum | one of the field’s enumOptions | anything else — the error lists the options |
tags | ["vip","renewal"], or "vip, renewal" | 42, true, an object |
first_name, email and the rest are set as the
contact’s own properties above, and company_description and agent_name resolve from your
company and your agent, so a value stored under them would be shadowed on every call.
tags takes two shapes
A tags field stores a string[] and accepts either the array or one comma-separated
string — so a single CSV cell holding several tags maps onto one field without your side
splitting it first. The two are equivalent:
PATCH /contacts/{id}
{ "fields": { "tags": ["vip", "renewal"] } }
// Same result
PATCH /contacts/{id}
{ "fields": { "tags": "vip, renewal" } }
"vip,, renewal," is two tags) and duplicates are
removed case-insensitively, keeping the spelling that came first — ["VIP","vip"] stores
["VIP"].
["north, east"] stores two tags, exactly as "north, east" does. The two
shapes would otherwise mean different things, and a value edited in the dashboard — which
renders the list as one comma-joined line — would split on the next save with no warning.422
naming the limit.
[], [""] and "," all say the contact has no tags, so
they clear the field exactly as null and "" do — you never get a key present with an
empty array behind it.422 rather than a
one-element list, because a caller sending 42 for a tags field has a mapping bug and a
silent ["42"] would be spoken on a call.
?createMissingFields=true
Off by default. When passed, a key in fields that your catalog does not know yet is
defined for you as a string field, instead of the request being rejected.
PATCH /contacts/{id}?createMissingFields=true
{ "fields": { "warranty_ref": "W-9921" } }
// warranty_ref now exists in your catalog, labelled "Warranty ref"
POST /contacts.
oder_number creates oder_number, visible in every
agent’s variable palette until somebody deletes it. That is why the option is opt-in per
request rather than a mode you can leave on.- It needs no extra scope. The same
write:contactsthat lets you define a field explicitly lets you define one implicitly. What it will still never do is quietly ignore an unknown key you did not ask it to create. - The field is always
string. The value is the only evidence available and it is a poor one:"1"could be a number, a boolean or an order reference, and a wrong guess becomes validation that rejects your next row.PATCH /contact-fields/{id}retypes it afterwards. Reserved keys, malformed keys and a company already at its field ceiling are all still refused.
POST /contact-fields — you get the right
type and label, and a typo fails loudly.
Managing Job Assignments
jobIds sets which jobs a contact is associated with. It replaces the array rather than adding to it:
// Assign the contact to several jobs
await updateContact("contact-uuid", {
jobIds: ["job-1-uuid", "job-2-uuid", "job-3-uuid"],
});
// Add one to the existing assignments
// Note: fetch current state first, since PATCH replaces the whole jobIds array
const contact = await getContact("contact-uuid");
await updateContact("contact-uuid", {
jobIds: [...contact.jobIds, "new-job-uuid"],
});
// Replace every assignment with one job
await updateContact("contact-uuid", {
jobIds: ["only-this-job-uuid"],
});
// Remove every job assignment
await updateContact("contact-uuid", {
jobIds: [],
});
jobIds must name an existing job belonging to your API key’s
company. An unknown id is a validation error, not a silent omission.jobIds updates lose assignments. Because the field replaces the array, adding
one job is a read-modify-write, and the endpoint offers no precondition to make that safe — no
If-Match, no version field. Two requests that both read ["job-1"] and each append their own
job leave the contact with whichever wrote last, and the other assignment is gone. It is not
reported: both calls answer 200.Serialise jobIds writes for a given contact — a queue or a lock of your own, keyed on the
contact id — rather than issuing them in parallel from several workers. Fields that are not
read-modify-write (email, status, metadata) do not have this problem.Status Values
status is one of:
| Value | Meaning |
|---|---|
UNDEFINED | No status set |
APPLIED | The starting point for an inbound contact |
IN_PROCESS | Somewhere in your process |
REJECTED | Closed out unsuccessfully |
ACCEPTED | Closed out successfully |
400.Company Isolation
You can only update contacts belonging to your API key’s company. Ownership is validated before anything is written.Error Scenarios
- 404 Not Found: the contact does not exist, or has been deleted
- 403 Forbidden: the contact belongs to a different company, or a
jobIdsentry names another company’s job - 400 Bad Request: invalid field values, or a
jobIdsentry naming no job at all
Related Resources
Contacts Resource Guide
Get Contact
Create Contact
Authorizations
API key for authentication using Bearer scheme
Path Parameters
Query Parameters
Required for ATS API keys to specify which company to access. Ignored for standard company API keys.
Define any key in fields that your catalog does not know yet, as a STRING field, instead of rejecting the request. Off by default, because a typo would otherwise become a permanent field in your catalog — visible in every agent's variable palette until somebody deletes it. A key the platform reserves, a malformed key, and a company already at its field ceiling are all still refused.
Body
The contact's first name
1 - 100"John"
The contact's last name
1 - 100"Doe"
The contact's email address
"john.doe@example.com"
The contact's phone number in E.164 format
^\+[1-9]\d{1,14}$"+421901234567"
GDPR expiry date in ISO 8601 format (must be in the future)
"2026-11-16"
Contact status
UNDEFINED, APPLIED, IN_PROCESS, REJECTED, ACCEPTED "IN_PROCESS"
Array of job IDs to assign the contact to (replaces existing assignments)
[
"123e4567-e89b-12d3-a456-426614174000",
"987e6543-e21b-12d3-a456-426614174001"
]
Custom metadata (replaces existing metadata, max 10KB, 5 levels deep, 50 keys)
{
"source": "LinkedIn",
"referredBy": "John Smith"
}
Catalogued field values, keyed by catalog key. MERGED key by key, unlike metadata which replaces: a key you omit keeps its value, and an explicit null clears one. Validated against each field's declared type, so an unknown key or a wrong-typed value is a 422 naming it, and the whole request is rolled back.
{
"order_number": "SO-40129",
"renewal_date": null
}
The contact's gender. Set to 'male' or 'female' to override auto-detection, or null to clear and revert to auto-detection.
male, female "female"
The contact's CV in plain text. This will be automatically anonymized.
50000"Jane Doe\nSoftware Engineer\nExperience: ..."
Optional work history items for the contact (replaces the existing ones).
20Show child attributes
Show child attributes
Response
Contact ID
"123e4567-e89b-12d3-a456-426614174000"
The contact's first name
"John"
The contact's last name
"Doe"
Contact status
UNDEFINED, APPLIED, IN_PROCESS, REJECTED, ACCEPTED "APPLIED"
The contact's catalogued field values, keyed by field key — the counterpart of metadata, and the only half an agent can speak. Each key is defined in the company catalog (GET /contact-fields) and addressable in a flow as {{contact.<key>}}. Written through fields on POST /contacts and PATCH /contacts/{id}, never through metadata. A field with no value is absent rather than null; {} means none are set.
{
"order_number": "SO-40128",
"is_vip": true,
"renewal_date": "2026-04-01"
}
Created timestamp (UTC)
"2025-11-20T10:30:00Z"
Updated timestamp (UTC)
"2025-11-20T10:30:00Z"
[Deprecated] Single job ID; use jobIds instead.
"987e6543-e21b-12d3-a456-426614174000"
Jobs the contact is assigned to.
50The contact's email address
"john.doe@example.com"
The contact's phone number
"+421915123456"
GDPR expiry date. Currently returned as a date (no time). NOTE: We plan to migrate to a timestamp with timezone (timestamptz) for global correctness.
"2026-11-16"
Overall rating/match score (0-100)
0 <= x <= 10085
Your own scratch space on the contact: free-form, unvalidated, and never read by an agent. Replaced wholesale on update. Not the place for values you want an agent to say — those are fields.
{
"source": "LinkedIn",
"externalId": "CAND-12345"
}
Number of analyses for this contact. Not currently populated by any endpoint — treat as absent.
2
Number of conversations for this contact. Keeps its original field name, and is not currently populated by any endpoint — treat as absent.
3
Convenience links to related collections. Endpoints may be added incrementally.
{
"analyses": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/analyses",
"interviews": "/v1/public/contacts/123e4567-e89b-12d3-a456-426614174000/conversations"
}
The contact's gender. Used for gender-aware addressing on the call. Null if not explicitly set (auto-detected from the name).
male, female "female"
The contact's anonymized CV in plain text.
"[NAME]\nSoftware Engineer\nExperience: ..."
Work history items for the contact.
20Show child attributes
Show child attributes