The X-Sitter API lets you read and change your company's data straight from your own system, for example your ERP, your online shop or a spreadsheet. All requests go to the same address and answer in JSON.

| | |
|---|---|
| **Address** | `https://app.x-sitter.com/api/v1` |
| **Format** | JSON (UTF-8) |
| **Authentication** | Token in the header `Authorization: Bearer xst_...` |

!!!primary Step by step
Guides: [Query stock](stock.md) and [Read and maintain articles](articles.md).
!!!

## What the API can do

| Area | Addresses | For whom |
|---|---|---|
| [**Stock**](stock.md) | `GET /api/v1/stock`, `GET /api/v1/stock/{id}` | Logisticians and clients (clients only if their logistician allows it) |
| [**Articles**](articles.md) | `GET`, `POST /api/v1/articles`, `GET`, `PATCH`, `DELETE /api/v1/articles/{id}` | Logisticians and clients (deleting only the logistician) |
| **Storage locations** | `GET`, `POST /api/v1/spots`, `GET`, `PUT`, `DELETE /api/v1/spots/{id}` | Logisticians only |

## Create a token

Every request needs a token. You create it yourself in X-Sitter:

1. Log in to X-Sitter, click your name in the top right corner and then **Settings** (German: *Einstellungen*).
2. Choose **API access** (*API Zugang*) in the menu on the left. If the entry is missing, your user does not have the permission for it; ask your company's administrator.
3. In the **API token** section, enter a **Name** (*Bezeichnung*) that tells you later what the token is for (e.g. "ERP integration").
4. Optional: set a date under **Valid until** (*Gültig bis*). Empty means unlimited.
5. Tick the **Permissions** the token needs, and only those. X-Sitter only offers permissions your user also has in X-Sitter itself.
6. Click **Create token** (*Token anlegen*).
7. The token (it starts with `xst_`) is shown **exactly once**. Copy it right away and store it in your system. X-Sitter only keeps a hash and cannot show it to you again later.

The list below shows all tokens of your company with their permissions, expiry date and when they were **last used** (*Zuletzt benutzt*). There you can **lock** (and enable again) or **delete** a token at any time. A deleted token stops working immediately.

!!!warning Treat the token like a password
Anyone who has the token can access your company's data with its permissions. Do not send it by email or chat, do not put it into publicly reachable code (e.g. JavaScript in the browser or a public Git repository), and create a separate token for every connected system. If a token has fallen into the wrong hands, delete it and create a new one.
!!!

## Permissions

Each token gets its permissions when it is created. If it lacks the permission for an address, the API answers with `403 scope_missing` and names the missing permission.

| Permission in X-Sitter | Technical name | Allows |
|---|---|---|
| Stock: read | `stock:read` | `GET /api/v1/stock`, `GET /api/v1/stock/{id}` |
| Articles: read | `articles:read` | `GET /api/v1/articles`, `GET /api/v1/articles/{id}` |
| Articles: create | `articles:create` | `POST /api/v1/articles` |
| Articles: change | `articles:update` | `PATCH /api/v1/articles/{id}` |
| Articles: delete | `articles:delete` | `DELETE /api/v1/articles/{id}` (logisticians only) |
| Storage locations: read / create / change / delete | `spots:read`, `spots:create`, `spots:update`, `spots:delete` | `/api/v1/spots` (logisticians only) |

In the German interface the groups are called *Artikel*, *Bestand* and *Lagerplätze*, the permissions *lesen*, *anlegen*, *ändern* and *löschen*.

## Logisticians and clients

X-Sitter distinguishes two kinds of companies:

- **Logistician:** runs the warehouse and manages the articles of its customers.
- **Client:** a customer of a logistician whose goods are stored and shipped there.

A token always works for the company it was created in. As a **client** you do not need to do anything else: you automatically see only your own articles and their stock.

As a **logistician** you can also use your token on behalf of one of your clients. Send the client's company number in the header `X-Company` (or in the parameter `company`). The permissions stay those of your token.

```bash
curl https://app.x-sitter.com/api/v1/stock \
  -H "Authorization: Bearer xst_YOUR_TOKEN" \
  -H "X-Company: 27"
```

## Fetching lists page by page

Addresses that return lists answer page by page. `page` selects the page, `per_page` the number of entries per page (default 25, at most 500). `meta` tells you how many entries and pages there are in total:

```json
"meta": { "page": 1, "per_page": 25, "total": 312, "total_pages": 13 }
```

Keep requesting the next page until `page` equals `total_pages`. You will find an example in the guide [Query stock](stock.md#step-5-fetch-all-pages).

## Errors

If something goes wrong, the API answers with a matching HTTP status and always the same structure:

```json
{
  "error": {
    "code": "scope_missing",
    "message": "The token has no right for stock:read.",
    "details": { "scope": "stock:read" }
  }
}
```

Evaluate the `code` in your program, not the text of the `message`. The text may change.

| Status | Meaning | Common codes |
|---|---|---|
| 400 | The request cannot be read, e.g. a parameter has the wrong format | `invalid_parameter`, `invalid_json`, `invalid_company` |
| 401 | No token sent, or it is unknown, locked or expired | `missing_token`, `invalid_token` |
| 403 | The token may not do this | `scope_missing`, `company_not_allowed`, `stock_not_visible` |
| 404 | There is nothing at this address | `article_not_found`, `spot_not_found`, `route_not_found` |
| 405 | The method does not fit the address (the header `Allow` names the allowed ones) | `method_not_allowed` |
| 409 | Not possible right now, e.g. the article number is already taken | `article_number_taken`, `spot_in_use` |
| 422 | A value in the request body is not accepted | `invalid_article_value`, `invalid_spot_value` |
| 500 | Error on the server | `internal_error` |

On a 500, try again after a short pause. If the error keeps coming back, contact support via **Create ticket** (*Ticket erstellen*) in the footer of X-Sitter and send the time, the address and the response (but never the token).
