← API v2 Overview

Contacts

Create and manage customer records, business contacts, communication details, tags, notes, and login actions.

Detecting Duplicates
Creating contacts from a form or import? Call POST /contacts/duplicate-check first to detect an existing match (by email, phone, name, company, VAT, or address). The API does not de-duplicate, so a retried create makes another record.

The Contact Object

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

Fields (35)
AttributeTypeRequiredDescriptionExample
idinteger-Contact id.
siteinteger-Site id, or 0 for none.
emailstring-Primary email address.
createdinteger-Unix timestamp the contact was created.
updatedinteger-Unix timestamp the contact was last updated.
dataobject-Contact detail.
data.typearray of string-Contact types, e.g. Customer, Supplier.
data.namestring-Full contact name.
data.companystring-Company or business name.
data.vatstring-VAT registration number.
data.addressobject-Postal address.
data.address.line1string-First address line.
data.address.line2string-Second address line.
data.address.line3string-Third address line.
data.address.citystring-Town or city.
data.address.statestring-County or state.
data.address.countrystring-Two-letter ISO country code (e.g. GB).
data.address.zipstring-Postcode or ZIP.
data.telephonestring-Landline number in international format.
data.mobilestring-Mobile number in international format.
data.dobstring (date)-Date of birth (YYYY-MM-DD).
data.licenseobject-Driving licence details.
data.license.numberstring-Licence number.
data.license.codestring-Licence check code.
data.license.checkedstring (date)-Date the licence was checked.
data.license.checked_bystring-Staff user id who checked the licence.
data.nistring-National Insurance number.
data.marketingenum-Marketing consent.
data.notesarray of object-Contact notes.
data.accountingobject-Accounting integration data.
data.nominalobject-Accounting nominal codes.
data.nominal.invoicestring-Sales (invoice) nominal code.
data.nominal.purchasestring-Purchase nominal code.
data.tagarray of object-Applied contact tags ({ name, checked, colour, type }). Same shape as GET /contacts/{id}/tags applied.
data.loginboolean-Whether customer login is enabled.
Example object
{
    "id": 0,
    "site": 0,
    "email": "",
    "created": 0,
    "updated": 0,
    "data": {
        "type": [
            ""
        ],
        "name": "",
        "company": "",
        "vat": "",
        "address": {
            "line1": "",
            "line2": "",
            "line3": "",
            "city": "",
            "state": "",
            "country": "",
            "zip": ""
        },
        "telephone": "",
        "mobile": "",
        "dob": "2026-01-01",
        "license": {
            "number": "",
            "code": "",
            "checked": "2026-01-01",
            "checked_by": ""
        },
        "ni": "",
        "marketing": "Yes",
        "notes": [
            {}
        ],
        "accounting": {},
        "nominal": {
            "invoice": "",
            "purchase": ""
        },
        "tag": [
            {
                "name": "",
                "checked": false,
                "colour": "",
                "type": "default"
            }
        ],
        "login": false
    }
}

Endpoints

GET List Contacts

GET /2.0/contacts · scope contacts:read

List contacts with pagination, and optional filtering by email, name, company, telephone, mobile, VAT, or postcode.

Parameters (12)
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.
emailquerystring-Filter by email. Supports wildcards (%) with the search:wildcard scope.
namequerystring-Filter by name.
companyquerystring-Filter by company.
vatquerystring-Filter by vat.
zipquerystring-Filter by zip.
telephonequerystring-Filter by telephone.
mobilequerystring-Filter by mobile.
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 contacts

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

{
    "success": true,
    "data": [
        {
            "id": 0,
            "site": 0,
            "email": "",
            "created": 0,
            "updated": 0,
            "data": {
                "type": [
                    ""
                ],
                "name": "",
                "company": "",
                "vat": "",
                "address": {
                    "line1": "",
                    "line2": "",
                    "line3": "",
                    "city": "",
                    "state": "",
                    "country": "",
                    "zip": ""
                },
                "telephone": "",
                "mobile": "",
                "dob": "2026-01-01",
                "license": {
                    "number": "",
                    "code": "",
                    "checked": "2026-01-01",
                    "checked_by": ""
                },
                "ni": "",
                "marketing": "Yes",
                "notes": [
                    {}
                ],
                "accounting": {},
                "nominal": {
                    "invoice": "",
                    "purchase": ""
                },
                "tag": [
                    {
                        "name": "",
                        "checked": false,
                        "colour": "",
                        "type": "default"
                    }
                ],
                "login": false
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 0,
            "per_page": 0,
            "total": 0,
            "total_pages": 0,
            "next_cursor": ""
        }
    }
}

POST Create Contact

POST /2.0/contacts · scope contacts:write

Create a contact. A name is required. Enabling login requires an email address.

Request body
AttributeTypeRequiredDescriptionExample
emailstring-Primary email address. Required when enabling login.jane.smith@example.com
siteinteger-Site id from /reference/sites; 0 for no site.0
typestring-One or more contact types. Accepts a single value or an array.["Customer"]
namestring-Full contact name. Required on create.Jane Smith
companystring-Company or business name.Smith Motors Ltd
vatstring-VAT registration number.GB123456789
addressobject-Postal address.
address.line1string-First address line.10 High Street
address.line2string-Second address line.
address.line3string-Third address line.
address.citystring-Town or city.Manchester
address.statestring-County or state.Greater Manchester
address.countrystring-Two-letter ISO country code from the configured country list (e.g. GB).GB
address.zipstring-Postcode or ZIP.M1 2AB
telephonestring-Landline number, as an international string ("441612345678") or a {country, number} object ({"country":"GB","number":"01612345678"}).441612345678
mobilestring-Mobile number, in the same format as telephone.447700900123
dobstring (date)-Date of birth (YYYY-MM-DD).1985-04-12
licenseobject-Driving licence details.
license.numberstring-Driving licence number.SMITH853120JS9AB
license.codestring-Licence check code.Ab12 Cd34 Ef
license.checkedstring (date)-Date the licence was checked (YYYY-MM-DD).2026-05-01
license.checked_byinteger-Staff user id who checked the licence, from /reference/staff-users.1
nistring-National Insurance number.QQ123456C
marketingenum-Marketing consent.No
nominalobject-Accounting nominal codes for this contact.
nominal.invoicestring-Sales (invoice) nominal code.4000
nominal.purchasestring-Purchase nominal code.5000
tagarray of string-Contact tags. Each item is a tag name string or { name, checked }; names must exist in the contact taxonomy (see GET /contacts/{id}/tags or /reference/tags?resource=contact). Replaces the full set.["Hot lead"]
documentarray of object-Attached document references.
loginboolean-Enable or disable customer login. Enabling login requires an email address.false
{
    "email": "jane.smith@example.com",
    "site": 0,
    "type": [
        "Customer"
    ],
    "name": "Jane Smith",
    "company": "Smith Motors Ltd",
    "vat": "GB123456789",
    "address": {
        "line1": "10 High Street",
        "line2": "",
        "line3": "",
        "city": "Manchester",
        "state": "Greater Manchester",
        "country": "GB",
        "zip": "M1 2AB"
    },
    "telephone": "441612345678",
    "mobile": "447700900123",
    "dob": "1985-04-12",
    "license": {
        "number": "SMITH853120JS9AB",
        "code": "Ab12 Cd34 Ef",
        "checked": "2026-05-01",
        "checked_by": 1
    },
    "ni": "QQ123456C",
    "marketing": "No",
    "nominal": {
        "invoice": "4000",
        "purchase": "5000"
    },
    "tag": [
        "Hot lead"
    ],
    "document": [
        {}
    ],
    "login": false
}
Responses
StatusDescription
201 CreatedContact created

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

{
    "success": true,
    "data": {
        "id": 0,
        "site": 0,
        "email": "",
        "created": 0,
        "updated": 0,
        "data": {
            "type": [
                ""
            ],
            "name": "",
            "company": "",
            "vat": "",
            "address": {
                "line1": "",
                "line2": "",
                "line3": "",
                "city": "",
                "state": "",
                "country": "",
                "zip": ""
            },
            "telephone": "",
            "mobile": "",
            "dob": "2026-01-01",
            "license": {
                "number": "",
                "code": "",
                "checked": "2026-01-01",
                "checked_by": ""
            },
            "ni": "",
            "marketing": "Yes",
            "notes": [
                {}
            ],
            "accounting": {},
            "nominal": {
                "invoice": "",
                "purchase": ""
            },
            "tag": [
                {
                    "name": "",
                    "checked": false,
                    "colour": "",
                    "type": "default"
                }
            ],
            "login": false
        }
    }
}

GET Get Contact

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

Retrieve a single contact 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 OKContact

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

{
    "success": true,
    "data": {
        "id": 0,
        "site": 0,
        "email": "",
        "created": 0,
        "updated": 0,
        "data": {
            "type": [
                ""
            ],
            "name": "",
            "company": "",
            "vat": "",
            "address": {
                "line1": "",
                "line2": "",
                "line3": "",
                "city": "",
                "state": "",
                "country": "",
                "zip": ""
            },
            "telephone": "",
            "mobile": "",
            "dob": "2026-01-01",
            "license": {
                "number": "",
                "code": "",
                "checked": "2026-01-01",
                "checked_by": ""
            },
            "ni": "",
            "marketing": "Yes",
            "notes": [
                {}
            ],
            "accounting": {},
            "nominal": {
                "invoice": "",
                "purchase": ""
            },
            "tag": [
                {
                    "name": "",
                    "checked": false,
                    "colour": "",
                    "type": "default"
                }
            ],
            "login": false
        }
    }
}

PATCH Update Contact

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

Update a contact. Only the supplied fields are changed; nested objects (address, license, nominal) are merged.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
emailstring-Primary email address. Required when enabling login.jane.smith@example.com
siteinteger-Site id from /reference/sites; 0 for no site.0
typestring-One or more contact types. Accepts a single value or an array.["Customer"]
namestring-Full contact name. Required on create.Jane Smith
companystring-Company or business name.Smith Motors Ltd
vatstring-VAT registration number.GB123456789
addressobject-Postal address.
address.line1string-First address line.10 High Street
address.line2string-Second address line.
address.line3string-Third address line.
address.citystring-Town or city.Manchester
address.statestring-County or state.Greater Manchester
address.countrystring-Two-letter ISO country code from the configured country list (e.g. GB).GB
address.zipstring-Postcode or ZIP.M1 2AB
telephonestring-Landline number, as an international string ("441612345678") or a {country, number} object ({"country":"GB","number":"01612345678"}).441612345678
mobilestring-Mobile number, in the same format as telephone.447700900123
dobstring (date)-Date of birth (YYYY-MM-DD).1985-04-12
licenseobject-Driving licence details.
license.numberstring-Driving licence number.SMITH853120JS9AB
license.codestring-Licence check code.Ab12 Cd34 Ef
license.checkedstring (date)-Date the licence was checked (YYYY-MM-DD).2026-05-01
license.checked_byinteger-Staff user id who checked the licence, from /reference/staff-users.1
nistring-National Insurance number.QQ123456C
marketingenum-Marketing consent.No
nominalobject-Accounting nominal codes for this contact.
nominal.invoicestring-Sales (invoice) nominal code.4000
nominal.purchasestring-Purchase nominal code.5000
tagarray of string-Contact tags. Each item is a tag name string or { name, checked }; names must exist in the contact taxonomy (see GET /contacts/{id}/tags or /reference/tags?resource=contact). Replaces the full set.["Hot lead"]
documentarray of object-Attached document references.
loginboolean-Enable or disable customer login. Enabling login requires an email address.false
{
    "email": "jane.smith@example.com",
    "site": 0,
    "type": [
        "Customer"
    ],
    "name": "Jane Smith",
    "company": "Smith Motors Ltd",
    "vat": "GB123456789",
    "address": {
        "line1": "10 High Street",
        "line2": "",
        "line3": "",
        "city": "Manchester",
        "state": "Greater Manchester",
        "country": "GB",
        "zip": "M1 2AB"
    },
    "telephone": "441612345678",
    "mobile": "447700900123",
    "dob": "1985-04-12",
    "license": {
        "number": "SMITH853120JS9AB",
        "code": "Ab12 Cd34 Ef",
        "checked": "2026-05-01",
        "checked_by": 1
    },
    "ni": "QQ123456C",
    "marketing": "No",
    "nominal": {
        "invoice": "4000",
        "purchase": "5000"
    },
    "tag": [
        "Hot lead"
    ],
    "document": [
        {}
    ],
    "login": false
}
Responses
StatusDescription
200 OKContact updated

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

{
    "success": true,
    "data": {
        "id": 0,
        "site": 0,
        "email": "",
        "created": 0,
        "updated": 0,
        "data": {
            "type": [
                ""
            ],
            "name": "",
            "company": "",
            "vat": "",
            "address": {
                "line1": "",
                "line2": "",
                "line3": "",
                "city": "",
                "state": "",
                "country": "",
                "zip": ""
            },
            "telephone": "",
            "mobile": "",
            "dob": "2026-01-01",
            "license": {
                "number": "",
                "code": "",
                "checked": "2026-01-01",
                "checked_by": ""
            },
            "ni": "",
            "marketing": "Yes",
            "notes": [
                {}
            ],
            "accounting": {},
            "nominal": {
                "invoice": "",
                "purchase": ""
            },
            "tag": [
                {
                    "name": "",
                    "checked": false,
                    "colour": "",
                    "type": "default"
                }
            ],
            "login": false
        }
    }
}

DELETE Delete Contact

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

Delete a contact.

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

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

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

Duplicate Check

POST Check for a Duplicate Contact

POST /2.0/contacts/duplicate-check · scope contacts:read

Check whether an existing contact already matches a given value (email, phone, name, company, VAT, or address) before creating one. Returns the matching contact id when a duplicate is found.

Request body
AttributeTypeRequiredDescriptionExample
typeenumYesWhich attribute to match on. phone matches both telephone and mobile.email
valuestringYesThe value to look for. A string for email/phone/name/company/vat; an address object (line1, city, country, ...) when type is address.customer@example.com
{
    "type": "email",
    "value": "customer@example.com"
}
Responses
StatusDescription
200 OKCheck for a Duplicate Contact

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

{
    "success": true,
    "data": {
        "type": "",
        "duplicate": false,
        "contact": 0
    }
}

Follow Blocks

GET Get Contact Follow-up Blocks

GET /2.0/contacts/{id}/follow-blocks · scope contacts:read

Report whether the contact has unsubscribed from email or SMS follow-ups, so a client can suppress marketing before contacting them.

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 OKGet Contact Follow-up Blocks

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

{
    "success": true,
    "data": {
        "contact": 0,
        "email": {
            "value": "",
            "blocked": false
        },
        "sms": {
            "value": "",
            "blocked": false
        }
    }
}

Notes

GET List Contact Notes

GET /2.0/contacts/{id}/notes · scope contact-notes:read

List the notes recorded against a contact.

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 OKContact notes

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

{
    "success": true,
    "data": [
        {
            "id": 0,
            "contact": 0,
            "created": 0,
            "user": 0,
            "note": ""
        }
    ]
}

POST Add Contact Note

POST /2.0/contacts/{id}/notes · scope contact-notes:write

Add a note to a contact, optionally attributed to a staff user.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Request body
AttributeTypeRequiredDescriptionExample
notestringYesThe note text (supports line breaks).Called customer to arrange a viewing for Saturday.
userinteger-Optional staff user id the note is attributed to, from /reference/staff-users.1
{
    "note": "Called customer to arrange a viewing for Saturday.",
    "user": 1
}
Responses
StatusDescription
201 CreatedContact note created

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

{
    "success": true,
    "data": {
        "id": 0,
        "contact": 0,
        "created": 0,
        "user": 0,
        "note": ""
    }
}

DELETE Delete Contact Note

DELETE /2.0/contacts/{id}/notes/{note_id} · scope contact-notes:delete

Delete a contact note.

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

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

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

Login

POST Reset Contact Login Password

POST /2.0/contacts/{id}/login/password/reset · scope contact-login:write

Reset the login password for a contact that has login enabled, returning the new password once.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKContact login password reset

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

{
    "success": true,
    "data": {
        "id": 0,
        "login": false,
        "password": ""
    }
}

POST Email Contact Login Details

POST /2.0/contacts/{id}/login/email · scope contact-login:write

Email login details to a contact that has login enabled.

Parameters (1)
ParameterInTypeRequiredDescriptionExample
idpathstringYesResource identifier in the path.
Responses
StatusDescription
200 OKContact login details emailed

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

{
    "success": true,
    "data": {
        "id": 0,
        "email": "",
        "emailed": false
    }
}

Tags

GET List Contact Tags

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

List the tags applied to a contact, plus the available contact 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 Contact 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 Contact Tags

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

Replace the tags applied to a contact. Each tag name must be available in the contact tag taxonomy. The same tag items can also be set inline via the contact 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 Contact 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
            }
        ]
    }
}