Cliento API reference: Customers

Base URL: https://api.cliento.com

The Customers APIs let an integration keep a location's customer register in step with another system: find customers, and create, change and delete them.

A customer is one of three types, each with its own API:

  • Persons. A person is an individual: the one who books, and the one the location sends reminders to.
  • Companies. A company owns a vehicle or pays the invoice.
  • Vehicles. A vehicle is what a garage or a car wash works on.

The Customers API searches all three types at once. Use it when you have a phone number or a reference and do not know which type it belongs to.

Each customer belongs to one location. The links between them, such as a vehicle's owner, are not available through the API yet.

What staff record about a person over time, such as a recipe, belongs to that person.

Persons

The Persons API lets an integration list a location's persons, find one, and create, change and delete them.

A person is an individual customer: someone who books an appointment, or the contact person for a company or a vehicle. The location communicates with persons, so the phone number, the email address and the consents for SMS and email reminders are on the person.

A person belongs to one location and has an id of the form per_.... Reading needs the scope customers:read, and writing needs customers:write.

Finding a person

Filter the list. Each filter matches the whole value, and several together match persons that have all of them:

  • ?email=, an email address. Letter case is ignored.
  • ?phoneNumber=, in E.164 format with the plus sign percent-encoded (%2B46701234567). A number that staff typed in another format is not found.
  • ?identityNumber=, a personnummer or other identity number as it is stored.
  • ?externalReference=, the id you gave the person when you created it.

Only externalReference is unique: no two persons, companies or vehicles at a location share one, though the reference of a deleted one can be used again. Two persons can share an email address or a phone number, and sometimes an identity number, so the other filters can return several persons and you choose between them.

When you do not know whether you are looking for a person, a company or a vehicle, search Customers instead.

Identity numbers

A person can have one identity number issued by an authority. It is sent and returned as identityNumber, with a type and a number. An identityNumber that is not null needs both. null in an update removes it. The number is kept as you send it. Only surrounding spaces and any HTML markup are removed, before it is checked and stored. A personnummer and a samordningsnummer are digits only, with no hyphen or space.

typeWhat it isAccepted numberExample
se_personnummerSwedish personal identity numberTwelve digits, YYYYMMDDNNNC: the full year, the day between 01 and 31, and a valid check digit198604122385
se_samordningsnummerSwedish coordination numberTwelve digits like a personnummer, with 60 added to the day (61 to 91), and a valid check digit198604722382
se_reservnummerSwedish reserve number, given in healthcare to someone without the two above3 to 32 characters: upper-case letters A to Z, digits and hyphens19860412AB27
foreignA personal identity number from another countryAny text of 1 to 255 characters120486-1234
otherAnything elseAny text of 1 to 255 charactersEMP-00417

The check digit is the last digit and follows the Luhn algorithm over the last ten digits, that is, without the century. A number that does not fit its type is refused with validation_failed and identityNumber.number among the fieldErrors. More types may be added, so accept a type you do not know in a response.

An identity number is not always unique. A create or an update is normally refused with duplicate when another person at the location already has the number with the same type. Staff can still register one number on several persons in Cliento, on purpose. A list filtered on that number then returns each of them. Do not rely on a type and number identifying exactly one person.

List persons

GET /v1/locations/{locationId}/persons

Scope: customers:read

Stability: preview

The location's persons, oldest first, one page at a time. To find one, use the filters instead of reading the whole list; "Finding a person" under Persons says how each one matches.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
emailquerystringNoOnly persons with exactly this email address, whatever its letter case. Example: anna.lindqvist@example.com.
phoneNumberquerystringNoOnly persons with exactly this mobile number, in E.164 format. Percent-encode the plus sign as %2B. Example: +46701234567.
identityNumberquerystringNoOnly persons with exactly this identity number, as it is stored: a Swedish personnummer is twelve digits. Example: 198604122385.
externalReferencequerystringNoOnly the person you created with this externalReference. Example: crm-88121.
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKPersonList
defaultAny failure. See the Errors section.Error

Create a person

POST /v1/locations/{locationId}/persons

Scope: customers:write

Stability: preview

Creates a person at the location. Send an externalReference, your own id for the person, to make the call safe to repeat. When a person at the location already has that reference, that person is returned unchanged with 200 and nothing is created. A person with an identity number that another person at the location already has, with the same type, is normally refused with duplicate.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: PersonCreate

Responses

StatusDescriptionBody
200A person with this externalReference already existed.Person
201The person was created.Person
defaultAny failure. See the Errors section.Error

Get a person

GET /v1/locations/{locationId}/persons/{personId}

Scope: customers:read

Stability: preview

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes

Responses

StatusDescriptionBody
200OKPerson
defaultAny failure. See the Errors section.Error

Get a person by id

GET /v1/persons/{personId}

Scope: customers:read

Stability: preview

The same person as under its location, found from its id. For a caller that holds an id and not the location it belongs to. The answer carries locationId.

Parameters

NameInTypeRequiredDescription
personIdpathstringYes

Responses

StatusDescriptionBody
200OKPerson
defaultAny failure. See the Errors section.Error

Update a person

PATCH /v1/locations/{locationId}/persons/{personId}

Scope: customers:write

Stability: preview

Changes only the fields in the request. Either all of them are changed or none. See PersonUpdate for how to clear a field.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: PersonUpdate

Responses

StatusDescriptionBody
200OKPerson
defaultAny failure. See the Errors section.Error

Delete a person

DELETE /v1/locations/{locationId}/persons/{personId}

Scope: customers:write

Stability: preview

A person with upcoming bookings cannot be deleted. Those bookings are cancelled or deleted in Cliento first.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Responses

StatusDescriptionBody
204No Content
defaultAny failure. See the Errors section.Error

Recipes

Industry: hair and beauty. The Recipes API is for hair salons. It lets an integration save the colour that was mixed for a customer, so that staff can read it in Cliento at the next visit. It is meant for a system that mixes or measures colour itself, such as a scale or a dispenser.

A recipe belongs to a person and describes one visit. It has one or more bowls. Each bowl lists its components and the amount of each.

Recipes are read and added under /v1/locations/{locationId}/persons/{personId}/recipes. A recipe has an id of the form rcp_.... Reading needs the scope customers:read, and adding needs customers:write.

  • The list is newest first, so its first recipe is what the person got the last time.
  • A recipe also shows in the person's log, the notes staff keep on a person in Cliento, written out as text. Staff can change or remove it there.
  • A recipe is not changed through the API. When the mix is adjusted, add a new one.
  • A recipe moves no stock. A component can name the product it was taken from (productId), but the withdrawal is recorded through the Stock movements API. To tie the two together, put the externalReference of that stock withdrawal in the recipe's stockReference.
  • Amounts are decimal strings, such as "22.5", in the unit you send with them.
  • properties are your own names and values, for what has no field, such as a processing time. They can be set on the recipe, a bowl or a component. Staff see them in Cliento, written out with the recipe in the person's log.
  • appData is a JSON object for your own system's use: it is stored and returned as it is, and never shown in Cliento.
  • A location that keeps medical records, such as a clinic, takes no new recipes: adding one there is refused with not_allowed.

List a person's recipes

GET /v1/locations/{locationId}/persons/{personId}/recipes

Scope: customers:read

Stability: preview

The person's recipes, newest first, one page at a time. The first one is what was mixed the last time.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKRecipeList
defaultAny failure. See the Errors section.Error

Add a recipe to a person

POST /v1/locations/{locationId}/persons/{personId}/recipes

Scope: customers:write

Stability: preview

Adds a recipe to the person. It also shows in the person's log in Cliento, where staff read it. A recipe is not changed afterwards through the API: when the mix is adjusted, add a new recipe. Send an Idempotency-Key so that a repeat of the call does not add the recipe twice. Not available at a location that keeps medical records.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: RecipeCreate

Responses

StatusDescriptionBody
201CreatedRecipe
defaultAny failure. See the Errors section.Error

Get a recipe

GET /v1/locations/{locationId}/persons/{personId}/recipes/{recipeId}

Scope: customers:read

Stability: preview

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
personIdpathstringYes
recipeIdpathstringYes

Responses

StatusDescriptionBody
200OKRecipe
defaultAny failure. See the Errors section.Error

Companies

The Companies API lets an integration list a location's companies, find one, and create, change and delete them.

A company is a business customer: the owner of a vehicle, or the one that pays the invoice for a job. The location does not communicate with a company about a booking. It communicates with a person, such as the company's contact person.

A company belongs to one location and has an id of the form com_.... Reading needs the scope customers:read, and writing needs customers:write.

  • organisationNumber is the Swedish organisation number: ten digits with a valid check digit, with no hyphen. A number that does not fit is refused with validation_failed.
  • department names one part of a company, such as Used cars, for a location that registers each part as a company of its own.
  • To find a company, filter the list on organisationNumber or on the externalReference you gave it.
  • An organisation number is not always unique. A create or an update is normally refused with duplicate when another company at the location already has the number, whatever its department. Staff can still register one number on several companies in Cliento, on purpose. That is how the parts of one company come to be several companies. Do not rely on a number identifying exactly one company.

List companies

GET /v1/locations/{locationId}/companies

Scope: customers:read

Stability: preview

The location's companies, oldest first, one page at a time. To find one, filter on its organisation number or your own reference.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
organisationNumberquerystringNoOnly companies with exactly this organisation number, ten digits. Example: 5560360793.
externalReferencequerystringNoOnly the company you created with this externalReference. Example: crm-88121.
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKCompanyList
defaultAny failure. See the Errors section.Error

Create a company

POST /v1/locations/{locationId}/companies

Scope: customers:write

Stability: preview

Creates a company at the location. Send an externalReference, your own id for the company, to make the call safe to repeat. When a company at the location already has that reference, that company is returned unchanged with 200 and nothing is created. A company with an organisation number that another company at the location already has is normally refused with duplicate.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: CompanyCreate

Responses

StatusDescriptionBody
200A company with this externalReference already existed.Company
201The company was created.Company
defaultAny failure. See the Errors section.Error

Get a company

GET /v1/locations/{locationId}/companies/{companyId}

Scope: customers:read

Stability: preview

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
companyIdpathstringYes

Responses

StatusDescriptionBody
200OKCompany
defaultAny failure. See the Errors section.Error

Get a company by id

GET /v1/companies/{companyId}

Scope: customers:read

Stability: preview

The same company as under its location, found from its id. For a caller that holds an id and not the location it belongs to. The answer carries locationId.

Parameters

NameInTypeRequiredDescription
companyIdpathstringYes

Responses

StatusDescriptionBody
200OKCompany
defaultAny failure. See the Errors section.Error

Update a company

PATCH /v1/locations/{locationId}/companies/{companyId}

Scope: customers:write

Stability: preview

Changes only the fields in the request. Either all of them are changed or none. See CompanyUpdate for how to clear a field.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
companyIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: CompanyUpdate

Responses

StatusDescriptionBody
200OKCompany
defaultAny failure. See the Errors section.Error

Delete a company

DELETE /v1/locations/{locationId}/companies/{companyId}

Scope: customers:write

Stability: preview

A company with upcoming bookings cannot be deleted. Those bookings are cancelled or deleted in Cliento first.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
companyIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Responses

StatusDescriptionBody
204No Content
defaultAny failure. See the Errors section.Error

Vehicles

Industry: automotive. The Vehicles API is for garages, car washes and other automotive businesses. It lets an integration list a location's vehicles, find one, and create, change and delete them.

A vehicle is what the job is done on: the car, not its owner. The owner is a person or a company. The location communicates with the vehicle's contact person, who is a person.

A vehicle belongs to one location and has an id of the form veh_.... Reading needs the scope customers:read, and writing needs customers:write.

  • registrationNumber identifies the vehicle. A vehicle needs a registration number or a description; it can have both.
  • make, model, modelYear and colour are filled in from the Swedish vehicle register when staff look the registration number up in Cliento. They are not set through the API and are left out for a vehicle that has not been looked up.
  • To find a vehicle, filter the list on registrationNumber or on the externalReference you gave it.
  • A registration number is not always unique. A create or an update is normally refused with duplicate when another vehicle at the location already has the number. Staff can still register one number on several vehicles in Cliento, on purpose. Do not rely on a number identifying exactly one vehicle.

List vehicles

GET /v1/locations/{locationId}/vehicles

Scope: customers:read

Stability: preview

The location's vehicles, oldest first, one page at a time. To find one, filter on its registration number or your own reference.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
registrationNumberquerystringNoOnly vehicles with exactly this registration number. Example: ABC123.
externalReferencequerystringNoOnly the vehicle you created with this externalReference. Example: crm-88121.
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKVehicleList
defaultAny failure. See the Errors section.Error

Create a vehicle

POST /v1/locations/{locationId}/vehicles

Scope: customers:write

Stability: preview

Creates a vehicle at the location. Send an externalReference, your own id for the vehicle, to make the call safe to repeat. When a vehicle at the location already has that reference, that vehicle is returned unchanged with 200 and nothing is created. A vehicle with a registration number that another vehicle at the location already has is normally refused with duplicate.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: VehicleCreate

Responses

StatusDescriptionBody
200A vehicle with this externalReference already existed.Vehicle
201The vehicle was created.Vehicle
defaultAny failure. See the Errors section.Error

Get a vehicle

GET /v1/locations/{locationId}/vehicles/{vehicleId}

Scope: customers:read

Stability: preview

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
vehicleIdpathstringYes

Responses

StatusDescriptionBody
200OKVehicle
defaultAny failure. See the Errors section.Error

Get a vehicle by id

GET /v1/vehicles/{vehicleId}

Scope: customers:read

Stability: preview

The same vehicle as under its location, found from its id. For a caller that holds an id and not the location it belongs to. The answer carries locationId.

Parameters

NameInTypeRequiredDescription
vehicleIdpathstringYes

Responses

StatusDescriptionBody
200OKVehicle
defaultAny failure. See the Errors section.Error

Update a vehicle

PATCH /v1/locations/{locationId}/vehicles/{vehicleId}

Scope: customers:write

Stability: preview

Changes only the fields in the request. Either all of them are changed or none. See VehicleUpdate for how to clear a field.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
vehicleIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Request body: VehicleUpdate

Responses

StatusDescriptionBody
200OKVehicle
defaultAny failure. See the Errors section.Error

Delete a vehicle

DELETE /v1/locations/{locationId}/vehicles/{vehicleId}

Scope: customers:write

Stability: preview

A vehicle with upcoming bookings cannot be deleted. Those bookings are cancelled or deleted in Cliento first.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
vehicleIdpathstringYes
Idempotency-KeyheaderstringNoA value you make up for this one request, such as a UUID. Send the same value when you retry and the first answer is returned; see Retrying safely. Example: 8e03978e-40d5-43e8-bc93-6894a57f9324.

Responses

StatusDescriptionBody
204No Content
defaultAny failure. See the Errors section.Error

Customers

The Customers API searches persons, companies and vehicles at once. Use it when you do not know which type of customer you are looking for. You can search by email address, by phone number, by your own reference, or by an identifying number such as a personnummer or a vehicle registration number.

A search returns a page of matching customers. Each match is a short entry that says which type it is. That type's API has the full record.

The Customers API is read-only. Each type is created, changed and deleted through its own API.

  • Each entry is short: its id, its type, its locationId, its name (for a vehicle, its description) and the number that identifies it. The id's prefix (per_, com_, veh_) and type say where to read the rest: Persons, Companies or Vehicles.
  • Filters match the whole value, and several together match what has all of them: ?email=, ?phoneNumber= (in E.164 format with the plus sign percent-encoded), ?number= (an identity number, an organisation number or a registration number) and ?externalReference=. Add ?type= to keep one type, and repeat it for several.
  • An externalReference is unique among everything at a location, whatever its type.

List customers of every type

GET /v1/locations/{locationId}/customers

Scope: customers:read

Stability: preview

The location's persons, companies and vehicles in one list of short entries, oldest first. Use it to find something when you do not know its type, for example from a phone number; then read it in full from Persons, Companies or Vehicles, as the id's prefix and type say.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
typequeryarray of stringNoOnly these kinds: person, company or vehicle. Repeat the parameter for several. Example: person.
emailquerystringNoOnly those with exactly this email address. Letter case is ignored. Example: anna.lindqvist@example.com.
phoneNumberquerystringNoOnly those with exactly this mobile number, in E.164 format. Percent-encode the plus sign as %2B. Example: +46701234567.
numberquerystringNoOnly those with exactly this number: an identity number, an organisation number or a registration number. Example: ABC123.
externalReferencequerystringNoOnly the one you created with this externalReference. Example: crm-88121.
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKCustomerList
defaultAny failure. See the Errors section.Error

List customers across locations

GET /v1/customers

Scope: customers:read

Stability: preview

Lists the persons, companies and vehicles of every location this API key can be used on, as short entries, one page at a time. The call works only when sharing customers between locations is turned on for the organisation in Cliento. Otherwise it is refused with not_allowed, and you list customers per location instead. Each entry has the locationId it is registered at. Read the full record, change it or delete it under that location, in Persons, Companies or Vehicles. The filters work as on a location's list.

Parameters

NameInTypeRequiredDescription
emailquerystringNoOnly those with exactly this email address. Letter case is ignored. Example: anna.lindqvist@example.com.
phoneNumberquerystringNoOnly those with exactly this mobile number, in E.164 format. Percent-encode the plus sign as %2B. Example: +46701234567.
externalReferencequerystringNoOnly those you created with this externalReference. A reference is unique within a location, not across them, so the list can return one match per location. Example: crm-88121.
numberquerystringNoOnly those with exactly this number: an identity number, an organisation number or a registration number. Example: ABC123.
typequeryarray of stringNoOnly these kinds: person, company or vehicle. Repeat the parameter for several. Example: person.
limitqueryinteger (int32)NoPage size, 1 to 200. Default 50.
afterquerystringNoThe nextCursor of the previous page.

Responses

StatusDescriptionBody
200OKCustomerList
defaultAny failure. See the Errors section.Error

Get a customer of any type

GET /v1/locations/{locationId}/customers/{customerId}

Scope: customers:read

Stability: preview

The short entry for a person, a company or a vehicle, by its id.

Parameters

NameInTypeRequiredDescription
locationIdpathstringYes
customerIdpathstringYes

Responses

StatusDescriptionBody
200OKCustomer
defaultAny failure. See the Errors section.Error

Get a customer of any type by id

GET /v1/customers/{customerId}

Scope: customers:read

Stability: preview

The short entry for a person, a company or a vehicle, found from its id. For a caller that holds an id and not the location it belongs to. The answer carries locationId.

Parameters

NameInTypeRequiredDescription
customerIdpathstringYes

Responses

StatusDescriptionBody
200OKCustomer
defaultAny failure. See the Errors section.Error

Customer log

Coming soon. Read and add the notes and files staff keep on a person, a company or a vehicle.

Schemas

Address

FieldTypeRequiredDescription
citystring or nullNoExample: Stockholm.
countrystring or nullNoFree text; an ISO 3166-1 alpha-2 code is recommended. Example: SE.
line1string or nullNoExample: Storgatan 12.
line2string or nullNoExample: Lgh 1102.
line3string or nullNo
postCodestring or nullNoExample: 111 51.

Communication

What the person has agreed to receive. In an update, a field you leave out keeps its value. For a new person smsReminders, emailReminders and reviewReminders start as true and marketing as false: send marketing as true only when the person has agreed to marketing.

FieldTypeRequiredDescription
emailRemindersbooleanNoBooking reminders by email.
marketingbooleanNoMarketing messages.
reviewRemindersbooleanNoRequests to review a visit.
smsRemindersbooleanNoBooking reminders by SMS.

Company

Represents a business a location serves. Belongs to one location.

FieldTypeRequiredDescription
addressAddressNo
createdAtstring (date-time)No
departmentstringNoA part of the company, when the location serves several of them. Example: Used cars.
emailstringNoExample: info@example.com.
externalReferencestringNoYour own id for it, as sent when it was created. Example: crm-88121.
idstringYesExample: com_6Tn3wRd8Kq1Vb5Xs9LmPyA.
locationIdstringYesExample: loc_4fK9xQ2mLr8TzB1vNc7HdW.
namestringNoExample: Bilfirman AB.
notesstringNoStaff-facing notes, at most 1000 characters.
organisationNumberstringNoThe Swedish organisation number: ten digits with a valid check digit, with no hyphen. Example: 5560360793.
otherPhoneNumberstringNoExample: +4686543210.
phoneNumberstringNoPhone number, in E.164 format when it was set through this API. Example: +46701234567.
updatedAtstring (date-time)No

CompanyCreate

FieldTypeRequiredDescription
addressAddressNo
departmentstringNoA part of the company, when the location serves several of them. Example: Used cars.
emailstringNoExample: info@example.com.
externalReferencestringNoYour own id for it, at most 100 characters, such as its id in your system. It makes the create safe to repeat and lets you find it again. Compared exactly, letter case included. Example: crm-88121.
namestringYesExample: Bilfirman AB.
notesstringNoStaff-facing notes, at most 1000 characters.
organisationNumberstringNoThe Swedish organisation number: ten digits with a valid check digit, with no hyphen. Example: 5560360793.
otherPhoneNumberstringNoExample: +4686543210.
phoneNumberstringNoPhone number in E.164 format: a plus sign, the country code and the number, at most 15 digits. Example: +46701234567.

CompanyList

FieldTypeRequiredDescription
dataarray of CompanyYes
nextCursorstringNoPass as after to fetch the next page. Absent on the last page. Example: com_6Tn3wRd8Kq1Vb5Xs9LmPyA.

CompanyUpdate

A JSON merge patch: send only what changes. A field you leave out keeps its value; a field set to null is cleared, except name, which cannot be cleared. address merges field by field.

FieldTypeRequiredDescription
addressAddress or nullNo
departmentstring or nullNoA part of the company, when the location serves several of them. Example: Used cars.
emailstring or nullNoExample: info@example.com.
namestringNoExample: Bilfirman AB.
notesstring or nullNoStaff-facing notes, at most 1000 characters.
organisationNumberstring or nullNoThe Swedish organisation number: ten digits with a valid check digit, with no hyphen. Example: 5560360793.
otherPhoneNumberstring or nullNoExample: +4686543210.
phoneNumberstring or nullNoPhone number in E.164 format: a plus sign, the country code and the number, at most 15 digits. Example: +46701234567.

Customer

The short entry for a person, a company or a vehicle. The id's prefix says which type, and that type's API has the rest.

FieldTypeRequiredDescription
idstringYesExample: per_2QCtWVSaVO7yCRYBj1zsbA.
locationIdstringYesExample: loc_4fK9xQ2mLr8TzB1vNc7HdW.
namestringNoExample: Anna Lindqvist.
numberstringNoThe number that identifies it, when it has one: a person's identity number, a company's organisation number or a vehicle's registration number. Example: 198604122385.
typestringYesperson, company or vehicle. It also says where to read the rest: Persons, Companies or Vehicles. More values may be added. Example: person.

CustomerList

FieldTypeRequiredDescription
dataarray of CustomerYes
nextCursorstringNoPass as after to fetch the next page. Absent on the last page. Example: per_2QCtWVSaVO7yCRYBj1zsbA.

CustomerOwner

Whose customer a person is within its location: the location's own, or that of one of the location's resources. A salon that rents out chairs uses it: a person served by a hairdresser who rents a chair is that resource's customer, and a person served by an employee is the location's. Many locations never record it, so unassigned is common and says nothing either way.

FieldTypeRequiredDescription
resourceIdstringNoThe resource (see Resources) whose customer the person is. Present when type is resource. Example: res_2QCtWVSaVO7yCRYBj1zsbA.
typestringYeslocation: the location's own customer. resource: the customer of one resource, named by resourceId. unassigned: not recorded. More values may be added. Values today: location, resource, unassigned.

Error

The body of every non-2xx response.

FieldTypeRequiredDescription
codestringYesStable, machine-readable error code. Values today: invalid_request, validation_failed, entity_not_found, duplicate, merchant_required, code_already_used, gift_card_already_used, pin_not_recognised, insufficient_stock, not_allowed, request_in_progress, idempotency_key_reused, unauthenticated, forbidden, account_blocked, rate_limited, route_not_found, method_not_allowed, internal_error.
detailsobject of any valueNoExtra detail. For validation_failed, fieldErrors maps each rejected field to the reason.
messagestringYesHuman-readable explanation. Not stable; do not parse it.

IdentityNumber

A number issued by an authority that identifies a person, such as a personnummer. The accepted format of each type is listed under Persons.

FieldTypeRequiredDescription
numberstringYesIn the format of its type: twelve digits for a Swedish personnummer. Example: 198604122385.
typestringYesThe kind of number, in lower case, such as se_personnummer or foreign. More values may be added. Example: se_personnummer.

Person

Represents an individual a location serves. Belongs to one location.

FieldTypeRequiredDescription
addressAddressNo
communicationCommunicationYes
createdAtstring (date-time)No
dateOfBirthstringNoISO 8601 date. Example: 1986-04-12.
emailstringNoExample: anna.lindqvist@example.com.
externalReferencestringNoYour own id for it, as sent when it was created. Example: crm-88121.
genderstringNoOne lower-case word such as female. More values may be added. Example: female.
idstringYesExample: per_2QCtWVSaVO7yCRYBj1zsbA.
identityNumberIdentityNumberNo
locationIdstringYesExample: loc_4fK9xQ2mLr8TzB1vNc7HdW.
namestringNoExample: Anna Lindqvist.
notesstringNoStaff-facing notes, at most 1000 characters.
onlineBookingBlockedbooleanYesTrue when the person may not book online.
otherPhoneNumberstringNoExample: +4686543210.
ownerCustomerOwnerYesWhose customer the person is within the location. See CustomerOwner.
phoneNumberstringNoMobile number, in E.164 format when it was set through this API. Example: +46701234567.
updatedAtstring (date-time)No

PersonCreate

FieldTypeRequiredDescription
addressAddressNo
communicationCommunicationNo
dateOfBirthstringNoISO 8601 date. Example: 1986-04-12.
emailstringNoExample: anna.lindqvist@example.com.
externalReferencestringNoYour own id for it, at most 100 characters, such as its id in your system. It makes the create safe to repeat and lets you find it again. Compared exactly, letter case included. Example: crm-88121.
genderstringNoValues today: male, female, other.
identityNumberIdentityNumberNo
namestringYesExample: Anna Lindqvist.
notesstringNoStaff-facing notes, at most 1000 characters.
onlineBookingBlockedbooleanNoSet to true to stop the person booking online.
otherPhoneNumberstringNoExample: +4686543210.
phoneNumberstringNoMobile number in E.164 format: a plus sign, the country code and the number, at most 15 digits. Example: +46701234567.

PersonList

FieldTypeRequiredDescription
dataarray of PersonYes
nextCursorstringNoPass as after to fetch the next page. Absent on the last page. Example: per_2QCtWVSaVO7yCRYBj1zsbA.

PersonUpdate

A JSON merge patch: send only what changes. A field you leave out keeps its value; a text field, identityNumber or address set to null is cleared, except name, which cannot be cleared. address merges field by field; identityNumber is replaced as a whole. The booleans (communication.*, onlineBookingBlocked) are true or false and cannot be null.

FieldTypeRequiredDescription
addressAddress or nullNo
communicationCommunicationNo
dateOfBirthstring or nullNoISO 8601 date. Example: 1986-04-12.
emailstring or nullNoExample: anna.lindqvist@example.com.
genderstring or nullNoValues today: male, female, other, null.
identityNumberIdentityNumber or nullNo
namestringNoExample: Anna Lindqvist.
notesstring or nullNoStaff-facing notes, at most 1000 characters.
onlineBookingBlockedbooleanNoSet to true to stop the person booking online.
otherPhoneNumberstring or nullNoExample: +4686543210.
phoneNumberstring or nullNoMobile number in E.164 format: a plus sign, the country code and the number, at most 15 digits. Example: +46701234567.

Recipe

A record of what was mixed for a person at one visit. Belongs to that person.

FieldTypeRequiredDescription
appDataobject of any valueNoThe JSON object of your own that is stored with the recipe, returned as it is. Example: {"formulaId":"F-2291"}.
bowlsarray of RecipeBowlYesThe bowls mixed, in order.
createdAtstring (date-time)YesExample: 2026-10-11T09:24:31Z.
idstringYesExample: rcp_4Kd8sWn2Qy6Hb9Tf3LmVxA.
notestringNoExample: Slightly warmer than last time..
personIdstringYesExample: per_6Jm2tRx8Lc4Nq7Bv5ZgWkD.
propertiesobject of stringNoExample: {"processingTime":"35 min"}.
stockReferencestringNoExample: treatment-2026-10-11-0042.
titlestringNoExample: Colour, roots and lengths.
updatedAtstring (date-time)NoWhen staff last changed the recipe in Cliento. Left out when they never have. Example: 2026-10-12T14:02:10Z.

RecipeBowl

One bowl: what was mixed together, usually colour and a developer.

FieldTypeRequiredDescription
componentsarray of RecipeComponentYesWhat went into the bowl, 1 to 20.
propertiesobject of stringNoYour own names and values for this bowl, with the same limits as a component's properties. Example: {"processingTime":"35 min"}.
ratiostringNoParts of colour to parts of developer. Example: 1:2.
titlestringNoWhat the bowl is for. At most 200 characters. Example: Roots.

RecipeComponent

One thing that went into a bowl.

FieldTypeRequiredDescription
amountstringYesHow much, in unit, as a decimal string greater than 0 with at most three decimals. Example: 30.
namestringYesWhat it is, as the hairdresser reads it. At most 200 characters. Example: Koleston Perfect 7/0.
productIdstringNoThe product the component was taken from, when it is one of the location's. Example: prd_5Tg8mPq1Xc7Jd2Ls9WbNrK.
propertiesobject of stringNoYour own names and values for this component, at most 30. A name is at most 100 characters and a value at most 500. Example: {"brand":"Wella"}.
rolestringNoWhat the component is in the mix, as one lower-case word such as colour or developer. The list is open, so accept a value you do not know. Example: colour.
shadestringNoThe shade code of a colour. At most 50 characters. Example: 7/0.
strengthPercentstringNoThe strength of a developer in per cent, as a decimal string greater than 0 and at most 100, with at most two decimals. Example: 6.
unitstringYesThe unit of amount, as the hairdresser reads it. At most 20 characters. Example: g.

RecipeCreate

What was mixed for a person at one visit.

FieldTypeRequiredDescription
appDataobject of any valueNoA JSON object of your own, for what the recipe has no field for. It is stored and returned as it is, and never shown in Cliento. At most 16 kB. A number keeps the precision of a double; send a longer one as a string. Example: {"formulaId":"F-2291"}.
bowlsarray of RecipeBowlYesThe bowls mixed, 1 to 20, in order.
notestringNoFree text. At most 4000 characters. Example: Slightly warmer than last time..
propertiesobject of stringNoYour own names and values for the whole recipe, with the same limits as a component's properties. Example: {"processingTime":"35 min"}.
staffIdstringNoThe staff member who made the recipe, shown as its author in the person's log. Without it the author is the API key. Example: stf_7Hn3kQw9Zr4Tb6Vy1MxPdE.
stockReferencestringNoThe externalReference of the stock document that took the recipe's products out of stock, when you recorded one. At most 100 characters. Example: treatment-2026-10-11-0042.
titlestringNoWhat the recipe is for. At most 200 characters. Example: Colour, roots and lengths.

RecipeList

FieldTypeRequiredDescription
dataarray of RecipeYes
nextCursorstringNoPass as after to fetch the next page. Absent on the last page. Example: rcp_4Kd8sWn2Qy6Hb9Tf3LmVxA.

Vehicle

Represents a vehicle a location works on. Belongs to one location.

FieldTypeRequiredDescription
colourstringNoFrom the vehicle register. Example: Red.
createdAtstring (date-time)No
descriptionstringNoWhat the vehicle is called in Cliento. A lookup in the vehicle register fills it in with the make, model, colour and year; staff can change it. Example: The red van.
externalReferencestringNoYour own id for it, as sent when it was created. Example: crm-88121.
idstringYesExample: veh_3Ks7pQx2Wn9Tb4Vd6HyRcE.
locationIdstringYesExample: loc_4fK9xQ2mLr8TzB1vNc7HdW.
makestringNoFrom the Swedish vehicle register, when staff have looked the vehicle up in Cliento. Not set through the API. Example: Volvo.
modelstringNoFrom the vehicle register. Example: V60.
modelYearinteger (int32)NoFrom the vehicle register. Example: 2021.
notesstringNoStaff-facing notes, at most 1000 characters.
registrationNumberstringNoThe registration number, one to seven characters. Example: ABC123.
updatedAtstring (date-time)No

VehicleCreate

A vehicle needs a registrationNumber or a description.

FieldTypeRequiredDescription
descriptionstringNoWhat the vehicle is called in Cliento, such as The red van. Example: The red van.
externalReferencestringNoYour own id for it, at most 100 characters, such as its id in your system. It makes the create safe to repeat and lets you find it again. Compared exactly, letter case included. Example: crm-88121.
notesstringNoStaff-facing notes, at most 1000 characters.
registrationNumberstringNoThe registration number, one to seven characters. Example: ABC123.

VehicleList

FieldTypeRequiredDescription
dataarray of VehicleYes
nextCursorstringNoPass as after to fetch the next page. Absent on the last page. Example: veh_3Ks7pQx2Wn9Tb4Vd6HyRcE.

VehicleUpdate

A JSON merge patch: send only what changes. A field you leave out keeps its value; a field set to null is cleared, but a vehicle must keep a registrationNumber or a description.

FieldTypeRequiredDescription
descriptionstring or nullNoWhat the vehicle is called in Cliento, such as The red van. Example: The red van.
notesstring or nullNoStaff-facing notes, at most 1000 characters.
registrationNumberstring or nullNoThe registration number, one to seven characters. Example: ABC123.