> For the complete documentation index, see [llms.txt](https://engyon.gitbook.io/engyon/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://engyon.gitbook.io/engyon/en/api/use-cases/creating-a-client.md).

# Creating a client

This use case shows how to set up a **client organisation** in Engyon via the API, including clients consisting of multiple legal entities, and how to assign users to that client.

On this page we use **Fictiva Holding** as an example client: a holding with a subsidiary, **Fictiva Subsidiary**.

**Required service account role:** API account manager (`api_account_manager`)

### Flow overview

1. (Optional) Look up industries and existing users/roles
2. Create the client organisation
3. Add subsidiaries (legal entities) under the client
4. Assign users to the client organisation

```mermaid
sequenceDiagram
    participant I as Integration
    participant API as Engyon API

    I->>API: POST /client-organisations/
    API-->>I: Client + root legal entity
    I->>API: POST /client-organisations/{id}/legal-entities/
    API-->>I: Subsidiary legal entity
    I->>API: POST /client-organisations/{id}/users/
    API-->>I: User assignment
```

### Requirements

| Data                  | Endpoint                                                 | Remarks                                                  |
| --------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| Industries (optional) | `GET /api/v1/industries/`                                | Use industry `id` values in `industry_ids`               |
| Existing users        | `GET /api/v1/users/`                                     | Users must already exist in Engyon; identified via email |
| Client roles          | `GET /api/v1/roles/?associated_model=ClientOrganisation` | Role names such as `client_manager` or `client_reader`   |

```bash
curl -X GET "https://audit.engyon.io/api/v1/industries/" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"

curl -X GET "https://audit.engyon.io/api/v1/roles/?associated_model=ClientOrganisation" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

### 1. Creating the client organisation

```
POST /api/v1/client-organisations/
```

#### Request fields

| Field                  | Type      | Required | Description                                                                                                                                                                                             |
| ---------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                   | string    | no       | External id. Unique within your audit firm. Cannot be changed after creation. If omitted, Engyon generates an id.                                                                                       |
| `name`                 | string    | yes      | Display name of the client                                                                                                                                                                              |
| `country`              | string    | yes      | ISO 3166-1 alpha-2 country code (for example `NL`)                                                                                                                                                      |
| `domains`              | string\[] | no       | Login domains for the organisation. Must be unique within Engyon.                                                                                                                                       |
| `number`               | string    | no       | Chamber of Commerce number / registration number                                                                                                                                                        |
| `allow_password_login` | boolean   | yes      | Whether users of this client are allowed to log in with email address and password                                                                                                                      |
| `industry_ids`         | string\[] | no       | External ids of industries                                                                                                                                                                              |
| `is_test_organisation` | boolean   | no       | If `true`, audits for this client do not consume credits and are deleted after a retention period. Forced to `true` if your audit firm itself is a test organisation. Cannot be changed after creation. |

#### Example

```bash
curl -X POST "https://audit.engyon.io/api/v1/client-organisations/" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "fictiva-holding",
    "name": "Fictiva Holding",
    "country": "NL",
    "domains": ["fictiva.example"],
    "number": "12345678",
    "allow_password_login": false,
    "is_test_organisation": true
  }'
```

#### Response (`201 Created`)

```json
{
  "id": "fictiva-holding",
  "name": "Fictiva Holding",
  "country": "NL",
  "domains": ["fictiva.example"],
  "number": "12345678",
  "allow_password_login": false,
  "industry_ids": [],
  "is_test_organisation": true
}
```

#### Important side effect: root legal entity

When a client organisation is created, Engyon automatically creates a ***root*****&#x20;legal entity** for that client with:

* the same **`id`** as the client organisation (`fictiva-holding` in the example)
* matching name, country, and registration number

You do **not** create the *root* legal entity yourself. You add subsidiaries in the next step; these must refer to an existing *parent* (usually this *root*).

#### Updating a client organisation

```
PATCH /api/v1/client-organisations/{client_organisation_id}/
```

You can update `name`, `country`, `domains`, `number`, `allow_password_login`, and `industry_ids`. You cannot change `id` or `is_test_organisation`.

{% hint style="warning" %}
When you include `domains` in a PATCH request, the list **fully replaces** the login domains of the organisation. Omit `domains` if you do not want to change them.
{% endhint %}

### 2. Adding legal entities (clients with multiple entities)

A client can consist of multiple legal entities — for example Fictiva Holding and Fictiva Subsidiary. Create each subsidiary under the client organisation.

```
POST /api/v1/client-organisations/{client_organisation_id}/legal-entities/
```

#### Request fields

| Field               | Type      | Required | Description                                                                                                    |
| ------------------- | --------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| `id`                | string    | no       | External id. Unique within the client organisation. Cannot be changed after creation.                          |
| `name`              | string    | yes      | Display name                                                                                                   |
| `country`           | string    | yes      | ISO 3166-1 alpha-2 country code                                                                                |
| `is_active`         | boolean   | no       | Default `true`                                                                                                 |
| `introduction_date` | date      | yes      | Date from when the entity is relevant (`YYYY-MM-DD`)                                                           |
| `termination_date`  | date      | no       | Optional end date                                                                                              |
| `parent_id`         | string    | yes      | External id of the parent legal entity within the same client (use the root client id for a direct subsidiary) |
| `industry_ids`      | string\[] | no       | External ids of industries                                                                                     |

#### Example — Adding Fictiva Subsidiary under Fictiva Holding

```bash
curl -X POST "https://audit.engyon.io/api/v1/client-organisations/fictiva-holding/legal-entities/" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "fictiva-dochter",
    "name": "Fictiva Subsidiary",
    "country": "NL",
    "introduction_date": "2020-01-01",
    "parent_id": "fictiva-holding"
  }'
```

#### Retrieving legal entities

```bash
curl -X GET "https://audit.engyon.io/api/v1/client-organisations/fictiva-holding/legal-entities/" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Accept: application/json"
```

You should at least see:

* `fictiva-holding` — the *root* legal entity
* `fictiva-dochter` — the subsidiary you created

#### Deletion rules

* Only **subsidiary** legal entities (with a *parent*) can be deleted.
* Deletion fails with `409 Conflict` if the legal entity is used in an audit.

### 3. Assigning users to the client organisation

Users must already exist in Engyon. The API assigns an existing user to the client; it does not invite a completely new person via email like the UI invitation flow sometimes does. The intended use is to assign users from your audit firm to the client.

```
POST /api/v1/client-organisations/{client_organisation_id}/users/
```

#### Request fields

| Field              | Type    | Required | Description                                                                                                                        |
| ------------------ | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `id`               | email   | yes      | Email address of the existing user                                                                                                 |
| `role`             | string  | yes      | App role for client organisations, for example `client_manager` or `client_reader`. Do **not** pass administrator role names here. |
| `is_administrator` | boolean | yes      | If `true`, the user also receives administrator rights on the client                                                               |

Available role names can be found with:

```
GET /api/v1/roles/?associated_model=ClientOrganisation
```

#### Example

```bash
curl -X POST "https://audit.engyon.io/api/v1/client-organisations/fictiva-holding/users/" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "id": "partner@example.com",
    "role": "client_manager",
    "is_administrator": true
  }'
```

#### Response (`201 Created`)

Typical fields include:

| Field              | Description                                                        |
| ------------------ | ------------------------------------------------------------------ |
| `id`               | User email                                                         |
| `name`             | Display name                                                       |
| `role`             | Assigned non-administrator role                                    |
| `is_administrator` | Whether administrator rights have been granted                     |
| `is_client`        | `true` if the user's primary organisation is a client organisation |
| `has_mfa_setup`    | Whether the user has set up MFA                                    |

#### Updating or deleting an assignment

| Method   | Path                                                 | Description                                              |
| -------- | ---------------------------------------------------- | -------------------------------------------------------- |
| `PATCH`  | `/api/v1/client-organisations/{id}/users/{user_id}/` | Update `role` and/or `is_administrator`                  |
| `DELETE` | `/api/v1/client-organisations/{id}/users/{user_id}/` | Remove the assignment (does not delete the user account) |

`{user_id}` is the user's email address (case-insensitive).

### Recommended sequence for Fictiva

1. Create client `fictiva-holding`
2. Create legal entity `fictiva-dochter` with `parent_id: "fictiva-holding"`
3. Assign the team members who need access at client level
4. Continue with [Creating an audit](/engyon/en/api/use-cases/creating-an-audit.md) with `client_organisation_id: "fictiva-holding"` and the correct `legal_entity_id`

### Related endpoints

| Method   | Path                                                                                      |
| -------- | ----------------------------------------------------------------------------------------- |
| `GET`    | `/api/v1/client-organisations/`                                                           |
| `POST`   | `/api/v1/client-organisations/`                                                           |
| `GET`    | `/api/v1/client-organisations/{client_organisation_id}/`                                  |
| `PATCH`  | `/api/v1/client-organisations/{client_organisation_id}/`                                  |
| `GET`    | `/api/v1/client-organisations/{client_organisation_id}/legal-entities/`                   |
| `POST`   | `/api/v1/client-organisations/{client_organisation_id}/legal-entities/`                   |
| `GET`    | `/api/v1/client-organisations/{client_organisation_id}/legal-entities/{legal_entity_id}/` |
| `PATCH`  | `/api/v1/client-organisations/{client_organisation_id}/legal-entities/{legal_entity_id}/` |
| `DELETE` | `/api/v1/client-organisations/{client_organisation_id}/legal-entities/{legal_entity_id}/` |
| `GET`    | `/api/v1/client-organisations/{client_organisation_id}/users/`                            |
| `POST`   | `/api/v1/client-organisations/{client_organisation_id}/users/`                            |
| `PATCH`  | `/api/v1/client-organisations/{client_organisation_id}/users/{user_id}/`                  |
| `DELETE` | `/api/v1/client-organisations/{client_organisation_id}/users/{user_id}/`                  |
