# Organizations endpoints

> Reference for listing, creating, updating and deleting organizations through the Scheduling API, including instance-token-only fields, settings, owners and the irreversible deletion flow.

Source: https://help.meetone.io/developers/scheduling-api/organizations-endpoints
Last updated: 2026-10-08

---

Organizations are the customer accounts on a MeetOne installation. These endpoints create and maintain them and, for instance tokens, delete them together with all of their data. Deleting an organization is irreversible; read [Delete an organization](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#delete-an-organization) before you use it.

The organizations endpoints exist only on installations with organizations. Elsewhere every one of them returns `404 Not Found`.

## Who can do what

| Endpoint | Instance token | Organization token |
|---|---|---|
| `GET /api/v1/organizations` | Every organization. | Only its own. |
| `GET /api/v1/organizations/{id}` | Any organization. | Its own; another organization returns `404`. |
| `POST /api/v1/organizations` | Yes. | `403` (`instance_token_required`). |
| `PATCH /api/v1/organizations/{id}` | All fields. | Its own, without the [instance-token-only fields](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#fields-only-instance-tokens-may-set). |
| `DELETE /api/v1/organizations/{id}` | Yes, with a [confirmation](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#delete-an-organization). | `403` (`instance_token_required`) for its own, `404` for any other. |

Read-only tokens can call the two `GET` endpoints only. Organization tokens cannot be created through the API; an administrator creates one for the organization under **Developer > API Tokens**.

## The organization object

| Field | Type | Description |
|---|---|---|
| `id` | string (uuid) | MeetOne's ID of the organization. |
| `external_id` | string, nullable | Your key. Unique within the installation. See [Identifiers](https://help.meetone.io/developers/scheduling-api/identifiers). |
| `name` | string, nullable | Name of the organization. |
| `first_name`, `last_name`, `email` | string, nullable | The contact person. |
| `address_street`, `address_street_number`, `address_zipcode`, `address_city` | string, nullable | The address. |
| `address_country` | string, nullable | ISO 3166-1 alpha-2 code, e.g. `DE`. |
| `billing_company`, `billing_company_addition`, `billing_first_name`, `billing_last_name`, `billing_email`, `billing_address_street`, `billing_address_street_number`, `billing_zipcode`, `billing_city`, `billing_country`, `billing_vat_id` | string, nullable | The billing contact and address. The billing contact defaults to the contact person. |
| `owners` | array | The users who own the organization, each with `id`, `external_id` and `email`. |
| `settings` | object | The [organization settings](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#settings) the API exposes. |
| `plan_handle` | string | The plan the organization is on. |
| `seats` | integer | Practitioner seats of the plan. |
| `seats_used` | integer | Practitioners currently using a seat. |
| `subscription_active` | boolean | Whether the organization may use the platform (trial, contract or subscription). |
| `trial_active`, `contract_active` | boolean | Whether the organization is in a trial or under a contract. |
| `trial_ends_at`, `contract_started_at`, `contract_ends_at` | string (date-time), nullable | The dates of the trial and the contract. |
| `features` | array of strings | Features enabled for the organization, e.g. `appointment_booking`. |
| `custom_domain`, `theme` | string, nullable | The organization's own domain and its theme. |
| `consent_accepted_at` | string (date-time), nullable | When the organization accepted the privacy policy and terms. |
| `created_at`, `updated_at` | string (date-time) | Timestamps. |

## List and show organizations

`GET /api/v1/organizations` and `GET /api/v1/organizations/{id}`

The list accepts `external_id`, `updated_since`, `page` and `per_page`. See [Errors & pagination](https://help.meetone.io/developers/getting-started/errors-and-pagination).

```bash
curl "https://acme.meetone.io/api/v1/organizations?external_id=crm-4711" \
  -H "Authorization: Bearer $TOKEN"
```

```json
{
  "data": [
    {
      "id": "3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90",
      "external_id": "crm-4711",
      "name": "Praxis Dr. Muster",
      "first_name": "Maria",
      "last_name": "Muster",
      "email": "maria.muster@praxis-muster.example",
      "address_street": "Hauptstraße",
      "address_street_number": "1",
      "address_zipcode": "12345",
      "address_city": "Musterstadt",
      "address_country": "DE",
      "billing_company": null,
      "billing_company_addition": null,
      "billing_first_name": "Maria",
      "billing_last_name": "Muster",
      "billing_email": "maria.muster@praxis-muster.example",
      "billing_address_street": null,
      "billing_address_street_number": null,
      "billing_zipcode": null,
      "billing_city": null,
      "billing_country": null,
      "billing_vat_id": null,
      "owners": [
        { "id": "b7d2e9c4-1a3f-4c58-8e66-2f9a0d7c5b13", "external_id": "staff-12", "email": "maria.muster@praxis-muster.example" }
      ],
      "settings": {
        "planner_day_start_hour": 8,
        "planner_day_end_hour": 18,
        "booking_min_lead_time_hours": null,
        "appointment_booking_show_avatar": false,
        "appointment_booking_show_personal_message": false,
        "appointment_booking_personal_message": null,
        "appointment_booking_personal_message_style": "info",
        "role_terminology": null
      },
      "plan_handle": "custom",
      "seats": 1,
      "seats_used": 1,
      "subscription_active": true,
      "trial_active": true,
      "trial_ends_at": "2026-10-22T12:00:00+02:00",
      "contract_active": false,
      "contract_started_at": null,
      "contract_ends_at": null,
      "features": ["appointment_booking"],
      "custom_domain": null,
      "theme": null,
      "consent_accepted_at": "2026-10-08T12:00:00+02:00",
      "created_at": "2026-10-08T12:00:00+02:00",
      "updated_at": "2026-10-08T12:00:00+02:00"
    }
  ]
}
```

## Create an organization

`POST /api/v1/organizations`

Instance tokens only. The body takes the contact, address and billing fields of the organization object, the `settings`, the [instance-token-only fields](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#fields-only-instance-tokens-may-set), and two extras that are not part of the object:

| Field | Type | Description |
|---|---|---|
| `consent_accepted` | boolean | Set `true` when the organization accepted the privacy policy and terms. Stamps `consent_accepted_at`. |
| `owner` | object | Creates the organization's first account. See [The owner](https://help.meetone.io/developers/scheduling-api/organizations-endpoints#the-owner). |

A billing contact is required. It defaults to the contact person, so send `first_name`, `last_name` and `email`, or the `billing_*` fields. Without contract data (`contract_active`), the organization starts in a trial; `trial_ends_at` defaults to the end of the installation's trial period.

```bash
curl -X POST "https://acme.meetone.io/api/v1/organizations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "crm-4711",
    "name": "Praxis Dr. Muster",
    "first_name": "Maria",
    "last_name": "Muster",
    "email": "maria.muster@praxis-muster.example",
    "address_street": "Hauptstraße",
    "address_street_number": "1",
    "address_zipcode": "12345",
    "address_city": "Musterstadt",
    "address_country": "DE",
    "features": ["appointment_booking"],
    "consent_accepted": true,
    "settings": { "planner_day_start_hour": 8, "planner_day_end_hour": 18 },
    "owner": {
      "email": "maria.muster@praxis-muster.example",
      "first_name": "Maria",
      "last_name": "Muster",
      "external_id": "staff-12",
      "notification": "invitation"
    }
  }'
```

A successful request returns `201 Created` with the organization in the shape shown above. The whole request is one transaction: if the owner or a setting is invalid, no organization is created.

### The owner

With `owner`, the organization gets its first account: a practitioner (`doctor`) who owns the organization. Without `owner` the organization has no owner; you can add owners later through the [users API](https://help.meetone.io/developers/scheduling-api/users-endpoints) with `organization_owner: true`.

| Field | Type | Required | Description |
|---|---|---|---|
| `email` | string | Yes | The owner's email address. Unique across the installation. |
| `first_name`, `last_name` | string | Yes | The owner's name. |
| `external_id` | string | No | Your key for the owner. |
| `notification` | string (enum) | No | How the owner hears about the account: `none` (default), `invitation` or `welcome`. |

| `notification` | What happens |
|---|---|
| `none` | The owner receives nothing. Your system tells them. |
| `invitation` | The invitation email of the admin area, with a sign-in link. |
| `welcome` | The welcome email of the website sign-up. |

Errors in the owner are reported under `owner.`, for example `owner.email` with the code `taken`, or `owner.notification` with the code `inclusion`.

## Update an organization

`PATCH /api/v1/organizations/{id}`

Send only the fields you want to change. An organization token can update its own organization; an instance token can update any organization and all fields.

```bash
curl -X PATCH "https://acme.meetone.io/api/v1/organizations/3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "billing_city": "Berlin",
    "settings": { "booking_min_lead_time_hours": 12 }
  }'
```

The response is `200 OK` with the updated organization. Changing the plan or the number of seats is billed exactly like a change made in the admin area. If the billing refuses it, the response is `422` and the error `code` names the reason: `ineligible` (plan not available for this organization), `invalid_seats`, `seats_below_used` (fewer seats than active practitioners), `no_change`, or `no_renewal` (a decrease needs a scheduled renewal).

### Fields only instance tokens may set

An organization token that sends one of these fields in a `PATCH` receives `403 Forbidden` with the code `attribute_forbidden`, and the `attribute` names the field. Nothing is changed.

| Field | Description |
|---|---|
| `external_id` | Your key for the organization. |
| `plan_handle`, `seats` | The plan and the number of practitioner seats. |
| `trial_active`, `trial_ends_at` | The trial. |
| `contract_active`, `contract_started_at`, `contract_ends_at` | The contract. |
| `features` | The features enabled for the organization, as an array. It replaces the current list. Only features the installation lets organizations have are accepted; anything else returns `422` with the code `invalid_features`. |
| `custom_domain`, `theme` | The organization's own domain and theme. |

```json
{
  "errors": [
    { "code": "attribute_forbidden", "attribute": "seats", "message": "Only an instance API token can set this attribute." }
  ]
}
```

Read-only fields are `id`, `owners`, `seats_used`, `subscription_active`, `consent_accepted_at`, `created_at` and `updated_at`.

### Settings

`settings` carries the settings the API exposes. Send only the settings you want to change; `null` resets one to the installation's default. Both token types can change them.

| Setting | Type | Description |
|---|---|---|
| `planner_day_start_hour` | integer 0-23, nullable | Start of the working day. Availabilities must lie within the working day. |
| `planner_day_end_hour` | integer 0-23, nullable | End of the working day. Must be later than the start. |
| `booking_min_lead_time_hours` | integer, 0 or more, nullable | How many hours ahead a slot has to be booked. See [Free slots and booking](https://help.meetone.io/developers/scheduling-api/availability-slots-and-booking). |
| `appointment_booking_show_avatar` | boolean | Online booking page: show the practitioner's avatar. |
| `appointment_booking_show_personal_message` | boolean | Online booking page: show a personal message. |
| `appointment_booking_personal_message` | string, nullable | The personal message. |
| `appointment_booking_personal_message_style` | string (enum) | `info`, `warning` or `error`. |
| `role_terminology` | string, nullable | The words the app uses for the two roles of an appointment, one of the presets the installation offers, e.g. `counseling`. |

A key that is not in this table returns `422` with the code `unsupported_setting` and the attribute `settings.<key>`; an invalid value returns `422` with the code `invalid`, or `after_start_hour` when the working day would end before it starts.

## Delete an organization

`DELETE /api/v1/organizations/{id}`

> **Warning**
>
> **Deleting an organization is irreversible.** It permanently deletes the organization and everything in it: its users, patients, appointments and video rooms, availabilities, questionnaires, messages, documents and its **clinical documentation** (medical records, observations, attachments and prescriptions). Nothing can be restored afterwards.
>
> **Legal retention obligations are yours.** Clinical documentation is usually subject to statutory retention periods. In Germany, treatment documentation has to be kept for at least ten years (§ 630f BGB). MeetOne does not check whether a retention period has expired. Export and archive everything you are required to keep before you delete, and do not send the confirmation until you have.

Instance tokens only. An organization token cannot delete its own organization (`403`, `instance_token_required`) and gets `404` for any other.

What the request does depends on whether the organization holds data and whether you confirmed:

| Situation | Response |
|---|---|
| The organization has no data at all: no users, appointments or other records. | `204 No Content`. It is deleted at once, no confirmation needed. |
| It has data, and the request has no `confirm_permanent_deletion=true`. | `409 Conflict` with the code `deletion_confirmation_required`. Nothing is changed. |
| It has data, and the request has `confirm_permanent_deletion=true`. | `202 Accepted`. Deletion starts. |

### Step 1: the request without confirmation

```bash
curl -X DELETE "https://acme.meetone.io/api/v1/organizations/3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90" \
  -H "Authorization: Bearer $TOKEN"
```

```json
{
  "errors": [
    {
      "code": "deletion_confirmation_required",
      "attribute": null,
      "message": "Deleting this organization permanently deletes all of its data, including its users, appointments and clinical documentation, and cannot be undone. Legal retention obligations, for example for clinical documentation, are your responsibility. To proceed, send confirm_permanent_deletion=true."
    }
  ]
}
```

### Step 2: the confirmed request

`confirm_permanent_deletion` is a query parameter. Sending it means you accept that all data will be deleted and that you have met your retention obligations.

```bash
curl -X DELETE "https://acme.meetone.io/api/v1/organizations/3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90?confirm_permanent_deletion=true" \
  -H "Authorization: Bearer $TOKEN"
```

```json
{
  "data": {
    "id": "3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90",
    "deletion_requested_at": "2026-10-08T14:30:00+02:00"
  }
}
```

### What happens after 202

- **At once.** The organization is marked for deletion and hidden. From then on the API answers `404` for it, its organization tokens stop working (`401`), and its users can no longer sign in; their sessions end. It is invisible to every token, also to an Instance API Token that lists across organizations: its users, appointments, availabilities and other records no longer appear. A second `DELETE` for the same organization returns `404`.
- **In the background.** MeetOne first removes the organization's API tokens and webhook endpoints, then deletes everything else it holds (appointments and video rooms, scheduling data, clinical documentation, messages, documents), erases its users, and finally deletes the organization itself. If a step fails, the deletion is retried and the organization stays hidden in the meantime.
- **A record of the deletion.** MeetOne keeps a record without personal data: the organization's `id`, `external_id` and name, the name of the API token that requested the deletion, the number of users and appointments, and when the deletion was requested and completed.

## Related

- [Scheduling API overview](https://help.meetone.io/developers/scheduling-api/overview)
- [Identifiers](https://help.meetone.io/developers/scheduling-api/identifiers)
- [Users endpoints](https://help.meetone.io/developers/scheduling-api/users-endpoints)
- [Authentication & API tokens](https://help.meetone.io/developers/getting-started/authentication-api-tokens)

Questions? Contact us at [support@meetone.io](mailto:support@meetone.io).
