# Cliento API overview

> **The Cliento API is under development**
>
> We welcome your feedback. Tell us [in the chat](https://developers.cliento.com/docs/help.md) what you're missing, or what your business
> needs.

The Cliento API gives your own systems server-to-server access to an organisation's data in
Cliento. It is a REST API with JSON bodies, authenticated with an API key and versioned in the
URL.

## Base URL

```
https://api.cliento.com
```

Every path starts with the version, for example `/v1/locations`.

## Authentication

Every request carries an API key as a bearer token, in the `Authorization` header. You create
keys on your [account page](/account); a key belongs to one organisation and can do only what
its [scopes](#scopes) allow.

Keep the key on your server. Never put it in a browser or a mobile app. For an app that runs
on the user's own device, an OAuth sign-in flow is under development.

## Your first request

Send your API key as a bearer token and list the locations the key can be used on:

```bash
curl https://api.cliento.com/v1/locations \
  -H "Authorization: Bearer $CLIENTO_API_KEY"
```

Lists and writes are addressed under a location, as `/v1/locations/{locationId}/...`. A single
item can also be read by its id, without its location, such as `GET /v1/persons/{personId}`,
for when you hold
an id and not the location it belongs to. The answer carries the item's `locationId`.

One list is not under a location. An organisation that shares its customers (persons, companies
and vehicles) between its locations can list them across every location the key can be used on,
with `GET /v1/customers`. That list and a location's own list,
`GET /v1/locations/{locationId}/customers`, are both paged, and a `nextCursor` works only on
the list it came from.

## The data model

A **location** is one place of business, such as one salon or one branch of a car wash. It
belongs to an organisation. Everything else belongs to a location, which is why lists and writes
start with `/v1/locations/{locationId}`.

The [API reference](/docs/api/reference/) has a page for each part:

- **Locations**: the [Locations API](/docs/api/reference/locations/#tag/locations) lists the
  locations a key can be used on.
- **Staff**: the [Staff API](/docs/api/reference/staff/#tag/staff) lists the people who work at
  a location. Other calls take a staff id to say who did something, such as who took
  stock out.
- **Customers**: a customer is a [person](/docs/api/reference/customers/#tag/persons), a
  [company](/docs/api/reference/customers/#tag/companies) or a
  [vehicle](/docs/api/reference/customers/#tag/vehicles). Each type has its own API that reads
  and writes it. The [Customers API](/docs/api/reference/customers/#tag/customers) searches all
  three at once, for when you do not know which type you are looking for. A
  [recipe](/docs/api/reference/customers/#tag/recipes) is the hair colour or treatment that
  was mixed for a person at a visit. It belongs to that person.
- **Booking**: a [resource](/docs/api/reference/booking/#tag/resources) is what gets booked:
  most often a person, sometimes a room or a piece of equipment. A
  [service](/docs/api/reference/booking/#tag/services) is one thing a location offers for
  booking, with a name, a duration and a price. A
  [booking](/docs/api/reference/booking/#tag/bookings) is a time on one or more resources,
  usually for a customer and the services booked. The Bookings API reads bookings. Creating,
  moving and cancelling a booking, and the APIs for schedules and availability, are coming
  soon.
- **Point of sale**: a [merchant](/docs/api/reference/point-of-sale/#tag/merchants) is the
  legal entity that sells at a location. A
  [gift card](/docs/api/reference/point-of-sale/#tag/gift-cards) belongs to a merchant. The APIs
  for sales, receipts and payments are coming soon.
- **Products and stock**: a location has one product list. Each product with stock tracking
  has a stock balance. The
  [Products API](/docs/api/reference/products-and-stock/#tag/products) reads the products and
  their balances. The
  [Stock movements API](/docs/api/reference/products-and-stock/#tag/stock-movements) reads the
  history behind a balance and records deliveries and withdrawals.
- **Colour bar**: for hair salons. The Colour bar APIs let an integration manage a salon's
  stock of hair colour. A
  [colour bar item](/docs/api/reference/colour-bar/#tag/colour-bar-items) is one article, such
  as one shade of a colour, with its own stock. Registering a
  [colour bar mix](/docs/api/reference/colour-bar/#tag/colour-bar-mixes) takes what was used
  from each item's stock.

## API reference

The [API reference](/docs/api/reference/) lists every
endpoint with its parameters, responses and code samples. It is generated from the API's OpenAPI
description, so it always matches the API. Its first page covers what applies to every call:

- [Authentication](/docs/api/reference/#description/authentication) and scopes
- [Identifiers](/docs/api/reference/#description/identifiers)
- [Live and test keys](/docs/api/reference/#description/live-and-test-keys)
- [Updating](/docs/api/reference/#description/updating)
- [Paging](/docs/api/reference/#description/paging)
- [Created and updated times](/docs/api/reference/#description/created-and-updated-times)
- [Errors](/docs/api/reference/#description/errors)
- [Rate limits](/docs/api/reference/#description/rate-limits)
- [Versioning](/docs/api/reference/#description/versioning)
- [Amounts](/docs/api/reference/#description/amounts)
- [Retrying safely](/docs/api/reference/#description/retrying-safely)

## Scopes

You choose a key's scopes when you create it on your [account page](/account), which lists the
scopes that exist. A call outside a key's scopes is answered with `403` and the
code `forbidden`.

Scopes are fixed when a key is created. A key made before a scope existed does not have it:
to use endpoints added later, create a new key with their scope. Gift cards, for example, need
`giftcards:read` or `giftcards:write`.

## Gift cards

A gift card is sold by a **merchant**: the legal entity that sells at a location. Most locations
have one. Where a location has several, pass `merchantId`; list them with
`GET /v1/locations/{locationId}/merchants`.

- **Amounts are decimal strings**, such as `"500.00"`. They are never JSON numbers.
- **`POST /v1/locations/{locationId}/gift-cards/import` records a card sold somewhere else**, for
  example in your web shop. There is no plain "create a gift card" call.
- **Importing is safe to retry.** Send your own `externalReference` with each card. The first
  call answers `201` with the new card; a repeat with the same reference answers `200` with the
  card that already exists, and creates nothing.
- **A refusal says which field and why.** The error's `details.fieldErrors` holds one sentence
  per refused field, stating the rule.
