Kwazi 1.0.0. Base URL: https://your-site.example/wp-json/kwazi/v1 (authentication). The OpenAPI document of your own site (GET /openapi.json) also lists your custom fields under ContactFields and OrganizationFields.
Audit log
GET /audit-log — Find audit log entries
Lists the audit log, newest first: who did what through which channel (app, API key, AI agent, system), with the key or agent by name. Kept 12 months. Returns at most limit items and a next_cursor.
Permission: kwazi_manage_integrations · Ability: kwazi/find-audit-entries
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
channel |
query | string (app, portal, api, ability, form, booking, import, email, system) | no | |
action |
query | string (max. 60) | no | |
cursor |
query | string (max. 64) | no | |
per_page |
query | integer (1–100) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
Booking (public)
POST /booking/book — Book an appointment as a website visitor (honeypot, time token, rate limit).
Public: no login (website visitors).
Answers: 201. Errors: error shape.
POST /booking/manage — Open an appointment with the token from its manage link.
Public: no login (website visitors).
Answers: 200. Errors: error shape.
POST /booking/manage/cancel — Cancel an appointment with the token from its manage link.
Public: no login (website visitors).
Answers: 200. Errors: error shape.
POST /booking/manage/reschedule — Move an appointment with the token from its manage link.
Public: no login (website visitors).
Answers: 200. Errors: error shape.
GET /booking/services — Services that can be booked online, for the booking widget.
Public: no login (website visitors).
Answers: 200. Errors: error shape.
GET /booking/slots — Free times of a service, for the booking widget.
Public: no login (website visitors).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
service |
query | string (uuid) | yes | |
staff |
query | integer (1–) | no | |
from |
query | string | no | |
to |
query | string | no |
Answers: 200. Errors: error shape.
Booking: appointments
GET /appointments — Find appointments
Lists appointments with their client: in a period of local days (from, to; at most 62 days) and/or of one contact (contact id), by start time; or everything changed since a moment (updated_since) in pages of limit with a next_cursor. Optionally one staff member (user id) and statuses (pending, confirmed, declined, cancelled, completed, no_show). With "only own" visibility a staff member only gets their own calendar.
Permission: kwazi_view_contacts · Ability: kwazi/find-appointments
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from |
query | string | no | |
to |
query | string | no | |
staff |
query | integer (1–) | no | |
status |
query | array of string (pending, confirmed, declined, cancelled, completed, no_show, pending_payment) | no | |
contact |
query | string (uuid) | no | |
updated_since |
query | string (date-time) | no | Polling: appointments changed at or after this moment (ISO 8601), in pages with per_page and cursor. |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
POST /appointments — Book an appointment
Books an appointment for a contact at a free start time from kwazi/get-available-slots. Without staff the least busy free staff member gets it. If the time was taken meanwhile, the error lists the nearest free times.
Permission: kwazi_manage_bookings · Ability: kwazi/book-appointment
| Body field | Type | Description |
|---|---|---|
contact |
string (uuid) | |
service |
string (uuid) | |
staff |
integer or null | |
starts_at |
string (date-time) | ISO 8601 with a time zone, e.g. 2026-10-19T08:00:00Z. |
notes |
string (max. 2000) | |
outside_hours |
boolean | Book outside working hours on purpose (never over another appointment). |
location_type |
string (in_person, client, phone, online) | |
location |
string (max. 255) | |
meeting_url |
string (max. 2048) | |
status |
string (confirmed, pending) |
Answers: 201: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
GET /appointments/{id} — Get an appointment
Returns one appointment with its service, staff member, client (name, email, phone), time, place and status.
Permission: kwazi_view_contacts · Ability: kwazi/get-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
PATCH /appointments/{id} — Update the note of an appointment
Replaces the internal note of an appointment (for the team only, never shown to the client).
Permission: kwazi_manage_bookings · Ability: kwazi/update-appointment-note
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
notes |
string (max. 2000) |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/cancel — Cancel an appointment
Cancels an appointment that is pending or confirmed. The client gets an email (and a calendar cancellation); the reason is internal and never sent to the client. It cannot be undone: book again if needed.
Permission: kwazi_manage_bookings · Ability: kwazi/cancel-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
reason |
string (max. 500) |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/complete — Mark an appointment as completed
Marks an appointment that has started as completed. No email is sent.
Permission: kwazi_manage_bookings · Ability: kwazi/complete-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/confirm — Confirm an appointment request
Confirms an appointment that waits for confirmation (status pending). The client gets an email with a calendar file and a link to cancel or move.
Permission: kwazi_manage_bookings · Ability: kwazi/confirm-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/decline — Decline an appointment request
Declines an appointment that waits for confirmation. The time is free again and the client gets an email; the reason is internal and never sent to the client.
Permission: kwazi_manage_bookings · Ability: kwazi/decline-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
reason |
string (max. 500) |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/no-show — Mark an appointment as no-show
Marks that the client did not come to an appointment that has started. No email is sent.
Permission: kwazi_manage_bookings · Ability: kwazi/mark-no-show
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/place — Change where an appointment takes place
Changes the place of a pending or confirmed appointment: location_type in_person (location = address; empty = the address of the service), client (location = the client’s address, required), phone (the client’s phone number) or online (meeting_url, http/https; empty = the staff member’s link). The client gets an email with the new place, a calendar file once confirmed and a new manage link.
Permission: kwazi_manage_bookings · Ability: kwazi/change-appointment-place
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
location_type |
string (in_person, client, phone, online) | |
location |
string (max. 255) | |
meeting_url |
string (max. 2048) |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
POST /appointments/{id}/reschedule — Move an appointment
Moves an appointment to another free time (starts_at, ISO 8601 with time zone; see kwazi/get-available-slots) and optionally another staff member (user id). outside_hours: true allows a time outside working hours, never over another appointment. The client gets an email with the new time and a new manage link.
Permission: kwazi_manage_bookings · Ability: kwazi/reschedule-appointment
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
starts_at |
string (date-time) | |
staff |
integer (1–) | |
outside_hours |
boolean |
Answers: 200: id, status, service, staff, contact, starts_at, ends_at, location, meeting_url, notes, source, submission, cancel_reason, created_at, updated_at. Errors: error shape.
GET /calendar — Get the calendar
Returns per staff member the working hours of each day (after time off, closures and extra hours) and the appointments that are not cancelled or declined, for local days from..to (at most 62 days). Use it to see who is free or busy on a day.
Permission: kwazi_view_contacts · Ability: kwazi/get-calendar
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from |
query | string | no | |
to |
query | string | no | |
staff |
query | integer (1–) | no |
Answers: 200: timezone, staff, appointments. Errors: error shape.
GET /slots — Get free times
Lists free start times (ISO 8601 UTC) for a service between two local days (at most 62 days apart), with the staff members free at each. Leave staff out for anyone who does the service.
Permission: kwazi_view_contacts · Ability: kwazi/get-available-slots
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
service |
query | string (uuid) | yes | |
staff |
query | integer (1–) | no | |
from |
query | string | no | |
to |
query | string | no |
Answers: 200. Errors: error shape.
Booking: services
GET /services — List services
Lists the bookable services: length, buffers, price (shown only), location (in_person, client, phone, online), confirmation (auto or review) and the user ids of the staff who do them.
Permission: kwazi_view_contacts · Ability: kwazi/list-services
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
include_archived |
query | boolean | no |
Answers: 200. Errors: error shape.
POST /services — Create a service
Creates a bookable service. name and duration_min are required; staff lists the user ids who do it.
Permission: kwazi_manage_crm · Ability: kwazi/create-service
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
description |
string (max. 2000) | |
duration_min |
integer (1–1440) | |
buffer_before |
integer (0–) | Minutes kept free before, only against other appointments; not shown to clients. |
buffer_after |
integer (0–) | |
price |
string or null | For example "45" or "45.50"; shown only. |
location_type |
string (in_person, client, phone, online) | |
location_details |
string (max. 255) | |
confirmation |
string (auto, review) | auto confirms online bookings at once; review keeps them pending until the team confirms. |
bookable_online |
boolean | |
min_notice_min |
integer or null | |
max_advance_days |
integer or null | |
sort_order |
integer | |
staff |
array of integer | WordPress user ids of the staff members who do it (see kwazi/list-staff). |
Answers: 201: id, name, description, duration_min, buffer_before, buffer_after, price, location_type, location_details, confirmation, bookable_online, min_notice_min, max_advance_days, form_id, sort_order, staff, archived, created_at, updated_at. Errors: error shape.
GET /services/{id} — Get a service
Returns one service, also when it is archived.
Permission: kwazi_view_contacts · Ability: kwazi/get-service
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, name, description, duration_min, buffer_before, buffer_after, price, location_type, location_details, confirmation, bookable_online, min_notice_min, max_advance_days, form_id, sort_order, staff, archived, created_at, updated_at. Errors: error shape.
PATCH /services/{id} — Update a service
Changes the given settings of a service; archived: false brings an archived service back. Existing appointments keep what they were booked with.
Permission: kwazi_manage_crm · Ability: kwazi/update-service
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
description |
string (max. 2000) | |
duration_min |
integer (1–1440) | |
buffer_before |
integer (0–) | Minutes kept free before, only against other appointments; not shown to clients. |
buffer_after |
integer (0–) | |
price |
string or null | For example "45" or "45.50"; shown only. |
location_type |
string (in_person, client, phone, online) | |
location_details |
string (max. 255) | |
confirmation |
string (auto, review) | auto confirms online bookings at once; review keeps them pending until the team confirms. |
bookable_online |
boolean | |
min_notice_min |
integer or null | |
max_advance_days |
integer or null | |
sort_order |
integer | |
staff |
array of integer | WordPress user ids of the staff members who do it (see kwazi/list-staff). |
archived |
boolean |
Answers: 200: id, name, description, duration_min, buffer_before, buffer_after, price, location_type, location_details, confirmation, bookable_online, min_notice_min, max_advance_days, form_id, sort_order, staff, archived, created_at, updated_at. Errors: error shape.
DELETE /services/{id} — Archive a service
Archives a service: it can no longer be booked, its appointments and history stay. Undo with kwazi/update-service and archived: false.
Permission: kwazi_manage_crm · Ability: kwazi/archive-service
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, name, description, duration_min, buffer_before, buffer_after, price, location_type, location_details, confirmation, bookable_online, min_notice_min, max_advance_days, form_id, sort_order, staff, archived, created_at, updated_at. Errors: error shape.
Booking: team
GET /closures — List closures
Lists the days or hours the whole business is closed (holidays, closing days).
Permission: kwazi_view_contacts · Ability: kwazi/list-closures
Answers: 200. Errors: error shape.
POST /closures — Close the business for a day or a period
Adds time off (type closed) or extra hours (type extra, needs start and end) for a staff member, for one day or a period, all day or between two times. Without user_id it closes the whole business (managers only).
Permission: kwazi_manage_bookings · Ability: kwazi/add-time-off
Answers: 201. Errors: error shape.
DELETE /exceptions/{id} — Remove time off
Removes time off, extra hours or a closure of the business. Only use this when the user explicitly asks.
Permission: kwazi_manage_bookings · Ability: kwazi/remove-time-off
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
GET /staff — List staff
Lists the staff members the user may see, with their weekly hours, the services they do and their meeting link for online appointments.
Permission: kwazi_view_contacts · Ability: kwazi/list-staff
Answers: 200. Errors: error shape.
POST /staff — Invite a staff member
Adds someone to the team by name, email address and role (staff by default; kwazi_admin; site_admin only by a website admin). A new address becomes a WordPress user with that role, who gets an email to choose a password; an existing user gets the role added (other roles stay; needs the right to promote that user). Confirm with the user first.
Permission: kwazi_manage_crm · Ability: kwazi/invite-staff
| Body field | Type | Description |
|---|---|---|
name |
string (max. 100) | |
email |
string (max. 190) | |
role |
string (site_admin, kwazi_admin, staff) | Default staff. A Kwazi admin gives staff or kwazi_admin; only a website admin gives site_admin. |
Answers: 200: user_id, created · 201: user_id, created. Errors: error shape.
GET /staff/invitations — List team invitations
Lists the invitations to the team that wait until the person accepts them: name, email address, role and until when the link works.
Permission: kwazi_manage_crm · Ability: kwazi/list-invitations
Answers: 200. Errors: error shape.
DELETE /staff/invitations/{id} — Revoke a team invitation
Withdraws an invitation that waits; its link stops working.
Permission: kwazi_manage_crm · Ability: kwazi/revoke-invitation
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string | yes |
Answers: 204. Errors: error shape.
PATCH /staff/{user} — Update a staff member
Sets the name clients see (1 to 100 characters), the fixed meeting link of a staff member (http or https; empty clears it) and/or replaces the services they do (service ids; managers only). Staff members may change their own name and link.
Permission: kwazi_manage_bookings · Ability: kwazi/update-staff
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
name |
string (max. 100) | |
meeting_url |
string (max. 2048) | |
services |
array of string (uuid) |
Answers: 200: user_id, name, hours, services, meeting_url, role, sees, invited, name_is_login, access, roles_you_can_give, can_remove, can_rename. Errors: error shape.
DELETE /staff/{user} — Remove a team member
Removes someone from the team. The successor (another team member) takes over their contacts, organizations and appointments; refused when one of those appointments falls on one of the successor’s. The account is deleted when it has nothing else on the website, else it only loses its Kwazi role. Cannot be undone; confirm with the user first.
Permission: kwazi_manage_crm · Ability: kwazi/remove-staff
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
Answers: 200: deleted, access_left. Errors: error shape.
GET /staff/{user}/exceptions — Time off and extra hours of a staff member
Returns the weekly hours of a staff member and their time off and extra hours.
Permission: kwazi_view_contacts · Ability: kwazi/get-staff-schedule
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
Answers: 200. Errors: error shape.
POST /staff/{user}/exceptions — Add time off or extra hours
Adds time off (type closed) or extra hours (type extra, needs start and end) for a staff member, for one day or a period, all day or between two times. Without user_id it closes the whole business (managers only).
Permission: kwazi_manage_bookings · Ability: kwazi/add-time-off
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
date_from |
string | |
date_to |
string | |
start |
string or null | |
end |
string or null | |
type |
string (closed, extra) | |
label |
string (max. 190) |
Answers: 201: id, user_id, date_from, date_to, start, end, type, label, appointments. Errors: error shape.
GET /staff/{user}/hours — Weekly hours of a staff member
Returns the weekly hours of a staff member and their time off and extra hours.
Permission: kwazi_view_contacts · Ability: kwazi/get-staff-schedule
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
Answers: 200. Errors: error shape.
PUT /staff/{user}/hours — Set working hours
Replaces the weekly working hours of a staff member. Weekdays left out have no hours. Staff members may set their own; managers anyone’s.
Permission: kwazi_manage_bookings · Ability: kwazi/update-staff-hours
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
hours |
object | Per ISO weekday ("1" = Monday … "7" = Sunday) a list of ["09:00", "12:00"] blocks, local time of the business. |
Answers: 200: 1, 2, 3, 4, 5, 6, 7. Errors: error shape.
PUT /staff/{user}/role — Set the role of a team member
Gives a team member one of three roles: site_admin (everything on the website and in Kwazi), kwazi_admin (everything in Kwazi, nothing else on the website) or staff (the rights of Settings → Roles). A Kwazi admin never gives or changes site_admin; nobody lowers their own role or removes the last website admin.
Permission: kwazi_manage_crm · Ability: kwazi/set-staff-role
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
user |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
role |
string (site_admin, kwazi_admin, staff) |
Answers: 200: user_id, name, hours, services, meeting_url, role, sees, invited, name_is_login, access, roles_you_can_give, can_remove, can_rename. Errors: error shape.
GET /team — List the team
Lists the people who can own contacts (WordPress users with access to Kwazi), with their user id. Use the id as owner_user_id when assigning a contact.
Permission: kwazi_view_contacts · Ability: kwazi/list-team
Answers: 200. Errors: error shape.
Booking: website
GET /booking-widget/embed — Get the embed codes of the booking widget
Returns a shortcode and block markup for the booking widget (all services bookable online, or only one service and/or one staff member) the pages that already show a booking widget (used_on) and the booking page on its own (booking_page: its address, or null while it is off). Visitors cannot book online yet when used_on is empty and booking_page is null. Put it on a page with kwazi/embed-booking-in-page.
Permission: kwazi_view_contacts · Ability: kwazi/get-booking-embed
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
service |
query | string (uuid) | no | |
staff |
query | integer (1–) | no |
Answers: 200: shortcode, block, used_on, booking_page. Errors: error shape.
POST /booking-widget/embed-in-page — Put the booking widget on a page
Adds the booking widget at the end of an existing page or post (page_id), or creates a new page with it (new_page_title). A new page is always a draft: tell the user to review and publish it (edit_url). Only works for pages the user may edit.
Permission: kwazi_manage_crm · Ability: kwazi/embed-booking-in-page
| Body field | Type | Description |
|---|---|---|
service |
string (uuid) | |
staff |
integer (1–) | WordPress user id of a staff member (see kwazi/list-staff). |
page_id |
integer (1–) | |
new_page_title |
string (max. 190) | |
publish |
boolean | Publish a new page right away (needs publish_pages; otherwise a draft). Not available through the ability. |
Answers: 200: page_id, status, edit_url, created. Errors: error shape.
Contacts
GET /contacts — Find contacts
Searches contacts (people) by name, email or phone, and filters by status, tag, owner, organization, source (see kwazi/list-contact-sources), last change, an appointment in a period, or no appointment since a moment (who has not been in since…). Returns at most limit contacts and a next_cursor for the next page. Only contacts the user may see are returned.
Permission: kwazi_view_contacts · Ability: kwazi/find-contacts
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
search |
query | string (max. 100) | no | |
status |
query | string (lead, customer, inactive) | no | |
marketing |
query | string (none, pending, subscribed, unsubscribed) | no | |
tag |
query | string (max. 100) | no | |
owner |
query | integer (1–) | no | |
organization |
query | string (uuid) | no | |
source |
query | string (max. 50) | no | |
appointment_from |
query | string (date-time) | no | With an appointment (not cancelled or declined) starting at or after this moment. |
appointment_to |
query | string (date-time) | no | With an appointment starting before this moment. |
no_appointment_since |
query | string (date-time) | no | Without an appointment (not cancelled or declined) since this moment, also who never had one. |
updated_since |
query | string (date-time) | no | |
created_since |
query | string (date-time) | no | |
include_deleted |
query | boolean | no | |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
POST /contacts — Create a contact
Creates a contact. Needs at least a name, an email address or a phone number. Fails with kwazi_duplicate and the existing id when the email address is already used: update that contact instead.
Permission: kwazi_edit_contacts · Ability: kwazi/create-contact
| Body field | Type | Description |
|---|---|---|
first_name |
string (max. 100) | |
last_name |
string (max. 100) | |
email |
string (max. 190) | |
phone |
string (max. 50) | |
status |
string (lead, customer, inactive) | |
source |
string (max. 50) | |
owner_user_id |
integer or null (1–) | |
tags |
array of string (max. 100) | |
fields |
object | Custom field values by field key; see kwazi/list-fields. |
Answers: 201: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /contacts/duplicates — Find duplicate contacts
Checks whether a contact with this email address already exists, before creating one. Only the email address makes two contacts the same; names and phone numbers may repeat. A match the user may not see is reported without an id.
Permission: kwazi_view_contacts · Ability: kwazi/find-duplicates
| Body field | Type | Description |
|---|---|---|
email |
string (max. 190) |
Answers: 200. Errors: error shape.
GET /contacts/sources — List contact sources
Lists where contacts came from (the source of each contact, e.g. a form, a fair or an import), alphabetically. Use one to filter kwazi/find-contacts.
Permission: kwazi_view_contacts · Ability: kwazi/list-contact-sources
Answers: 200. Errors: error shape.
GET /contacts/{id} — Get a contact
Returns one contact with its custom fields, tags, the organizations it belongs to and its most recent timeline entries (notes, changes, bookings). Use the id from kwazi/find-contacts.
Permission: kwazi_view_contacts · Ability: kwazi/get-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
PATCH /contacts/{id} — Update a contact (fills empty values; ?mode=overwrite overwrites)
Enriches or corrects a contact. By default (mode fill_empty) only empty values are filled and tags are added; existing values are never overwritten. Use mode overwrite only when the user asks to replace values. Every change is logged with old and new values.
Permission: kwazi_edit_contacts · Ability: kwazi/update-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
mode |
string (fill_empty, overwrite) |
Answers: 200. Errors: error shape.
DELETE /contacts/{id} — Delete a contact
Moves a contact to the trash. It can be restored with kwazi/restore-contact until the trash is emptied. Only use this when the user explicitly asks to delete.
Permission: kwazi_delete_contacts · Ability: kwazi/delete-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
GET /contacts/{id}/activities — Get the timeline of a contact
Returns timeline entries of a contact, newest first: notes, changes (with old and new values, channel and actor), links with organizations. Use next_cursor to page back in time.
Permission: kwazi_view_contacts · Ability: kwazi/get-contact-timeline
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes | |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
GET /contacts/{id}/consents — Get the consents of a contact
Returns what a contact agreed to, oldest first: purpose (e.g. privacy, newsletter), the text exactly as the person saw it, when, and whether it was verified (confirmed by email). Consent from a public form is not verified.
Permission: kwazi_view_contacts · Ability: kwazi/get-contact-consents
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200. Errors: error shape.
POST /contacts/{id}/marketing/request — Ask a contact for marketing consent
Mails the contact a confirmation link; only after the person clicks it is the contact subscribed to marketing (double opt-in). Needs an email address; one mail per day at most. For an unsubscribed contact, a reason is required (e.g. "asked by phone on 14/10"). Never tell the user someone is subscribed before they confirmed.
Permission: kwazi_edit_contacts · Ability: kwazi/request-marketing-consent
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
reason |
string (max. 255) |
Answers: 200: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /contacts/{id}/marketing/unsubscribe — Unsubscribe a contact from marketing
Unsubscribes the contact from all marketing, at once. The address is remembered (as a hash), also if the contact is deleted later, so it is never subscribed again without the person confirming by email.
Permission: kwazi_edit_contacts · Ability: kwazi/unsubscribe-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /contacts/{id}/merge — Merge two contacts
Merges contact other_id into contact id when they are the same person. id wins: only its empty values are filled from other_id. Tags, organizations, timeline, consents, submissions and appointments move to id; values of other_id that differ are kept in the "merged" timeline entry. other_id is deleted for good. Only use this when the user explicitly asks to merge.
Permission: kwazi_delete_contacts · Ability: kwazi/merge-contacts
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
other_id |
string (uuid) |
Answers: 200: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /contacts/{id}/notes — Add a note to a contact
Adds a plain-text note to the timeline of a contact, e.g. a call summary or a follow-up reminder.
Permission: kwazi_edit_contacts · Ability: kwazi/add-note
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
body |
string (max. 65535) |
Answers: 201: type, subject, body, data, channel, actor_label, user_id, contact, created_at. Errors: error shape.
GET /contacts/{id}/organizations — Organizations a contact belongs to, with the role
Returns one contact with its custom fields, tags, the organizations it belongs to and its most recent timeline entries (notes, changes, bookings). Use the id from kwazi/find-contacts.
Permission: kwazi_view_contacts · Ability: kwazi/get-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200. Errors: error shape.
POST /contacts/{id}/restore — Restore a contact
Takes a contact out of the trash, with its fields, tags, links and timeline.
Permission: kwazi_delete_contacts · Ability: kwazi/restore-contact
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, first_name, last_name, email, phone, status, marketing, marketing_updated_at, source, owner_user_id, tags, fields, organization, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
Custom fields
GET /field-groups — Groups of custom fields
Lists the custom fields of contacts or organizations (key, label, type, choices) and their groups. Use the keys in the fields object of create and update abilities.
Permission: kwazi_view_contacts · Ability: kwazi/list-fields
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
entity |
query | string (contact, organization, submission) | yes |
Answers: 200. Errors: error shape.
POST /field-groups — Create a field group
Adds a group, e.g. "Billing", to show related custom fields together on screens.
Permission: kwazi_manage_crm · Ability: kwazi/create-field-group
| Body field | Type | Description |
|---|---|---|
entity |
string (contact, organization, submission) | |
label |
string (max. 190) |
Answers: 201: id, entity, label, sort_order. Errors: error shape.
PATCH /field-groups/{id} — Update a field group
Renames a field group or changes its position among the other groups.
Permission: kwazi_manage_crm · Ability: kwazi/update-field-group
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
label |
string (max. 190) | |
sort_order |
integer (0–) |
Answers: 200: id, entity, label, sort_order. Errors: error shape.
DELETE /field-groups/{id} — Delete a field group
Deletes a field group. Its fields stay and simply lose their group. Only use this when the user explicitly asks to delete.
Permission: kwazi_manage_crm · Ability: kwazi/delete-field-group
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
GET /fields — Custom fields of contacts or organizations
Lists the custom fields of contacts or organizations (key, label, type, choices) and their groups. Use the keys in the fields object of create and update abilities.
Permission: kwazi_view_contacts · Ability: kwazi/list-fields
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
entity |
query | string (contact, organization, submission) | yes | |
include_archived |
query | boolean | no |
Answers: 200. Errors: error shape.
POST /fields — Create a custom field
Adds a custom field to contacts or organizations. The key is derived from the label and never changes. Types: text, long_text, email, phone, url, number, date, dropdown, choices, checkbox. Dropdown and choices need options.
Permission: kwazi_manage_crm · Ability: kwazi/create-field
| Body field | Type | Description |
|---|---|---|
entity |
string (contact, organization, submission) | |
type |
string (text, long_text, email, phone, url, number, date, dropdown, choices, checkbox) | |
label |
string (max. 190) | |
options |
array of string (max. 190) | Choices, for dropdown and choices fields. |
group |
string or null (uuid) | |
show_in_list |
boolean |
Answers: 201: id, entity, key, label, type, options, group, sort_order, source, show_in_list, archived, created_at. Errors: error shape.
PATCH /fields/{id} — Update a custom field
Changes the label, choices, group, order or list visibility of a custom field, or archives it (archived: true). Archiving hides the field but keeps its values; archived: false brings it back. Key and type never change.
Permission: kwazi_manage_crm · Ability: kwazi/update-field
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
label |
string (max. 190) | |
options |
array of string (max. 190) | Choices, for dropdown and choices fields. |
group |
string or null (uuid) | |
show_in_list |
boolean | |
sort_order |
integer (0–) | |
archived |
boolean |
Answers: 200: id, entity, key, label, type, options, group, sort_order, source, show_in_list, archived, created_at. Errors: error shape.
DELETE /fields/{id} — Archive a custom field (its values are kept)
Changes the label, choices, group, order or list visibility of a custom field, or archives it (archived: true). Archiving hides the field but keeps its values; archived: false brings it back. Key and type never change.
Permission: kwazi_manage_crm · Ability: kwazi/update-field
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200. Errors: error shape.
Exports
GET /exports/audit-log.csv — Export the audit log
Exports the audit log as CSV text (UTF-8, header row first), optionally for one channel or action. The export itself is recorded in the audit log.
Permission: kwazi_manage_integrations · Ability: kwazi/export-audit-log
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
channel |
query | string (app, portal, api, ability, form, booking, import, email, system) | no | |
action |
query | string (max. 60) | no |
Answers: 200 (CSV). Errors: error shape.
GET /exports/contacts.csv — Export contacts
Exports the contacts matching the filters as CSV text (UTF-8, header row first), with the same filters as kwazi/find-contacts. Only contacts the user may see are included.
Permission: kwazi_export_contacts · Ability: kwazi/export-contacts
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
search |
query | string (max. 100) | no | |
status |
query | string (lead, customer, inactive) | no | |
marketing |
query | string (none, pending, subscribed, unsubscribed) | no | |
tag |
query | string (max. 100) | no | |
owner |
query | integer (1–) | no | |
organization |
query | string (uuid) | no | |
source |
query | string (max. 50) | no | |
appointment_from |
query | string (date-time) | no | With an appointment (not cancelled or declined) starting at or after this moment. |
appointment_to |
query | string (date-time) | no | With an appointment starting before this moment. |
no_appointment_since |
query | string (date-time) | no | Without an appointment (not cancelled or declined) since this moment, also who never had one. |
created_since |
query | string (date-time) | no | |
ids |
query | array of string (uuid) | no | |
separator |
query | string (,, 😉 | no |
Answers: 200 (CSV). Errors: error shape.
GET /exports/organizations.csv — Export organizations
Exports the organizations matching the filters as CSV text (UTF-8, header row first): name, VAT number, contact details, address, owner, number of linked contacts and custom fields.
Permission: kwazi_export_contacts · Ability: kwazi/export-organizations
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
search |
query | string (max. 100) | no | |
owner |
query | integer (1–) | no | |
separator |
query | string (,, 😉 | no |
Answers: 200 (CSV). Errors: error shape.
GET /exports/submissions.csv — Export form submissions
Exports the form submissions the user may see as CSV, one column per submitted value, filtered by form and status.
Permission: kwazi_manage_forms · Ability: kwazi/export-submissions
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
form |
query | integer (1–) | no | |
status |
query | string (received, spam) | no | |
separator |
query | string (,, 😉 | no |
Answers: 200 (CSV). Errors: error shape.
Forms
GET /forms — List forms
Lists every form with its status (publish or draft), its definition, the pages that show it and the number of submissions received and blocked as spam in the last 30 days.
Permission: kwazi_view_contacts · Ability: kwazi/list-forms
Answers: 200. Errors: error shape.
POST /forms — Create a form
Creates a form, as a draft unless status is publish. Give a definition, or a template key from kwazi/list-form-templates (fields the template needs are created). Each field element needs a target from the field library (e.g. contact.first_name, contact.email, submission.fields.message; see kwazi/list-fields). A consent element with marketing: true asks the visitor to confirm by email before they are subscribed. Put it on a page with kwazi/embed-in-page. Leave notify.emails empty: the user adds notification addresses in the app.
Permission: kwazi_manage_forms · Ability: kwazi/create-form
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
status |
string (draft, publish) | |
definition |
object | elements (field, heading, paragraph, consent), submit_label, after_submit, notify, new_contacts. A field element links to a target such as contact.email or contact.fields.<key>; a consent element with marketing: true asks for confirmation by email. |
template |
string (max. 50) |
Answers: 201: id, name, status, definition, submissions_30d, spam_30d, used_on, booking, created_at, updated_at. Errors: error shape.
GET /forms/templates — List form templates
Lists ready-made forms (contact, quote request, callback request, newsletter) with their definition. Create one with kwazi/create-form and the template key.
Permission: kwazi_manage_forms · Ability: kwazi/list-form-templates
Answers: 200. Errors: error shape.
GET /forms/{id} — Get a form
Returns one form with its full definition: elements (fields linked to contact, organization or submission fields, headings, paragraphs, consents), the button text, what happens after sending and who is notified.
Permission: kwazi_view_contacts · Ability: kwazi/get-form
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 200: id, name, status, definition, submissions_30d, spam_30d, used_on, booking, created_at, updated_at. Errors: error shape.
PATCH /forms/{id} — Update a form
Changes the name, the status (publish or draft) and/or the definition of a form. A definition replaces the whole previous one: send every element again. Notification addresses (notify.emails) can be kept or removed here, not added: the user adds those in the app.
Permission: kwazi_manage_forms · Ability: kwazi/update-form
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
status |
string (draft, publish) | |
definition |
object | elements (field, heading, paragraph, consent), submit_label, after_submit, notify, new_contacts. A field element links to a target such as contact.email or contact.fields.<key>; a consent element with marketing: true asks for confirmation by email. |
Answers: 200: id, name, status, definition, submissions_30d, spam_30d, used_on, booking, created_at, updated_at. Errors: error shape.
DELETE /forms/{id} — Delete a form
Moves a form to the trash; its submissions stay. Pages that show it will no longer show a form. Only use this when the user explicitly asks to delete.
Permission: kwazi_manage_forms · Ability: kwazi/delete-form
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 204. Errors: error shape.
POST /forms/{id}/duplicate — Duplicate a form
Makes a draft copy of a form, with " (copy)" after the name.
Permission: kwazi_manage_forms · Ability: kwazi/duplicate-form
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 201: id, name, status, definition, submissions_30d, spam_30d, used_on, booking, created_at, updated_at. Errors: error shape.
GET /forms/{id}/embed — Get the embed codes of a form
Returns a shortcode (works in any editor) and block markup (block editor) to show a form on a page.
Permission: kwazi_view_contacts · Ability: kwazi/get-embed
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 200: shortcode, block. Errors: error shape.
POST /forms/{id}/embed-in-page — Put a form on a page
Adds the form at the end of an existing page or post (page_id), or creates a new page with it (new_page_title). A new page is always a draft: tell the user to review and publish it (edit_url). Only works for pages the user may edit.
Permission: kwazi_manage_forms · Ability: kwazi/embed-in-page
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
| Body field | Type | Description |
|---|---|---|
page_id |
integer (1–) | |
new_page_title |
string (max. 190) |
Answers: 200: page_id, status, edit_url, created · 201: page_id, status, edit_url, created. Errors: error shape.
POST /forms/{id}/submit — Submit a published form as a website visitor (honeypot, time token, rate limit).
Public: no login (website visitors).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 200. Errors: error shape.
GET /forms/{id}/token — A fresh time token for a published form (pages served from a cache).
Public: no login (website visitors).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | integer | yes |
Answers: 200. Errors: error shape.
Imports
POST /imports — Upload a CSV import
Uploads CSV text (max. 5 MB, header row first) to import contacts. Nothing is imported yet: the result shows the columns, a guessed mapping and a preview. Check the mapping with the user, then call kwazi/start-import.
Permission: kwazi_import_contacts · Ability: kwazi/create-import
| Body field | Type | Description |
|---|---|---|
file_name |
string (max. 190) | |
csv |
string (max. 5242880) |
Answers: 201: id, file_name, status, headers, mapping, options, preview, totals, errors, created_at, finished_at. Errors: error shape.
GET /imports/{id} — Get an import
Returns the status, totals and first errors of a CSV import.
Permission: kwazi_import_contacts · Ability: kwazi/get-import
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, file_name, status, headers, mapping, options, preview, totals, errors, created_at, finished_at. Errors: error shape.
PATCH /imports/{id} — Correct the column mapping and options of an import
Imports the rows of an uploaded CSV, optionally with a corrected mapping and options. duplicates: fill_empty (default; only fills empty values of an existing contact with the same email address), skip or overwrite. tag is added to every imported contact. Large files continue in the background; check with kwazi/get-import.
Permission: kwazi_import_contacts · Ability: kwazi/start-import
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200. Errors: error shape.
GET /imports/{id}/errors.csv — The rows of an import that failed, with the reason
Returns the status, totals and first errors of a CSV import.
Permission: kwazi_import_contacts · Ability: kwazi/get-import
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200 (CSV). Errors: error shape.
POST /imports/{id}/start — Start an import
Imports the rows of an uploaded CSV, optionally with a corrected mapping and options. duplicates: fill_empty (default; only fills empty values of an existing contact with the same email address), skip or overwrite. tag is added to every imported contact. Large files continue in the background; check with kwazi/get-import.
Permission: kwazi_import_contacts · Ability: kwazi/start-import
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
mapping |
array of string | Target per column, in column order: first_name, last_name, email, phone, status, source, tags, fields.<key>, or "" to skip the column. |
options |
object |
Answers: 200: id, file_name, status, headers, mapping, options, preview, totals, errors, created_at, finished_at. Errors: error shape.
Marketing (public)
POST /marketing/confirm — Confirm a marketing subscription with the token from the email (double opt-in).
Public: no login (website visitors).
| Body field | Type | Description |
|---|---|---|
token |
string (max. 200) |
Answers: 200. Errors: error shape.
POST /marketing/unsubscribe — Unsubscribe from marketing with the token from an email.
Public: no login (website visitors).
| Body field | Type | Description |
|---|---|---|
token |
string (max. 200) |
Answers: 200. Errors: error shape.
Organizations
GET /organizations — Find organizations
Searches organizations (companies, associations…) by name, VAT number, email or city. Returns at most limit organizations and a next_cursor for the next page.
Permission: kwazi_view_contacts · Ability: kwazi/find-organizations
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
search |
query | string (max. 100) | no | |
updated_since |
query | string (date-time) | no | |
owner |
query | integer (1–) | no | |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
POST /organizations — Create an organization
Creates an organization. Needs a name. VAT numbers are stored without spaces or dots; a website without https:// gets it added.
Permission: kwazi_edit_contacts · Ability: kwazi/create-organization
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
vat_number |
string (max. 30) | |
email |
string (max. 190) | |
phone |
string (max. 50) | |
website |
string (max. 2048) | |
address_line |
string (max. 255) | |
postal_code |
string (max. 20) | |
city |
string (max. 100) | |
country |
string (max. 2) | ISO 3166-1 alpha-2 code, e.g. BE. |
owner_user_id |
integer or null (1–) | |
fields |
object | Custom field values by field key; see kwazi/list-fields. |
Answers: 201: id, name, vat_number, email, phone, website, address_line, postal_code, city, country, owner_user_id, fields, contacts_count, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /organizations/duplicates — Find similar organizations
Before creating an organization: lists existing ones with the same name (ignoring legal forms such as BV, NV, SRL or GmbH, case and punctuation), the same VAT number or the same email address, each with its reasons. Creating a similar one is still allowed, e.g. for a second branch.
Permission: kwazi_view_contacts · Ability: kwazi/find-organization-duplicates
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
vat_number |
string (max. 30) | |
email |
string (max. 190) |
Answers: 200. Errors: error shape.
GET /organizations/possible-duplicates — List possible duplicate organizations
Lists pairs of organizations that may be the same (same name without legal form, VAT number or email address), oldest first, at most 100. Pairs marked with kwazi/dismiss-organization-duplicate are left out. Merge a real duplicate with kwazi/merge-organizations.
Permission: kwazi_view_contacts · Ability: kwazi/list-organization-duplicates
Answers: 200. Errors: error shape.
GET /organizations/{id} — Get an organization
Returns one organization with its custom fields and the people linked to it (with their role). Only people the user may see are listed.
Permission: kwazi_view_contacts · Ability: kwazi/get-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, name, vat_number, email, phone, website, address_line, postal_code, city, country, owner_user_id, fields, contacts_count, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
PATCH /organizations/{id} — Update an organization (fills empty values; ?mode=overwrite overwrites)
Enriches or corrects an organization. By default (mode fill_empty) only empty values are filled; existing values are never overwritten. Use mode overwrite only when the user asks to replace values.
Permission: kwazi_edit_contacts · Ability: kwazi/update-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
mode |
string (fill_empty, overwrite) |
Answers: 200. Errors: error shape.
DELETE /organizations/{id} — Delete an organization
Moves an organization to the trash. Its people stay. It can be restored with kwazi/restore-organization. Only use this when the user explicitly asks to delete.
Permission: kwazi_delete_contacts · Ability: kwazi/delete-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
GET /organizations/{id}/activities — Get the timeline of an organization
Returns the timeline of an organization and of the people linked to it, newest first. Each entry about a person names that person. Use next_cursor to page back in time.
Permission: kwazi_view_contacts · Ability: kwazi/get-organization-timeline
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes | |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
GET /organizations/{id}/contacts — People linked to an organization, with their role
Returns one organization with its custom fields and the people linked to it (with their role). Only people the user may see are listed.
Permission: kwazi_view_contacts · Ability: kwazi/get-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200. Errors: error shape.
PUT /organizations/{id}/contacts/{contact_id} — Link a contact to an organization, with a role
Links a person to an organization with an optional role (e.g. Owner, Accountant), or changes the role of an existing link. is_primary marks the main organization of that person.
Permission: kwazi_edit_contacts · Ability: kwazi/link-contact-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes | |
contact_id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
DELETE /organizations/{id}/contacts/{contact_id} — Unlink a contact from an organization
Removes the link between a person and an organization. Both stay; the timeline keeps a record of the link.
Permission: kwazi_edit_contacts · Ability: kwazi/unlink-contact-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes | |
contact_id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
POST /organizations/{id}/merge — Merge two organizations
Merges organization other_id into organization id when they are the same. id wins: only its empty values are filled from other_id. People, timeline and submissions move to id; values of other_id that differ are kept in the "merged" timeline entry. other_id is deleted for good. Only use this when the user explicitly asks to merge.
Permission: kwazi_delete_contacts · Ability: kwazi/merge-organizations
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
other_id |
string (uuid) |
Answers: 200: id, name, vat_number, email, phone, website, address_line, postal_code, city, country, owner_user_id, fields, contacts_count, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
POST /organizations/{id}/not-duplicate — Mark organizations as different
Marks two organizations as not the same (e.g. two branches with one VAT number), so the pair no longer appears in kwazi/list-organization-duplicates.
Permission: kwazi_edit_contacts · Ability: kwazi/dismiss-organization-duplicate
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
other_id |
string (uuid) |
Answers: 204. Errors: error shape.
POST /organizations/{id}/restore — Restore an organization
Takes an organization out of the trash, with its links to people and its custom fields.
Permission: kwazi_delete_contacts · Ability: kwazi/restore-organization
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, name, vat_number, email, phone, website, address_line, postal_code, city, country, owner_user_id, fields, contacts_count, last_activity, created_at, updated_at, deleted_at. Errors: error shape.
Overview
GET /overview — Get the overview
Returns what is going on: today’s appointments (how many are still to come), the requests waiting for confirmation (soonest 5 and the total), new contacts and form submissions of the last 7 days, and the 10 newest timeline entries with their contact. Only what the user may see. Use it to answer "what is on today?" or "anything new?".
Permission: kwazi_view_contacts · Ability: kwazi/get-overview
Answers: 200: today, requests, new_contacts, submissions, activity. Errors: error shape.
Privacy
POST /privacy/erase — Erase personal data
Permanently erases the person with this email address and everything linked to them (GDPR erasure request). This cannot be undone and skips the trash. Only use this when the user explicitly asks to erase someone’s data.
Permission: kwazi_manage_crm · Ability: kwazi/erase-personal-data
| Body field | Type | Description |
|---|---|---|
email |
string (email; max. 190) |
Answers: 200: erased. Errors: error shape.
POST /privacy/personal-data — Export personal data
Returns everything Kwazi holds about the person with this email address (GDPR access request): contact details, custom fields, tags, organizations, timeline and consents, also from the trash. Returns null when there is nobody with that address.
Permission: kwazi_manage_crm · Ability: kwazi/export-personal-data
| Body field | Type | Description |
|---|---|---|
email |
string (email; max. 190) |
Answers: 200. Errors: error shape.
Settings
GET /settings/api-access — Get who may use application passwords
Returns the roles that may reach Kwazi with an application password (they skip two-factor login), and the roles to choose from. Other plugins are not affected.
Permission: kwazi_manage_integrations · Ability: kwazi/get-api-access
Answers: 200: roles, available. Errors: error shape.
PATCH /settings/api-access — Change who may use application passwords
Sets the roles that may reach Kwazi with an application password. A change of rights: hidden from MCP by default.
Permission: kwazi_manage_integrations · Ability: kwazi/update-api-access
| Body field | Type | Description |
|---|---|---|
roles |
array of string |
Answers: 200: roles, available. Errors: error shape.
GET /settings/booking — Get the booking settings
Returns the booking settings: grid of start times, notice and horizon for visitors, how long before the start a visitor may still cancel, reminders, terms and the default form for the details step. The business details are in kwazi/get-general-settings.
Permission: kwazi_view_contacts · Ability: kwazi/get-booking-settings
Answers: 200: slot_step, min_notice_min, max_advance_days, cancel_notice_hours, late_cancel_text, reminder_enabled, reminder_hours, terms_text, default_confirmation, client_changes, max_open_bookings, form_id. Errors: error shape.
PATCH /settings/booking — Update the booking settings
Changes the booking settings that are given; anything left out stays. A service can set its own notice, horizon and form instead. Business details are changed with kwazi/update-general-settings.
Permission: kwazi_manage_crm · Ability: kwazi/update-booking-settings
| Body field | Type | Description |
|---|---|---|
slot_step |
integer (0–240) | Minutes between start times (0 = the length of the service; otherwise at least 5). |
min_notice_min |
integer (0–43200) | Default earliest start for visitors, in minutes from now. |
max_advance_days |
integer (1–730) | Default latest start for visitors, in days from now. |
cancel_notice_hours |
integer (0–720) | Visitors may cancel or move until this many hours before the start. |
late_cancel_text |
string (max. 1000) | Shown to a visitor when it is too late to cancel or move (empty = a standard text). |
reminder_enabled |
boolean | Send one reminder email before each confirmed appointment. |
reminder_hours |
integer (1–168) | How many hours before the start the reminder goes out. |
terms_text |
string (max. 1000) | Plain text above the book button, e.g. a cancellation fee (empty = none). |
default_confirmation |
string (auto, review) | Confirmation mode of a new service that sets none: auto (confirmed at once) or review (the team confirms each request). |
client_changes |
boolean | Visitors may cancel and move online with the link in their mail (until cancel_notice_hours before the start). |
max_open_bookings |
integer (0–50) | Upcoming appointments (requested or confirmed) one contact can book online; 0 = no maximum. The team can always book more. |
form_id |
integer | Default form for the details step (see kwazi/list-forms); it must have a required email field. |
Answers: 200: slot_step, min_notice_min, max_advance_days, cancel_notice_hours, late_cancel_text, reminder_enabled, reminder_hours, terms_text, default_confirmation, client_changes, max_open_bookings, form_id. Errors: error shape.
GET /settings/form-style — Get the style of forms
Returns the site style of forms and the booking widget: font, sizes, weights, colours (hex), radius and the submit button (icon, width). A property that is missing follows the theme. A form can override any property in its definition (style).
Permission: kwazi_view_contacts · Ability: kwazi/get-form-style
Answers: 200: font, size, color, label_size, label_weight, label_style, label_transform, label_color, heading_size, heading_weight, heading_color, field_background, field_border, field_text, field_radius, focus_color, button_background, button_text, button_radius, button_weight, button_transform, button_decoration, button_width, button_icon, button_icon_position, error_color, background, container. Errors: error shape.
PATCH /settings/form-style — Change the style of forms
Changes the site style of forms and the booking widget; only the properties sent change, "" or null puts one back to the theme. Colours are hex (#rrggbb), sizes whole pixels. Mind the contrast between text and background.
Permission: kwazi_manage_crm · Ability: kwazi/update-form-style
| Body field | Type | Description |
|---|---|---|
font |
string or null | theme, system-sans, system-serif, system-mono, kwazi:inter, kwazi:lora, kwazi:merriweather, kwazi:montserrat, kwazi:nunito, or theme:<slug> for a font of the theme. |
size |
integer or string or null (12–24) | |
color |
string or null | |
label_size |
integer or string or null (12–24) | |
label_weight |
integer or string or null (400, 500, 600, 700, ) | |
label_style |
string or string or null (normal, italic, ) | |
label_transform |
string or string or null (none, uppercase, ) | |
label_color |
string or null | |
heading_size |
integer or string or null (16–40) | |
heading_weight |
integer or string or null (400, 500, 600, 700, ) | |
heading_color |
string or null | |
field_background |
string or null | |
field_border |
string or null | |
field_text |
string or null | |
field_radius |
integer or string or null (0–24) | |
focus_color |
string or null | |
button_background |
string or null | |
button_text |
string or null | |
button_radius |
integer or string or null (0–40) | |
button_weight |
integer or string or null (400, 500, 600, 700, ) | |
button_transform |
string or string or null (none, uppercase, ) | |
button_decoration |
string or string or null (none, underline, ) | |
button_width |
string or string or null (auto, full, ) | |
button_icon |
string or string or null (arrow-right, chevron-right, send, check, check-circle, calendar, clock, mail, phone, message, user, users, download, heart, star, sparkles, gift, ticket, lock, plus, ) | |
button_icon_position |
string or string or null (left, right, ) | |
error_color |
string or null | |
background |
string or null | |
container |
string or string or null (card, plain, ) |
Answers: 200: font, size, color, label_size, label_weight, label_style, label_transform, label_color, heading_size, heading_weight, heading_color, field_background, field_border, field_text, field_radius, focus_color, button_background, button_text, button_radius, button_weight, button_transform, button_decoration, button_width, button_icon, button_icon_position, error_color, background, container. Errors: error shape.
GET /settings/general — Get the general settings
Returns the business details (name, email for clients, phone, VAT number, address), the currency of prices, the trusted proxy header, and the time zone and first day of the week of WordPress.
Permission: kwazi_manage_crm · Ability: kwazi/get-general-settings
Answers: 200: business, reply_to, currency, country, countries, ip_header, ip_headers, ip_headers_seen, timezone, week_start. Errors: error shape.
PATCH /settings/general — Change the general settings
Changes the business details, the currency, the country for phone numbers and/or the trusted proxy header that are given. The email for clients cannot be changed this way. The proxy header decides the rate limits of public forms: hidden from MCP by default.
Permission: kwazi_manage_crm · Ability: kwazi/update-general-settings
| Body field | Type | Description |
|---|---|---|
business |
object | |
currency |
string | Currency of prices (ISO 4217), e.g. EUR. |
country |
string (BE, NL, FR, DE, AT, CH, GB, ) | Country of the business (ISO 3166-1 alpha-2): imported and submitted phone numbers starting with 0 get its calling code. Empty keeps numbers as typed. |
ip_header |
string | Proxy header with the visitor’s address (e.g. HTTP_CF_CONNECTING_IP), or empty for the direct connection. Only choose one of a proxy the site is surely behind: anyone can send these headers. |
Answers: 200: business, reply_to, currency, country, countries, ip_header, ip_headers, ip_headers_seen, timezone, week_start. Errors: error shape.
GET /settings/portal — Get portal settings
Returns the staff portal settings: its path and address, whether staff stay out of wp-admin, required two-factor login, sign-out after inactivity, logo and "Powered by Kwazi", plus the active 2FA plugin and login protection.
Permission: kwazi_manage_crm · Ability: kwazi/get-portal-settings
Answers: 200: path, staff_out, require_2fa, idle_hours, logo_id, powered_by, booking_page, host, url, pretty_urls, path_status, logo_url, two_factor, login_protection, site_admin, booking_url, host_reachable, host_https, host_checked_at, host_active. Errors: error shape.
PATCH /settings/portal — Change portal settings
Changes the portal settings that are given. Security settings (two-factor login, wp-admin access, sign-out): hidden from MCP by default.
Permission: kwazi_manage_crm · Ability: kwazi/update-portal-settings
| Body field | Type | Description |
|---|---|---|
path |
string (max. 50) | Path of the portal on the site, e.g. kwazi for /kwazi/: lower-case letters, digits and hyphens. A path a page, post or other route uses cannot be chosen. |
staff_out |
boolean | Users with only the Kwazi staff role are sent from wp-admin to the portal. |
require_2fa |
boolean | Everyone with a Kwazi role needs active two-factor login (from a 2FA plugin) for the app, the portal and the API through a browser login. |
idle_hours |
integer (1, 8, 24) | Sign a Kwazi user out after this many hours without a request. |
logo_id |
integer or null | Image from the media library for the portal, its login screen and the booking page; null = the business name. |
powered_by |
boolean | Show a small "Powered by Kwazi" on the booking widget and page, the portal login and client emails. Off unless turned on. |
booking_page |
boolean | The booking widget on its own page without the theme, at the portal path + /book (or /book on the portal host). Off unless turned on. |
host |
string (max. 253) | Own (sub)domain of the portal, e.g. team.example.com; "" for none. The portal moves there once kwazi/check-portal-host passed. |
Answers: 200: path, staff_out, require_2fa, idle_hours, logo_id, powered_by, booking_page, host, url, pretty_urls, path_status, logo_url, two_factor, login_protection, site_admin, booking_url, host_reachable, host_https, host_checked_at, host_active. Errors: error shape.
POST /settings/portal/check-host — Check the portal host
Checks that the portal host (its own subdomain) reaches this site and has valid HTTPS. When both pass, the portal moves to that host; until then it stays on its path.
Permission: kwazi_manage_crm · Ability: kwazi/check-portal-host
Answers: 200: path, staff_out, require_2fa, idle_hours, logo_id, powered_by, booking_page, host, url, pretty_urls, path_status, logo_url, two_factor, login_protection, site_admin, booking_url, host_reachable, host_https, host_checked_at, host_active. Errors: error shape.
GET /settings/portal/path — Check a portal path
Whether a path can be the address of the staff portal: null when free, otherwise invalid, reserved (a WordPress path) or in_use (a page, post or other route).
Permission: kwazi_manage_crm · Ability: kwazi/check-portal-path
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
path |
query | string (max. 100) | yes |
Answers: 200: path, status, url. Errors: error shape.
GET /settings/privacy — Get the privacy settings
Returns how long Kwazi keeps spam, the webhook log, the audit log and deleted contacts (in days), and whether deleting the plugin deletes all Kwazi data too.
Permission: kwazi_manage_crm · Ability: kwazi/get-privacy-settings
Answers: 200: delete_on_uninstall, retention. Errors: error shape.
PATCH /settings/privacy — Change the privacy settings
Sets whether deleting the plugin deletes all Kwazi data and tables too. Hidden from MCP by default: it decides about all data.
Permission: kwazi_manage_crm · Ability: kwazi/update-privacy-settings
| Body field | Type | Description |
|---|---|---|
delete_on_uninstall |
boolean |
Answers: 200: delete_on_uninstall, retention. Errors: error shape.
GET /settings/roles — Get roles and visibility
Returns what each role may do in Kwazi (its Kwazi capabilities) and which records it sees (all, or only its own contacts and appointments), plus the roles that can be added. The administrator is fixed. Needs the right to give users roles.
Permission: kwazi_manage_crm · Ability: kwazi/get-roles
Answers: 200: roles, available. Errors: error shape.
PATCH /settings/roles/{role} — Change a role
Sets the Kwazi capabilities of a role (all of them; an empty list takes the role out of Kwazi) and/or which records it sees. Every capability needs kwazi_view_contacts; you can only give rights you have. A change of rights: hidden from MCP by default.
Permission: kwazi_manage_crm · Ability: kwazi/update-role
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
role |
path | string | yes |
| Body field | Type | Description |
|---|---|---|
capabilities |
array of string (kwazi_manage_crm, kwazi_view_contacts, kwazi_edit_contacts, kwazi_delete_contacts, kwazi_import_contacts, kwazi_export_contacts, kwazi_manage_bookings, kwazi_manage_forms, kwazi_manage_integrations) | |
visibility |
string (all, own) | all: every contact and appointment; own: contacts the user owns and appointments with them. |
Answers: 200: roles, available. Errors: error shape.
GET /settings/telemetry — Get what is shared with Kwazi
Whether anonymous usage statistics and the company profile are shared with Kwazi (both off unless the site owner turned them on in the app), and exactly what the statistics would send. Consent can only be given or taken by a person in the app.
Permission: kwazi_manage_crm · Ability: kwazi/get-telemetry
Answers: 200: stats, profile, profile_data, last_sent, live, payload. Errors: error shape.
PATCH /settings/telemetry — Give or take consent to share with Kwazi (only from the app: consent comes from a person, not an integration or AI assistant)
| Body field | Type | Description |
|---|---|---|
stats |
boolean | Share anonymous usage statistics once a week. |
profile |
boolean | Share the company profile for product news (a confirmation email comes first). |
profile_data |
object | company, website, name, email, sector, team_size. |
Answers: 200. Errors: error shape.
Submissions
GET /submissions — Find form submissions
Lists form submissions, newest first, filtered by form and status (received or spam). Only submissions of contacts the user may see are returned. Returns at most limit items and a next_cursor.
Permission: kwazi_view_contacts · Ability: kwazi/find-submissions
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
form |
query | integer (1–) | no | |
status |
query | string (received, spam) | no | |
contact |
query | string (uuid) | no | |
per_page |
query | integer (1–100) | no | |
cursor |
query | string (max. 64) | no | |
created_since |
query | string (date-time) | no | Only submissions received at or after this moment (ISO 8601). Submissions do not change after they are sent, so poll on this. |
Answers: 200: items, next_cursor, total. Errors: error shape.
GET /submissions/{id} — Get a form submission
Returns one form submission: the values as sent, the linked contact and organization, the page it came from and, for spam, why it was blocked.
Permission: kwazi_view_contacts · Ability: kwazi/get-submission
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, form, status, result, contact, organization, values, page, spam_reason, error, created_at. Errors: error shape.
DELETE /submissions/{id} — Delete a form submission
Permanently deletes a form submission. The contact it created stays. Only use this when the user explicitly asks to delete.
Permission: kwazi_manage_forms · Ability: kwazi/delete-submission
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
POST /submissions/{id}/not-spam — Mark a submission as not spam
Takes a submission out of spam and processes it as if it came in normally: the contact is created or filled in.
Permission: kwazi_manage_forms · Ability: kwazi/mark-submission-not-spam
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, form, status, result, contact, organization, values, page, spam_reason, error, created_at. Errors: error shape.
Tags
GET /tags — List tags
Lists every tag with its slug. Use a slug to filter kwazi/find-contacts, or a name to tag a contact.
Permission: kwazi_view_contacts · Ability: kwazi/list-tags
Answers: 200. Errors: error shape.
POST /tags — Create a tag (or get the existing one with the same slug)
Creates a tag, or returns the existing tag with the same slug. Tags are also created automatically when you tag a contact.
Permission: kwazi_edit_contacts · Ability: kwazi/create-tag
Answers: 200: name, slug · 201: name, slug. Errors: error shape.
This document
GET /openapi.json — This document: the OpenAPI 3.1 description of this installation
Answers: 200. Errors: error shape.
Webhooks
GET /webhook-deliveries/{id} — Get a webhook delivery
Returns one delivery: the body as sent, its status, attempts, last HTTP status and error, and when it is tried again.
Permission: kwazi_manage_integrations · Ability: kwazi/get-webhook-delivery
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, event, event_id, status, attempts, response_code, error, duration_ms, next_attempt_at, created_at, delivered_at, payload. Errors: error shape.
POST /webhook-deliveries/{id}/resend — Resend a webhook delivery
Tries a delivery again right away, with a fresh signature, and returns the result.
Permission: kwazi_manage_integrations · Ability: kwazi/resend-webhook-delivery
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, event, event_id, status, attempts, response_code, error, duration_ms, next_attempt_at, created_at, delivered_at, payload. Errors: error shape.
GET /webhooks — List webhooks
Lists every webhook with its address, events, whether it is on, and why it paused (20 failures in a row, or an unreadable secret). Secrets are never returned.
Permission: kwazi_manage_integrations · Ability: kwazi/list-webhooks
Answers: 200. Errors: error shape.
POST /webhooks — Create a webhook
Subscribes an https address to public events. Returns the signing secret once. Hidden from MCP by default: only run it when the site owner asks for this exact address.
Permission: kwazi_manage_integrations · Ability: kwazi/create-webhook
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
url |
string (max. 500) | https address on port 443 of a public host. |
events |
array of string (contact.created, contact.updated, contact.deleted, contact.restored, contact.merged, contact.erased, organization.created, organization.updated, organization.deleted, organization.restored, organization.merged, marketing.subscribed, marketing.unsubscribed, form.submitted, appointment.booked, appointment.confirmed, appointment.declined, appointment.rescheduled, appointment.place_changed, appointment.cancelled, appointment.completed, appointment.no_show) | |
active |
boolean |
Answers: 201: webhook, secret. Errors: error shape.
GET /webhooks/events — List webhook events
Lists the public events a webhook can subscribe to on this site, such as contact.created or appointment.booked. Events of apps that are switched off are not listed.
Permission: kwazi_manage_integrations · Ability: kwazi/list-webhook-events
Answers: 200. Errors: error shape.
GET /webhooks/{id} — Get a webhook
Returns one webhook: address, events, on or off, pause reason and the last 4 characters of its secret.
Permission: kwazi_manage_integrations · Ability: kwazi/get-webhook
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, name, url, events, active, paused, failures, secret_hint, created_at, updated_at. Errors: error shape.
PATCH /webhooks/{id} — Update a webhook
Changes the name, address, events or on/off of a webhook. Switching a webhook paused for failures on again resumes it. Hidden from MCP by default.
Permission: kwazi_manage_integrations · Ability: kwazi/update-webhook
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
| Body field | Type | Description |
|---|---|---|
name |
string (max. 190) | |
url |
string (max. 500) | https address on port 443 of a public host. |
events |
array of string (contact.created, contact.updated, contact.deleted, contact.restored, contact.merged, contact.erased, organization.created, organization.updated, organization.deleted, organization.restored, organization.merged, marketing.subscribed, marketing.unsubscribed, form.submitted, appointment.booked, appointment.confirmed, appointment.declined, appointment.rescheduled, appointment.place_changed, appointment.cancelled, appointment.completed, appointment.no_show) | |
active |
boolean |
Answers: 200: id, name, url, events, active, paused, failures, secret_hint, created_at, updated_at. Errors: error shape.
DELETE /webhooks/{id} — Delete a webhook
Deletes a webhook and its delivery log. Only use this when the user explicitly asks to delete.
Permission: kwazi_manage_integrations · Ability: kwazi/delete-webhook
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 204. Errors: error shape.
GET /webhooks/{id}/deliveries — Find webhook deliveries
Lists the deliveries of a webhook (kept 30 days), newest first, optionally by status: queued, retrying, delivered or failed. Returns at most limit items and a next_cursor.
Permission: kwazi_manage_integrations · Ability: kwazi/find-webhook-deliveries
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes | |
status |
query | string (queued, retrying, delivered, failed) | no | |
cursor |
query | string (max. 64) | no | |
per_page |
query | integer (1–100) | no |
Answers: 200: items, next_cursor, total. Errors: error shape.
POST /webhooks/{id}/secret — Make a new webhook secret
Replaces the signing secret of a webhook; the old one stops working at once. Returns the new secret once. Hidden from MCP by default.
Permission: kwazi_manage_integrations · Ability: kwazi/regenerate-webhook-secret
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: webhook, secret. Errors: error shape.
POST /webhooks/{id}/test — Send a test event to a webhook
Sends a signed webhook.test event right away and returns the delivery with the HTTP status of the receiver.
Permission: kwazi_manage_integrations · Ability: kwazi/test-webhook
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id |
path | string (uuid) | yes |
Answers: 200: id, event, event_id, status, attempts, response_code, error, duration_ms, next_attempt_at, created_at, delivered_at, payload. Errors: error shape.
apps
GET /apps — List apps
Lists the Kwazi apps (Contacts, Forms, Booking and installed add-ons) and whether each is on. The abilities of an app that is off do not exist.
Permission: kwazi_view_contacts · Ability: kwazi/list-apps
Answers: 200. Errors: error shape.
PATCH /apps/{app} — Turn an app on or off
Turns an app on or off for the whole site. Off: its screens, routes, abilities, website parts and reminders are gone; its data stays and comes back when it is turned on. Contacts is always on. A change for the whole site: hidden from MCP by default.
Permission: kwazi_manage_crm · Ability: kwazi/update-app
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
app |
path | string | yes |
| Body field | Type | Description |
|---|---|---|
enabled |
boolean |
Answers: 200. Errors: error shape.
feedback
POST /feedback/deactivate — Send why the plugin is deactivated (the plugins screen asks; only the reason, the text and the versions go to Kwazi)
| Body field | Type | Description |
|---|---|---|
reason |
string | temporary, missing_feature, too_hard, not_working, other_tool or other. |
text |
string (max. 1000) |
Answers: 200. Errors: error shape.
integrations
GET /integrations/ai — Get the status for AI assistants
Whether the Abilities API and the MCP Adapter are there (with its server address), which roles may connect with an application password, what connecting with one prompt needs for the reader (site, login, whether application passwords are available and allowed with Kwazi), and every Kwazi ability with whether an assistant may use it (mcp) and whether it only reads.
Permission: kwazi_manage_integrations · Ability: kwazi/get-ai-status
Answers: 200: abilities_api, adapter, connect_roles, abilities, connect. Errors: error shape.
setup
GET /setup — Get the state of the setup guide
Whether the setup guide (opening hours, a first service, a booking page and the choices about sharing) is done or skipped.
Permission: kwazi_manage_crm · Ability: kwazi/get-setup
Answers: 200: done, dismissed. Errors: error shape.
PATCH /setup — Mark the setup guide done or skipped
Marks the setup guide done and/or skipped, so it no longer opens by itself. The steps themselves are the abilities for hours, services and the booking page.
Permission: kwazi_manage_crm · Ability: kwazi/update-setup
| Body field | Type | Description |
|---|---|---|
done |
boolean | |
dismissed |
boolean |
Answers: 200: done, dismissed. Errors: error shape.
support
GET /support — Get the support status
Whether Kwazi support can be reached from the app, and exactly what technical info a support request carries when the person ticks it. Sending a request can only be done by a person in the app.
Permission: kwazi_view_contacts · Ability: kwazi/get-support
Answers: 200: live, environment. Errors: error shape.
POST /support/requests — Send a question, bug or idea to Kwazi support (only from the app: a person sends it, not an integration or AI assistant)
| Body field | Type | Description |
|---|---|---|
type |
string | question, bug, idea. |
subject |
string | One line, at most 150 characters. |
message |
string | At most 5000 characters. |
reply_to |
string | Where Kwazi replies. |
include_environment |
boolean | Send the technical info of GET /support along. |
Answers: 200. Errors: error shape.
