Skip to content

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.

ActionMethodURL
Create leadPOSThttps://dashboard.dealerstudio.com.au/api/v1/leads
Update leadPUThttps://dashboard.dealerstudio.com.au/api/v1/leads/{id}

OpenAPI reference: Create Lead, Update Lead.

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.

{
"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"
}
}

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).

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.

FieldTypeDescription
emailstringCustomer email address
phonestringCustomer phone number
dealership_idintegerDealership ID, or use dealership_slug instead
categorystringLead category — must be an exact match from the accepted values
sourcestringLead source — must be an exact match from the accepted values

Send a PUT request to /api/v1/leads/{id} with the same { "lead": { ... } } wrapper.

Every create and update request must include a dealership identifierdealership_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."
}
{
"lead": {
"dealership_id": 123,
"message": "Updated enquiry notes"
}
}
  • 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 OK with { "message": "You cannot edit this lead" }.
  • Payments: If the lead already has a payment, sending payment_attributes returns { "message": "Payment already exists" }.

These fields map directly to the lead record.

FieldTypeRequiredDescription
namestringNoCustomer full name
last_namestringNoCustomer last name
emailstringYes (create)Customer email
phonestringYes (create)Customer phone
messagestringNoFree-text enquiry message
dealership_idintegerYes (create and update)Dealership ID
dealership_slugstringYes (create and update)Alternative to dealership_id
categorystringYes (create)See Category
sourcestringYes (create)See Source
marketing_sourcestringNoSee Marketing source
subcategorystringNoForm or funnel label; must match an allowed subcategory if provided
location_idintegerNoDealership location ID
website_idintegerNoWebsite ID
website_slugstringNoAlternative to website_id
page_idintegerNoPage the lead was submitted from
car_idintegerNoVehicle ID in Dealer Studio
stocknumstringNoMatches an in-stock vehicle by stock number when car_id is not supplied
providerstringNoLead supplier name (e.g. Carsales)
provider_idstringNoExternal reference from the supplier
tagsstring[]NoTags applied to the lead and its cluster
goldenbooleanNoMark the cluster as high priority
team_member_idintegerNoAssign to a dealership user (by ID)
user_emailstringNoAssign to a dealership user (by email)
send_customer_emailbooleanNoWhether to send the customer confirmation email
disable_strict_validationbooleanNoWhen true, skips strict email and phone validation
skip_website_location_validationbooleanNoWhen true, skips validation that website_id and location_id belong to the lead’s dealership
linked_query_paramsobjectNoClick IDs and UTM parameters from the customer’s landing page — see Marketing attribution
visited_pagesstring[]NoPaths the customer visited before submitting (may include query strings)
user_agentstringNoBrowser user-agent string from the submission
address_attributesobjectNoCustomer 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.

These fields are not columns on the lead itself. They are stored on the contact record linked to the lead.

FieldTypeFormatMaps to
first_namestringcontact.first_name
last_namestringcontact.last_name (also stored on lead.last_name)
dobstringDD/MM/YYYY or YYYY-MM-DDcontact.date_of_birth
postcodestringcontact.postcode (via fields)
business_namestringcontact.business_name (via fields)
abnstringcontact.abn (via fields)
sms_verifiedbooleancontact.sms_verified

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.

{
"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.

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.

Values must match exactly (case and spacing). The authoritative list is in the OpenAPI schema on Create Lead.

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

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.

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.

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:

KeyDescription
gclidGoogle Ads click ID
gbraid, wbraidGoogle Ads enhanced conversions click IDs
gad_campaignidGoogle Ads campaign ID
fbclidMeta (Facebook/Instagram) click ID
utm_sourceCampaign source (e.g. google, facebook, email)
utm_mediumCampaign medium (e.g. cpc, email)
utm_campaignCampaign name
utm_content, utm_termOptional 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.

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 presentmarketing_source set to
gclid, gbraid, wbraid, or gad_campaignidAdwords
fbclid, or utm_source of facebook / fbFacebook
utm_source of igInstagram
utm_source of msgMessenger
utm_source of anAudience Network
utm_source of tiktokTikTok
utm_source of youtubeYouTube
utm_source of chatgpt.comChatGPT
utm_source of qr_codeQR Code
utm_source of gmb or googlemapsGMB
utm_source of email, or utm_medium of emailEmail
utm_source of smsSMS
utm_source of carsalesCarsales
utm_source of linkedinLinkedin
utm_source of crmCRM

utm_campaign is taken from the first value when the parameter is sent as an array.

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.

  1. On page load, read query parameters from the customer’s browser URL (for example via window.location.search).
  2. Persist them in session storage or your form state until the customer submits.
  3. Include them in linked_query_params on POST /api/v1/leads.

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.

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_options

OpenAPI 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 fieldDescription
idUse this as lead_status_option_id when updating a cluster
nameHuman-readable status name (also accepted as legacy lead_state)
status_typeInternal category: new, working, converted, delivered, lost, or invalid
pipelineWhich 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).

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.

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.

PurposeEndpoint
Dealership locations and usersGET /api/v1/apikeys/apikey_details.json
Lead status optionsGET /api/v1/dealerships/{slug}/lead_status_options
Update lead statusPUT /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.