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 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. |
DELETE /api/v1/organizations/{id} |
Yes, with a confirmation. | 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. |
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 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.
curl "https://acme.meetone.io/api/v1/organizations?external_id=crm-4711" \
-H "Authorization: Bearer $TOKEN"
{
"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, 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. |
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.
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 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.
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. |
{
"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. |
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}
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
curl -X DELETE "https://acme.meetone.io/api/v1/organizations/3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90" \
-H "Authorization: Bearer $TOKEN"
{
"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.
curl -X DELETE "https://acme.meetone.io/api/v1/organizations/3f6c1a52-8d4e-4b7a-9e21-5c0d7a4b1e90?confirm_permanent_deletion=true" \
-H "Authorization: Bearer $TOKEN"
{
"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
404for 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 secondDELETEfor the same organization returns404. - 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_idand 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
Questions? Contact us at support@meetone.io.