← API v2 Overview

Leads

Capture enquiries, manage follow-up, associate vehicles, record messages, and send replies through MotorDesk communication channels.

The Lead Object

Generated from the OpenAPI schema. Always matches the live API.

Fields (31)
AttributeTypeRequiredDescriptionExample
idinteger-Lead id.4009
siteinteger-Site id, or 0 for none.0
channelstring-Channel the lead came in on (e.g. api, website, email).website
referenceinteger-Lead reference number.10472
namestring-The lead's name.Jane Doe
emailstring-The lead's email address.jane.doe@example.com
phonestring-The lead's landline number.01612345678
mobilestring-The lead's mobile number.07700900123
contactinteger or null-Linked contact id, or null.110153
typearray of string-Lead enquiry type(s), in snake_case (e.g. test_drive, part_exchange). See /reference/lead-types.["test_drive"]
statusobject-Primary workflow status.
status.idinteger-Status code (0-5).0
status.nameenum-Status name.new
ratinginteger or null-AI buying-intent rating: 5 ready to transact, 4 specific vehicle and questions, 3 genuine interest, 2 vague or early, 1 not a buyer. Null when not rated. Never a spam score (see status junk).4
summarystring or null-AI summary of where the conversation stands, at most 12 words, or null.Wants Saturday test drive of the Golf, asked for finance figures.
createdinteger-Unix timestamp the lead was created.1781303332
updatedinteger-Unix timestamp the lead was last updated.1781309000
sessionstring-Visitor session reference (full view only).
avatarstring-Avatar reference (full view only).
assignarray of integer-Staff user ids the lead is assigned to (full view only).
tagarray of object-Applied lead tags ({ name, checked, colour, type }), full view only. Same shape as GET /leads/{id}/tags applied.
statboolean-Statistics flag: whether the lead counts toward reporting/KPIs (full view only).
reopenstring (date) or null-Date a closed lead will auto-reopen, or null (full view only).
dataobject-Lead detail (source, message, subject, url, vehicle, appointment, junk) (full view only).
aiobject or null-The AI's latest read of the conversation, or null when it has not run (full view only).
ai.intentstring or null-Main aim, as one of the ids used by type (e.g. test_drive, finance, part_exchange, email for a general enquiry), or other.test_drive
ai.rating_reasonstring or null-Why the rating was given.
ai.next_actionstring or null-Suggested next step for the dealer.
ai.junkboolean-Whether the AI considered the latest message junk. Only high-confidence junk on an unanswered lead moves it to status junk.
ai.junk_confidenceenum or null-
ai.processedinteger or null-Unix timestamp the AI last processed the lead.
Example object
{
    "id": 4009,
    "site": 0,
    "channel": "website",
    "reference": 10472,
    "name": "Jane Doe",
    "email": "jane.doe@example.com",
    "phone": "01612345678",
    "mobile": "07700900123",
    "contact": 110153,
    "type": [
        "test_drive"
    ],
    "status": {
        "id": 0,
        "name": "new"
    },
    "rating": 4,
    "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
    "created": 1781303332,
    "updated": 1781309000,
    "session": "",
    "avatar": "",
    "assign": [
        0
    ],
    "tag": [
        {
            "name": "",
            "checked": false,
            "colour": "",
            "type": "default"
        }
    ],
    "stat": false,
    "reopen": "2026-01-01",
    "data": {},
    "ai": {
        "intent": "test_drive",
        "rating_reason": "",
        "next_action": "",
        "junk": false,
        "junk_confidence": "high",
        "processed": 0
    }
}

Endpoints

GET List Leads

GET /2.0/leads · scope leads:read

List leads with pagination and optional filters (status, channel, site, customer, created/updated range).

Parameters (18)
ParameterInTypeRequiredDescriptionExample
pagequeryinteger-Page number, starting at 1 (offset pagination).
per_pagequeryinteger-Results per page (maximum 500).
viewqueryenum-Response detail: "simple" for a compact object or "full" for the complete object.
sitequeryinteger-Filter by site id.
statusquerystring-Filter by status, as the code or the name the lead reads back: 0 new, 1 new_message, 2 read, 3 replied, 4 closed, 5 junk.replied
channelquerystring-Filter by channel.
referencequeryinteger-Filter by reference.
namequerystring-Filter by name.
emailquerystring-Filter by email. Supports wildcards (%) with the search:wildcard scope.
phonequerystring-Filter by phone.
mobilequerystring-Filter by mobile.
contactqueryinteger-Filter by contact id.
vehiclequeryinteger-Filter to leads associated with this vehicle id.
rating_minqueryinteger-Only leads the AI rated at or above this buying intent (1-5). Unrated leads are excluded.4
createdquerystring-Unix timestamp exact match, or a two-element array [from, to] for a range. An empty bound is open-ended.
updatedquerystring-Unix timestamp exact match, or a two-element array [from, to] for a range. An empty bound is open-ended.
cursorquerystring-Keyset pagination cursor from a previous response's meta.pagination.next_cursor. When supplied, page/total are not returned.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKPaginated leads

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": [
        {
            "id": 4009,
            "site": 0,
            "channel": "website",
            "reference": 10472,
            "name": "Jane Doe",
            "email": "jane.doe@example.com",
            "phone": "01612345678",
            "mobile": "07700900123",
            "contact": 110153,
            "type": [
                "test_drive"
            ],
            "status": {
                "id": 0,
                "name": "new"
            },
            "rating": 4,
            "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
            "created": 1781303332,
            "updated": 1781309000,
            "session": "",
            "avatar": "",
            "assign": [
                0
            ],
            "tag": [
                {
                    "name": "",
                    "checked": false,
                    "colour": "",
                    "type": "default"
                }
            ],
            "stat": false,
            "reopen": "2026-01-01",
            "data": {},
            "ai": {
                "intent": "test_drive",
                "rating_reason": "",
                "next_action": "",
                "junk": false,
                "junk_confidence": "high",
                "processed": 0
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 0,
            "per_page": 0,
            "total": 0,
            "total_pages": 0,
            "next_cursor": ""
        }
    }
}

POST Create Lead

POST /2.0/leads · scope leads:write

Create a lead.

Request body
AttributeTypeRequiredDescriptionExample
siteinteger-Site id from /reference/sites; 0 for no site.0
channelstring-Lead channel, e.g. api, website, email, sms. Defaults to api.api
channel_idstring-External reference for the channel (e.g. a messaging thread id).
namestring-The lead's name.Jane Smith
emailstring-The lead's email address.jane.smith@example.com
phonestring-Landline number in international format.441612345678
mobilestring-Mobile number in international format.447700900123
contactinteger-Existing contact id to link this lead to.77684
typestring-Lead enquiry type(s) in snake_case (e.g. test_drive, part_exchange). See /reference/lead-types. Defaults to email (general enquiry).test_drive
dataobject-Free-form detail object stored against the lead.{}
statusinteger-Primary status code: 0 new, 1 new_message, 2 read, 3 replied, 4 closed, 5 junk. Prefer the named status field on /leads/{id}/status to change state after creation.0
tagarray of string-Lead tags. Each item is a tag name string or { name, checked }; names must exist in the lead taxonomy (see GET /leads/{id}/tags or /reference/tags?resource=lead). Replaces the full set.[]
notifyboolean-Whether to fire new-lead notifications on create. Defaults to true.true
vehicleinteger-Create only: stock vehicle id the enquiry is about; the vehicle is associated with the new lead exactly as POST /leads/{id}/vehicles would. On an existing lead use that endpoint instead. Use this or vehicle_tag.85481
vehicle_tagstring-Create only: vehicle tag the enquiry is about, as an alternative to vehicle.HbSDTp97
{
    "site": 0,
    "channel": "api",
    "channel_id": "",
    "name": "Jane Smith",
    "email": "jane.smith@example.com",
    "phone": "441612345678",
    "mobile": "447700900123",
    "contact": 77684,
    "type": "test_drive",
    "data": {},
    "status": 0,
    "tag": [],
    "notify": true,
    "vehicle": 85481,
    "vehicle_tag": "HbSDTp97"
}
Responses
StatusDescription
201 CreatedLead created

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 4009,
        "site": 0,
        "channel": "website",
        "reference": 10472,
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "phone": "01612345678",
        "mobile": "07700900123",
        "contact": 110153,
        "type": [
            "test_drive"
        ],
        "status": {
            "id": 0,
            "name": "new"
        },
        "rating": 4,
        "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
        "created": 1781303332,
        "updated": 1781309000,
        "session": "",
        "avatar": "",
        "assign": [
            0
        ],
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "stat": false,
        "reopen": "2026-01-01",
        "data": {},
        "ai": {
            "intent": "test_drive",
            "rating_reason": "",
            "next_action": "",
            "junk": false,
            "junk_confidence": "high",
            "processed": 0
        }
    }
}

GET Get Lead

GET /2.0/leads/{id} · scope leads:read

Retrieve a single lead by id.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKLead

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 4009,
        "site": 0,
        "channel": "website",
        "reference": 10472,
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "phone": "01612345678",
        "mobile": "07700900123",
        "contact": 110153,
        "type": [
            "test_drive"
        ],
        "status": {
            "id": 0,
            "name": "new"
        },
        "rating": 4,
        "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
        "created": 1781303332,
        "updated": 1781309000,
        "session": "",
        "avatar": "",
        "assign": [
            0
        ],
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "stat": false,
        "reopen": "2026-01-01",
        "data": {},
        "ai": {
            "intent": "test_drive",
            "rating_reason": "",
            "next_action": "",
            "junk": false,
            "junk_confidence": "high",
            "processed": 0
        }
    }
}

PATCH Update Lead

PATCH /2.0/leads/{id} · scope leads:write

Update a lead. Only the supplied fields are changed.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
siteinteger-Site id from /reference/sites; 0 for no site.0
channelstring-Lead channel, e.g. api, website, email, sms. Defaults to api.api
channel_idstring-External reference for the channel (e.g. a messaging thread id).
namestring-The lead's name.Jane Smith
emailstring-The lead's email address.jane.smith@example.com
phonestring-Landline number in international format.441612345678
mobilestring-Mobile number in international format.447700900123
contactinteger-Existing contact id to link this lead to.77684
typestring-Lead enquiry type(s) in snake_case (e.g. test_drive, part_exchange). See /reference/lead-types. Defaults to email (general enquiry).test_drive
dataobject-Free-form detail object stored against the lead.{}
statusinteger-Primary status code: 0 new, 1 new_message, 2 read, 3 replied, 4 closed, 5 junk. Prefer the named status field on /leads/{id}/status to change state after creation.0
tagarray of string-Lead tags. Each item is a tag name string or { name, checked }; names must exist in the lead taxonomy (see GET /leads/{id}/tags or /reference/tags?resource=lead). Replaces the full set.[]
notifyboolean-Whether to fire new-lead notifications on create. Defaults to true.true
vehicleinteger-Create only: stock vehicle id the enquiry is about; the vehicle is associated with the new lead exactly as POST /leads/{id}/vehicles would. On an existing lead use that endpoint instead. Use this or vehicle_tag.85481
vehicle_tagstring-Create only: vehicle tag the enquiry is about, as an alternative to vehicle.HbSDTp97
{
    "site": 0,
    "channel": "api",
    "channel_id": "",
    "name": "Jane Smith",
    "email": "jane.smith@example.com",
    "phone": "441612345678",
    "mobile": "447700900123",
    "contact": 77684,
    "type": "test_drive",
    "data": {},
    "status": 0,
    "tag": [],
    "notify": true,
    "vehicle": 85481,
    "vehicle_tag": "HbSDTp97"
}
Responses
StatusDescription
200 OKLead updated

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 4009,
        "site": 0,
        "channel": "website",
        "reference": 10472,
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "phone": "01612345678",
        "mobile": "07700900123",
        "contact": 110153,
        "type": [
            "test_drive"
        ],
        "status": {
            "id": 0,
            "name": "new"
        },
        "rating": 4,
        "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
        "created": 1781303332,
        "updated": 1781309000,
        "session": "",
        "avatar": "",
        "assign": [
            0
        ],
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "stat": false,
        "reopen": "2026-01-01",
        "data": {},
        "ai": {
            "intent": "test_drive",
            "rating_reason": "",
            "next_action": "",
            "junk": false,
            "junk_confidence": "high",
            "processed": 0
        }
    }
}

DELETE Delete Lead

DELETE /2.0/leads/{id} · scope leads:delete

Delete a lead.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKLead deleted

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "deleted": false
    }
}

Status

PATCH Update Lead Status

PATCH /2.0/leads/{id}/status · scope leads:write

Set lead state. status sets the primary workflow state (new, new_message, read, replied, closed, junk); junk and closed/reopen are conveniences over it; stat toggles the separate statistics flag. status cannot be combined with closed or junk.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
statusenum-Set the primary workflow status directly. new=unactioned lead, new_message=unread inbound message, read=acknowledged, replied=staff has replied, closed, junk. Overrides any current status (including junk).read
junkboolean-true marks the lead as junk (status junk); false clears junk and resets to new.false
closedboolean-true closes the lead (status closed); false reopens it (status new_message).true
reopenstring (date) or null-Optional date (YYYY-MM-DD) to automatically reopen a closed lead; null clears it. Only meaningful with closed=true.2026-09-01
statboolean-The statistics flag (separate from status): whether this lead counts toward reporting/KPIs.true
{
    "status": "read",
    "junk": false,
    "closed": true,
    "reopen": "2026-09-01",
    "stat": true
}
Responses
StatusDescription
200 OKLead status updated

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 4009,
        "site": 0,
        "channel": "website",
        "reference": 10472,
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "phone": "01612345678",
        "mobile": "07700900123",
        "contact": 110153,
        "type": [
            "test_drive"
        ],
        "status": {
            "id": 0,
            "name": "new"
        },
        "rating": 4,
        "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
        "created": 1781303332,
        "updated": 1781309000,
        "session": "",
        "avatar": "",
        "assign": [
            0
        ],
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "stat": false,
        "reopen": "2026-01-01",
        "data": {},
        "ai": {
            "intent": "test_drive",
            "rating_reason": "",
            "next_action": "",
            "junk": false,
            "junk_confidence": "high",
            "processed": 0
        }
    }
}

Assign

PATCH Assign Lead to Staff

PATCH /2.0/leads/{id}/assign · scope leads:write

Set the staff users a lead is assigned to. The supplied set replaces the current assignment; an empty array clears it.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
assignarray of integerYesStaff user ids to assign the lead to. An empty array clears the assignment. See /reference/staff-users.[12,34]
{
    "assign": [
        12,
        34
    ]
}
Responses
StatusDescription
200 OKAssign Lead to Staff

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 4009,
        "site": 0,
        "channel": "website",
        "reference": 10472,
        "name": "Jane Doe",
        "email": "jane.doe@example.com",
        "phone": "01612345678",
        "mobile": "07700900123",
        "contact": 110153,
        "type": [
            "test_drive"
        ],
        "status": {
            "id": 0,
            "name": "new"
        },
        "rating": 4,
        "summary": "Wants Saturday test drive of the Golf, asked for finance figures.",
        "created": 1781303332,
        "updated": 1781309000,
        "session": "",
        "avatar": "",
        "assign": [
            0
        ],
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "stat": false,
        "reopen": "2026-01-01",
        "data": {},
        "ai": {
            "intent": "test_drive",
            "rating_reason": "",
            "next_action": "",
            "junk": false,
            "junk_confidence": "high",
            "processed": 0
        }
    }
}

Acknowledge

POST Acknowledge Open Leads

POST /2.0/leads/acknowledge · scope leads:write

Mark every new or unread lead (status new or new_message) as read in one call.

Responses
StatusDescription
200 OKAcknowledge Open Leads

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "acknowledged": false
    }
}

Tags

GET List Lead Tags

GET /2.0/leads/{id}/tags · scope leads:read

List the tags applied to a lead, plus the available lead tag taxonomy.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKList Lead Tags

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "applied": [
            {
                "name": "Hot lead",
                "checked": false,
                "colour": "success",
                "type": "default"
            }
        ],
        "available": [
            {
                "name": "",
                "colour": "",
                "type": "default",
                "defaulted": false
            }
        ]
    }
}

PUT Set Lead Tags

PUT /2.0/leads/{id}/tags · scope leads:write

Replace the tags applied to a lead. Each tag name must be available in the lead tag taxonomy. The same tag items can also be set inline via the lead create/update `tag` field.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
tagsarray of stringYesThe full set of tags to apply. Each item is a tag name string, or an object { name, checked }.[{"name":"MOT","checked":true},{"name":"Valet","checked":false}]
{
    "tags": [
        {
            "name": "MOT",
            "checked": true
        },
        {
            "name": "Valet",
            "checked": false
        }
    ]
}
Responses
StatusDescription
200 OKSet Lead Tags

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "applied": [
            {
                "name": "Hot lead",
                "checked": false,
                "colour": "success",
                "type": "default"
            }
        ],
        "available": [
            {
                "name": "",
                "colour": "",
                "type": "default",
                "defaulted": false
            }
        ]
    }
}

Vehicles

GET List Lead Vehicles

GET /2.0/leads/{id}/vehicles · scope lead-vehicles:read

List vehicles associated with a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKLead vehicle associations

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": [
        {
            "id": 5521,
            "lead": 4009,
            "appointment": 0,
            "vehicle": 85481
        }
    ]
}

POST Associate Vehicle or Appointment with Lead

POST /2.0/leads/{id}/vehicles · scope lead-vehicles:write

Associate a vehicle and/or an appointment with a lead. Provide vehicle (a stock id) or vehicle_tag to link a vehicle, appointment to link an appointment, or both. At least one is required; vehicle takes precedence over vehicle_tag.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
vehicleinteger-Stock vehicle id to associate. Use this or vehicle_tag.85481
vehicle_tagstring-Alphanumeric vehicle tag to associate, as an alternative to vehicle.HbSDTp97
appointmentinteger-Appointment id to link to the lead. May be supplied on its own (no vehicle) to associate just an appointment.747
{
    "vehicle": 85481,
    "vehicle_tag": "HbSDTp97",
    "appointment": 747
}
Responses
StatusDescription
201 CreatedLead vehicle association created

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 5521,
        "lead": 4009,
        "appointment": 0,
        "vehicle": 85481
    }
}

DELETE Remove Lead Vehicle

DELETE /2.0/leads/{id}/vehicles/{vehicle_id} · scope lead-vehicles:delete

Remove a vehicle association from a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
vehicle_idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKLead vehicle association deleted

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "deleted": false
    }
}

Messages

GET List Lead Messages

GET /2.0/leads/{id}/messages · scope lead-messages:read

List the messages recorded against a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKLead messages

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": [
        {
            "id": 88213,
            "lead": 4009,
            "sender": "0",
            "message": {
                "m": "Is this still available?"
            },
            "created": 1781303332,
            "delivered": 1781303340,
            "viewed": 0
        }
    ]
}

POST Add Lead Message

POST /2.0/leads/{id}/messages · scope lead-messages:write

Add a message to a lead. By default a staff-sent message (sender = a user id) is dispatched to the lead through the reply pipeline (status becomes replied) and a customer message (sender 0) is recorded inbound (status becomes new_message). Set send=false to record without dispatching. When send is true a channel is required.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
messagestringYesThe message body. A plain string is the common case; an object may carry structured fields (m, subject, html, text).Thanks for your enquiry. The vehicle is still available. When would suit you for a viewing?
senderintegerYesWho sent the message: 0 = the customer/lead (inbound), or a staff user id (outbound reply). See /reference/staff-users.0
sendboolean-Whether to dispatch the message to the lead through the reply pipeline (email/SMS/messaging). Defaults to true for staff senders and false for customer messages. Requires a staff sender and a channel.true
channelenum-Delivery channel, required when send is true.email
notifyboolean-For recorded (send=false) messages: whether to update lead status and fire live notifications. Defaults to true.true
previewboolean-When send is true, return a rendered preview without dispatching or recording.false
repliesboolean-When sending by email, include the prior message thread. Defaults to true.true
plain_textboolean-When sending by email, send plain text instead of the HTML template.false
mediaobject-Optional media attachment for messaging channels.
media.filestring-Base64 media data (optionally a data: URL). Alternative to url.
media.typeenum-i=image, vi=video.
media.urlstring-Publicly reachable https URL of the media.
media.mimestring-MIME type matching the media type, e.g. image/jpeg or video/mp4.
{
    "message": "Thanks for your enquiry. The vehicle is still available. When would suit you for a viewing?",
    "sender": 0,
    "send": true,
    "channel": "email",
    "notify": true,
    "preview": false,
    "replies": true,
    "plain_text": false,
    "media": {
        "file": "",
        "type": "i",
        "url": "",
        "mime": ""
    }
}
Responses
StatusDescription
201 CreatedLead message created

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 88213,
        "lead": 4009,
        "sender": "0",
        "message": {
            "m": "Is this still available?"
        },
        "created": 1781303332,
        "delivered": 1781303340,
        "viewed": 0
    }
}

GET Get Lead Message

GET /2.0/leads/{id}/messages/{message_id} · scope lead-messages:read

Retrieve a single lead message by id.

Parameters (3)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
message_idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKLead message

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 88213,
        "lead": 4009,
        "sender": "0",
        "message": {
            "m": "Is this still available?"
        },
        "created": 1781303332,
        "delivered": 1781303340,
        "viewed": 0
    }
}

PATCH Update Lead Message

PATCH /2.0/leads/{id}/messages/{message_id} · scope lead-messages:write

Update a recorded lead message.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
message_idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
messagestringYesThe message body. A plain string is the common case; an object may carry structured fields (m, subject, html, text).Thanks for your enquiry. The vehicle is still available. When would suit you for a viewing?
senderintegerYesWho sent the message: 0 = the customer/lead (inbound), or a staff user id (outbound reply). See /reference/staff-users.0
sendboolean-Whether to dispatch the message to the lead through the reply pipeline (email/SMS/messaging). Defaults to true for staff senders and false for customer messages. Requires a staff sender and a channel.true
channelenum-Delivery channel, required when send is true.email
notifyboolean-For recorded (send=false) messages: whether to update lead status and fire live notifications. Defaults to true.true
previewboolean-When send is true, return a rendered preview without dispatching or recording.false
repliesboolean-When sending by email, include the prior message thread. Defaults to true.true
plain_textboolean-When sending by email, send plain text instead of the HTML template.false
mediaobject-Optional media attachment for messaging channels.
media.filestring-Base64 media data (optionally a data: URL). Alternative to url.
media.typeenum-i=image, vi=video.
media.urlstring-Publicly reachable https URL of the media.
media.mimestring-MIME type matching the media type, e.g. image/jpeg or video/mp4.
{
    "message": "Thanks for your enquiry. The vehicle is still available. When would suit you for a viewing?",
    "sender": 0,
    "send": true,
    "channel": "email",
    "notify": true,
    "preview": false,
    "replies": true,
    "plain_text": false,
    "media": {
        "file": "",
        "type": "i",
        "url": "",
        "mime": ""
    }
}
Responses
StatusDescription
200 OKLead message updated

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 88213,
        "lead": 4009,
        "sender": "0",
        "message": {
            "m": "Is this still available?"
        },
        "created": 1781303332,
        "delivered": 1781303340,
        "viewed": 0
    }
}

DELETE Delete Lead Message

DELETE /2.0/leads/{id}/messages/{message_id} · scope lead-messages:delete

Delete a lead message.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
message_idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKLead message deleted

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "deleted": false
    }
}

Notes

GET List Lead Notes

GET /2.0/leads/{id}/notes · scope lead-notes:read

List the internal notes recorded against a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKList Lead Notes

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": [
        {
            "id": 2,
            "lead": 4009,
            "created": 1781303332,
            "user": 12,
            "note": "Customer prefers a callback after 5pm."
        }
    ]
}

POST Add Lead Note

POST /2.0/leads/{id}/notes · scope lead-notes:write

Add an internal note to a lead, optionally attributed to a staff user.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
notestringYesThe note text (supports line breaks).Customer prefers a callback after 5pm.
userinteger-Optional staff user id the note is attributed to, from /reference/staff-users.1
{
    "note": "Customer prefers a callback after 5pm.",
    "user": 1
}
Responses
StatusDescription
200 OKAdd Lead Note

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 2,
        "lead": 4009,
        "created": 1781303332,
        "user": 12,
        "note": "Customer prefers a callback after 5pm."
    }
}

DELETE Delete Lead Note

DELETE /2.0/leads/{id}/notes/{note_id} · scope lead-notes:delete

Delete a lead note.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
note_idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKDelete Lead Note

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "deleted": false
    }
}

Appointments

GET List Lead Appointments

GET /2.0/leads/{id}/appointments · scope lead-appointments:read

List appointments associated with a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
fieldsquerystring-Comma-separated dot-paths to return only those fields, e.g. id,data.stock.price_channel.
Responses
StatusDescription
200 OKList Lead Appointments

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": [
        {
            "id": 0,
            "lead": 0,
            "contact": 0,
            "type": "appointment",
            "calendar": "",
            "booking": "",
            "date": "2026-01-01",
            "time": "",
            "purpose": "",
            "duration": 0,
            "duration_type": "m",
            "note": "",
            "user": [
                0
            ],
            "vehicle": 0,
            "persist": false,
            "done": false,
            "created": 0
        }
    ]
}

POST Create Lead Appointment

POST /2.0/leads/{id}/appointments · scope lead-appointments:write

Create an appointment for a lead. Provide an optional vehicle (a stock id) or vehicle_tag to also link the appointment to a vehicle of interest, mirroring the lead vehicles endpoint.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
datestring (date)YesAppointment date (YYYY-MM-DD).2026-09-01
timestringYesAppointment time (HH:MM, 24-hour).14:30
typeenum-The appointment kind. Defaults to appointment.appointment
purposestring-Free-text purpose/title for the appointment.Test drive
durationinteger or null-Duration in the unit given by duration_type.30
duration_typeenum-Duration unit: m=minutes, h=hours.m
notestring-Internal note.Customer prefers the afternoon.
userarray of integer-Staff user ids who own the appointment.[12]
calendarstring-Calendar name. See /appointments/calendars.Sales
persistboolean-Whether the appointment persists across status changes.false
vehicleinteger-Optional stock vehicle id to also link to the lead with this appointment. Use this or vehicle_tag.85481
vehicle_tagstring-Optional alphanumeric vehicle tag, as an alternative to vehicle.HbSDTp97
{
    "date": "2026-09-01",
    "time": "14:30",
    "type": "appointment",
    "purpose": "Test drive",
    "duration": 30,
    "duration_type": "m",
    "note": "Customer prefers the afternoon.",
    "user": [
        12
    ],
    "calendar": "Sales",
    "persist": false,
    "vehicle": 85481,
    "vehicle_tag": "HbSDTp97"
}
Responses
StatusDescription
200 OKCreate Lead Appointment

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "lead": 0,
        "contact": 0,
        "type": "appointment",
        "calendar": "",
        "booking": "",
        "date": "2026-01-01",
        "time": "",
        "purpose": "",
        "duration": 0,
        "duration_type": "m",
        "note": "",
        "user": [
            0
        ],
        "vehicle": 0,
        "persist": false,
        "done": false,
        "created": 0
    }
}

DELETE Remove Lead Appointment

DELETE /2.0/leads/{id}/appointments/{appointment_id} · scope lead-appointments:delete

Remove an appointment from a lead.

Parameters (2)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
appointment_idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKRemove Lead Appointment

Failures use the standard error responses (4xx/5xx) with the shared error envelope.

{
    "success": true,
    "data": {
        "id": 0,
        "deleted": false
    }
}