curl --request PUT \
--url https://devapi.prov.ae/v2/public/leads/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"budgetMin": "1200000",
"budgetMax": "1800000",
"areaOfInterest": "Dubai Marina",
"quiz": {
"quizKey": "buyer_qualification_v2",
"quizName": "Buyer qualification",
"locale": "en",
"answers": [
{
"questionKey": "timeframe",
"label": "When are you looking to buy?",
"optionKeys": [
"3_6_months"
]
},
{
"questionKey": "purpose",
"label": "Purpose",
"value": "Investment"
}
]
}
}
'import requests
url = "https://devapi.prov.ae/v2/public/leads/{id}"
payload = {
"budgetMin": "1200000",
"budgetMax": "1800000",
"areaOfInterest": "Dubai Marina",
"quiz": {
"quizKey": "buyer_qualification_v2",
"quizName": "Buyer qualification",
"locale": "en",
"answers": [
{
"questionKey": "timeframe",
"label": "When are you looking to buy?",
"optionKeys": ["3_6_months"]
},
{
"questionKey": "purpose",
"label": "Purpose",
"value": "Investment"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
budgetMin: '1200000',
budgetMax: '1800000',
areaOfInterest: 'Dubai Marina',
quiz: {
quizKey: 'buyer_qualification_v2',
quizName: 'Buyer qualification',
locale: 'en',
answers: [
{
questionKey: 'timeframe',
label: 'When are you looking to buy?',
optionKeys: ['3_6_months']
},
{questionKey: 'purpose', label: 'Purpose', value: 'Investment'}
]
}
})
};
fetch('https://devapi.prov.ae/v2/public/leads/{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://devapi.prov.ae/v2/public/leads/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'budgetMin' => '1200000',
'budgetMax' => '1800000',
'areaOfInterest' => 'Dubai Marina',
'quiz' => [
'quizKey' => 'buyer_qualification_v2',
'quizName' => 'Buyer qualification',
'locale' => 'en',
'answers' => [
[
'questionKey' => 'timeframe',
'label' => 'When are you looking to buy?',
'optionKeys' => [
'3_6_months'
]
],
[
'questionKey' => 'purpose',
'label' => 'Purpose',
'value' => 'Investment'
]
]
]
]),
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://devapi.prov.ae/v2/public/leads/{id}"
payload := strings.NewReader("{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PUT", 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.put("https://devapi.prov.ae/v2/public/leads/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://devapi.prov.ae/v2/public/leads/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updated": true,
"updatedFields": [
"budgetMin",
"budgetMax",
"closingAreaId",
"quizAnswers"
],
"intakeUnresolved": {},
"needsIntakeReview": true,
"rerouted": true,
"assignedTo": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"slug": "sarah-ahmed",
"name": "Sarah Ahmed",
"email": "<string>",
"phone": "<string>",
"whatsappPhone": "<string>",
"active": true
}
}{
"statusCode": 400,
"code": "BAD_REQUEST",
"message": "<string>",
"errors": [
"<string>"
],
"details": {},
"path": "/v2/public/leads",
"timestamp": "2023-11-07T05:31:56Z"
}{
"statusCode": 401,
"code": "OAUTH_TOKEN_EXPIRED",
"message": "OAuth access token expired",
"path": "/v2/public/projects/filters",
"timestamp": "2026-07-27T06:31:04.512Z"
}{
"statusCode": 400,
"code": "BAD_REQUEST",
"message": "<string>",
"errors": [
"<string>"
],
"details": {},
"path": "/v2/public/leads",
"timestamp": "2023-11-07T05:31:56Z"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too Many Requests",
"path": "/v2/public/leads",
"timestamp": "2026-07-27T06:31:04.512Z"
}Update a lead — details that arrive later
For the case where you do not have the whole enquiry at once: the name, email and phone go in with POST /public/leads, and the quiz answers, budget and area follow minutes or hours later.
Send only what changed. An omitted field is left alone, an explicit null clears the column, and a value that matches no CRM record leaves the column as it was rather than blanking it — a typo never erases a good value. A field you do send wins over what the lead had, including a value an agent typed, so only send fields you are authoritative about.
leadPhones and leadEmails are APPENDED, never replaced, so re-sending the one number you know is free. Quiz answers supersede the previous answers for the same quizKey, which makes a retry idempotent.
The lead’s workflow is not writable here at all: stage, status, assigned agent, funnel board and the aging clock stay Provident’s, whatever is sent.
New details DO send a lead nobody holds back through the assignment engine (see rerouted); a lead an agent already holds is never taken off them. Every update that changes something also posts a note on the lead’s timeline naming your integration and what changed.
PATCH is accepted as an alias for the same operation — the semantics are PATCH’s either way. This is not a way around the merge window: if the customer enquires again, POST it.
curl --request PUT \
--url https://devapi.prov.ae/v2/public/leads/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"budgetMin": "1200000",
"budgetMax": "1800000",
"areaOfInterest": "Dubai Marina",
"quiz": {
"quizKey": "buyer_qualification_v2",
"quizName": "Buyer qualification",
"locale": "en",
"answers": [
{
"questionKey": "timeframe",
"label": "When are you looking to buy?",
"optionKeys": [
"3_6_months"
]
},
{
"questionKey": "purpose",
"label": "Purpose",
"value": "Investment"
}
]
}
}
'import requests
url = "https://devapi.prov.ae/v2/public/leads/{id}"
payload = {
"budgetMin": "1200000",
"budgetMax": "1800000",
"areaOfInterest": "Dubai Marina",
"quiz": {
"quizKey": "buyer_qualification_v2",
"quizName": "Buyer qualification",
"locale": "en",
"answers": [
{
"questionKey": "timeframe",
"label": "When are you looking to buy?",
"optionKeys": ["3_6_months"]
},
{
"questionKey": "purpose",
"label": "Purpose",
"value": "Investment"
}
]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
budgetMin: '1200000',
budgetMax: '1800000',
areaOfInterest: 'Dubai Marina',
quiz: {
quizKey: 'buyer_qualification_v2',
quizName: 'Buyer qualification',
locale: 'en',
answers: [
{
questionKey: 'timeframe',
label: 'When are you looking to buy?',
optionKeys: ['3_6_months']
},
{questionKey: 'purpose', label: 'Purpose', value: 'Investment'}
]
}
})
};
fetch('https://devapi.prov.ae/v2/public/leads/{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://devapi.prov.ae/v2/public/leads/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'budgetMin' => '1200000',
'budgetMax' => '1800000',
'areaOfInterest' => 'Dubai Marina',
'quiz' => [
'quizKey' => 'buyer_qualification_v2',
'quizName' => 'Buyer qualification',
'locale' => 'en',
'answers' => [
[
'questionKey' => 'timeframe',
'label' => 'When are you looking to buy?',
'optionKeys' => [
'3_6_months'
]
],
[
'questionKey' => 'purpose',
'label' => 'Purpose',
'value' => 'Investment'
]
]
]
]),
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://devapi.prov.ae/v2/public/leads/{id}"
payload := strings.NewReader("{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}")
req, _ := http.NewRequest("PUT", 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.put("https://devapi.prov.ae/v2/public/leads/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://devapi.prov.ae/v2/public/leads/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"budgetMin\": \"1200000\",\n \"budgetMax\": \"1800000\",\n \"areaOfInterest\": \"Dubai Marina\",\n \"quiz\": {\n \"quizKey\": \"buyer_qualification_v2\",\n \"quizName\": \"Buyer qualification\",\n \"locale\": \"en\",\n \"answers\": [\n {\n \"questionKey\": \"timeframe\",\n \"label\": \"When are you looking to buy?\",\n \"optionKeys\": [\n \"3_6_months\"\n ]\n },\n {\n \"questionKey\": \"purpose\",\n \"label\": \"Purpose\",\n \"value\": \"Investment\"\n }\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"updated": true,
"updatedFields": [
"budgetMin",
"budgetMax",
"closingAreaId",
"quizAnswers"
],
"intakeUnresolved": {},
"needsIntakeReview": true,
"rerouted": true,
"assignedTo": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"slug": "sarah-ahmed",
"name": "Sarah Ahmed",
"email": "<string>",
"phone": "<string>",
"whatsappPhone": "<string>",
"active": true
}
}{
"statusCode": 400,
"code": "BAD_REQUEST",
"message": "<string>",
"errors": [
"<string>"
],
"details": {},
"path": "/v2/public/leads",
"timestamp": "2023-11-07T05:31:56Z"
}{
"statusCode": 401,
"code": "OAUTH_TOKEN_EXPIRED",
"message": "OAuth access token expired",
"path": "/v2/public/projects/filters",
"timestamp": "2026-07-27T06:31:04.512Z"
}{
"statusCode": 400,
"code": "BAD_REQUEST",
"message": "<string>",
"errors": [
"<string>"
],
"details": {},
"path": "/v2/public/leads",
"timestamp": "2023-11-07T05:31:56Z"
}{
"statusCode": 429,
"code": "RATE_LIMITED",
"message": "Too Many Requests",
"path": "/v2/public/leads",
"timestamp": "2026-07-27T06:31:04.512Z"
}Authorizations
The access_token returned by POST /oauth2/token, sent as Authorization: Bearer <access_token>. It is an opaque string, not a JWT.
Path Parameters
Lead id returned by POST /public/leads. A merged id works too — it is the surviving lead.
Body
Fields to change on an existing lead. Same names, lookups and forgiving matching as CreateLeadRequest; everything is optional, including phone and email — an update carrying nothing but a quiz block is normal. Omit a field and it is left alone. Send an explicit null and the column is cleared. Send a value that matches no CRM record and the column keeps what it had, with the value reported in intakeUnresolved. leadPhones and leadEmails are APPENDED to the lead, never replacing what is there. Quiz answers supersede the previous answers for the same quizKey only. assignedBy, funnel and distributionType are create-only and absent here: an external system does not move a lead between agents, between funnel boards, or onto a different aging clock.
Phone numbers. Used FIRST to match an existing contact. Use E.164 format for reliable matching. Required unless leadEmails is supplied.
64["+971501234567"]
Email addresses. Used to match an existing contact when no phone matches. Required unless leadPhones is supplied.
255["john.doe@example.com"]
255"John"
255"Ahmad"
Second given name — used when no middle name is supplied.
255"A."
255"Doe"
Company name for corporate enquiries.
255"Acme Real Estate"
LOOKUP. Lead type display name, e.g. Primary Buyer, Secondary Buyer, Primary Buyer and Secondary Buyer, Tenant, Landlord, Broker, Seller, Owner, Mortgages. Ask Provident for the full list. The shorthand Primary / Secondary / Primary and Secondary is accepted as an alias for the corresponding … Buyer type, in either direction. Omit this on a listing enquiry and it is derived from the listing — see listingId.
255"Primary Buyer"
Free text priority indicator.
64"High"
LOOKUP. Marketing's segmentation of the lead.
Standard, Luxury, Super Luxury 255"Luxury"
LOOKUP. Marketing's grading of the lead.
A, B, C, D 255"A"
LOOKUP. Location the lead is interested in.
"Dubai Marina"
LOOKUP. Property type the lead is interested in. Matched case-insensitively after trimming, and a regular English plural also matches the singular catalogue entry (Apartments → Apartment, Townhouses → Townhouse), so a form offering plural choices needs no mapping on your side.
255"Apartment"
Minimum budget. Numeric string; a JSON number is also accepted.
"1000000"
Maximum budget. Numeric string; a JSON number is also accepted.
"2500000"
LOOKUP. ISO 4217 currency code for the budget values.
3"AED"
Free-text message or callback reason from the form.
"Looking for a 2BR with sea view, ready to move in Q4."
LOOKUP. Languages the lead speaks, by code or name. Unrecognised entries are ignored.
255["ar", "English"]
LOOKUP. Provident listing UUID. Takes precedence over referenceNo when both are sent.
A resolved listing also fills in what the form did not ask. Each field below is taken from the listing ONLY where this payload leaves it empty — anything you send always wins, and a quiz answer mapped to the same field beats the listing too:
leadType— from the listing category and offering type: Primary -> Primary Buyer, Secondary -> Secondary Buyer, and any rental listing -> Tenant whatever its category.- developer, location, property type, bedrooms, currency — copied from the listing. The location fills the lead's own location and does not overwrite
areaOfInterest. budgetMin— the listing price, unless the price is on application or it would exceed abudgetMaxyou sent.budgetMaxis never derived.
Sending a value we then fail to match (an unknown developer name, say) is still reported in intakeUnresolved even though the listing goes on to fill that field.
The listing's own agent, where it has one, becomes the lead owner and wins over assignedBy.
LOOKUP. Listing reference number, used when listingId is not supplied. A reference number matching MORE THAN ONE listing counts as unresolved, and nothing is inherited. See listingId for what a resolved listing fills in.
128"PR-123456"
LOOKUP. Lead source. Send this — an unrecognised or omitted source leaves the lead with no source attribution.
255"Website"
LOOKUP. Sub-sources. Only those linked to the resolved source are kept; ignored entirely when source did not resolve.
255["Callback Form", "Team Page"]
LOOKUP. Marketing type, e.g. Organic or Paid.
255"Organic"
LOOKUP. What the user did — e.g. Submit Form, Call, Whatsapp Click, DM, Webpush, Gamification.
255"Submit Form"
LOOKUP. CRM campaign name.
255"Spring 2026 Landing Page"
CREATED ON FIRST SIGHT. Advertising campaign name — the one field here that is not a strict lookup: a name Provident has never seen creates the campaign instead of being discarded. Omit it when you send metaFacebook; the Meta campaign fills it.
255"Google Ads — Q3"
LOOKUP. Developer the enquiry is about, matched on name or slug — Sobha Realty or sobha-realty. Values come from GET /public/developers.
255"Sobha Realty"
Developer uuid from GET /public/developers. Takes precedence over developerName; a non-uuid value here is treated as a name instead of being discarded.
"8ecf4fcd-ec63-5764-8524-7cd917494dbe"
LOOKUP. Website NAME or DOMAIN the lead came from — either resolves, matched case-insensitively. Prefer the domain (provident.ae, providentestate.com); it survives a display-name change. Ask Provident to add your domain before you start sending it.
255"provident.ae"
Full URL of the page the submission originated from.
"https://prov.ae/en/dubai-marina?utm_source=google"
Locale segment of the URL path, e.g. en.
32"en"
Google Ads click id.
512Facebook click id.
512512"google"
512"cpc"
512"spring-2026"
512"dubai marina apartments"
512"hero-cta"
Name of the web form the visitor submitted. Falls back to metaFacebook.formName (truncated to 255) when omitted.
255"contact-popup-form"
Ad set / ad group name on your side. Free text — distinct from the campaignName lookup. Falls back to metaFacebook.adgroupName (truncated to 255) when omitted.
255"test ww"
Referring URL the visitor arrived from.
"https://sobha-city.provident.ae/?utm_source=Google+Ads"
Submitter IP. IPv4, IPv6 and proxy chains all fit.
64"217.165.113.16"
Browser user-agent string captured at submission.
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
When the visitor submitted the form on your side. Distinct from the CRM's own createdAt, which is when we received it. An unparseable value is ignored rather than failing the request.
"2026-07-27T13:45:31.728Z"
LOOKUP. Country code (e.g. AE) or full country name. When omitted, the API attempts to infer it from a trailing two-letter segment of pageUrl.
255"AE"
Meta / Facebook / Instagram (or TikTok) lead-ads metadata. Send only for leads originating from an ad-platform lead form. The standard fields above still drive routing.
Stored alongside the lead AND copied onto it: metaCampaignId + metaCampaignName become the lead's advertising campaign (matched on the Meta campaign id, and created if Provident has never seen it, so campaign names need no prior agreement); finalPageName, adName/adId, adgroupName/adgroupId and formName/formId become filterable columns on the lead. Matching on the id is what makes a rename safe — rename a campaign in Ads Manager and its leads stay on one campaign in the CRM. campaignName is a different, strictly-matched field: the CRM's own campaign, which drives routing.
The whole object is discarded when metaLeadId is absent. metaLeadId is unique across the CRM: it prevents the metadata being attached twice, but it does NOT prevent a duplicate lead — de-duplicate on your side.
Show child attributes
Show child attributes
A dynamic quiz / survey submitted with the lead — for landing pages that ask a set of questions. Unlike every other field in this API, the questions do NOT have to be agreed with Provident in advance: questions and options register themselves the first time they arrive, so a new quiz starts capturing answers with no API change on either side. Answers are searchable in the CRM, shown on the lead, and — for questions Provident maps to a CRM field — used to fill that field on the lead itself.
Show child attributes
Show child attributes
Your handle for the specific automation behind this lead — a Make scenario name, a webhook id, a form build. Free text: stored verbatim, never matched against anything, and never reported in intakeUnresolved.
It identifies an INTEGRATION, not a submission, so keep it stable across every lead that automation sends; a per-lead unique id makes it useless for grouping. Values are only distinguished within one sender, so two partners can both use scenario-1.
Do NOT put your own name here. The submitting OAuth client is recorded automatically from the access token — there is no field for it, because attribution a sender can write is not attribution.
128"make:meta-leadgen-eu"
Response
Applied
False when the submission changed nothing — every value sent was already the lead's. Not an error.
Lead columns this submission actually changed, by CRM name (closingAreaId is what areaOfInterest fills). leadPhones/leadEmails appear when a new one was added, quizAnswers when answers were written, metaFacebook when the Meta block was stored.
[ "budgetMin", "budgetMax", "closingAreaId", "quizAnswers" ]
Values sent on THIS submission that matched no CRM record, keyed by the field you sent. Merged with whatever was already unresolved on the lead — an update never clears a flag it did not answer.
Show child attributes
Show child attributes
True when intakeUnresolved is non-empty.
True when the new details sent the lead back through the assignment engine. Only ever true for a lead nobody held — an update never moves a lead away from the agent working it. Routing is asynchronous: poll GET /public/leads/{id}/assignment for the outcome.
The agent holding the lead as this response was written, or null.
Show child attributes
Show child attributes