Creating and Updating Leads
This guide covers the public API endpoints for creating and updating leads, including accepted field formats and how to look up dealership-specific values such as lead status options.
For authentication setup, see Authentication. For updating lead outcomes (status) after creation, see Updating Lead Outcomes.
Endpoints
Section titled “Endpoints”| Action | Method | URL |
|---|---|---|
| Create lead | POST | https://dashboard.dealerstudio.com.au/api/v1/leads |
| Update lead | PUT | https://dashboard.dealerstudio.com.au/api/v1/leads/{id} |
OpenAPI reference: Create Lead, Update Lead.
Headers
Section titled “Headers”Every request must include:
{ "Authorization": "Bearer YOUR_API_KEY", "Accept": "application/json", "Content-Type": "application/json"}Your API key must include access to the target dealership. See the LMS overview for how to request a key and retrieve dealership identifiers.
Create lead
Section titled “Create lead”Minimal example
Section titled “Minimal example”{ "lead": { "name": "Jane Doe", "email": "jane@example.com", "phone": "0412345678", "dealership_id": 123, "category": "New Vehicle Enquiry", "source": "Website", "message": "Interested in a test drive" }}Success response
Section titled “Success response”201 Created:
{ "id": 456789, "lead_cluster_id": 123456}id— the new lead record.lead_cluster_id— the customer cluster this lead belongs to. Leads with the same email or phone at the same dealership are grouped into one cluster. Use this ID when updating lead status (see Lead status below).
Validation errors
Section titled “Validation errors”If a field value is invalid, the API returns 422 Unprocessable Content with a JSON object describing the problem. Field names map to arrays of error messages.
Unknown location_id:
{ "location_id": ["is invalid: no location found with this id"]}location_id that belongs to a different dealership:
{ "location_id": ["must belong to dealership"]}Unknown page_id:
{ "page_id": ["is invalid: no page found with this id"]}Use GET /api/v1/dealerships/{dealership_slug}/locations to look up valid location IDs for a dealership.
Required fields
Section titled “Required fields”| Field | Type | Description |
|---|---|---|
email | string | Customer email address |
phone | string | Customer phone number |
dealership_id | integer | Dealership ID, or use dealership_slug instead |
category | string | Lead category — must be an exact match from the accepted values |
source | string | Lead source — must be an exact match from the accepted values |
Update lead
Section titled “Update lead”Send a PUT request to /api/v1/leads/{id} with the same { "lead": { ... } } wrapper.
Every create and update request must include a dealership identifier — dealership_id, dealership_slug, or dealer_code — even when you are only changing other fields (for example message). Other lead fields can be omitted; only the dealership identifier and the fields you want to change need to be sent.
If the dealership identifier is missing, the API returns 422 Unprocessable Content:
{ "message": "dealership_id is required. Include dealership_id, dealership_slug, or dealer_code in the lead payload."}Example
Section titled “Example”{ "lead": { "dealership_id": 123, "message": "Updated enquiry notes" }}Restrictions
Section titled “Restrictions”- Dealership identifier: Required on every request (see above).
- Age limit: API key requests cannot update leads created more than 3 days ago. Older updates return
200 OKwith{ "message": "You cannot edit this lead" }. - Payments: If the lead already has a payment, sending
payment_attributesreturns{ "message": "Payment already exists" }.
Field reference
Section titled “Field reference”Standard lead fields
Section titled “Standard lead fields”These fields map directly to the lead record.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Customer full name |
last_name | string | No | Customer last name |
email | string | Yes (create) | Customer email |
phone | string | Yes (create) | Customer phone |
message | string | No | Free-text enquiry message |
dealership_id | integer | Yes (create and update) | Dealership ID |
dealership_slug | string | Yes (create and update) | Alternative to dealership_id |
category | string | Yes (create) | See Category |
source | string | Yes (create) | See Source |
marketing_source | string | No | See Marketing source |
subcategory | string | No | Form or funnel label; must match an allowed subcategory if provided |
location_id | integer | No | Dealership location ID |
website_id | integer | No | Website ID |
website_slug | string | No | Alternative to website_id |
page_id | integer | No | Page the lead was submitted from |
car_id | integer | No | Vehicle ID in Dealer Studio |
stocknum | string | No | Matches an in-stock vehicle by stock number when car_id is not supplied |
provider | string | No | Lead supplier name (e.g. Carsales) |
provider_id | string | No | External reference from the supplier |
tags | string[] | No | Tags applied to the lead and its cluster |
golden | boolean | No | Mark the cluster as high priority |
team_member_id | integer | No | Assign to a dealership user (by ID) |
user_email | string | No | Assign to a dealership user (by email) |
send_customer_email | boolean | No | Whether to send the customer confirmation email |
disable_strict_validation | boolean | No | When true, skips strict email and phone validation |
skip_website_location_validation | boolean | No | When true, skips validation that website_id and location_id belong to the lead’s dealership |
linked_query_params | object | No | Click IDs and UTM parameters from the customer’s landing page — see Marketing attribution |
visited_pages | string[] | No | Paths the customer visited before submitting (may include query strings) |
user_agent | string | No | Browser user-agent string from the submission |
address_attributes | object | No | Customer address — saved on the contact, not the lead (see below) |
Provide one of dealership_id, dealership_slug, or dealer_code on every create and update request.
Contact fields sent on the lead payload
Section titled “Contact fields sent on the lead payload”These fields are not columns on the lead itself. They are stored on the contact record linked to the lead.
| Field | Type | Format | Maps to |
|---|---|---|---|
first_name | string | — | contact.first_name |
last_name | string | — | contact.last_name (also stored on lead.last_name) |
dob | string | DD/MM/YYYY or YYYY-MM-DD | contact.date_of_birth |
postcode | string | — | contact.postcode (via fields) |
business_name | string | — | contact.business_name (via fields) |
abn | string | — | contact.abn (via fields) |
sms_verified | boolean | — | contact.sms_verified |
Date of birth (dob)
Section titled “Date of birth (dob)”Send date of birth as dob on the lead payload:
{ "lead": { "name": "Jane Doe", "email": "jane@example.com", "phone": "0412345678", "dealership_id": 123, "category": "New Vehicle Enquiry", "source": "Website", "dob": "01/01/1980" }}Accepted formats:
DD/MM/YYYY— e.g.01/01/1980(recommended for Australian integrations)YYYY-MM-DD— e.g.1980-01-01(ISO 8601 date)
Both formats are parsed when the contact is created or updated. Invalid dates are ignored silently.
You can also send dob inside the fields object, or as fields["Date Of Birth"]. The top-level dob key is the simplest approach.
Do not use date_of_birth on the lead payload — that field belongs to the Contact API, not lead create/update.
Address (address_attributes)
Section titled “Address (address_attributes)”{ "lead": { "address_attributes": { "street": "123 Example Street", "city": "Melbourne", "state": "VIC", "state_long": "Victoria", "postcode": 3000, "country": "Australia" } }}The address is geocoded and saved on the contact. It is not stored on the lead record.
Custom fields (fields)
Section titled “Custom fields (fields)”Any parameter that is not a recognised lead column is automatically moved into the lead’s fields JSON object. Keys are normalised to snake_case (e.g. firstName becomes first_name). Contact fields such as first_name, dob, and address_attributes are excluded and stored on the contact instead (see Contact fields).
You can send custom data either at the top level or explicitly in fields:
{ "lead": { "name": "Jane Doe", "email": "jane@example.com", "phone": "0412345678", "dealership_id": 123, "category": "New Vehicle Enquiry", "source": "Website", "preferred_contact_time": "Morning", "fields": { "campaign_id": "summer-2026", "referral_code": "partner-xyz" } }}Both preferred_contact_time and the explicit fields entries are stored under fields on the lead.
For marketing attribution (Google click IDs, Facebook click IDs, UTM tags), use linked_query_params on the lead payload — not fields. See Marketing attribution below.
For document request leads, include document_type in fields (car_analysis, ppsr, or equifax). This applies when category is Document Request, or when category is New Vehicle Enquiry or Used Vehicle Enquiry and subcategory is Document Request.
Accepted enum values
Section titled “Accepted enum values”Values must match exactly (case and spacing). The authoritative list is in the OpenAPI schema on Create Lead.
Category
Section titled “Category”Common values include:
Sales: New Vehicle Enquiry, Used Vehicle Enquiry, Test Drive Booking, Special Offer Enquiry, Fleet Enquiry, Finance Enquiry, Insurance Enquiry, Subscription Enquiry, Team Member Enquiry, Vehicle Reservation, Online Purchase, Brochure Download, Document Request, Referral Enquiry
Trade: Trade-In Enquiry, Sell My Car Enquiry
Service: Service Booking, Service Enquiry, Parts Enquiry, Service Retention, Loan Car Booking
General: General Enquiry, Survey, Competition Enquiry, Phone Call, Event Enquiry, SMS Campaign
Source
Section titled “Source”Common values include: Website, Walk In, Carsales, Autotrader, Phone Call, SMS Connect, Facebook, Facebook Marketplace, Manufacturer, Referral, Drive, Event, Mobile App, Google, Google Ads, Repeat, Retention, and others — see the OpenAPI enum for the full list.
If your API key has a default source configured, source may default when omitted.
Marketing source
Section titled “Marketing source”Optional attribution field. Values include: Facebook, Google, Adwords, Organic, Unknown, QR Code, Email, SMS, GMB, Carsales, Instagram, Popup, Linkedin, CRM, Messenger, Audience Network, TikTok, YouTube, ChatGPT, Drive, CFive AI Receptionist.
You can set marketing_source explicitly, but in most integrations you should omit it and let Dealer Studio derive it from linked_query_params (see below).
Marketing attribution (click IDs and UTM parameters)
Section titled “Marketing attribution (click IDs and UTM parameters)”When a customer lands on your site or app from a tracked campaign, capture the query parameters from the page URL (for example gclid, fbclid, utm_source) and send them in the lead create payload.
Important: Attribution parameters must be sent in the JSON request body, nested under lead.linked_query_params. Appending them to the API URL (for example POST /api/v1/leads?gclid=...) has no effect.
Recommended: linked_query_params
Section titled “Recommended: linked_query_params”Send click IDs and UTM parameters as a key/value object on the lead:
{ "lead": { "name": "Jane Doe", "email": "jane@example.com", "phone": "0412345678", "dealership_id": 123, "category": "New Vehicle Enquiry", "source": "Website", "linked_query_params": { "gclid": "EAIaIQobChMI...", "utm_source": "google", "utm_medium": "cpc", "utm_campaign": "dealer_sem" }, "visited_pages": ["/new-cars/toyota-camry?gclid=EAIaIQobChMI..."], "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" }}Common keys include:
| Key | Description |
|---|---|
gclid | Google Ads click ID |
gbraid, wbraid | Google Ads enhanced conversions click IDs |
gad_campaignid | Google Ads campaign ID |
fbclid | Meta (Facebook/Instagram) click ID |
utm_source | Campaign source (e.g. google, facebook, email) |
utm_medium | Campaign medium (e.g. cpc, email) |
utm_campaign | Campaign name |
utm_content, utm_term | Optional UTM dimensions |
Any additional query parameter keys from the landing page may also be included; they are stored on the lead for reporting and exports.
Automatic attribution
Section titled “Automatic attribution”When linked_query_params is present, Dealer Studio sets marketing_source and utm_campaign on the lead from those values. You do not need to send marketing_source unless you want to override the derived value.
| Parameters present | marketing_source set to |
|---|---|
gclid, gbraid, wbraid, or gad_campaignid | Adwords |
fbclid, or utm_source of facebook / fb | Facebook |
utm_source of ig | Instagram |
utm_source of msg | Messenger |
utm_source of an | Audience Network |
utm_source of tiktok | TikTok |
utm_source of youtube | YouTube |
utm_source of chatgpt.com | ChatGPT |
utm_source of qr_code | QR Code |
utm_source of gmb or googlemaps | GMB |
utm_source of email, or utm_medium of email | Email |
utm_source of sms | SMS |
utm_source of carsales | Carsales |
utm_source of linkedin | Linkedin |
utm_source of crm | CRM |
utm_campaign is taken from the first value when the parameter is sent as an array.
Fallback: page URL in fields
Section titled “Fallback: page URL in fields”If you do not send linked_query_params, Dealer Studio can parse UTM and click-ID parameters from the query string of url in fields (the full page URL where the customer submitted the form):
{ "lead": { "name": "Jane Doe", "email": "jane@example.com", "phone": "0412345678", "dealership_id": 123, "category": "New Vehicle Enquiry", "source": "Website", "url": "https://dealer.example.com/enquiry?utm_source=google&gclid=abc123&utm_campaign=dealer_sem" }}The url key is stored in fields automatically when it is not a recognised lead column. Prefer linked_query_params when you have discrete values — it is explicit, and takes precedence when both are sent.
Integration pattern
Section titled “Integration pattern”- On page load, read query parameters from the customer’s browser URL (for example via
window.location.search). - Persist them in session storage or your form state until the customer submits.
- Include them in
linked_query_paramsonPOST /api/v1/leads.
Lead status
Section titled “Lead status”Lead status is not set on POST /api/v1/leads or PUT /api/v1/leads/{id}. When a lead is created, its cluster is assigned the dealership’s default new status automatically.
To read or update status, use the lead cluster endpoints instead.
Looking up valid status values
Section titled “Looking up valid status values”Lead status options are dealership-specific. Each dealership (and pipeline) can have custom status names. Do not hard-code status IDs or names — fetch them first:
GET /api/v1/dealerships/{dealership_slug}/lead_status_optionsOpenAPI reference: List lead status options.
Example response (abbreviated):
[ { "id": 762, "name": "new", "status_type": "new", "active": true, "position": 1, "pipeline": { "id": 45, "name": "Sales" } }, { "id": 763, "name": "contacted", "status_type": "working", "active": true, "position": 2, "pipeline": { "id": 45, "name": "Sales" } }]| Response field | Description |
|---|---|
id | Use this as lead_status_option_id when updating a cluster |
name | Human-readable status name (also accepted as legacy lead_state) |
status_type | Internal category: new, working, converted, delivered, lost, or invalid |
pipeline | Which pipeline this status belongs to |
Default status names for most dealerships are: new, contacted, converted, delivered, lost, and spam. Dealers can rename these or add custom statuses (e.g. Technigo Working).
Updating lead status
Section titled “Updating lead status”Use the lead_cluster_id returned from lead create:
PUT /api/v1/dealerships/{dealership_slug}/lead_clusters/{lead_cluster_id}Preferred — pass the ID from the lookup endpoint:
{ "lead_cluster": { "lead_status_option_id": 762 }}Legacy — pass the status name as lead_state (must match a status name for that dealership’s pipeline):
{ "lead_cluster": { "lead_state": "contacted" }}See Updating Lead Outcomes for full details.
Clustering behaviour
Section titled “Clustering behaviour”When a lead is created, Dealer Studio automatically groups it into a lead cluster based on matching customer email or phone at the same dealership. A returning customer with the same contact details is added to their existing open cluster rather than creating a duplicate contact.
The create response includes both id (lead) and lead_cluster_id (cluster). Store lead_cluster_id if you need to update status or receive cluster-level webhooks later.
Related endpoints
Section titled “Related endpoints”| Purpose | Endpoint |
|---|---|
| Dealership locations and users | GET /api/v1/apikeys/apikey_details.json |
| Lead status options | GET /api/v1/dealerships/{slug}/lead_status_options |
| Update lead status | PUT /api/v1/dealerships/{slug}/lead_clusters/{id} |
| Lead events (calls, SMS, notes) | POST /api/v1/lead_events |
See the LMS overview for the full integration workflow.