eva crm Public API
Leads

Create a lead

POST /v1/leads — one call creates the customer, contact and lead, idempotently.

POST Create a lead

POST/v1/leads

Creates the customer, contact and lead in one call. The lead lands in your default lead workflow at its first stage, with the CRM's usual on-creation automations (stage actions, team assignment, notifications). If a customer with the same email and phone already exists, the lead is attached to them rather than creating a duplicate; otherwise a new customer and contact are created.

The call is idempotent on reference: the same reference returns the same lead with created: false, so retries are safe.

Requirements

Three rules a single field cannot express. A body that breaks one is a 422 naming the field.

  • reference is required.
  • A name: firstName and/or lastName, or companyName.
  • A way to contact them: at least one of email, phoneNumber, mobile.

Everything else is optional. Send what you have. GET /v1/leads/fields is the authoritative list, generated from the validator, with the valid values for every option field.

Request body · identityapplication/json
referencestring · max 200Required

Your own id for this submission, unique per submission, such as your form's row id. The same reference returns the same lead.

sourcestring · max 100

A label for where the lead came from. Stored on the lead and filterable. Idempotency is per reference within a source.

Default: public-api
testboolean

Marks the lead as test data, excluded from reporting and from lists unless asked for.

Default: false
Request body · person
firstNamestring · max 100One of required
At least one of: firstName, lastName, companyName
lastNamestring · max 100One of required
At least one of: firstName, lastName, companyName
companyNamestring · max 250One of required
At least one of: firstName, lastName, companyName
titleoption

An option's id or name, from the CRM's title list.

customerTypeoption

An option's id or name.

Request body · contact
emailstring · email · max 255One of required
At least one of: email, phoneNumber, mobile
phoneNumberstring · max 50One of required

Normalised: spaces, dashes and brackets are removed and +44 becomes 0.

At least one of: email, phoneNumber, mobile
mobilestring · max 50One of required

Normalised as phoneNumber. 07… numbers are mobiles.

At least one of: email, phoneNumber, mobile
addressstring · max 250
address2string · max 250
address3string · max 250
townstring · max 100
countystring · max 100
postcodestring · max 20

Upper-cased.

countryoption

An option's id or name.

what3Wordsstring · max 100
Request body · consent
marketingEmailboolean
marketingSmsboolean
marketingPostboolean
Request body · attribution
marketingoption

A marketing source's id or name, from your organisation's list.

subSourceCampaignoption · depends on marketing

A campaign's id or name. Sent alone, its source is filled in; sent with marketing, they must agree. Campaign names repeat under every source, so a campaign sent by name is looked up within the marketing you sent; alone it is usually ambiguous and you will be asked for its id.

leadTypeoption

An option's id or name, such as Windows.

mainInterestoption
salesAreaoption
leadProductTypesoption[] · max 50

Shares its list with mainInterest; that is how the CRM models it.

Request body · property
propertyTypeoption
propertyCategoryoption
planningRequiredoption
planningTypeoption
propertyOtherstring · max 250
yearBuiltinteger · 1000 to 2200
Request body · assignment and free text
assignedTostring · user id or email

Who holds the lead. See Users. An unknown or disabled user is a 422.

messagestring · max 5000

The customer's message.

advancedDataobject

Any JSON object, kept as sent.

expectedCloseDatestring · date or date-time

Read in your timezone.

Deprecated aliasesthe old webhook's names, still accepted
idstring · max 200

Use reference.

namestring · max 200

Use firstName and lastName.

phonestring · max 50

Use phoneNumber or mobile.

emailMarketingboolean

Use marketingEmail.

smsMarketingboolean

Use marketingSms.

Option fields take an option's id or its name: "leadType": "Repairs" and "leadType": "3340ec93-…" are the same. See Conventions. Unknown properties in the body are ignored; unknown query parameters on GET are not.

Responses
201
Created.
200
This `reference` was seen before; the original lead is returned with `created: false`.
422
Invalid payload, a broken requirement, or an option that does not resolve. `fields` names each offender.
502
The CRM did not answer. Nothing was created; retry the same request.
Example request
curl https://api.evacrm.co.uk/v1/leads \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "web-form-8812",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane@example.com",
    "mobile": "07700 900123",
    "address": "1 High Street",
    "town": "Reading",
    "postcode": "rg1 1aa",
    "leadType": "Windows",
    "marketing": "Website",
    "marketingEmail": true,
    "message": "Please call after 5pm",
    "assignedTo": "tuan@example.com"
  }'
Example response · 201
{
  "created": true,
  "reference": "web-form-8812",
  "lead": { "uuid": "1e4e3f90-4384-42ce-90c3-540db5343964", "code": "L013898" },
  "customer": { "uuid": "7b1d…", "code": "CUS007378" }
}

Migrating from the old webhook

The webhooks.evacrm.co.uk intake accepted nine fields: id, name, email, phone, postcode, message, smsMarketing, emailMarketing. All are still accepted here with the same meaning, so an existing integration can switch the URL and add the key header without other changes. GET /v1/leads/fields lists them as deprecated with replacedBy.

Two long-standing bugs are fixed in the process: real JSON booleans ("emailMarketing": true) were recorded as false by the old intake, and +447… numbers were filed as landlines. Prefer the explicit fields (firstName/lastName, mobile/phoneNumber, marketingEmail) for anything new.

On this page