Changelog

Every API change is listed here with version and date. Breaking changes only ship as a new path version with at least twelve months notice.

v1.411.0 · November 10, 2026

  • New: attendance reports for a selection. learning.createAttendanceReport accepts contactListId (a class; its members who are participants count) or contactIds (1 to 500 participants), not both; without either, all participants as before. PDF and CSV name only those selected. Two reports in force may not overlap only for the same person (409 period-overlaps), and attendance-finalized applies only to the people in the report. If nobody in the selection is a participant: no-participants. Every report carries selection (course, contactList, contacts), contactListId and contactIds.

v1.410.0 · November 10, 2026

  • New: events learning.attendance.minimumAtRisk (a course's minimum attendance can only be reached by attending all remaining sessions) and learning.attendance.minimumUnreachable (it can no longer be reached), once per stage, course and contact, checked daily, only for your organization's courses. Payload contains only IDs and numbers: courseId, sharedCourseId (null), contactId, attendedCount, pastCount, totalCount, requiredCount, minimumPercent; the same calculation as status in learning.getCourseAttendance.

v1.409.0 · November 10, 2026

  • New: finalised attendance reports. learning.createAttendanceReport (POST /learning/courses/{id}/attendance-reports) freezes a course's list for a period (from, to, calendar days inclusive) or, without them, for the whole course, and issues a PDF with verification code (document); every dated session in the period must be over (409 sessions-pending), at least one must fall into it (no-sessions), and no report in force may share a day (409 period-overlaps). learning.listAttendanceReports, learning.getAttendanceReport (with frozen sessions and data), learning.getAttendanceReportCsv and learning.cancelAttendanceReport (also cancels the PDF). Entries for sessions of a report in force are rejected by learning.createAttendanceEntry and learning.revokeAttendanceEntry with 409 attendance-finalized. While reports are not enabled in an environment, finalising returns feature-not-available with reason: "attendance-reports-disabled".

v1.408.0 · November 10, 2026

  • New: attendance list of a class. learning.getContactListAttendance (GET /contact-lists/{id}/learning-attendance) returns, per current class member and appointment lesson of all courses the class has through an access, the same cells as learning.getCourseAttendance, plus attended and status per course and attended and rate across all courses. Every session carries courseId and sharedCourseId (null for your own courses); a member without a grant of a course has notParticipant: true and no cells there. learning.getContactListAttendanceCsv returns the same list as CSV. Read-only; entries and reports are per course.

v1.407.0 · November 10, 2026

  • New: manage finder profiles. finder.listProfiles (GET /finder/profiles) returns all practitioner profiles of the organization in every state, filterable by status and contactId; the public view stays GET /finder/practitioners. finder.deleteProfile (DELETE /finder/profiles/{id}, scope finder:write) permanently deletes an archived profile together with its enquiries, review rounds, certificates and locations and says in the response how many there were; a profile in any other state returns 409 conflict with reason: "profile-not-archived".
  • Changed: contacts.merge (POST /contacts/{id}/merge) no longer fails because of an archived finder profile. It is deleted during the merge, together with its enquiries, review rounds, certificates and locations; at most one profile remains (the one that is not archived, otherwise the survivor's, otherwise the most recently changed). 409 with practitioner-profiles-on-multiple now only comes when two profiles that are not archived would meet.

v1.406.0 · November 9, 2026

  • New: attendance entries. learning.createAttendanceEntry adds “on site” (onSite, counts as attended and completes the lesson) or “excused” (excused) with a reason to an appointment lesson; at most one per participant and lesson (409 already-recorded). learning.revokeAttendanceEntry revokes it and returns it with revokedAt. Every cell of the attendance list carries entry. The list, its CSV and the entries also accept the courseId of a shared course (learning.listSharedCourses) as {id}, without the provider's appointment. While entries are not enabled in an environment, adding one returns feature-not-available with reason: "attendance-entries-disabled".

v1.405.0 · November 9, 2026

  • New: attendance list of a course. learning.getCourseAttendance returns, per participant and appointment lesson, minutes and share within the appointment (measured in the live room, only the time from start to end), measurement (upcoming, measured, absent, notMeasured, cancelled), attended, rate and status against the completion's minimum attendance (onTrack, atRisk, unreachable); learning.getCourseAttendanceCsv returns the same list as CSV. Only for your organization's courses; a shared course still returns not-found (comes with the manual entries).
  • Changed: an appointment lesson counts as attended only if the person was in the live room during the appointment (only the time from start to end), not merely in the open room before or after. This affects the lesson state in learning.getCourseParticipant right away, and completedCount in learning.getCourseProgress, learning.listCompletions and the learning.course.completed event once completion depends on appointment lessons. Lessons already recorded stay completed; the rule applies from the next recording on.

v1.404.0 · November 9, 2026

  • New: resend invoices that were released but not sent. POST /invoices/plan-runs/resend (body like release, runId) and POST /invoices/resend-released (ids, 1 to 200) send only invoices that are released but not yet sent, with 200 and { sent, notSent, notSentInvoices, skipped }: notSent as in the release (reason → count), notSentInvoices per invoice with id, number and reason (key of the dispatch logic), skipped for ids without such an invoice. ORG_ADMIN only. New on GET /invoices/plan-runs: releasedNotSent per run.
  • Changed: GET /invoices/plan-runs also lists a run when waiting is 0 and releasedNotSent is greater than 0. Automatically sent invoices (subscription follow-ups, release of submitted and plan invoices, initial collection) are SENT after sending and emit invoices.invoice.sent, like sending with POST /invoices/{id}/send; previously they stayed ISSUED without an event.

v1.403.0 · November 9, 2026

  • New: payment terms for many contacts. POST /contacts/billing-defaults/update (scope contacts:write) sets the default payment terms on contactIds (1 to 500) or on all matches of a filter with the fields of GET /contacts (q, type, tag, responsible, directDebitMandate), exactly one of the two; paymentTermId: null removes their own. Response { matched, unchanged, overwritten, updated } with 200. POST /contacts/billing-defaults/update/preview (scope contacts:read) counts with the same body without changing anything, { matched, unchanged, overwritten }. More than 5,000 matches: 422 precondition-failed, reason: too-many-contacts, with matched. Archived payment terms count as not found (404). Like PATCH /contacts/{id}/billing-defaults, the run emits no event. New on GET /contacts: directDebitMandate=valid|notValid, contacts with or without a valid SEPA direct debit mandate (status GUELTIG and not expired after 36 months without use).

v1.402.0 · November 7, 2026

  • Changed: accesses, grants, classes on an access and accesses on an article now work with either right LERN_BIBLIOTHEK (library) or LERN_KURSE (courses), as shown by GET /organization/entitlements; previously only with LERN_BIBLIOTHEK. Affected: learning.listAccesses, learning.createAccess, learning.updateAccess, learning.archiveAccess, learning.unarchiveAccess, learning.listGrants, learning.grantAccess, learning.revokeAccess, learning.revokeAccessOfContact, learning.getAccessContactLists, learning.setAccessContactLists, learning.getArticleAccesses, learning.setArticleAccesses. A collection in an access still needs LERN_BIBLIOTHEK, a course needs LERN_KURSE; creating an access with a collection AND a course needs both, otherwise feature-not-available. Exception: learning.setAccessCollections and learning.setAccessCourses with an empty list work with either right. The automation actions lern-zugang-gewaehren and lern-zugang-entziehen call learning.grantAccess and learning.revokeAccessOfContact and follow the same rule.

v1.401.0 · November 7, 2026

  • New: responsibleContactId (nullable) on the course (learning.getCourse, learning.listCourses, learning.updateCourse): a contact listed as a teacher who answers questions and submissions in the portal under “As teacher”. The two fields exclude each other; setting one clears the other. Both with a value at once gives invalid_combination, a contact not listed as a teacher gives not-found at body.responsibleContactId.
  • New: feedback.contactId (nullable) on every round in learning.getSubmission: the contact teacher if they gave the feedback in the portal; userId is then null.

v1.400.0 · November 7, 2026

  • New: sharedCourseId (nullable) on every submission (learning.listSubmissions, learning.getSubmission) and every completion (learning.listCompletions) and in the events learning.submission.submitted, learning.submission.reviewed and learning.course.completed: the share if the course belongs to another organization (go straight to learning.getSharedCourse), null for your own courses.
  • New: certificateTemplateId also on every entry of learning.listSharedCourses, not only in learning.getSharedCourse.

v1.399.0 · November 7, 2026

  • New: learning.setSharedCourseCertificate sets your own certificate template for a shared course or removes it (null); participants who already completed without a certificate get it afterwards (issuedCount). Plus certificateTemplateId on learning.getSharedCourse. The providing organization's template does not apply to you.
  • Changed: learning.listCourseParticipants, learning.getCourseParticipant, learning.completeParticipantLesson, learning.reopenParticipantLesson, learning.getCourseProgress and learning.resetQuizAttempts also accept the courseId of a shared course (from learning.listSharedCourses); participants are your contacts with a grant through that share. learning.getCourse still returns 404 for this ID.
  • Changed: learning.listSubmissions and learning.listCompletions also return submissions and completions of shared courses; their courseId is the ID of the providing organization's course, and the courseId filter applies to both. The same ID appears in learning.submission.* and learning.course.completed.

v1.398.0 · November 6, 2026

  • New: learning.releaseSharedCourseItem releases an item (course, module, lesson) of a shared course for everyone who currently has it through an access, one “release now” intervention with a reason per person (released counts them; 0 is not an error). Plus waitsForAppointment on the course, every module and every lesson in learning.getSharedCourse.
  • Changed: in shared courses, a condition “after an appointment” of the providing organization appears with you as manual (never afterAppointment). It is marked by waitsForAppointment in learning.getSharedCourse; release it with learning.releaseSharedCourseItem or learning.createIntervention.
  • Changed: learning.createIntervention now also accepts the course, a module and a lesson of a shared course when the grant's access carries that share.

v1.397.0 · November 6, 2026

  • New: courses other organizations have shared with your organization. learning.listSharedCourses (with providerName, createdAt, endedAt, active; ended shares while access is still running with you), learning.getSharedCourse (header and outline, read only, in the shape of your own courses) and learning.setAccessSharedCourses. sharedCourseIds on every access and on learning.createAccess. An ended share can't be newly added (422 shared-course-ended); an unknown one is reported at body.sharedCourseIds.

v1.396.0 · November 6, 2026

  • New: share courses with other organizations, provider side. learning.listCourseShareConnections (active course-sharing connections), learning.listCourseShares (shares of a course with participantCount, the number of participants with active access at the other organization, no names), learning.shareCourse (201, created) and learning.endCourseShare (access already running there continues until it ends; already ended: 409 already-ended). Administrators only. Errors: 404 connection-unknown, 422 connection-not-active, connection-revoked, connection-wrong-purpose, course-not-published.
  • Changed: learning.archiveCourse ends the course's shares with other organizations; access already running there continues until it ends. Restoring (learning.unarchiveCourse) does not reopen them.

v1.395.0 · November 6, 2026

  • New on every collection (learning.listCollections, learning.createCollection, learning.updateCollection and every response carrying a collection): recommendation (“Related”, the same shape as on courses: another collection, a course or your own link), writable on create and update; null removes it, if the field is missing it stays. A collection cannot recommend itself (422 at recommendation.collectionId).

v1.394.0 · November 6, 2026

  • New on every course (learning.*Course*): withoutLearningControl (“without learning control”: no questions to the teacher and no assignment lessons; quizzes and appointment lessons stay; default false), writable on learning.createCourse and learning.updateCourse. Switching it on while the course has assignment lessons (drafts included): 422 precondition-failed with assignments-present, lessonIds (at most 100) and assignmentCount.
  • Changed: In a course with withoutLearningControl, learning.createLesson with type: "assignment" is refused (422 precondition-failed, without-learning-control), and the course import doesn't create assignment lessons from the source or switch any to assignment; they are listed under kept with reason: "without-learning-control". Clients should treat unknown reasons in kept generically.

v1.393.0 · November 6, 2026

  • New on learning.getAppointmentMaterial and learning.updateAppointmentMaterial: recordingCollectionId (effective collection of the recording) and the override recordingCollectionOverride ({ collectionId } or null = as the appointment type; there is no “no collection” on the appointment, unknown: 422 at body.recordingCollectionOverride.collectionId with not-found). If the effective collection changes without recordingFolderOverride, the appointment uses the appointment type's folder again.
  • New: learning.addAppointmentRecordings (POST /appointments/{id}/learning-material/recordings) puts finished video recordings of the appointment without learning content into the appointment's collection, folder and period as drafts after the fact; answers 200 with created and recordings. 422 recording-consent-incomplete (fixable with confirmIncompleteConsent: true) and no-target-collection. Plus the list recordings on learning.getAppointmentMaterial (only what the access may see).
  • Changed: visibleDaysAfterRelease is now writable on learning.createContent and learning.updateContent (1 to 3650 or null) and applies to any content, not only recordings; previously read-only on recordings. Invalid: 422 at body.visibleDaysAfterRelease.

v1.392.0 · November 6, 2026

  • New on the signer slots of a PDF template (templates.getPdf, templates.updatePdf, signerSlots): contactId, a suggested contact with an email address who signs via the e-signature link (for example a teacher who isn't a member). A slot carries userId or contactId, never both. If the contact is missing or has no email address: 422 on body.signerSlots with invalid_reference.
  • New on issued documents (letters.getIssued and the other responses with the document, signature.slots): suggestedContactId, the contact the template suggests for the slot (null if it suggests a member or no one).

v1.391.0 · November 6, 2026

  • Changed behaviour: if a task belongs to a follow-up from the call list (the pipeline creates it), the card follows it: PATCH /tasks/{id} with a new dueDate moves the card's follow-up; status DONE, DELETE /tasks/{id} or dueDate: null withdraw it (a parked card keeps it); reopened, it returns with the task's due date. Also applies to POST /tasks/{id}/status. Other fields don't change the card.

v1.390.0 · November 6, 2026

  • Changed: For a Metabolic Balance case, the most recent submission of the questionnaire that hasn't served an earlier case of this client record counts, even if it came before the start; previously only one after the start. form.responseId/form.submittedAt on clients.listMetabolicBalanceCases and startMetabolicBalanceCase and the handover (…/handover, …/handover/send) follow this rule; submittedAt can be before startedAt. This also applies to cases already running.
  • Changed: The handover to Metabolic Balance (…/handover, bloodValues, and …/handover/send) only takes values from approved reports, read or entered by hand; previously a read report was enough, even as a draft. Rejected reports count nowhere. In the case (report), reports entered by hand count once submitted; if everything is read but not everything approved yet, the report step says so.

v1.389.0 · November 5, 2026

  • New on learning.getAppointmentTypeMaterial and learning.setAppointmentTypeMaterial: recordingFolderId (folder of the target collection for the recording, null = top level; not in the collection: 422) and recordingVisibleDays (visible for N days after release, 1 to 3650, null = unlimited). If recordingCollectionId changes without a new folder, the folder becomes null.
  • New on learning.getAppointmentMaterial and learning.updateAppointmentMaterial: effective recordingFolderId and recordingVisibleDays, plus the overrides recordingFolderOverride ({ folderId } or null = as the appointment type) and recordingVisibleDaysOverride ({ days } or null). A folder no longer in the collection acts as top level.
  • New on content: visibleDaysAfterRelease (read-only, recordings only, otherwise null). Changed behaviour in the contact view: a recording with a period no longer appears after that many days from the contact's release (search with contactId, media); the release stays in learning.listReleases, and the content stays in the organization's library.

v1.388.0 · November 5, 2026

  • Changed behaviour: material after the lesson (the run at the end of the appointment and learning.releaseAppointmentMaterial) goes per content to everyone with running access to its collection, registered for the appointment or not; with attendeesOnly to those measured as present who have access. Previously it went to the registered participants, and anyone without a reply was left out. recipientCount counts distinct contacts.
  • Changed behaviour: releasing the material publishes unpublished contents (drafts excepted). With attendeesOnly they stay unpublished and are visible in the contact view only to the recipients; such a content does not appear for absentees, not even by the collection's schedule.

v1.387.0 · November 5, 2026

  • Teachers hold appointments: resourceId on appointments.create (and on recurrences) now also accepts a teacher (teacher on the resource), for any appointment type and at any time, without staffing and without working hours; the only check is whether they already have an appointment then (otherwise 409 conflict with slot-taken). appointments.reschedule keeps an appointment's teacher even without resourceId. Online appointments of a teacher get the live room. Previously such a resourceId returned the error that the resource does not hold the appointment type.

v1.386.0 · November 5, 2026

  • Teachers (a contact hosting lessons, without free slots): GET, PUT and DELETE /appointment-teachers/{contactId} (appointments.getTeacher, appointments.setTeacher, appointments.removeTeacher). getTeacher returns isTeacher, resourceId, removable, upcomingCount and the next at most 20 appointments (upcoming with participantCount, without names); a contact that is not a teacher responds with isTeacher: false. setTeacher is idempotent and responds with 200; removeTeacher responds with 204, with upcoming appointments 409 conflict with reason upcoming-appointments and extra.count. A missing or foreign contact returns 404, a company validation-failed at params.contactId with code not-a-person. Every resource gains teacher (appointments.listResources, appointments.getResource).

v1.385.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-client/plans/{planId}/copy-pdf (clients.copyMetabolicBalancePlanPdf, no body, 200) copies the PDF of a plan of the linked client at Metabolic Balance into the record as a protected copy, only on this explicit call per plan. Response { planId, documentId, copiedAt, created }; if the PDF is already in the record (own copy or a case's PDF), the same id comes back with created: false and nothing is fetched again. Reasons: 404 if the plan doesn't belong to the linked client; 422 metabolic-balance-client-not-linked and metabolic-balance-plan-without-pdf (with extra.planState); 409 metabolic-balance-pdf-failed (with extra.error) and metabolic-balance-copy-in-progress (a stuck attempt expires after five minutes).
  • New on clients.listMetabolicBalanceClientPlans per plan: documentId, the plan's PDF in the record (a case's PDF or a copied one), otherwise null; the file via documents.downloadUrl.

v1.383.0 · November 5, 2026

  • New: existing records at Metabolic Balance on the client record. GET /clients/{id}/metabolic-balance-client (clients.getMetabolicBalanceClient) reads which client at MBG the record is linked with (not linked: 200 with linked: false). GET …/metabolic-balance-client/candidates (clients.searchMetabolicBalanceClients, search 2 to 100 characters) searches the whole MBG account: at most 10 candidates, never anonymized ones, ranked with match. PUT …/metabolic-balance-client (clients.linkMetabolicBalanceClient, { patientId }, 200) links only on this explicit call; claritos reads the client at MBG first: 422 validation-failed at body.patientId, 409 metabolic-balance-client-linked-elsewhere with extra.clientId. DELETE …/metabolic-balance-client (clients.unlinkMetabolicBalanceClient, 204) removes only the link at claritos. GET …/metabolic-balance-client/plans (clients.listMetabolicBalanceClientPlans) and …/blood-tests (clients.listMetabolicBalanceBloodTests, newest first, at most 20) read at MBG on every call, nothing is stored; without a link { data: [] }.
  • If the record is linked, …/handover/send takes that client and doesn't check for duplicates; if the coach chooses or creates a client when sending, a record without a link is linked with it.

v1.381.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-cases/{caseId}/handover/release-plan (clients.releaseMetabolicBalancePlan, { phase, allowedTreatMeals, allowedOils }, 200) approves the plan at MBG and shares it with the client; claritos sends the client an email without health information and shows the plan in their client portal. Whether MBG notifies them itself is open; claritos doesn't undo a release; never twice, and calling again after a partial failure continues. Reasons: 422 metabolic-balance-not-generated (with extra.planState), 409 metabolic-balance-already-released, plus the known ones.
  • New on the handover's mbg: releaseDefaults (the plan's values at MBG as defaults) and releasedAt.

v1.380.0 · November 5, 2026

  • New: the review chat with the Metabolic Balance back office. GET /clients/{id}/metabolic-balance-cases/{caseId}/handover/chat (clients.listMetabolicBalanceChatMessages) reads the last 100 messages, oldest first, at MBG on every call (claritos stores no messages; reading marks nothing as read; without a chat an empty list). POST …/handover/chat (clients.postMetabolicBalanceChatMessage, { text }, 200) sends a message; 409 metabolic-balance-no-chat without a chat. The Idempotency-Key protects against sending twice.
  • New on the handover's mbg: chatAvailable and chatUnreadSince.

v1.379.0 · November 5, 2026

  • New on the handover's mbg: planDocumentId (the plan PDF in the record, copied into the protected storage as soon as the plan is generated at MBG; if MBG generates it again, claritos replaces the file under the same id, and if that fails, the previous one stays) and planPdfError (no-pdf, fetch-failed, not-a-pdf, too-large; no further attempt after five failures). Get the file via documents.downloadUrl with this id, only for keys with the client data permission; claritos never hands out MBG's own links.

v1.378.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-cases/{caseId}/handover/generate-plan (clients.generateMetabolicBalancePlan) generates the plan at Metabolic Balance. Every call that generates costs one plan on the organization's account at MBG; the body requires confirmCost: true, and a repeated call never generates twice. Responds 200 with the handover. Reasons: 422 metabolic-balance-not-sent, metabolic-balance-not-ready (with extra.checkErrors); 409 metabolic-balance-already-generated (with extra.planState), plus the known ones.
  • New on the handover's mbg: generationRequestedAt, verificationReason (our own keys), blockReason (text from MBG, at most 500 characters) and lastCheckedAt. claritos checks plans that are waiting for something (generation, review): shortly after generating and every five minutes.

v1.377.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-cases/{caseId}/handover/laboratory (clients.createMetabolicBalanceLaboratory) creates a new laboratory in the coach's laboratory management at Metabolic Balance and selects it in the case. The input profile comes from the report: unit and normal range for the client's sex, otherwise MBG's presets; no personal data. Responds 200 with the handover. 409 metabolic-balance-laboratory-exists with extra.laboratoryId if a laboratory with the same name already exists (select it with PATCH …/handover); if only the profile fails, calling again continues. Further reasons: 422 metabolic-balance-not-connected, validation-failed (for example body.countryId); 409 case-closed, metabolic-balance-rejected, metabolic-balance-unavailable.
  • New on the handover (GET, PATCH, send): options.countries (countries from MBG) and options.reportLaboratory (name, matchedLaboratoryId, suggestedCountryId).

v1.376.0 · November 5, 2026

  • Changed: affiliates.createCoupon (POST /affiliate-coupons), affiliates.updateCoupon (PATCH /affiliate-coupons/{id}) and affiliates.updateClimateContribution (PUT /affiliate-climate-contribution) require the right AFFILIATE_VERWALTUNG (see GET /organization/entitlements). Without it they answer 403 feature-not-available with reason affiliate-license, like affiliates.activity. Exception: updateCoupon with active: false (switching off) keeps working without the right, as do affiliates.deleteCoupon and affiliates.disableTracking. The same rule applies in the app.

v1.375.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-cases/{caseId}/handover/send sends the handover to Metabolic Balance: create the client and plan or take the existing ones, transfer all sections and the blood test, ask MBG whether a plan can be generated. Nothing is generated. Calling again continues and never creates anything twice. Beforehand claritos searches the client in the MBG account; a match is never taken over silently: 409 metabolic-balance-duplicate with up to five candidates in extra.candidates, then choose with patient ({ mode: "existing", patientId } or { mode: "new" }). After that claritos asks about an open draft at MBG that did not come from this case (MBG allows one per client): 409 metabolic-balance-draft-exists with extra.draft (planId, createdAt, state), here too before anything is written; take it over and overwrite it with overwriteDraftPlanId, on the second call together with patient. Further reasons: 422 handover-incomplete (with extra.missing), collection-too-old, metabolic-balance-not-connected; 409 case-closed, metabolic-balance-rejected (with extra.providerMessage), metabolic-balance-unavailable.
  • New on the handover (GET, PATCH, send): mbg with the client and plan at MBG (patientId, planId), planState in our own keys, canGenerate, checkErrors as delivered by MBG, sentAt, outOfGlobalRange; null until sent.

v1.374.0 · November 5, 2026

  • Changed: couplings.prospectsRequired on pipelines.update (PATCH /pipelines/{id}) counts as met as soon as the prospect has any card in a pipeline of the organization, whatever its state (open, parked, closed), no longer only a card in this pipeline. Only a prospect with no card at all gets the request to assign it or, with prospectsAutomatic, a card. This prevents duplicate cards for the same person.
  • Changed: The backfill of the requirement (pipelines.getBackfill and pipelines.startBackfill, GET/POST /pipelines/{id}/backfill) now only takes prospects without any card in the organization; prospects that already have a card in another pipeline, even a closed one, are no longer added. candidates counts accordingly.

v1.373.0 · November 5, 2026

  • Imprint and privacy policy: supplements to the continuously generated template. GET /organization/legal-texts lists mode, supplements and sections on every entry (null for other kinds) as well as dpoNotAppointed. New PUT /organization/legal-texts/{kind}/supplements. DELETE /organization/legal-texts/{kind} discards the own text; supplements are kept, without supplements as before. PATCH /organization/legal-texts accepts dpoNotAppointed. isCustomized is still only true for an own text (same as mode own), supplements alone do not change it; version also increases when the supplements change.

v1.371.0 · November 5, 2026

  • New: read and prepare the handover of a case to Metabolic Balance. GET /clients/{id}/metabolic-balance-cases/{caseId}/handover returns the sections as in the MB portal with a status (ready, unclear, optional, attention), the plan settings, the choices (options: laboratories, languages, MBG's lists), the blood values with the report's unit in MBG's spelling (no conversion) and two levels (outside-norm, outside-global), the questionnaire's free-text answers to assign, and blockers. PATCH on the same path changes settings and assignments partially. Our own keys: dietGoal none/lose/regulation/gain, healthTrigger in camelCase; IDs at Metabolic Balance come from options. Nothing is sent yet.

v1.370.0 · November 5, 2026

  • New: POST /clients/{id}/metabolic-balance-cases/{caseId}/request-report asks the client for the lab report again. The call messages the client immediately through the case's channel, with the upload link; once a report has been read, the message names the missing required values. If the previous file request no longer accepts uploads, a new one is created (then in fileRequest). Every call messages again. Response 200 with the case; 409 case-closed or send-failed, 422 case-not-sent, contact-without-email, sender-missing, metabolic-balance-not-connected.
  • New on the case object (GET and POST /clients/{id}/metabolic-balance-cases): report with phase (none, reading, redaction, failed, read), requiredCount, receivedCount, missing, optionalRequested, optionalReceived as { key, name } (key like markerKey in biomarkers.listProfileItems) and lastRequestedAt. Reports linked to the case's lab request in the lab tab count as well.

v1.369.0 · November 5, 2026

  • New: Metabolic Balance cases on the client record. GET /clients/{id}/metabolic-balance-cases lists the cases with their state (delivery, intake questionnaire, lab report, handover, plan). POST /clients/{id}/metabolic-balance-cases starts a case: releases the lab request from the profile, issues the link to the intake questionnaire and creates the file request for the lab report (channel email or portal). The message to the client is sent in the background as soon as the lab request PDFs are ready; delivery.sentAt is therefore set later and can be read with the GET. Requires the right METABOLIC_BALANCE (otherwise 403 metabolic-balance-license) and a connected account (otherwise 422 metabolic-balance-not-connected); one open case per record (409 case-open).

v1.368.0 · November 5, 2026

  • New right METABOLIC_BALANCE (connection to the Metabolic Balance portal) in GET /organization/entitlements and in the license endpoints. It has no prerequisite and unlocks the connection to the portal in the organization's settings; the key is entered there, not via the API.
  • GET /organization/integrations lists the integration metabolicBalance for business organizations (settings under bereich=schnittstellen): without the right METABOLIC_BALANCE with state not-enabled, otherwise not-connected, faulty (last check failed) or connected.

v1.367.0 · November 4, 2026

  • New: courseId on learning.searchCourses limits the search to one course.
  • Course search now also finds pages of a lesson's PDF files (matchIn: "pdfPage"), with the new field lessonMaterialId; for pages of the lesson's own PDF medium it stays null.

v1.366.0 · November 4, 2026

  • Appointment types can be duplicated: POST /appointment-types/{id}/duplicate (appointments.duplicateType, scope appointments:write, the same permission as createType) creates an inactive copy, with “(Kopie)”, “(copy)” or “(копия)” added to the name in every stored language and a new slug (…-kopie, …-kopie-2); response 201 with the copy. The setup is copied including staffing and services; brand, form, call guide, place, phone, reminder plan and checkout link point to the same objects. Appointments, booking links and the partner release are not copied (partnerRelease NONE). If the original points to a call guide, checkout link or reminder plan that createType would not accept, the same error as there is returned.

v1.365.1 · November 4, 2026

  • Fixed: includeArchived=false on pipelines.list (GET /pipelines) and pipelines.listSlas (GET /pipelines/slas) used to return archived items as well (any non-empty value counted as true). The parameter now takes true or false.

v1.365.0 · November 4, 2026

  • Courses can name their two outline levels (levelNames: first for modules, second for submodules), set in the request language and translated like other course texts; null or an empty string returns all languages to the default. Names carry no number: the portal numbers items itself only where the titles carry none.

v1.364.0 · November 4, 2026

  • Learning platform, courses: description and instructor.description are formatted text (HTML; plain text remains allowed and becomes paragraphs) and accept up to 20,000 characters instead of 5,000 in learning.createCourse and learning.updateCourse. claritos sanitizes the HTML on save. Behaviour: anyone who displayed description as plain text so far now sees markup such as <p>; treat it as HTML before displaying. The course import (learning.startCourseImport) now also sanitizes both texts on save and turns plain text into paragraphs; the 20,000 limit does not apply there. If a text only exceeds 20,000 characters after sanitizing, createCourse/updateCourse reports too_big on the field.

v1.363.0 · November 4, 2026

  • Learning platform, course folders and courses in collections: new endpoints learning.listCourseFolders, createCourseFolder, updateCourseFolder, moveCourseFolder, deleteCourseFolder (folders of courses, at most two levels, without release rule), learning.orderCourseItems (POST /learning/courses/order) and listCollectionCourses, addCollectionCourse, updateCollectionCourse, removeCollectionCourse (course as a tile in a collection; grants no access). New on the course: folderId, position and collections; learning.updateCourse accepts folderId. New on collection folders: courseCount; learning.deleteFolder reports movedCourseCount; learning.orderItems knows type course. Behaviour: folders, contents and course tiles of one collection level now share the numbers in position. An import creates no course folders and moves nothing that was sorted in.

v1.362.0 · November 4, 2026

  • Learning platform, searching courses: new endpoint learning.searchCourses (GET /learning/courses/search), additive. Searches courses, modules and lessons (titles, descriptions, the instructor's name, line and text, lesson texts, speech and PDF pages of their media); flat rows like learning.searchContents, with type (course, module, lesson), modulePath and lessonType; with contactId from the contact's point of view (locked, unlockReasons), without it with draft. learning.searchContents stays unchanged and returns NO course hits; to get both, call both searches.

v1.361.0 · November 4, 2026

  • Learning platform, courses: instructor has two new fields, jobTitle (line below the name on the card in the portal, per language) and imageAssetId (photo from the media library, null = initials); always in the response, optional in learning.updateCourse. The import tree (learning.startCourseImport) carries neither photo nor jobTitle; a later import leaves both as they are. New field recommendation (“Related”, at most one entry, oneOf by type: collection, another course or a custom link with title and image), always in the response (null without an entry), optional in learning.updateCourse (null removes it); learning.createCourse does not set it. If the target is deleted, the entry is null.

v1.360.0 · November 4, 2026

  • Learning platform, skipping ahead: new field allowSeeking (boolean, default true) on the collection (read, learning.createCollection, learning.updateCollection) and on the course (read, learning.updateCourse). With false the portal only allows jumps in video and audio up to the furthest point already watched. Behaviour: progress then rises per report by at most the time elapsed since the previous report (times 1.25, plus 15 seconds); a single report no longer marks a video as viewed. With true, that is for all existing collections and courses, progress behaves as before; the limit applies only with false.

v1.359.0 · November 3, 2026

  • Body size per endpoint: learning.startCourseImport (POST /learning/course-imports) now accepts up to 4 MB (4,194,304 bytes), all other calls still up to 1 MB. Until now the framework rejected every body over 1 MB with 413, including on the course import, which promises 4 MB; a course with about 250 lessons failed on this. Every operation with a body states its limit in the spec as x-max-body-bytes, and the 413 response (payload-too-large) states it as maxBodyBytes. Size is counted in bytes (UTF-8), also for a request without Content-Length.

v1.358.0 · November 3, 2026

  • Learning platform, lesson materials: learning.createLessonMaterial (POST /learning/lessons/{id}/materials, 201) attaches a file from the media library (without title the title of the media file, at most 50, beyond that conflict with too-many-materials), learning.updateLessonMaterial and learning.deleteLessonMaterial (/learning/lesson-materials/{id}), learning.orderLessonMaterials (POST …/materials/order). A material from an import is not changed (conflict, material-from-import); if removed it returns with the next import, materials added by hand stay with every import. New materials on every response with a lesson, always present ([] without material), each with media as on the lesson.

v1.357.0 · November 3, 2026

  • Biomarkers, renamed before delivery: the count fields on biomarkers.listAxes (and in the responses of createAxis, updateAxis, orderAxes) are draftEntryCount, lockedEntryCount and ruleCount instead of draftEntries, lockedEntries and rules, like markerCount and ruleCount in this domain (1.356.0 was never on any environment).

v1.356.0 · November 3, 2026

  • Biomarkers, axes by hand: the axes of biomarker profiles can now be maintained without importing the profile workbook. New biomarkers.listAxes (GET /biomarker-axes, with the number of entries in drafts draftEntryCount and in released, retired or adopted profiles lockedEntryCount, rules ruleCount, deletable, deleteBlockedBy), biomarkers.createAxis (POST; without key the next free one such as "A18"; a key in use gives 409 axis-key-taken, the key order is not allowed), biomarkers.updateAxis (PATCH /biomarker-axes/{key}, name and note; the key stays), biomarkers.orderAxes (PUT /biomarker-axes/order, every key exactly once, returns the ordered list) and biomarkers.deleteAxis (DELETE; entries in drafts lose the axis; 409 axis-in-locked-profile while a released, retired or adopted profile names it, axis-in-rule while a rule calculates with it). On entries: biomarkers.listProfileItems (GET /biomarker-profiles/{id}/items, marker, sex, axisKey, familyKey, assignment) and biomarkers.setItemAxis (PUT /biomarker-profiles/{id}/items/{itemId}/axis, only in own drafts, otherwise 409 profile-not-draft or profile-licensed; axisKey: null removes the assignment; returns the entry as listProfileItems does); a change sets assignment to ACHSE_FESTGELEGT.

v1.355.0 · November 3, 2026

  • Learning platform, courses on an access: learning.setAccessCourses (PUT /learning/accesses/{id}/courses) sets the courses of an access, replaces the list in the given order and leaves the collections untouched; an unknown course gives not-found at body.courseIds, without the right for courses feature-not-available. New courseIds in the responses of access and grant, always present ([] without courses), and optional in learning.createAccess (an empty list needs no right). Drafts and archived courses as with collections. Events unchanged.

v1.354.0 · November 3, 2026

  • Learning platform, create course: learning.createCourse (POST /learning/courses, 201) creates an empty course, as a draft released immediately and without source; a later import does not touch it. Fields title (required), description, type and selfPacedStart as in learning.updateCourse, response as learning.getCourse with an empty outline.

v1.353.0 · November 3, 2026

  • Conversations, assignee and relation: inbox.listConversations and inbox.getConversation now carry assigneeUserId, the responsible person (member of the organization; only while they are a member), and relatedTo, what the conversation relates to, as a union distinguished by type. Currently there is only { type: "lesson", courseId, lessonId }: a question a customer asked about a lesson in the portal; the responsible person is then the teacher of the course (responsibleUserId, 1.352.0). If the course or lesson is deleted, that value is null. Without an assignee or relation both fields are null, so for all existing conversations. New filter assigneeUserId on inbox.listConversations, assigneeUserId=none for nobody assigned. Setting the assignee comes with a later version.

v1.352.0 · November 3, 2026

  • Learning platform, teacher on the course: courses carry responsibleUserId, the member of the organization who receives questions from the portal about lessons of this course (assigneeUserId of the conversation); null = nobody. Settable via learning.updateCourse; a non-member gives not-found at body.responsibleUserId. If the person leaves the organization, the value stays but counts as nobody. Independent of instructor (the displayed instructor).
  • License, behaviour (spec unchanged): for licenses with a version (model: version), the right LIVE_RAUM now follows from the organization’s video tier (included, booked, or as a single exception on the tenant with Start); a separate release on the organization is no longer needed. Versions no longer list LIVE_RAUM in choiceList nor as a bookable module (bookable); this applies on reading to every version, including ones already published, and booking the module is rejected (conflict, reason rejected). Newly saved versions no longer contain it either. The video tiers are what can be booked. Licenses without a version (model: existing) are unchanged.

v1.351.0 · November 3, 2026

  • License, video tiers with name and version: next to the key (tier) there is the name in the language of the request (tierName; custom tiers with their own name, START, PLUS, PRO with a fixed text) on organization.getLicenseChoices (also in the responses of setLicenseChoices and setVideoTier: video.tierName, video.booked[].tierName), organization.getLicense (modules[].tierName, bookable[].tierName, perOrganization[].videoTierName) and the preview of a cycle change (modules[].tierName). The number of the tier's version appears where an organization sees its tier: video.tierVersionNumber, perOrganization[].videoTierVersionNumber, and on bookable[] the version a new booking would get today (tierVersionNumber). A custom tier has a key made from its first name that never changes afterwards, so display the name.

v1.350.0 · November 3, 2026

  • Conversations: new channel portal (channel on inbox.listConversations and inbox.getConversation, filter channel=portal, channels.portal in inbox.getConversationCounts). It covers messages in the customer portal in the communication area, one conversation per thread; protected record post does not appear. subject is the thread's subject, counterpart is null, messages in the history carry HTML. Clients that branch on channel receive a new value.

v1.349.0 · November 3, 2026

  • Learning platform, fill in the blanks and question pool: the type of a quiz question gains the value blanks (fill in the blanks); clients that branch on the type need a branch for it. New on the question: blanks (per blank answers, the accepted answers; null for single and multiple, for blanks options is empty). Blanks appear in the text as {{1}}, {{2}} …, counting from 1; comparison ignores upper and lower case and collapses whitespace. learning.createQuestion and learning.updateQuestion accept type blanks with blanks (1 to 20 blanks, 1 to 10 answers each of up to 100 characters); placeholders that don't match the blanks give invalid at body.blanks, a blank without an answer required at body.blanks[i].answers, too many or too long answers too-large. PUT /learning/questions/{id}/answers gives wrong-type at params.id for fill-in-the-blank questions. New on the quiz: questionsPerAttempt (question pool: each attempt draws this many questions at random, null all; when saving at most as many as the quiz has, otherwise invalid at body.questionsPerAttempt; if questions are deleted later, each attempt takes all). Import and getCourseMissing stay with single and multiple.

v1.348.0 · November 3, 2026

  • Learning platform, extended quiz: The quiz of a lesson (learning.updateQuiz, readable on the lesson) gains maxAttempts (maximum attempts per person, 1 to 100, null unlimited; reset attempts don't count), timeLimitMinutes (1 to 600, null none; counted on the server from “Start quiz” in the portal, after it runs out and a short tolerance a submission counts as not passed) and showSolution (never default as before, afterSubmit, afterPass: when the portal shows the correct answers). Out of range gives invalid at body.maxAttempts or body.timeLimitMinutes. learning.getCourseParticipant carries quiz with attemptCount, lastScore, passed, remainingAttempts per quiz lesson (otherwise null). New POST /learning/courses/{id}/participants/{contactId}/lessons/{lessonId}/quiz-attempts/reset (learning.resetQuizAttempts): attempts stay in the history but no longer count; a running attempt ends; a lesson that is not a quiz gives wrong-type at params.lessonId.

v1.347.0 · November 3, 2026

  • Certificates and PDF templates: new field kind TRIGGER_VALUE in pdfFieldKind (templates.*, letters.getIssued) for a value the process supplies when issuing; binding is currently only course.title, the course title on course completion on the learning platform. Issued by hand, such a field stays empty. Clients that branch on kind receive a new value. Certificates gain sourceKind (COURSE_COMPLETION) and sourceId (the id from learning.listCompletions or completionId from learning.course.completed) when a process issued them without a signed-in person, otherwise both null. One completion yields at most one certificate.

v1.346.0 · November 3, 2026

  • Learning platform, participants: GET /learning/courses/{id}/participants (learning.listCourseParticipants, by name, filter active as true/false, with lessonCount, completedLessonCount, progressPercent, lastActivityAt, completedAt, grantId of the applicable grant) and GET /learning/courses/{id}/participants/{contactId} (learning.getCourseParticipant: per lesson status completed/open/locked, completedAt, completedManually, unlocksAt, unlockReasons, plus interventions). Tick off by hand: POST …/participants/{contactId}/lessons/{lessonId}/complete with reason (learning.completeParticipantLesson, already completed stays unchanged) and …/reopen (learning.reopenParticipantLesson, only lessons ticked off by hand, otherwise 422 precondition-failed with reason not-manual). Interventions in the personal schedule (also for the library): POST /learning/grants/{id}/interventions (learning.createIntervention, 201, union over type: pause with startDate/endDate, move with targetType/targetId/date, releaseNow with targetType/targetId, extendEnd with endDate; reason required; an item not belonging to the grant returns not-found at body.targetId), GET /learning/grants/{id}/interventions (learning.listInterventions) and POST /learning/interventions/{id}/revoke (learning.revokeIntervention, repeatable). GET /learning/courses/{id}/progress (learning.getCourseProgress): per lesson startedCount and completedCount, plus participantCount. unlockReasons now carry targetType with afterItem.

v1.345.0 · November 3, 2026

  • Learning platform, completion and certificate: The course (learning.getCourse, writable via PATCH /learning/courses/{id}) gains completionRule with requiredLessons (all all lessons except drafts, selected only requiredLessonIds) and minAttendancePercent (1 to 100 % of appointment lessons, rounded up; with all, appointments then count through the share; null none), always set, in a PATCH it replaces the whole rule; plus certificateTemplateId (PDF template, templates.getPdf). A lesson outside the course returns not-found at body.completionRule.requiredLessonIds[i], a percentage out of range invalid, an unknown template not-found, an archived one invalid at body.certificateTemplateId. New GET /learning/completions (learning.listCompletions): completions, most recently changed first, filters courseId, contactId, updatedSince, with certificate (status none/pending/issued/failed, issuedDocumentId readable via letters.getIssued, failureReason). New event learning.course.completed (once per participant and course). If the course has a template, the certificate is issued on completion (status issued with issuedDocumentId, on failure failed with failureReason); when the team sets a template, completions without a certificate receive it retroactively.
  • Automations: the triggers learning.course.completed, learning.submission.submitted and learning.submission.reviewed can be limited to courses (filter courseId, kind course, “one of”), for instance to start a next step only when a particular course is completed.

v1.344.0 · November 3, 2026

  • Learning platform, submissions: GET /learning/submissions (learning.listSubmissions) lists participants’ submissions in lessons of type assignment, most recently changed first, with filters courseId, lessonId, contactId, status (submitted, returned, accepted) and updatedSince; never drafts. GET /learning/submissions/{id} (learning.getSubmission) returns the submitted rounds with text, files (documentId, filename, mimeType, sizeBytes; download via GET /documents/{id}/download-url) and the feedback per round. POST /learning/submissions/{id}/feedback (learning.createSubmissionFeedback, 201) gives feedback on the last submitted round: result accepted completes the lesson, returned sends it back, grade optional; without a submitted round 422 precondition-failed with reason not-submitted, with feedback already given already-answered. New events learning.submission.submitted and learning.submission.reviewed.
  • Automations: the trigger learning.submission.reviewed can be filtered by the result of the feedback (result: accepted, returned), for instance to start a next step only for accepted submissions.

v1.343.0 · November 3, 2026

  • Learning platform, course types: type (selfPaced, class) is writable on PATCH /learning/courses/{id} (learning.updateCourse); new selfPacedStart (access with the participant’s access, default; firstOpen when they first open it in the portal), readable on the course and writable. It only applies to selfPaced and stays stored on a class course; a class course starts on the shared start date of the class the participant came through, or with their access if the class has none. “From day n” and immediately count from this start; a start in the future locks until then.
  • Learning platform, appointment lessons: POST /learning/courses/{id}/lessons (learning.createLesson) takes type: "appointment"; appointmentId on createLesson and PATCH /learning/lessons/{id} (learning.updateLesson, null removes it); on a lesson of another type invalid, an appointment that does not exist in the organization not-found, each at body.appointmentId. New GET /learning/lesson-appointments/options (learning.lessonAppointmentOptions: active appointment types with kind and capacity, running recurring series) and GET /learning/lesson-appointments (learning.listLessonAppointments: appointments to choose with exactly one of appointmentTypeId and recurrenceId, none required, both invalid; upcoming first, paged via cursor). afterAppointment can now be chosen in course rules; an appointment outside the organization returns not-found at body.rule.conditions[i].appointmentId.

v1.342.0 · November 3, 2026

  • Classes, shared start: GET /contact-lists, GET /contact-lists/{id}, POST /contact-lists and PATCH /contact-lists/{id} carry startDate, the class's shared start as a calendar day yyyy-mm-dd in the organisation's time zone (null: no start yet); learning platform courses for this class start on this day. PATCH /contact-lists/{id} (contacts.updateList) now takes { name?, startDate? }, at least one of the two (otherwise validation-failed with required); startDate: null clears the start, a day that doesn't exist or a year outside 2000 to 2100 gives validation-failed at body.startDate, and then the name isn't changed either. Subgroups have no start.

v1.341.0 · November 2, 2026

  • Learning platform, release rules per course item: rule and display on PATCH /learning/courses/{id} (learning.updateCourse; always set on the course, default immediately), PATCH /learning/modules/{id} and PATCH /learning/lessons/{id} (learning.updateModule, learning.updateLesson; null = none of its own, the one above applies) and in their responses; hasOwnRule on modules and lessons in learning.getCourse. In a course, afterItem points to module or lesson, and afterQuiz.quizId is the ID of the lesson of type quiz. A reference that does not exist in the course returns not-found, an item waiting for itself or for something below it cycle, a lesson of another type for afterQuiz wrong-type, each at body.rule.conditions[i]. POST /learning/releases/preview (learning.previewRule) also takes courseId (with moduleId or lessonId) instead of collectionId; exactly one of the two.
  • The condition schema is shared and gets wider: afterItem.targetType now also knows module and lesson. Rules of a collection, its folders and contents never contain module/lesson (they are rejected there with invalid at body.rule.conditions[i].targetType), rules of a course never collection/content. The release endpoints (targetType on listReleases, release, withdrawRelease) stay with collection/content.

v1.340.0 · November 2, 2026

  • Appointment types now carry waitingRoom in liveRoom (AUTO, ON, OFF; default AUTO): the waiting room in the claritos live room. Anyone who isn't the host or a co-moderator waits until the appointment goes live. AUTO lets the live room decide by type: on for lessons and group appointments, otherwise off. If the field is omitted in a PATCH, the stored value stays. Applies at every entry, so also to appointments already booked; if the host switches it in the room, that comes first. Read via appointments.getType/listTypes, set via createType/updateType.

v1.339.0 · November 2, 2026

  • Learning platform: a course from GoHighLevel can also be imported in the app as a library collection; each lesson becomes an open entry until a file is assigned. New: GET /learning/collections/{id}/missing (learning.getCollectionMissing, open and dismissed entries with path and expectedType), PUT /learning/collection-entries/{id}/media (learning.setCollectionEntryMedia, creates the content; idempotent for the same file, 409 for a different one, wrong-type or media-not-ready at body.assetId), POST /learning/collection-entries/{id}/dismiss and /reopen (learning.dismissCollectionEntry, learning.reopenCollectionEntry, 204).
  • Course import runs (learning.getCourseImport, learning.listCourseImports, learning.startCourseImport) now have targetType (course or collection) and collectionId. Runs can now also be collections (only from the GoHighLevel importer in the app): then courseId is empty without the run having failed, and missingVideos counts the open entries. listCourseImports filters with targetType; collection runs emit no learning.courseImport.* events.

v1.338.0 · November 2, 2026

  • Learning platform, course outline: modules with POST /learning/courses/{id}/modules (learning.createModule), PATCH /learning/modules/{id} (learning.updateModule), POST /learning/modules/{id}/move (learning.moveModule), DELETE /learning/modules/{id} (learning.deleteModule; without cascade submodules and lessons move one level up, with ?cascade=true they are deleted, response with movedLessonCount, movedModuleCount, with cascade also deletedLessonCount, deletedModuleCount), POST /learning/courses/{id}/modules/order (learning.orderModules). Lessons with GET/PATCH/DELETE /learning/lessons/{id} (learning.getLesson, learning.updateLesson, learning.deleteLesson with 204), POST /learning/courses/{id}/lessons (learning.createLesson), POST /learning/lessons/{id}/move (learning.moveLesson), POST /learning/courses/{id}/lessons/order (learning.orderLessons). Quiz with PATCH /learning/lessons/{id}/quiz (learning.updateQuiz: passMark, passedText, failedText), POST /learning/lessons/{id}/questions (learning.createQuestion), PATCH/DELETE /learning/questions/{id} (learning.updateQuestion, learning.deleteQuestion with 204), POST /learning/lessons/{id}/questions/order (learning.orderQuestions). A third module level returns validation-failed with code too-deep at body.parentId, unfitting answers invalid at body.options.
  • Fixed: includeArchived=false on learning.listAccesses, learning.listCollections, learning.listContents and learning.listCourses used to return archived items as well (any non-empty value counted as true). The parameter now takes true or false.

v1.337.0 · November 2, 2026

  • Learning platform, courses: new endpoints GET /learning/courses (learning.listCourses), GET/PATCH /learning/courses/{id} (learning.getCourse with outline, learning.updateCourse), POST /learning/courses/{id}/publish (learning.publishCourse; if videos or correct answers are missing, 422 with reason course-incomplete, missingVideoCount, missingAnswerCount, fixable with confirmIncomplete: true), POST /learning/courses/{id}/archive and /unarchive, GET /learning/courses/{id}/missing (learning.getCourseMissing), PUT /learning/lessons/{id}/media (learning.setLessonMedia, 409 if media is already set) and PUT /learning/questions/{id}/answers (learning.setQuestionAnswers, correctIndexes as positions from 0).

v1.336.0 · November 2, 2026

  • Learning platform, course import: claritos now fetches an import’s files (images, videos, audio, materials) into the media library. New on each entry of files[] (GET /learning/course-imports/{id}, learning.listCourseImports): failureReason (only with failed: not-https, blocked-network, too-large, timeout, wrong-type, source-error, invalid-url, dns-failed, too-many-redirects, connection-aborted, empty, internal-error), httpStatus (only with source-error) and assetId (with done). New counts.filesPending, also in the event learning.courseImport.completed: files arrive after this event, filesPending > 0 means it is still running. Video and audio up to 2 GiB, otherwise 200 MB.

v1.335.0 · November 2, 2026

  • Learning platform, classes on an access: new endpoints GET /learning/accesses/{id}/contact-lists (learning.getAccessContactLists) and PUT /learning/accesses/{id}/contact-lists (learning.setAccessContactLists, complete set contactListIds, response with grantedCount and revokedCount). A selected class grants the access to all current members (source class), a removed one ends only those grants (event learning.access.ended with reason class); grants from other sources stay. New contactListIds on the access. learning.listAccesses now also returns notifyOnGrant, like the single read.

v1.334.0 · November 2, 2026

  • Learning platform, folders in collections (two levels: folder and subfolder): new endpoints GET/POST /learning/collections/{id}/folders (learning.listFolders, learning.createFolder), PATCH/DELETE /learning/folders/{id} (learning.updateFolder, learning.deleteFolder with movedContentCount and movedFolderCount; items and subfolders move up one level), POST /learning/folders/{id}/move (learning.moveFolder) and POST /learning/collections/{id}/items/order (learning.orderItems, folders and items of one level). New folderId on items (read, createContent, addContents, updateContent; null = top level), folderPath on search hits and folderId in learning.previewRule. A third level is rejected with the code too-deep. learning.orderContents still orders only the given items.

v1.333.0 · November 2, 2026

  • New: the contact's customer portal passkeys GET /contacts/{id}/portal-passkeys (contacts.getPortalPasskeys, contacts:read): passkeyCount, lastUsedAt and per passkey data[] with id (ID of the entry at claritos, not the credential ID), label (provider or device), createdAt, lastUsedAt. The API never returns public keys or credential IDs. Plus DELETE /contacts/{id}/portal-passkeys (contacts.removePortalPasskeys, contacts:write): removes all passkeys, for example after a lost phone; the person then signs in with a code again. Response { removedCount } with status 200, removedCount: 0 without passkeys; unknown contact not-found.

v1.332.0 · November 2, 2026

  • Conversations, sentiment: every conversation in GET /inbox/conversations and GET /inbox/conversations/{id} carries sentiment (positive, neutral, negative, null = not rated yet), the sentiment of the most recently rated incoming email. New filter sentiment (positive, neutral, negative, none = not rated yet); it sets the channel to email, because text messages are never rated. GET /inbox/conversation-counts adds sentiments { positive, neutral, negative, none }, counted over open email conversations.

v1.331.0 · November 2, 2026

  • Learning platform, course import: new endpoints POST /learning/course-imports (learning.startCourseImport, 202), GET /learning/course-imports/{id} (learning.getCourseImport) and GET /learning/course-imports (learning.listCourseImports, filters sourceSystem, sourceCourseId). A program sends a complete course (modules, submodules, lessons, quizzes with correct answers; files as addresses), claritos imports it in the background as a draft; a second import from the same origin adds to it. New events learning.courseImport.completed and learning.courseImport.failed (with reason).

v1.330.0 · November 2, 2026

  • Learning platform, several contents at once: new endpoint POST /learning/collections/{id}/contents (learning.addContents) with assetIds (1 to 50 media library files). One unpublished content is created per file at the end of the collection, in the order of assetIds; the title is the file's name in the media library. Response 201 { created, failed }; an error with one file does not stop the others, failed gives the reason per file (not-found, media-not-ready, limit-reached, failed).

v1.329.0 · November 2, 2026

  • Learning platform, email on new access: every access carries notifyOnGrant (on by default, writable in POST /learning/accesses and PATCH /learning/accesses/{id}). When it is on, a contact receives an email with the link to the portal as soon as the access takes effect for them. Every grant also carries accessEmailStatus (pending, sent, skipped, failed), accessEmailSkipReason (with skipped: disabled, alreadyActive, noEmail, companyWithContacts, ambiguousEmail, beforeIntroduction) and accessEmailAt.

v1.328.0 · November 2, 2026

  • Learning platform, recordings without full course consent: POST /learning/contents with a document of a live session not all participants consented to answers 422 precondition-failed with reason recording-consent-incomplete, consentedCount, participantCount and fixable: true; with the new field confirmIncompleteConsent: true it is created and the confirmation is recorded. Every content also carries consentConfirmation (null or confirmedAt, consentedCount, participantCount, confirmedByUserId, confirmedByApiKeyId).

v1.327.0 · November 2, 2026

  • Learning platform, search: GET /learning/contents/search (q 2 to 100 characters, limit 1 to 100, no paging). Hits in title, description, what is said (positionMs) and PDF pages (pdfPage), field matchIn, excerpt. With contactId only what that contact sees, locked hits with locked and unlockReasons; without it the whole library including drafts (draft). Term too short: 422 validation-failed at query.q.

v1.326.0 · November 2, 2026

  • Learning platform, material after the lesson: GET/PUT /appointment-types/{id}/learning-material (list from the library released at the end of every appointment of this type, recordingCollectionId for the recording as a draft, attendeesOnly), GET/PATCH /appointments/{id}/learning-material (add, hide, overriding attendeesOnly, withheld; response with releasedAt and recipientCount) and POST /appointments/{id}/learning-material/release (release now; with “attendees only” but no measurement 422 precondition-failed, reason attendance-not-measured). Releases are reported via learning.content.released with source appointment.

v1.325.0 · November 2, 2026

  • Learning platform: collections carry notifyDelivery, the team's default for notifications to participants (bellOnly, push, emailNow, emailDaily, emailWeekly, sms; null means the claritos default, i.e. weekly overview). Read in GET /learning/collections, set via POST /learning/collections and PATCH /learning/collections/{id}. The bell in the portal is always added; each member can change it for themselves. With notify: false the field is not read.

v1.324.0 · November 2, 2026

  • Learning platform: the full library via the API. Collections (GET/POST /learning/collections, PATCH /learning/collections/{id}, …/publish, …/archive and …/unarchive, POST /learning/collections/order) with a release rule as rule (match all or any, at most five conditions: immediately, afterDays, fromWeek, onDate, afterItem, afterQuiz, afterAppointment, fromLevel, manual), display and duration. Contents (GET /learning/collections/{id}/contents, POST /learning/contents from the media library assetId, a document or an https link, PATCH, …/media for a new version, …/publish, …/archive, …/unarchive, order) with usage releasedTo/seenBy. Create and maintain accesses (POST /learning/accesses, PATCH, …/archive, …/unarchive, PUT …/collections). Releases: GET /learning/releases, POST /learning/releases (manual), POST /learning/releases/withdraw, POST /learning/releases/preview (calculate a rule in advance, writes nothing). Accesses of an article: GET/PUT /articles/{id}/learning-accesses.

v1.323.0 · November 2, 2026

  • New: conversations, email threads and SMS histories in one list. GET /inbox/conversations filters by view (open, starred, closed), channel, mailbox, unread, contact tag or tag group (contactTagMode any/all), campaign (campaignId: replies since sending, as in the campaign report) and search; sort waiting puts first whoever has waited longest (waitingSince); paging uses cursor and limit as everywhere. GET /inbox/conversations/{id} returns the history, POST /inbox/conversations/update sets read, unread, star, unstar (for the person behind the key) and close and reopen (for everyone) for many at once, with results per id (updated, notFound), GET /inbox/conversation-counts the counts per view, channel, mailbox, contact tag and campaign, PUT /inbox/conversations/{id}/contact assigns a contact. inbox.listThreads and related endpoints stay unchanged.

v1.322.0 · November 2, 2026

  • New in automations: two learning platform actions. “Grant learning platform access” calls POST /learning/grants, “Revoke learning platform access” calls POST /learning/grants/revoke; the latter only revokes grants made manually, through the API or by an automation, grants from a purchase or a class stay. GET /automation-catalog lists both, the field accessId with the source learningAccess. In addition, the events learning.access.granted and learning.access.ended carry the days of the grant as grant.startDate and grant.endDate, like the grant in GET /learning/grants.

v1.321.0 · November 2, 2026

  • New area learning (learning platform, rights learning:read and learning:write): GET /learning/accesses lists the accesses, GET /learning/grants the grants of a contact or an access, POST /learning/grants grants an access (repeatable; via the API with source api, from an automation with source automation), POST /learning/grants/{id}/revoke revokes it with a reason, POST /learning/grants/revoke revokes an access from a contact. Only grants created manually, via the API or by an automation are revoked; grants from a purchase or a class answer 422 precondition-failed with reason grant-source-protected. Requires the organization right LERN_BIBLIOTHEK, otherwise 403 feature-not-available.

v1.320.0 · November 2, 2026

  • New: three learning platform events for webhooks and automations. learning.access.granted when a contact receives an access, from any source (grant.source: manual, api, automation, purchase or class). learning.access.ended when an access actually ends, by revocation or expiry, also at a later point in time, with grant.endedAt and grant.reason (manual, api, automation, payment, cancelled, ended, class or expired). learning.content.released when a collection or a content item becomes available to a contact (release.targetType collection or content, release.source rule, appointment or manual). One event per contact; the payload carries IDs, names and timestamps, no learning progress. Events are sent once the learning platform is in operation.

v1.319.0 · November 2, 2026

  • Three new rights for the learning platform in GET /organization/entitlements and in the license endpoints: LERN_BIBLIOTHEK (library), LERN_KURSE (courses) and LERN_COMMUNITY (community). They have no prerequisite; endpoints of the learning platform itself will follow.
  • DELETE /articles/{id} now also answers 409 in-use when a purchase of the article grants an access of the learning platform (usage.learningAccesses).

v1.318.0 · November 1, 2026

  • New: replies from the CRM via a SendGrid domain. PUT /sendgrid/domains/{id}/crm-replies with enabled selects a domain with a ready reply area (at most one; another domain loses the selection) or releases it; the domain carries crmReplies. The reply-to of emails from the contact is then the sender before the @ on the reply host (own sender name, otherwise the part before the @ of their sending address, only if unique, otherwise the organization's reply alias); the reply reaches that person. Without a ready reply area 422 precondition-failed with reason sendgrid-replies-not-set-up; in production, until the privacy policy addendum, reason sendgrid-personal-not-released.

v1.317.0 · November 1, 2026

  • New: record consent to appointment reminders POST /contacts/{id}/reminder-service/subscribe (contacts.subscribeReminders, contacts:write), the counterpart of contacts.unsubscribeReminders, for example for consent given during onboarding before the first appointment. Body: channels (email, sms; without it both, as far as the contact has a value) and note (required, how consent was given). Response like getReminderService plus revocationKept: channels the contact unsubscribed from themselves; nothing is recorded there. The acting person is stored with the entry; without one no-acting-user; without a value on the contact validation-failed.

v1.316.0 · November 1, 2026

  • Changed, spec unchanged: conversation.sendEmail, conversation.getComposeOptions and conversation.checkPermission also work for a contact with a client record without client data release (previously 404 not-found). The email is a normal conversation email and appears in general sent mail; client-file post is then not possible. Only callers with the release read the conversation of such a contact (conversation.list, getEntry, getReplyBasis). q in GET /outbound-emails searches each word on its own in subject, recipient address and name of the contact the email went to, with umlauts also in their spelling with e. Email campaigns: a new campaign starts with client protection off (clientProtection.enabled false); POST /email-campaigns/{id}/client-protection with enabled: false needs client data and clients:read only when emails of the campaign are already in the client area.

v1.315.0 · November 1, 2026

  • New: co-moderators for group appointments. POST /appointments/{id}/co-moderators/check shows free, busy or already per appointment before inviting; POST /appointments/{id}/co-moderators invites a team member (userId) or a contact (contactId), scope appointment or series (this and all following appointments of the recurrence; later appointments of the recurrence take them over), busy and already invited appointments are listed in skipped; POST /appointments/{id}/co-moderators/remove removes them (removed). The co-moderator gets their own invitation with a calendar file and link, is co-host in the claritos live room from entry and takes no seat; a team member with a resource is blocked for the time. 422 co-moderator-without-email, not-a-group-appointment, appointment-not-open. Participants carry isCoModerator (side PROVIDER); hosts and the contactId filter of GET /appointments do not count co-moderators.

v1.314.0 · November 1, 2026

  • Appointment types carry practiceRelevant (default false): does the appointment type concern the practice? Only then do its emails appear, in an organization with a practice, in the sent mail of the client area; otherwise in general sent mail (letters.listEmails). Read via appointments.getType/listTypes, set via createType/updateType. When switched, emails already sent move along. Switching off needs client data (clients:read, released for the API), otherwise 403 forbidden with reason practice-off-needs-client-access. Changed, spec unchanged: appointments held by phone, at the practice or as a home visit no longer get a video room; meetingUrl stays empty there.

v1.313.0 · November 1, 2026

  • Changed in the rule language, spec unchanged: a name in a formula that is the main name of exactly one lab value means that value, even if other values carry it as a search term ({{Kreatinin}} is serum creatinine, no longer mehrdeutigerName). Two values with the same main name stay ambiguous. formula in rule responses writes a name only if reading it leads back to the same target, otherwise the identifier ({{loinc:2160-0}}, {{G-A1-01}}); every formula can be sent back unchanged. Lab values of kind index or ratio without a unit of their own have no unit in formulas ({{HOMA-IR}} >= 2.5); before, the label of the system catalog counted as a unit and einheitFehlt was returned.

v1.312.0 · October 31, 2026

  • New in automations: a filter on an answer in a form for the trigger forms.response.submitted. In trigger.filter, use response.answers.‹field› with the key of an option as the value, field and option as in GET /forms/{id}/analysis (the field has the form kind:id, for example def:… or std:…). The filter matches when the answer contains the option, so with multiple choice also alongside others; yes/no is true or false. At most ten such entries per rule, all must match. GET /automation-catalog lists the filter with kind formAnswer and path response.answers. Client record forms do not report answers, so the filter never matches there.

v1.311.0 · October 31, 2026

  • Changed: DELETE /appointments/{id}/participants/{contactId} also removes the last participant of a lesson or an internal-only group appointment; the appointment stays with free seats. Before, this returned last-participant (for events the last one could already leave). The removed participant still gets their cancellation.

v1.310.0 · October 31, 2026

  • New: word cloud of free texts in GET /forms/{id}/analysis. Each free-text question carries terms (items with term, display, count, kind word, pair or answer, plus belowThreshold and hidden), counted without AI: per submission, from 3 submissions, at most 40, without email addresses, web addresses, phone numbers, numbers and filler words; other questions have terms: null. New at the top level: hiddenTerms. PUT /forms/{id}/analysis/hidden-terms with terms replaces the list of hidden terms (admins only, forms:write); a single word also hides every word pair it's part of.

v1.309.0 · October 31, 2026

  • New: GET /forms/{id}/analysis/group returns the contacts behind the filters of an analysis (period, link, language, answer as in GET /forms/{id}/analysis) as contactIds, plus withoutContact for submissions without a contact. Use it like the “Act” tab to create a contact list (POST /contact-lists, POST /contact-lists/{id}/members) or a task (POST /tasks).

v1.308.0 · October 31, 2026

  • New: response tracking of a form's personal links. GET /forms/{id}/follow-up returns for each link to a contact or prospect its status (submitted, started, opened, not-opened, expired), when and how often it was reminded and remindBlockedBy; links to a client record don't count. POST /forms/{id}/follow-up/remind with linkIds (at most 50) and templateId (message template for contacts) sends each person the template with their personal link, on behalf of the acting person through the same sending point as POST /contacts/{id}/conversation/email; requires email:write. Skipped are links that are submitted, expired, without contact or address, or reminded in the last 24 hours (skipped); without a sender 422 precondition-failed with reason no-sender.

v1.307.0 · October 31, 2026

  • New: relationships in a form's answers. GET /forms/{id}/analysis/relations checks every pair of two questions (choice, yes/no, options of a multiple choice with at least 3 mentions, numbers; personal details never) and, with contacts:read, features of the contact behind the submission (country, tags, classes, supporting partner, stage per pipeline, year created; contactFeatures). Pairs are checked across the submissions that have both features (at least 10, groups of at least 5), with Fisher's exact test, chi-squared, Mann-Whitney or Kruskal-Wallis and then the Benjamini-Hochberg correction across all pairs: findings with level relationship (q below 0.05) or hint (below 0.1), at most 20, plus checked and tooSmall. With compareA and compareB also comparison: cross table or groups with median and range, level from the same correction. Filters as for GET /forms/{id}/analysis.

v1.306.0 · October 31, 2026

  • New: AI analysis of a form. GET /forms/{id}/analysis/ai returns the summary of the latest run: statements with kind (counted, classified) and evidence (options, submissions), themes of free texts with their submissions, suggestions for new options; every number in a statement is in the fact sheet, others are not returned (discarded). POST /forms/{id}/analysis/ai starts a run (202, runId), PUT /forms/{id}/analysis/ai/setting switches it on or off per form (admins; switching off deletes summaries). The questions, counted results and free texts go to the AI; fields for name, postal address, date of birth, email address and telephone number are left out insofar as they can be recognised as such (prepared personal fields, fields of type email, phone, URL, own fields whose label sounds like it). Requires the organization's right to AI analysis (403 feature-not-available). Also new in GET /forms/{id}/analysis: dataQuality with answers to hidden questions, multiple submissions, missing required answers.

v1.305.0 · October 31, 2026

  • New: physical activity as the catalog sport of the rule language, the Compendium of Physical Activities 2024 (not yet delivered). GET /physical-activities searches a code (also partial) or words of the English description; every hit names compendium (adult, older-adult, wheelchair), group, met with metBasis (MET, MET60, METWC, not comparable with each other) and the citation in source. An entry is the code with its leading zero (01003); when a rule is saved or approved it must be imported, otherwise eintragUnbekannt. GET /standard-catalogs shows activities (count, compendia, inPlan, planRelease, sources). PATCH /standard-catalogs/sport with { inPlan } releases physical activity for the client's plan or withdraws that, only a person with the right “Approve rules”, never an automation and never the MCP (403 forbidden); the plan shows name, duration and frequency, no MET value. Without release, physical activity counts in internalLeftOut.

v1.304.0 · October 31, 2026

  • New: the WHO's ICD-11 as the catalog icd11 of the rule language, next to icd10gm (not yet delivered). GET /diagnosis-codes takes catalog (icd10gm by default or icd11); every hit now carries titleDeMissing (ICD-11 only: the German pre-release has no title for the code yet, title is then the English one), titleEn and uri (ICD-11 only; code, title and URI belong together whenever they are passed on, WHO licence). When a rule is saved or approved, an ICD-11 code must exist in the active version, otherwise eintragUnbekannt; a diagnosis never appears in a personal plan and counts in internalLeftOut. Changed: GET /standard-catalogs returns diagnoses as a list of the active diagnosis catalogs (id, version, count) instead of a single object; 1.303.0 had not been delivered yet.

v1.303.0 · October 31, 2026

  • New: foods as the catalog lebensmittel of the rule language (not yet delivered). An entry is the slug of a food from GET /foods/search; when a rule is saved or approved it must exist in the database, otherwise eintragUnbekannt. GET /rulebook-catalogs lists lebensmittel with the entries the organization's rules use. GET /standard-catalogs shows foods (count, inPlan, planRelease, sources) and the active ICD-10-GM; PATCH /standard-catalogs/lebensmittel with { inPlan } releases foods for the client's plan or withdraws that, only a person with the right “Approve rules”, never an automation and never the MCP (403 forbidden). Without release, foods stay internal and count in internalLeftOut of personal plans.

v1.302.0 · October 31, 2026

  • New: ICD-10-GM diagnoses as the catalog icd10gm of the rule language (not yet delivered). GET /diagnosis-codes?q= searches the active version for a code (also partial, E11) or words in the title, German or Russian, and returns code, official title, Russian title (titleRuFrom names the parent code when the code has none of its own), level and whether the code is codable; catalog with version and source notice, null while no version is imported. GET /rulebook-catalogs lists icd10gm once a version exists; there entries only names the codes that rules of the organization use. When a rule is saved or approved, every code in empfehlung(icd10gm; <code>) must be in the active version, otherwise eintragUnbekannt. Diagnoses never appear in a client's plan.

v1.301.0 · October 31, 2026

  • New: GET /forms/{id}/responses/export, a form's submissions as CSV. One row per submission, oldest first: ID, time (Berlin), link, language, then one column per question in the order of the form. Choices as today's label (otherwise the submission's label), numbers as numbers, measurements and grids in their own columns, a repeating group in one cell, corrections included. The same filters as GET /forms/{id}/analysis. Column headers in locale; comma for en, otherwise semicolon with decimal comma; BOM first. Client record forms only with client data enabled and clients:read.

v1.300.0 · October 31, 2026

  • New: GET /forms/{id}/analysis, the analysis of a form with the same figures as the “Analysis” page. Per question the base (shown: who was shown it; for conditional questions only where the condition applied), counts by option key including options that no longer exist (inForm: false), free texts of an “Other” option at that option (otherTexts), statistics for numbers and measurements, free texts verbatim; personal details only counted (kind: personal). Plus submissions per day and language and dropOff, the drop-off chain from the form's measurement. Filters from, to, link (personal, none or the ID of a public link), language, question with option. Client record forms only with client data enabled and clients:read.

v1.299.0 · October 30, 2026

  • Consent log (GET /consent-log): new purpose purposes.partnerAttribution (partner attribution: a purchase is attributed to the partner whose referral code brought the visitor). In older entries it is false. The export (GET /consent-log/export) has one more column for it, „Partner-Zuordnung“, after „Auf diesem Geraet angemeldet bleiben“.

v1.298.0 · October 30, 2026

  • New: client protection on email campaigns. Field clientProtection (enabled, changedAt; null without an active practice module) and PUT /email-campaigns/{id}/client-protection with { enabled }, in any status. Off: emails to recipients with a record appear in general sent mail and on the contact; those already sent move along, on brings them back into the client area. Switching off only with client data enabled, clients:read and access of the acting person to the client area (403 client-access-required); without the practice module 422 practice-module-inactive.

v1.297.0 · October 30, 2026

  • GET /organization/invitations: invitations that were never accepted (pending, expired, revoked) are deleted the day after they expire and no longer appear afterwards, not even with status=EXPIRED; a DELETE /organization/invitations/{id} on such an invitation then returns 404 instead of 204. Accepted invitations remain. The description of the status field says so.

v1.296.0 · October 30, 2026

  • New: derivation (not yet delivered). GET /personal-plans/{id}/derivation returns the run a personal plan was created from, in the shape of POST /rulebooks/{id}/compute, plus the origin of each value read (origins: date, lab report); only people with the right “Approve rules”, otherwise 403 physicians-only. GET /care-enrollments/{id}/derivation returns the suggestion a care enrollment was started from: rulebook, version and rule per template and module, with the trace as a list (level, value, origin, date); without that right only rulebook and version (physicianView: false). Plans and enrollments from before have no derivation (run or derivation empty).

v1.295.0 · October 30, 2026

  • New right FORMULAR_KI (AI analysis of forms) in GET /organization/entitlements and in the license endpoints. It has no prerequisite and unlocks the AI parts of the form analysis once they are delivered; figures and charts do not depend on it.

v1.294.0 · October 30, 2026

  • Changed (operator decision, not yet delivered): what rules say about a person is read only by people with the right “Approve rules”. POST /rulebooks/{id}/compute and GET /rule-runs/{id} otherwise answer 403 physicians-only (allowed via MCP for such a person, never for an automation without a person); GET /clients/{id}/rule-runs stays. For everyone else, personal plans come without rules on the recommendations, and recommendations that have become internal come without name, text and details.

v1.293.0 · October 30, 2026

  • Personal plans only contain lifestyle and well-being (operator decision, not yet delivered): own catalogs are internal until a person with the right “Approve rules” releases them for the plan (inPlan in PATCH /rulebook-catalogs/{key}, read as inPlan and planRelease; only in the lifestyle areas, other answers 409 area-never-in-plan). Entries carry doctorsOnly (set only by the same people, PATCH …/entries/{entryKey}). Neither via an automation or MCP (403 release-needs-person). professionalOnly is removed. On plans: internalLeftOut instead of professionalOnlyLeftOut, internalEntries, lifestyleConfirmation, gap recommendations-internal, 409 all-internal instead of professional-only; POST /personal-plans/{id}/release requires confirmLifestyle: true.

v1.292.0 · October 30, 2026

  • Changed from 1.291.0 (not yet delivered): release.waitingFor in GET /organization/license carries English values (receivables, payables, subscriptions, affiliate-sales, affiliate-claims, affiliate-credit-notes, affiliate-drafts, affiliate-clawbacks, affiliate-other, otherwise other). Releasing an organization and revoking that stay in the app (operator decision), because a deletion comes at the end.

v1.291.0 · October 30, 2026

  • New in GET /organization/license: per organization release (a running release: since, read-only until, phase read-only or stopped, backup requested and sent, what holds up the deletion, whether it can be revoked) and releasable (whether it can be released). Releasing and revoking themselves are done in the app for now.

v1.290.0 · October 30, 2026

  • New: license changes over the API, always in two steps. POST /organization/license/changes/preview calculates the change of a module (quantity, cycle) in advance: effect at once with a pro-rata invoice or at the cutoff, amount now and per period, with a checksum; POST /organization/license/changes confirms it with that checksum. POST /organization/license/cycle-change/preview and POST /organization/license/cycle-change switch the package between monthly and yearly (continue for choosable yearly modules). Confirming requires the Idempotency-Key header (422 on headers.idempotency-key); if anything changed since the preview, 409 preview-outdated. Tenant owner only; confirming also works during the read-only period. New reasons (409): no-contract, package-ending, below-usage, change-pending, contract-error; 422 on body.cycle and body.quantity.

v1.289.0 · October 30, 2026

  • New: the organization’s license over the API (license model). GET /organization/license shows the tenant’s license like the License tab (package with version, cycle, price, state, cutoff, organizations, modules, and per organization its choices and video tier), tenant owner only. GET /organization/license/choices shows this organization’s choice slots, choices and video tier (tenant owner or ORG_ADMIN). PUT /organization/license/choices chooses modules for the choice slots, PUT /organization/license/video-tier assigns a booked video tier; both tenant owner only, a free slot applies at once, a change from the next monthly cutoff, and both also work during the read-only period. Without the tenant owner 403 forbidden with reason tenant-owner-required.

v1.288.0 · October 30, 2026

  • New: the read-only period of the license model also applies to the API and the API MCP. When an organization’s license has ended, the API accepts only reading calls for 30 days; after that writing is locked as well. A writing call then gets 403 forbidden with reason license-read-only, phase (read-only or locked) and until (last day of the read-only period). Only endpoints with an exception for the phase go through; today, during the read-only period, POST /backups/runs and PUT /backups/password (backups count as export) as well as DELETE /affiliate-coupons/{id}, PATCH /affiliate-coupons/{id} with active: false and DELETE /affiliate-tracking/webhook (ending things). After the read-only period none of them goes through. Reading calls, including POST …/validate and previews, do not change; the organization’s automations keep running during the read-only period.

v1.287.0 · October 30, 2026

  • New in GET /rooms/settings: recordingStorage with the organization's storage for live room video recordings: tier (video tier, null without a tier), usedBytes, limitBytes (null without a limit) and state (free, warning from 80 %, full from 100 %, unlimited). Only video recordings whose document still exists count; the audio recording for the summary does not. When the storage is full, no new video recording starts; meetings continue without one. PATCH /rooms/settings still answers with summary only.
  • Changed behavior, spec unchanged: PATCH /organization/members/{userId} with clientAccess: true responds 403 forbidden with reason: practice-read-only when the organization's practice is read-only (module ended or read-only phase). An existing grant stays; revoking (false) always works.

v1.286.0 · October 30, 2026

  • Changed behavior on the practice endpoints (rulebooks and catalogs, rule connections and cases, personal plans, care plans, care enrollments and sessions, biomarker profiles and rule sets), spec unchanged: if an organization's practice module has ended or the organization is in its read-only period (licence model), read endpoints, requesting the PDF of a personal plan, computing without saving (POST /rulebooks/{id}/compute) and ending stay available (POST /rule-cases/{id}/withdraw, DELETE /rule-connections/{id}, POST /personal-plans/{id}/withdraw, POST /care-plans/{id}/retire); before, they answered feature-not-available. Writing endpoints then answer 403 forbidden with reason practice-read-only. Without a practice it stays feature-not-available.

v1.285.0 · October 30, 2026

  • New: PATCH /rule-connections/{id} with creditAccountId (or null) sets the partner's credit account on a rule connection, computing organization only, ORG_ADMIN only. From then on every release of a personal plan from a case of this connection books 1 credit on that account (usage); withdrawing the plan or the case reverses it; without an account nothing is booked. An unknown or closed account yields 422 on body.creditAccountId (invalid_reference). GET /rule-connections now carries creditAccount in asComputing ({ id, program, customer } or null).
  • New value PERSONAL_PLAN in source of credit entries (GET /credits/accounts/{id}): usage and reversal from a personal plan delivered to a partner organization.

v1.284.0 · October 30, 2026

  • New on care plan templates: modules. GET, POST, PUT /care-plans and POST /care-plans/validate carry modules ([{ key, name }]) and moduleKey on phases and sessions: parts that only go into a care enrollment when recommended. A phase with a module takes its sessions along; a session gets its own module only in a phase without one. Without a given key it is derived from the name (lowercase letters, digits, hyphens) and stays across versions, because rules recommend the module by it. New 422 errors on body.modules (too_big, required, duplicate) and on the moduleKey of a phase or session (invalid_reference).
  • New: variants per session, variants ([{ moduleKey, callGuideId, durationMinutes }], at most 5, one per module). If the module is chosen at the start, the variant's call guide and duration apply; the first chosen one wins. 422 on body.sessions.{n}.variants (invalid_value, required without call guide and duration); an unknown call guide or a duration the appointment type does not offer is reported as for the session, on callGuideId or durationMinutes.
  • Changed from 1.282.0: saving a draft that has modules without modules, or that has variants without any session naming variants, now answers 422 required on body.modules or body.sessions instead of 409 rejected. An empty modules list removes all modules; a session without variants loses its variants as soon as another session names the field.
  • New when starting a care enrollment (POST /care-enrollments): modules, the keys of the chosen modules. Parts of other modules do not go into the enrollment and sessions are renumbered; without the field none. GET /clients/{id}/care-plan-suggestions names the recommended ones. 422 on body.modules: invalid_reference for a key that is not part of the version, too_small if fewer than two sessions would remain. The copy carries modules (the chosen ones) and moduleKey on phases and sessions, plus variantModuleKey on sessions (the module whose variant applies); the variants themselves are not in it.

v1.283.0 · October 30, 2026

  • New on GET /rule-cases: retainUntil, the end of a case’s retention period at the computing organization: ten years after its last event (computing or withdrawal), as with the record (§ 630f (3) German Civil Code). Nothing is deleted automatically.

v1.282.0 · October 30, 2026

  • Changed behavior on POST /care-plans and PUT /care-plans/{id} (spec unchanged): if a draft has modules or per-session variants (created in the app), saving without them is rejected with 409 conflict and reason rejected instead of silently removing them. Modules and variants in the template endpoints follow in a later version; suggestions carry them since 1.281.0 (modules).

v1.281.0 · October 30, 2026

  • New on GET /clients/{id}/care-plan-suggestions: whole (whether the whole template is recommended) and modules, the template’s recommended modules with key, name and sources. A module is a part of a template (phases or sessions) that only goes into a care enrollment when recommended; a template also appears when only a module in it is recommended.

v1.280.0 · October 29, 2026

  • New: judgements on hints from other organizations’ runs go back to the computing organization, with the reason and the partner organization’s name, without the person’s name; not when the connection is revoked or the case withdrawn. PUT /care-sessions/{id}/foreign-hints/{runId}/{rule} answers with sent, foreignHints carry judgementSent. At the computing organization GET /rulebooks/{id}/hint-stats counts them (accurate/notAccurate over all, fromPartners the partners’ share); new GET /rulebooks/{id}/hint-objections (client data, clients:read): the latest objections per rule with reason, by and fromPartner.

v1.279.0 · October 29, 2026

  • New: hints from runs of other organizations in the cockpit. GET /care-sessions/{id}/hints returns foreignHints: per computing organization and rulebook the latest valid run on the record, with runId, computedBy, rulebook, versionNumber, approvedBy, computedAt, reportId and the same fields as hints. PUT /care-sessions/{id}/foreign-hints/{runId}/{rule} stores the judgement (judgement, reason, runHash; only a person, never automation or MCP, 403 judgement-needs-person; a withdrawn run: 409 conflict with reason run-withdrawn). The judgement stays in your own organization.

v1.278.0 · October 29, 2026

  • New: the PDF of a personal plan. POST /personal-plans/{id}/pdf requests it (202; only for released or withdrawn plans, a draft: 409 conflict with reason not-released), GET /personal-plans/{id}/pdf reads the state (status: none, pending, ready, failed, plus documentId); when done with a signed link (url, filename, expiresAt, valid for a few minutes). One PDF is created per state of the plan; after a withdrawal the state is none, a new one carries the note. Client data, access log.

v1.277.0 · October 29, 2026

  • New: personal plans from a partner organization’s case (computing across the boundary, /rule-cases). GET /rule-cases/{id}/personal-plans lists them, POST /rule-cases/{id}/personal-plans creates a draft from the result stored with the case (language, title); a withdrawn case: 409 conflict with reason case-withdrawn. With POST /personal-plans/{id}/release a read-only copy goes into the record at the partner; if the record is gone there: 409 partner-record-missing.
  • New on plans: fromOrganization (copy from another organization, its name; otherwise null), fromCase (created from a case) and on a single plan delivered (delivered to the partner). POST /personal-plans/{id}/withdraw also withdraws a delivered copy; a copy can only be withdrawn by its source (409 foreign-plan). When the computing organization withdraws the case (POST /rule-cases/{id}/withdraw), its plans no longer apply either.

v1.276.0 · October 29, 2026

  • New: personal plans (client data, biomarkers:* and clients:*, access log). POST /clients/{id}/personal-plans computes a rulebook’s effective version (rulebookId, optional reportId) and creates a draft with the recommendations from own catalogs and their texts (409 no-recommendation, professional-only); GET /clients/{id}/personal-plans, GET/PATCH/DELETE /personal-plans/{id} (title, coverNote, remove, texts; drafts only, 409 not-draft). POST /personal-plans/{id}/release and …/withdraw only by a person with the right “Approve rules”, never automation or MCP (403 release-needs-person, approve-right-missing); release only without gaps (409 plan-incomplete with gaps). The organization’s notice: GET/PATCH /personal-plan-settings (setting it like releasing).
  • New on own catalogs: professionalOnly in GET/POST/PATCH /rulebook-catalogs…; entries of such catalogs never appear in a personal plan.

v1.275.0 · October 29, 2026

  • New: own recommendation catalogs with texts. POST /rulebook-catalogs creates a catalog (names, area: nutrition, exercise, sleep, mental, supplements, other; the key is derived from the first name and stays), GET /rulebook-catalogs/{key} reads it with all entries and texts, PATCH /rulebook-catalogs/{key} changes names, area, order or archived. Entries: POST /rulebook-catalogs/{key}/entries (names, texts per language as HTML, sanitized on save) and PATCH /rulebook-catalogs/{key}/entries/{entryKey}. A name may appear only once in a catalog (422 duplicate at body.names); too many catalogs or entries 409 too-many.
  • Changed: GET /rulebook-catalogs lists, besides the paths catalog, your own catalogs that aren’t archived (without archived entries). A rule recommends an entry like a path; a name of several words may also appear in the formula without quotation marks (recommendation(Sleep; calm breathing)).

v1.274.0 · October 29, 2026

  • GET /clients/{id}/care-plan-suggestions now also includes paths from other organizations' runs (rule-runs, the latest per computing organization and rulebook) if you have adopted their care plan: the suggestion is your own copy. New per source: computedBy (name of the computing organization, otherwise null); rulebookId is null for such sources. Care plans are adopted in the user interface only.

v1.273.0 · October 29, 2026

  • New: computing across the boundary of an organization. GET /rule-connections, POST /rule-connections (create a connection with your own rulebooks, the rech_… code is returned once and can be redeemed for seven days), POST /rule-connections/redeem (redeem another organization's code, legalBasisConfirmed: true confirms the legal basis) and DELETE /rule-connections/{id}. Creating, redeeming and revoking ORG_ADMIN only; creating and redeeming only by a person, never an automation and never via MCP (403 forbidden with reason connection-needs-person).
  • New: POST /clients/{id}/rule-runs has the other organization compute via an active connection: only the values the rulebook's effective version reads travel, plus name, date of birth, age and sex; never from an automation (403 request-needs-person). A run without formulas comes back: GET /clients/{id}/rule-runs, GET /rule-runs/{id} (result object as with compute, rules with names, unit, groups and hint). The computing organization sees its cases under GET /rule-cases and withdraws one with POST /rule-cases/{id}/withdraw (right “Approve rules”, only a person); the run at the partner then carries status: withdrawn.

v1.272.0 · October 29, 2026

  • GET /rulebook-sources now also lists grids and repeating groups of the forms on the client record: per grid cell anamnese:<block>.<row>.<column> (with a single column anamnese:<block>.<row>), per choice column of a repeating group a set anamnese:<block>.<column> over all rows and anamnese:<block>.anzahl. POST /rulebooks/{id}/compute reads them from the latest submission that answered the block, with corrections.
  • New: GET /rulebook-catalogs with the catalogs rules give recommendations from, today the catalog of paths (weg: the care plan templates, key is the first version of a template). New: GET /clients/{id}/care-plan-suggestions (careplans:read and clients:read, client data, access log) with the paths the approved rulebooks suggest for a client, each with the rules and the latest released version (plan). A suggestion starts nothing; start with POST /care-enrollments.

v1.271.0 · October 29, 2026

  • Hints in the cockpit: every rule in the responses under /rulebooks carries hint ({ color, action } with color red, gold or grey, otherwise null). When saving (PUT /rulebooks/{id}/draft/rules/{key}, POST /rulebooks/{id}/draft/validate), hint sets the hint, null removes it, omitted keeps it. Only a rule that results in yes or no can be a hint (422 on body.hint); the hint is part of the checksum. New: GET /rulebooks/{id}/hint-stats with the coaches' judgements per rule (accurate, notAccurate).
  • New in careplans: GET /care-plans/{id}/rulebooks, POST /care-plans/{id}/rulebooks (attach a rulebook, only in a draft of an own care plan, otherwise 409 plan-not-editable), PATCH /care-plans/{id}/rulebooks/{rulebookId} (active, always) and DELETE /care-plans/{id}/rulebooks/{rulebookId}. GET /care-sessions/{id}/hints returns the hints of a session (red, gold, grey, state applies or cannot-assess with missing, judgement, runHash; clients:read, access log). PUT /care-sessions/{id}/hints/{versionId}/{rule} stores the judgement (accurate, or not-accurate with reason), only by a person: never an automation, never an AI agent via MCP (403 forbidden with reason judgement-needs-person).

v1.270.0 · October 29, 2026

  • GET /rulebook-sources now lists, besides lab values and details of the person, the anamnesis from the record fields (anamnese:<key of the field>, for measurements with several parts anamnese:<key>.<part>) and the state of a care plan (plan:sitzung, plan:tag, plan:phase). Rules may read them. POST /rulebooks/{id}/compute includes the anamnesis; it does not know the state of a care plan because it computes without a session: rules that need it come out as unknown (unknown).
  • Changed: callMinutes in GET /affiliates/activity now counts only the duration of conversations: calls with a finished call note that records more than a voicemail, or with a call guide and a result, and answered calls without a note of 30 seconds or more that are not a voicemail. Previously it counted the duration of every answered call, voicemails included, so values may be lower. calls is unchanged.
  • Changed: PATCH /organization rejects a change of type to BUSINESS or HOLDING with 409 conflict and reason: organization-limit when the license package has no free place for another business or holding organization. This applies only to packages with a set number of organizations; existing licenses without such a number are not affected.

v1.269.0 · October 29, 2026

  • New: rulebooks of the rule language under /rulebooks (biomarkers:read, biomarkers:write), the same as in the app's “Rules” area. Reading and maintaining: GET /rulebooks, GET /rulebooks/{id} (with ?version= a specific version), POST /rulebooks, PATCH /rulebooks/{id}, DELETE /rulebooks/{id} and GET /rulebook-sources (what rules can read: lab values and details of the person, with names and units). Rules in the draft: PUT /rulebooks/{id}/draft/rules/{key} as a formula (formula, in the language of the request, as in the formula line) or as a tree (expression), POST /rulebooks/{id}/draft/validate as a dry run and DELETE /rulebooks/{id}/draft/rules/{key}. Every rule comes back as a formula in three languages and as a tree. Versions: POST /rulebooks/{id}/versions (draft as a copy of the effective one), DELETE /rulebooks/{id}/draft and POST /rulebooks/{id}/draft/approve.
  • Approving (POST /rulebooks/{id}/draft/approve) is only allowed for a person with the organization's “Rules” right (otherwise 403 forbidden with reason approve-right-missing), never for an automation and never for an AI agent via MCP (403 forbidden with reason approve-needs-person): approval is a physician's decision. A version with errors answers 422, one without rules 409 version-empty. On approval a checksum over the rules is stored (checksum).
  • New: POST /rulebooks/{id}/compute with { clientId, rules? } (biomarkers:read and clients:read, plus client data enabled; the access is recorded in the access log) computes the effective version with the client's released lab values and returns the result object: values, inputs, groups, trace, the version with checksum and approval, and hash. Without an approved version 409 no-effective-version; if the rules no longer match their checksum, 409 checksum-mismatch and nothing is computed.
  • Deprecated: the eight endpoints under /biomarker-rule-sets (biomarkers.listRuleSets, getRuleSet, createRuleSet, validateRules, replaceRules, deleteRuleSet, confirmRuleSet, unconfirmRuleSet). They keep answering until 31 December 2026, with the Deprecation and Sunset headers, and are removed afterwards. In the API MCP they are hidden as of this version. Their rule sets are not carried over; create rules under /rulebooks.

v1.268.0 · October 27, 2026

  • Fixed: POST /email-campaigns/{id}/report/fetch-reasons now also assigns bounces that SendGrid reports in the same second as the send (such as immediate rejections by Gmail). SendGrid keeps the time in its suppression lists in whole seconds; such entries were treated as before the send and counted under withoutEntry.

v1.267.0 · October 27, 2026

  • Changed: after Bounces and Blocks, POST /email-campaigns/{id}/report/fetch-reasons also reads SendGrid's Invalid Emails list, but only for bounces that have no reason yet and no entry in Bounces; a match is stored like a bounce (type bounce, source suppression-list). New in the response: read.invalidEmails. A restricted key needs suppression.invalid_emails.read for this; if the permission is missing or SendGrid returns an error, read.invalidEmails is null (instead of 0 for read and empty or not needed), the reasons from Bounces and Blocks are kept and these mails count under withoutEntry.

v1.266.0 · October 27, 2026

  • New: the finder's basic settings GET /finder/settings (finder:read: enabled, brandId, taxonomyCount) and PATCH /finder/settings (finder:write, body { brandId }, null for the organisation's default board). Only organisation admins may update (otherwise 403 forbidden); if the finder is not switched on, 403 feature-not-available; a board that does not exist in the organisation, 422 validation-failed with invalid_reference at body.brandId. The boards come from GET /sites/brands. New scope finder:write: extend your keys if you want to set the setting.

v1.265.0 · October 27, 2026

  • New: merge contacts POST /contacts/{id}/merge (contacts:write). The contact in the path stays; the contacts in mergeContactIds (1 to 20, same type) are moved onto it with all their references and deleted; final. fieldSources names, per field, the id of the participant whose value applies; tags are combined. Response { contact, mergedContactIds, reassignedReferences }. 409 with reason type-mismatch, bookings-on-multiple or one per block (client-records-on-multiple, practitioner-profiles-on-multiple, sales-profiles-on-multiple, company-profiles-on-multiple, marketplace-subscriptions-on-multiple, calendars-on-multiple). The same procedure as in the app.
  • New: event contacts.contact.merged, once per merge, also from the app, with the surviving contact (contact, same form as in contacts.contact.updated), mergedContactIds and reassignedReferences. There is no contacts.contact.deleted for the deleted contacts and no contacts.contact.updated for the surviving one: move your records of the deleted ids onto the surviving contact. Until now, merging sent no event.
  • Changed: the two 409 responses of DELETE /contacts/{id} (in-use, client-record-retained) name the way POST /contacts/{id}/merge in detail.
  • Changed: contacts.contact.created now also fires for practitioners the Longevity Finder creates when reviewing a certificate, and for profiles taken over one at a time from another directory. Every new contact now fires it, whichever way it is created; bulk imports and bulk takeovers remain the exception (1.263.0), as do test cases claritos hands over to an organization for practice.

v1.264.0 · October 27, 2026

  • New: campaign report GET /email-campaigns/{id}/report with delivery, bounce reasons (SMTP code, SendGrid category, server response without email addresses), batches, providers, domains, consequences (block list, withdrawals, not counting the revocation of an import's consents), replies, clicks by link, opens and booked appointments; plus the halt with SendGrid's message (run.providerMessage, run.haltMeaning). Requests that were probably not a person (security filters, prefetches) are counted separately (botClicks, prefetches).
  • New: GET /email-campaigns/{id}/recipients (cursor pagination, filters group, batch, domain, provider, reasonType, smtpCode, reasonCategory, search, updatedSince) and GET /email-campaigns/{id}/recipients/{recipientId} with the history of all events, suppression, consent, replies (conversation, time and sentiment only), clicks, opens and appointments (appointmentId, appointmentTypeId, appointmentTypeName in the organization's main language, status as in GET /appointments). Both also require contacts:read.
  • New: POST /email-campaigns/{id}/report/fetch-reasons fetches bounce reasons from SendGrid's suppression lists (nothing is changed at SendGrid; repeatable); 409 with reason sendgrid-suppression-forbidden if the key may not read the lists. New: GET/PUT /email-campaigns/tracking with clicksPerPerson (clicks per person or per link only, organization setting; admins only can change it).
  • New: events campaigns.email.clicked and campaigns.email.opened, only for requests that probably came from a person; sent about eight seconds after the request, so that a security filter opening all links of an email at once is detected first. occurrence is first for a recipient's first click on this link or their first open, otherwise repeat. contactId, recipientId and occurrence are only included if the organization counts clicks per person (otherwise null); if it counts per link only, claritos filters programs without a browser, too early requests and HEAD, but not bursts, since no request carries a person. Both are automation triggers, with a filter on one campaign and on occurrence. Changed: campaigns have the field measureOpens (measure opens with an own image, default off), readable and settable on create and update.

v1.263.0 · October 27, 2026

  • Changed: contacts.contact.created now also fires for these new contacts: a new buyer from a checkout (also when a licence is set up), in the affiliate programme (approving an application, closer service, team in the partner portal, an additional person from the application form, an adopted prospect), a contact person adopted from a letter, a new business partner when a receipt is created, and relatives a customer adds in the portal. If the new contact carries tags, contacts.tag.added fires for each tag, as with POST /contacts. If an existing contact is used, no event fires.
  • Changed: bulk takeovers no longer send events, neither contacts.contact.created nor contacts.tag.added: the takeover of Stripe customers, DATEV master data and the portal's partner list in accounting, and the credits master data import, including via POST /credits/import-profiles/{id}/master-data. Previously one event fired per new contact, and a single run often creates hundreds. This also applies to the contact person such a takeover creates when a person with a VAT ID becomes a company. If claritos instead splits an existing contact this way (matching to DATEV, a changed VAT ID in the partner list, sorting sole proprietorships, the contact form), contacts.contact.created still fires for the new contact person. If you need these contacts, read them after the run with GET /contacts.

v1.262.0 · October 27, 2026

  • Changed: contacts.contact.created now also fires when a form creates a new contact: submissions through a form link (/f/…), a funnel form or POST /forms/{id}/responses, a personal link (POST /forms/{id}/personal-links), and company and sales-rep profiles. Previously only contacts created by hand, through POST /contacts and from documents fired it. If the form finds an existing contact, no event fires. The rule: every new contact fires, bulk imports do not; further creation paths follow and will be listed here.

v1.261.0 · October 27, 2026

  • New: a form's licence logo in two steps, POST /forms/{id}/license-logo/upload (signed URL) and POST /forms/{id}/license-logo/confirm (only then does the form show the logo; if the file has not arrived: 422 at body.storageKey), removed with DELETE /forms/{id}/license-logo; GET /forms/{id} includes licenseLogoUrl. POST /forms/{id}/personal-links creates or finds the contact from a person's details (values with std: fields, optional documentId) and returns a prefilled link valid for seven days (url, contactId, validUntil; 201, requires forms:write and contacts:write). New reason target-not-supported (409) for forms whose target has no personal link. Archived forms: 409 archived for all four.

v1.260.0 · October 27, 2026

  • New: PATCH /forms/{id} changes a form's settings like the form builder (name, address form, public link, portal, consentMode, display, address finder, licence note, completion); slug, target, pages and consents are still set with PUT (sending them returns 422 invalid_combination); an archived form returns 409 archived. GET /forms/{id}/share-link reads and POST /forms/{id}/share-link creates the organization's share link (repeatable; new reason public-access-disabled, 409). GET /forms/{id} and the responses of POST /forms, PUT /forms/{id} and inserting a template include the settings: showProgress, showSummary, showFieldLabels, showClientHeader, reminderService, recognitionCard, translateResponses, thirdPartyMode, addressFinderMode, addressFinderPlaceholder, licenseLabel, completion. Changed: publicUrl in GET /forms and GET /forms/{id} is now only the organization's link; previously it could be an affiliate's referral link, attributing every submission through it to that affiliate. Without an organization link it is null.

v1.259.0 · October 26, 2026

  • New events contacts.websiteAnalysis.completed and contacts.websiteAnalysis.failed, exactly once per website analysis run, including runs from the portal, call guides, meetings and the API. The websiteAnalysis payload carries only identifiers and state: contactId (requested), targetContactId (holding the result), topicId, topicName, language, source (app, portal, callGuide, meeting, api), userId, partnerContactId, affiliateId, startedAt, finishedAt; for completed also pagesRead and unverifiedQuotes, for failed the fixed reason as in failure.reason of the GET. No page or result text: the result comes from GET /contacts/{id}/website-analysis. Available as automation triggers with filters on source and reason.

v1.258.2 · October 26, 2026

  • Changed: website analysis no longer has an enablement switch. enabled is dropped from the responses of GET/POST/PUT /contacts/{id}/website-analysis and GET/PUT /website-analysis/settings, and starting no longer answers 403 feature-not-available. 1.258.0 and 1.258.1 were never in production.

v1.258.1 · October 26, 2026

  • Changed: POST /contacts/{id}/website-analysis uses the organization's language when language is omitted (if de, en or ru, otherwise de) and answers 403 feature-not-available before any other check while the feature is not enabled in the environment.

v1.258.0 · October 26, 2026

  • New: website analysis on the contact. GET /contacts/{id}/website-analysis (contacts.getWebsiteAnalysis) reads conversation starters from the contact's website (current as HTML with the pages read, running, failure, history, dailyLimit); for a partner's prospect the result is kept on the company contact (targetContactId). POST (contacts.startWebsiteAnalysis, 202) starts it with topicId and language, PUT (contacts.updateWebsiteAnalysis) saves a version by hand; both require an acting user. Errors: 422 precondition-failed with reason: no-website or daily-limit-reached, 409 analysis-running, 403 feature-not-available while the feature is not enabled in the environment.
  • New: GET/PUT /website-analysis/topics (contacts.listWebsiteTopics, contacts.setWebsiteTopics) reads and replaces the topic prompts of the organization or, with campaignId, of an affiliate campaign (name, prompt, isDefault, at most 20, one default). GET/PUT /website-analysis/settings (contacts.getWebsiteAnalysisSettings, contacts.setWebsiteAnalysisSettings) reads and sets the daily limit (dailyLimit 0 to 500). Changes ORG_ADMIN only.

v1.257.0 · October 26, 2026

  • Call guides: nextCallGuideId on points and answers in the content of /call-guides (read and write), “continue with call guide …”. The exit then becomes an end: the run completes with its result, and the target guide starts in the same call. A next other than null alongside it returns 422 invalid_combination at that exit; a target that is not an active call guide of the organization returns 422 sprung-ziel-unbekannt.
  • Event callguides.run.completed: guideRun.previousRunId (the run this one was continued from with “continue with call guide …”, otherwise null) and guideRun.nextGuideId (the target call guide if the run ends with a jump, otherwise null).

v1.256.0 · October 26, 2026

  • Custom fields: GET /organization/custom-fields (with folders), POST /organization/custom-fields, PATCH /organization/custom-fields/{id}, POST /organization/custom-fields/{id}/archive and /unarchive. Reading with organization:read, writing with organization:write and ORG_ADMIN. Slug, type and entities are fixed after creation (422 immutable); options carry a fixed key, and renaming via the key leaves stored values untouched. New reasons custom-field-slug-taken and system-field (both 409).

v1.255.0 · October 26, 2026

  • Pipelines (PI.37): stages carry partnerRights (view, moveIn, moveOut, edit, delete), readable and writable via the stage endpoints (only as a whole; without view no other right). For a closing stage moveIn means closing and moveOut taking up again. partnerVisibility stays readable (derived from the rights) and writable (converted into rights, never delete); partnerRights takes precedence.

v1.254.0 · October 26, 2026

  • Pipelines (PI.31, call list): callList.businessOnly (businesses and freelancers only, B2B; the dialer never asks for consent in this pipeline, a withdrawal still blocks), writable via PATCH /pipelines/{id}. Every change is logged; callList.businessOnlyChange names the latest (at, via, userId, read-only).

v1.253.0 · October 26, 2026

  • Pipelines (PI.28, call list): stages carry onCallList (cards in the open stage are on the call list), pipelines callList with busy (followUp with busyFollowUpMinutes or end), noAnswerRetryMinutes, ringSeconds, hours (days 1–7, from, to) and firstCallStageId; writable via PATCH /pipelines/{id} (callList, partial) and on stages (onCallList). The list itself is dialed by the dialer in the portal or CRM.

v1.252.0 · October 25, 2026

  • Pipelines (PI.27): new GET /pipelines/lead-quality (from, to, optional pipelineId): entries of the sales pipelines created in the period, per source (kind form/funnel/existing with sourceId and name, otherwise via) and per campaign (utmCampaign, utmSource) with leads, open, parked, won, lost, unqualified and the shares unqualifiedShare, wonShare (0 to 1 of all leads of the group).

v1.251.0 · October 25, 2026

  • Pipelines (PI.26): entries carry leadSource (form, funnel or existing for existing prospects, with sourceId and utm from the funnel visit: source, medium, campaign), for new entries from now on. New GET/POST /pipelines/{id}/backfill: backfill of the required pipeline, adds prospects of the released partners without an open or parked entry to the first stage (running/finished/failed, candidates, created, failed); also starts by itself when couplings.prospectsRequired is switched on. Without the requirement precondition-failed (prospects-not-required), while one runs conflict.

v1.250.0 · October 25, 2026

  • Call guides (Telephony TW.48b): notReached[].cardStatusEvent accepts absence (out-of-office message); the situation template sets it on the absence situation. The values follow the pipelines' card status triggers (PI.22b).

v1.249.0 · October 25, 2026

  • Pipelines (PI.22b): new card status trigger absence (call: out-of-office message) next to busy, noAnswer, voicemail and invalidNumber, on card statuses (trigger), in the pipelines.entry.cardStatusChanged event and as situation of POST /pipelines/entries/{id}/outcome (one attempt, no stage move).

v1.248.0 · October 25, 2026

  • Pipelines, sales process (PI.25): stages name appointmentTypeIds and a role (preSetter, setter, closer). When an appointment of a named type is booked, rescheduled, cancelled or missed for the contact of an open entry, the card status follows; on a booking the host becomes responsible and holds the role of the stage, whoever was responsible until then holds the role before. New requirement kind appointment with appointmentTypeId (null = any type). Entries carry bookedAppointmentTypeIds and roles (person, name, appointment). An unknown appointment type returns invalid_reference.

v1.247.0 · October 25, 2026

  • Call guides (/call-guides, read and write): content.results[].pipelineEffect with pipelineId, stageId, reasonId, packageId, cardStatusId is the result’s effect in the pipeline on completion. content.notReached[].cardStatusEvent (busy, noAnswer, voicemail, invalidNumber, the same values as trigger in pipelines.entry.cardStatusChanged) is the event with which a situation sets the card status. Until now the API showed neither, and a PATCH with content dropped them.

v1.246.0 · October 25, 2026

  • Pipelines, sales process (PI.24): POST /pipelines/entries/{id}/outcome records an outcome on the card: card status, stage with reason (same requirements as moveEntry), package and follow-up in one call, or notReached with situation (busy, noAnswer, voicemail, invalidNumber): one attempt, never a stage move. Entries carry attemptsInStage and lastAttemptAt (every stage move resets attempts to 0). New path guide in via (outcome of a guide) in the history and in pipelines.entry.stageChanged/cardStatusChanged.

v1.245.0 · October 25, 2026

  • New: GET /contacts/{id}/phone-consent and PUT /contacts/{id}/phone-consent (contacts.getPhoneConsent, contacts.setPhoneConsent): the contact's consent to phone calls, separate from email and SMS. Response with state (granted, revoked, none), since, number, callable (yes dial: company or documented consent; ask ask first: consumer without consent; no do not dial: revoked, companies included) and history with reason and by (userId or contactId, name). PUT takes granted, reason (required, at most 2,000 characters) and optionally number, only with an acting user (no-acting-user); a non-member gets 403.
  • New: GET /contacts/{id}/reminder-service (contacts.getReminderService) and POST /contacts/{id}/reminder-service/unsubscribe (contacts.unsubscribeReminders): whether the contact may receive appointment reminders by email and SMS (email, sms, each with state, value, since), and unsubscribing from both channels, repeatable, only with an acting user who is a member.

v1.244.0 · October 25, 2026

  • Automations: the trigger pipelines.entry.cardStatusChanged has the filter “card status: one of”, listed in the catalog (GET /automation-catalog) as path toCardStatus.id with kind pipelineCardStatus. It is stored like pipelineStage as a list of IDs (the new card status); IDs that do not belong to the organization or to the selected pipelines are rejected on save.

v1.243.0 · October 25, 2026

  • Call guides: (1) callguides.run.completed now fires on the first explicit completion of a run (“complete call”) with the result the person chooses (resultId/resultName), no longer by itself once the main path reaches its end; still once per run, reopening and completing again report nothing. (2) New content.notReached on /call-guides (read and write): “not reached” situations with id, name and suggestion (hours, businessDays, manual, none). A completion with such a situation reports no callguides.run.completed; a later completion with a result reports once. Until now the API did not show the list, and a PATCH with content dropped it. (3) A checkout action may carry links: []: then only the pipeline entry’s checkout link applies; if the entry carries one, it wins even over the action’s own links. A checkout action is now incomplete only without templateId.

v1.242.0 · October 25, 2026

  • SendGrid feedback (SV.198): POST /sendgrid/events now creates only ONE webhook per SendGrid account. If the account already has one from claritos (for example from another organization on the same account), the connection attaches to it; further ones are merged. New reasons in 422 precondition-failed: sendgrid-webhook-limit (the SendGrid plan allows no further webhook) and sendgrid-webhook-forbidden (SendGrid rejected the key for webhooks); both used to come as sendgrid-events-failed, which now carries SendGrid's reason in detail. checkError can now be sendgridVerbindung.fehler.ereignisseTarif or sendgridVerbindung.fehler.ereignisseRecht. Events only reach the organization whose email they concern: bounces of another organization on the same account no longer block an address.

v1.241.0 · October 25, 2026

  • Pipelines, sales process (PI.23): packages. Pipelines carry packages (name, article, checkout link, default), PUT /pipelines/{id}/packages saves the whole list (at most one default, missing ones archived, org admins only). Entries carry packageId, packageName and checkoutLinkId; set packageId in POST /pipelines/entries, PATCH /pipelines/entries/{id} and moveEntry (article and net value from the package unless valueCents is in the same call). New requirement kind package (path body.packageId). The default is not written to new entries on its own.
  • Pipelines, support (PI.19b): a released SLA credit goes to invoicing and appears as a “discount” on the next subscription invoice or the next manual draft. New slaCredit.status scheduled with scheduledAt; if the handover fails, it stays released with handoverError, and POST …/sla-credit/release tries again.

v1.240.0 · October 23, 2026

  • Pipelines, sales process (PI.22): card status, where things stand on the card independent of the stage. Pipelines carry cardStatuses (name, colour, order, trigger), entries cardStatus and cardStatusSince. New: PUT /pipelines/{id}/card-statuses saves the whole list (missing ones are archived, org admins only), GET /pipelines/{id}/card-statuses/report returns open entries and time per stage and card status plus the changes in the period. PATCH /pipelines/entries/{id} sets cardStatusId (null = none), GET /pipelines/entries filters by cardStatusId (none = without). New event pipelines.entry.cardStatusChanged with fromCardStatus, toCardStatus, trigger and via; creation emits none, created already carries the status.

v1.239.0 · October 23, 2026

  • New: POST /invoices/{id}/collect collects an open subscription invoice right away from the subscription's card or direct debit mandate instead of waiting for the daily run. Response result: charged (card charged, confirmation via webhook) or submitted (direct debit submitted, paid once the money arrives). 409 with reason not-collectable, skipped or collection-failed.

v1.238.0 · October 23, 2026

  • New: complete a session of a care enrollment (practice BP.3a). POST /care-sessions/{id}/complete completes the session and its guide in one go: first the run with guide.outcomeId (required if the guide has outcomes) and guide.reasons (a reason per open required step; if one is missing, 422 with path body.guide.reasons.<step>); if that fails, the session stays open. POST /care-sessions/{id}/reopen reopens both. New field completedAt. Changed: running is false after completion (before: four hours from the start), and start on a completed session answers conflict with session-completed.

v1.237.0 · October 23, 2026

  • Pipelines, sales process (PI.21): fourth closing type parked (added per pipeline via POST /pipelines/{id}/stages with type: "parked", at most once). Parking requires a reason and followUpAt in the future, otherwise 422 with the path body.followUpAt (kind followUp in checkMove). Entries carry followUpAt; every move sets it anew. The forecast states parked (count, value) and does not count parked entries. The trigger pipelines.entry.closed also filters on outcome parked.

v1.236.0 · October 23, 2026

  • Appointment types carry callGuideId: the call guide (GET /call-guides) suggested during calls and meetings of this type. Read via appointments.getType/listTypes, set via createType/updateType (null for none). Only an active call guide of this organization, otherwise validation-failed at body.callGuideId.

v1.235.0 · October 23, 2026

  • Changed: PATCH /contacts/{id} carries a changed email or phone number over to the partner prospects linked to this contact, and rejects instead of letting contact and prospect drift apart: 409 conflict with reason: prospect-email-taken if another prospect of the organization already has the new email; 400 validation-failed at body.email (required) if the email of a prospect without a company name would be cleared; 409 reason: prospect-not-saved if the prospect could not be saved. In all three cases the contact is unchanged. Unchanged fields trigger nothing.

v1.234.0 · October 22, 2026

  • Pipelines, closing in support (PI.19): stages carry noReply (remindAfter, closeAfter, unit businessDays or days): reminder and closing without a reply in a stage with a paused clock, both with a short email to the customer (channel system). Entries carry noReplyRemindAt, noReplyCloseAt, previousEntryId (a reply more than 14 days after closing creates a new case; within 14 days it reopens the old one) and slaCredit (credit once per case with a breached target, with a structured calculation). New POST /pipelines/entries/{id}/sla-credit/release and …/discard (ORG_ADMIN, ORG_ACCOUNTANT; 409 sla-credit-decided, sla-credit-zero). The source of a message via the API is now human with a person's OAuth access, ai via the API MCP, otherwise automatic. The forecast states valueMode and risk; support pipelines return the expected credits there as negative values instead of null.

v1.233.0 · October 22, 2026

  • Pipelines: two names from 1.229.0 aligned with the rule for count fields before they ship: on the SLA caseCount instead of casesCount, in the entry's slaTargets[] breachCount instead of breaches.

v1.232.0 · October 22, 2026

  • Forms: POST /responses/{id}/pdf requires forms:write instead of forms:read, like every endpoint that renders a PDF (invoices.renderPdf, orders.renderPdf, time.renderReportPdf): it creates a document and starts the rendering. The status (GET /responses/{id}/pdf/{documentId}) stays at forms:read. 1.231.0 was never released with forms:read.

v1.231.0 · October 22, 2026

  • Submission PDF through the API: POST /responses/{id}/pdf renders the PDF on the organization's letterhead (202 with documentId, status pending), GET /responses/{id}/pdf/{documentId} returns the status (pending, ready with url, failed), POST /responses/{id}/pdf/{documentId}/send emails it to the client of the record. Client-record forms only with client-data release, clients:read and client-record access of the acting person; without client-record access 403 forbidden with reason client-access-required (now also for POST /form-templates/{id}/insert). Sending: 422 not-a-client-form or contact-without-email, 409 pdf-not-ready.

v1.230.0 · October 22, 2026

  • Form library templates through the API: GET /form-templates (own ones and those provided by other organizations, filter targetEntity, search q), GET /form-templates/{id} (preview in the form of address addressForm), POST /form-templates/{id}/insert (new form from the template, 201 with the definition and notes), POST /form-templates (provide an own form, with templateId as a new version) and DELETE /form-templates/{id} (own only; inserted forms stay). Reading with forms:read, writing with forms:write and only for organization admins; a client-record template only with client-record access (forbidden) and a practice profile (feature-not-available). targetEntity in GET /forms and GET /forms/{id} now lists all four targets (also VERTRIEBLER_PROFIL and VERTRIEB_FIRMENPROFIL); the responses already carried them, the description was missing.

v1.229.0 · October 22, 2026

  • Pipelines, support with SLAs (stage 4): new /pipelines/slas (read, create, update with archived, delete only when unused, otherwise 409 sla-in-use) with calendar (weeklyHours like the opening hours), deadlines per kind (firstResponse, nextResponse, update, restore, resolution) and priority with an explicit unit (minutes, hours, businessMinutes, businessHours, businessDays), consequence as a capped credit, customers. New GET/POST /pipelines/entries/{id}/messages (a reply to the customer goes out by email; the server derives source, via the API automatic). Entries carry descriptionHtml, priority, requestedPriority, sla, slaStatus, slaDueAt, slaTargets, restoredAt (writable: description, priority, restored), stages slaClock, pipelines customerPortalRequests. Events pipelines.entry.slaDueSoon, pipelines.entry.slaBreached, pipelines.message.created. New reason not-a-support-case.

v1.228.0 · October 22, 2026

  • Replace forms through the API: PUT /forms/{id} replaces a form as a whole with the same body as POST /forms (header with defaults where nothing is given, pages, elements). What the body does not know stays (releases, links, completion, display); existing submissions stay readable. Response 200 with the definition and build. targetEntity cannot be changed (422 at body.targetEntity); an archived form returns 409 conflict with reason archived as in POST /forms/{id}/responses, a slug of another form 409 form-slug-taken. Organization admins only, scope forms:write. The reason archived now has a text on the errors page.

v1.227.0 · October 22, 2026

  • Create forms through the API: POST /forms creates a form as a whole (header, pages, elements by kind: text, standardField, field with new for a new custom field, matrix, repeater; conditions in condition; checkboxes in consents), through the same builder as the form builder. Response 201 with the definition as in GET /forms/{id} plus build (createdFields, reusedFields, notes). POST /forms/validate checks the same body without saving (valid, errors, notes, planned pages, elements and fields). GET /forms/building-blocks lists standard fields, existing custom fields, field types for new fields, the condition syntax and the layout of matrix and repeater. Organization admins only (otherwise 403 forbidden); scope forms:write to create, forms:read to validate and for building blocks. Errors 422 validation-failed with path body.pages.<i>.elements.<j>… (indexes from 0) and code invalid_reference, required, invalid_value, invalid_combination or too_big; a slug that is taken returns 409 conflict with reason form-slug-taken (an error with this code in the dry run). Client-record forms only with a practice profile.

v1.226.0 · October 22, 2026

  • Forms: POST /forms/{id}/archive and POST /forms/{id}/unarchive archive a form or restore it, as in the form builder (scope forms:write, organization admins only, otherwise 403 forbidden; a key without an acting person gets no-acting-user). Response 200 with the form; a second call changes nothing. An archived form accepts nothing through its links, POST /forms/{id}/responses returns 409 (archived). New in GET /forms/{id}: consentMode, the consent mode of the form (none, optional, promotion).

v1.225.0 · October 22, 2026

  • Partner keys (lead API): besides the organization's keys there are keys bound to exactly one partner (affiliate), issued by the partner in the partner portal or by an admin of the organization. A partner key only calls GET /forms/{id}, POST /forms/{id}/responses and POST /appointment-types/{id}/partner-links, otherwise 403 forbidden with reason partner-key-endpoint; the API MCP does not accept it. It always submits for its own partner (another affiliateId returns 422 at body.affiliateId, code partner-affiliate), sees only forms released for the partner portal that create prospects (otherwise 404), and only its partner's prospects. In GET /forms/{id}, responseCount then counts only its partner's submissions and publicUrl is null. Guide: /developers/partner-leads.

v1.224.0 · October 22, 2026

  • Email campaigns in two kinds (kind: marketing or notice). A notice goes without marketing consent and without an unsubscribe link to everyone in the selection, takes templates with purpose transactional and needs no check before starting (deepCheckRequired). The content now lives in the campaign: subject, bodyHtml, subjectInformal, bodyHtmlInformal and salutation, copied from the template and editable without changing the template (template with modified). Also document (a document as a personal link per recipient, linkExpiresDays) and attachment (PDF up to 5 MB). GET /email-campaigns/setup lists kinds, personalSender and kind per template; GET /email-campaigns filters by kind, POST /email-campaigns/recipient-count takes kind. New: POST /email-campaigns/{id}/document/replace (corrected version, the links stay) and GET and PUT /email-campaigns/notice-permissions (who besides the admins may send notices). Members with this right see only notices through the API and send from their personal SendGrid address (senderLocalPart and senderDomain may then be omitted); for admins nothing changes. kind cannot be changed after creation (422 immutable). New errors: 422 unknown-field at body.bodyHtml for fields that don't exist, 403 campaign-kind-not-allowed, 422 notice-sender-missing, download-links-not-configured and campaign-document-missing.

v1.223.0 · October 22, 2026

  • Forms: two values of bookingError on POST /forms/{id}/responses now match appointments.createPartnerLink (1.220.0): prospect-without-contact instead of contact-missing and appointment-type-not-released-to-partner instead of appointment-type-not-released. The old names from 1.221.0 were never released.

v1.222.0 · October 22, 2026

  • New alert kind AUTOMATION_RUN_HALTED (in GET /organization/api-alerts and PUT /organization/api-alerts/rules/{kind}): when an automation halts a run for a fixable reason (precondition-failed with fixable: true), it notifies the owner and org admins through the bell, by email if configured, at most once per rule and reason within 24 hours. Missing required details of a pipeline stage are the exception: they still create a task.

v1.221.0 · October 22, 2026

  • Forms: POST /forms/{id}/responses optionally takes appointmentTypeId and senderContactId. With an appointment type the response additionally contains bookingUrl, the personal partner booking link of the new prospect (books with the affiliate without entering data again), or bookingError, why there is none: prospect-not-found (no prospect, e.g. without an affiliate), contact-missing, appointment-type-not-released, sender-not-in-team, booking-failed. If only the link fails, the submission remains (201). This additionally needs the scope appointments:write, otherwise 403 insufficient-scope before submitting. With a partner key the link only works for prospects of its own affiliate. Without appointmentTypeId the response is unchanged.

v1.220.0 · October 22, 2026

  • New: POST /appointment-types/{id}/partner-links (appointments.createPartnerLink) returns, given a prospectId, the partner's personal booking link for that prospect, existing or new (kind PARTNER, with contactId, affiliateId, senderContactId). Same rules as in the partner portal: only appointment types released to the partner, sender from the partner's team (optional senderContactId, otherwise the prospect's responsible person or the partner's owner). New reasons for precondition-failed: prospect-without-contact, appointment-type-not-released-to-partner.

v1.219.0 · October 22, 2026

  • Pipelines: the forecast scenarios are named worst, normal, best (in forecast.months[].weightedCents, in the buckets and in the stages' effectiveProbability), the writable stage fields probabilityWorst/probabilityBest. They replace bad/good and probabilityBad/probabilityGood from 1.218.0, which was never released.

v1.218.0 · October 22, 2026

  • Pipelines, forecast and learning: new GET /pipelines/{id}/forecast (twelve months from the current one, weighted value per month in the scenarios bad, normal, good, buckets overdue, withoutDate, later, measured share, date source; per open stage effective probability, time in stage and time to close; forecast is null without value mode revenue). Stages carry effectiveProbability (effective probability under learningMode with scenarios, measuredPercent, decidedCases) and probabilityBad/probabilityGood (scenarios set by hand, writable with POST/PATCH .../stages). Behavior: learningMode now takes effect; an entry's probability and weightedValueCents use the stage's effective probability instead of the default when not overridden (unchanged with learningMode default).

v1.217.0 · October 22, 2026

  • Pipelines: couplings carries prospectsRequired (affiliates' prospects are tracked in this pipeline; when an affiliate works on one without an entry, the portal asks to assign it) and prospectsAutomatic (create in the entry stage without asking), readable in GET /pipelines/{id}, writable with PATCH /pipelines/{id}.

v1.216.0 · October 22, 2026

  • Automations: three new actions for pipelines in the catalog (GET /automation-catalog) and in POST/PATCH /automations, one endpoint each: pipelines.createEntry (create entry), pipelines.moveEntries (set stage, also closing with a reason; the contact's most recent or all open entries, or a specific one) and pipelines.updateEntry (value, responsible person, close date). A stage's required details apply here too: if one is missing, the step fails as fixable. New filter kinds pipeline and pipelineStage ("one of") on the pipelines.entry.* triggers, outcome on closing. New date sources pipelines.entry.expectedCloseDate and pipelines.entry.rotting (entry has been in its stage too long). Field sources pipeline, pipelineStage, pipelineReason, object entry. Fixed: "one of" filters did not apply to date triggers until now.

v1.215.0 · October 22, 2026

  • Pipelines, couplings: pipelines carry couplings (quoteValue, quoteAcceptedStageId, paidMeansSuccessful, leadSources), readable in GET /pipelines and GET /pipelines/{id}, writable with PATCH /pipelines/{id} (leadSources replaces the list as a whole). New GET /pipelines/assignments and POST /pipelines/assignments/{id}/resolve: open assignments of payments, accepted quotes and leads to an entry when the entry is not unambiguous. New POST /pipelines/entries/move for automations: set the stage for a specific entry, the most recent open one or all open ones of a contact; all or nothing, missing details as precondition-failed with stage-requirements-missing and fixable: true.

v1.214.0 · October 22, 2026

  • Pipelines: stages have an optional color (one of the twelve category colours, like color in call guides; null = no colour), readable in GET /pipelines/{id} and settable with POST /pipelines/{id}/stages and PATCH /pipelines/{id}/stages/{stageId}. The pipeline carries stageColorDisplay (dot = dot next to the name, fill = header in full colour), default dot, settable with PATCH /pipelines/{id}.

v1.213.0 · October 21, 2026

  • New: lesson media for the live room (domain appointments). GET/PUT /appointment-types/{id}/lesson-media reads or replaces the appointment type’s list (assetIds, at most 50, order = position). GET/PATCH /appointments/{id}/lesson-media shows the appointment’s effective list (media) and its deviations (added, hidden); add adds items for this appointment only, hide hides items of the appointment type, a field that is set replaces its list. After the appointment has ended, 422 precondition-failed with appointment-ended. GET /lesson-media/options searches library videos and PDFs (q). Writing requires the right to manage appointments.

v1.212.0 · October 21, 2026

  • Forms, behaviour only, for submissions through the public link (/f/…): if the person is securely known (personal link to a contact, remembered device or an email address confirmed by code) and an advertising consent for exactly the address or number in the field exists that is at most 24 months old and not withdrawn, the form does not ask again. The submission (GET /forms/{id}/responses, GET /responses/{id}, forms.response.submitted) then carries no entry with purpose MARKETING for this channel; that is not a no, the consent state is kept on the contact. A ticked checkbox appears as before. Submissions through POST /forms/{id}/responses are not affected.

v1.211.0 · October 21, 2026

  • New: pipelines (domain pipelines, scopes pipelines:read and pipelines:write). GET/POST /pipelines, GET/PATCH /pipelines/{id}, stages (/pipelines/{id}/stages, order via PUT …/stages/order) and closing reasons (/pipelines/{id}/reasons); only org admins maintain pipelines and stages. Entries under /pipelines/entries: create, update, move (also closing), move/check, reopen, history. Moving applies the same requirements as the app, added up when skipping: if something is missing you get 422 with one stage-requirement error each; locked gives precondition-failed with stage-skip-locked or stage-back-locked (fixable: false), an archived pipeline pipeline-archived (fixable: true). Events pipelines.entry.created, .stageChanged, .closed, .valueChanged. Amounts as valueCents. Also DELETE /articles/{id}: 409 in-use as well when pipeline entries take their value from the article (usage.pipelineEntries).

v1.210.1 · October 21, 2026

  • Behaviour: the mollie source of the subscription forecast (/provider-subscriptions) returns figures as soon as the organization has connected Mollie with the subscriptions.read permission (new connections request it, existing ones reconnect once). Subscriptions of all the organization's Mollie profiles are read, synced nightly and via POST /provider-subscriptions/sync; netCents stays empty (Mollie gives no net amount). Until the reconnect it stays needs-reconnect. Specification unchanged.

v1.210.0 · October 21, 2026

  • New: subscription forecast for subscriptions created at the payment provider itself (not claritos's own under /subscriptions). GET /provider-subscriptions lists the mirror (filter source: stripe-connect, stripe-platform, mollie; status; contactId via the e-mail). GET /provider-subscriptions/forecast returns per currency this month from today and the next eleven months, gross or with net=true net, and per source state, syncedAt, needsReconnect. POST /provider-subscriptions/sync starts the sync (202; 409 sync-locked with retryAfter, 409 source-not-ready). Scopes subscriptions:read and subscriptions:write. Mollie reports needs-reconnect until the organization has reconnected Mollie with access to subscriptions.

v1.209.0 · October 21, 2026

  • Changed: GET /affiliates/activity now also counts emails sent from the partners' mailboxes in the partner portal (mail client and talk guides) under emails, including per person (people[].counts.emails, previously null). Only time, person and number of recipients are kept, no content; counted from the introduction. Marketing material sends only count up to the organization's first such record, otherwise the same email would appear twice. The example is corrected: previousPeriod has the same length as period.

v1.208.0 · October 21, 2026

  • New: subscription directly from the first invoice. Invoices have the field subscription (intervalMonths 1 to 60, periods 2 to 600 or null = until cancelled; null = no subscription), readable and writable via POST /invoices and PATCH /invoices/{id}. On issuing (POST /invoices/{id}/issue) the subscription is created and the invoice is its first period (billingContractId); the service period is set to that period. Errors: 422 at body.subscription…, body.contactId or body.items, 409 subscription-exists.
  • New: subscription status AWAITING_FIRST_PAYMENT (GET /subscriptions, filter status): created from an invoice, first invoice still open. Once paid, the subscription changes to ACTIVE and due follow-up invoices are created right away; cancelling the first invoice sets it to CANCELLED. Clients that only know the previous four values should not treat an unknown status as running.

v1.207.0 · October 21, 2026

  • New: GET /affiliates/activity returns affiliate activity like the dashboard card: calls and talk time, meetings (appointments and live rooms), sales with revenue per currency, new prospects, messages (email, SMS, letter) and completed tasks, per affiliate and person, for from to to (default the last 30 days) and the same length of time before. Filter affiliateId. Requires affiliate management in the license, otherwise 403 feature-not-available.

v1.206.0 · October 21, 2026

  • New: GET /contacts filters by responsible person with responsible, comma-separated (at most 20): user ids of members, me for the acting person of the key, partner for contacts looked after only by a partner. The same rule as the app's “Responsible” filter applies (a member before a partner; someone who has left the organization does not count); responsible=me matches the “Only mine” switch. A key without a creator gets 422 no-acting-user for me, an unknown value 400 validation-failed.

v1.205.1 · October 21, 2026

  • Fixed: DELETE /invoices/{id} answered 204 for a draft without deleting it (since 1.179.0; every draft not belonging to a credits run was affected). It is now deleted. If no row is deleted (for example because the draft was issued at the same moment), the endpoint answers 404 not-found instead of 204. Drafts of a credits run remain 409 credits-run.

v1.205.0 · October 21, 2026

  • Changed: POST/PATCH /message-templates accept the field {{terminlink.<appointment-type-id>}} (previously 400 unknown-field). Allowed are, for usage: contacts, appointment types with a personal link, and for the partner portal those released to partners; otherwise 400 unknown-field naming the appointment type. When sending, it becomes a personal booking link per recipient (a link in HTML). New: if it cannot be created for the contact, POST /outbound-emails and POST /sms with vorlageId respond with 422 and reason: booking-link-unavailable instead of sending with an empty spot.

v1.204.0 · October 21, 2026

  • New: reminderService in POST /appointments: the customer wants appointment reminders (reminder service), only at their explicit request, no if omitted; single appointments only, recorded for the contact's email address and mobile number with the source “API”; an earlier revocation by the customer stays. Changed: reminders before the appointment are scheduled for customers again but are only sent with this consent (checked at send time, against exactly that address or number), and each carries a link to unsubscribe. Confirmation, cancellation and rescheduling are always sent.

v1.203.0 · October 20, 2026

  • New: contactId in POST /appointment-types/{id}/links returns this contact's personal booking link, existing or new (kind PERSONAL): the appointment belongs to the contact; if the appointment type has no form, it books without further details. The appointment type needs the “personal link” release; new reasons for precondition-failed: appointment-type-not-personal, appointment-type-internal-only. Without contactId, a new open link as before.

v1.202.0 · October 20, 2026

  • New: reminderPlanId in POST /appointment-types and PATCH /appointment-types/{id} assigns a reminder plan to the appointment type (GET /appointment-reminder-plans), null means no reminders. If omitted, a new appointment type gets the organization's default plan and an existing one keeps its plan. Changed: reminders before the appointment are not scheduled for customers until they agree to the reminder service; confirmation, cancellation and rescheduling are always sent.

v1.201.0 · October 20, 2026

  • Task reminders (core KR.41). New: GET /tasks/reminder-settings and PUT /tasks/reminder-settings (tasks:read/tasks:write, writing for organization admins only) read and set the defaults: times before the due time in minutesBefore (0, 15, 60, 180, 1440, 2880, 10080; unknown values are dropped silently) and channels in channels (BELL, EMAIL, SMS). Without saved settings the bell when due applies; email and SMS only once an admin turns them on. Tasks with a due date now trigger reminders to the responsible person, also when created through the API. New on the task: dueHasTime (whether dueDate carries a time). When writing dueDate, a date alone or midnight UTC counts as without a time; without a time the task is due on its day and the reminder comes at 8:00 (Berlin). kind on SMS (GET /sms, sms.message.* events) has the new value TASK_REMINDER.

v1.200.0 · October 20, 2026

  • New: PATCH /telephony (telephony.updateOptions) turns the organization's answering machine detection on or off (answeringMachineDetection), and GET /telephony shows its state in the new field answeringMachineDetection (false without a connected account). Detection starts out on for every organization: on outgoing calls, Twilio reports whether a person, an answering machine or a fax answered; the call statistics need this to count voicemails. It runs in the background, the person called does not wait, and Twilio charges it per answered call on the organization's account. ORG_ADMIN only, scope telephony:write.

v1.199.0 · October 20, 2026

  • New: sessions of a care enrollment (practice BP.2). GET /care-enrollments/{id}/sessions lists the opened sessions, GET /care-sessions/{id} reads one. POST /care-enrollments/{id}/sessions/open opens the session at a position of the copy (created the first time, the same one afterwards), POST /care-enrollments/{id}/sessions creates an ad-hoc session outside the plan (adHoc, without position; for example in a crisis, only in an active or paused enrollment, otherwise conflict with enrollment-ended). POST /care-sessions/{id}/start starts a session: running is then true for four hours. PATCH /care-sessions/{id} sets the session type (standard, safety, gentle, catch-up, relief) with a short reason. Rights as for enrollments: careplans:read/:write and clients:read/:write, client data release, access log. The call guide run of a session has no endpoint; its ID is in guideRunId.

v1.198.0 · October 20, 2026

  • Forms, behaviour only, for submissions through the public link (/f/…): (1) For a form with advertising whose email or phone is confirmed by a link after submitting, the form asks for the advertising consent only after submitting. A “yes” is then appended to the submission: GET /forms/{id}/responses and GET /responses/{id} then show an accepted consent with purpose MARKETING that forms.response.submitted did not contain at submission time; there is no separate event for the later “yes”. A “no” leaves nothing behind. The advertising consent only takes effect with the click in the confirmation. (2) New consent type “marketing campaign”: the submit button is the request for advertising, the wording appears above it. The submission carries the consent as accepted true without a checkbox having been shown. Submissions through POST /forms/{id}/responses are not affected; there, advertising consents remain checkboxes.
  • Documentation only: the example of GET /forms/{id} now shows an optional advertising checkbox (purpose MARKETING, required false) instead of the removed request checkbox (purpose INQUIRY, since 1.197.0). The submission example keeps INQUIRY, because older submissions carry it.

v1.197.0 · October 20, 2026

  • Forms, behaviour only: the required checkbox “contact about my request” (purpose INQUIRY) is gone. Answering a request needs no consent; the form shows a privacy notice instead. GET /forms/{id} no longer lists a consent with INQUIRY in consents. Advertising consents (MARKETING) and older checkboxes that combine request and advertising (purpose null, channel email or phone) only appear when the form allows advertising; that is the default for all existing forms. Custom consents (channel CUSTOM) are unchanged. POST /forms/{id}/responses no longer requires a request checkbox for email or phone: validation-failed with body.consents.<elementId> now only comes for custom required consents and older combined checkboxes. A true sent for the removed checkbox is not an error; it is not stored. New submissions (GET /forms/{id}/responses, forms.response.submitted) and consent/consentPurposes of leads.lead.created no longer carry INQUIRY; older submissions keep it, so the value stays in the schema.

v1.196.0 · October 20, 2026

  • Changed: appointment series have up to 100 instead of 10 steps. In POST /appointment-series-templates and PATCH /appointment-series-templates/{id}, steps takes 2 to 100 steps and samePersonAsStep up to 100; likewise appointments in POST /appointment-series, {step} in /appointment-series/{id}/steps/{step} and following in POST /appointments/{id}/reschedule-with-series.

v1.195.0 · October 19, 2026

  • Changed: the text of a reminder step (bodyHtml, also in informal) in PATCH /appointment-reminder-steps/{id} now keeps only the markup of the editor: paragraphs, bold, italic, underline, strikethrough, lists and line breaks. A link becomes its text, images and attributes are removed. Confirmation, cancellation and rescheduling messages are always sent and must not carry promotional content.

v1.194.0 · October 19, 2026

  • New, ORG_ADMIN only: read the organization's API alerts (GET /organization/api-alerts: calls and errors for 24 hours and 7 days, rules per kind, last alerts, alert address), set an alert kind (PUT /organization/api-alerts/rules/{kind}) and set the alert address (PUT /organization/api-alerts/email). Also read the installations of the claritos app in LeadConnector (GET /organization/integrations/leadconnector) and disconnect one (DELETE /organization/integrations/leadconnector/{id}); installing still happens in LeadConnector itself. Scopes organization:read or organization:write.

v1.193.0 · October 19, 2026

  • New event careplans.enrollment.resumed: a paused care enrollment runs again (status ACTIVE from PAUSED). Payload as for the other careplans.enrollment.* (IDs and states only); client data, only to endpoints with clientsData. Also available as an automation trigger.

v1.192.0 · October 19, 2026

  • New: firstSessionIsOnboarding on GET /care-plans/{id} (and the responses of the other template endpoints) and on copy of care enrollments. true means: session 1 is the onboarding and is called session 0 in the app; positions, series and time windows still count from 1. Writable on POST/PUT /care-plans and in the dry run POST /care-plans/validate, optional; false if omitted, also on PUT, because the tree is replaced as a whole.

v1.191.0 · October 18, 2026

  • New: area careplans (care plans of the practice), scopes careplans:read/careplans:write, group "Contacts and clients". Templates: GET/POST /care-plans, GET/PUT/DELETE /care-plans/{id}, GET /care-plans/options, dry run POST /care-plans/validate, POST /care-plans/{id}/release, …/retire, …/versions. A plan is written as a whole tree (header, phases, sessions), only an own draft can be changed (409 plan-not-draft), gaps to release are listed in gaps. Care enrollments (client data, additionally clients:read/clients:write and client-data enablement, access log): GET/POST /care-enrollments, GET /care-enrollments/{id}, GET /clients/{id}/care-enrollments, POST /care-enrollments/{id}/events, …/status, appointments via GET …/appointment-proposal and POST …/appointments (plus appointments:read/appointments:write). Everywhere the practice licence right and an acting person with access to client records; release and retire only with the approval right. Events careplans.enrollment.started, .paused, .ended (only to endpoints with clientsData, IDs and states only).

v1.190.0 · October 18, 2026

  • New in the biomarkers domain: biomarker rule sets. GET/POST /biomarker-rule-sets, GET/DELETE /biomarker-rule-sets/{id}, PUT …/{id}/rules (rules as a whole), POST /biomarker-rule-sets/validate (dry run without saving), POST …/{id}/confirm and …/{id}/unconfirm. Conditions in English (value, unit, present/missing), markers as house-list keys. Confirming only by a person with the release right, never from an automation (403 confirm-needs-person); a confirmed rule set cannot be changed (409 rule-set-confirmed).

v1.189.1 · October 18, 2026

  • Behaviour: a deadline extension (POST /dunning/open-items/{openItemId}/extension, dueDate) now runs until the end of the granted day (UTC), not only until 00:00. On the granted day itself a second extension therefore answers 409 extension-exists, and the dunning run continues only from the following day. Stored and printed date unchanged.
  • Behaviour: DELETE /articles/{id} now also answers 409 in-use when the article is on quote or order lines (any status), in subscription contracts, on commission credit notes, in organization settings, the commission article of a campaign or attached to an access hook. usage has the fields quoteLines, orderLines, subscriptionLines, commissionCreditLines, accessHooks, organizationSettings, campaignCommissions for this. Instead of deleting: archive.

v1.189.0 · October 18, 2026

  • New: biomarkers domain (the practice’s biomarkers, only with the organization’s practice right). GET /biomarker-profiles lists the biomarker profiles with status, version, marker count and deletable/deleteBlockedBy; DELETE /biomarker-profiles/{id} deletes a profile as long as it was never used (never released, in no lab request, never passed on, no later version), otherwise 409 conflict with reason. Reading and writing need an acting person with access to client records; profiles are not client data.

v1.188.0 · October 18, 2026

  • New on mailboxes.*: attachmentHandling (receipt, receiptStack, document or null) sets how attachments sent to a shared mailbox are handled, like the per-kind addresses on inbox.claritos.io. Each kind belongs to at most one shared mailbox per organization; otherwise 409 with reason: handling-taken. Personal mailboxes always return null.

v1.187.0 · October 18, 2026

  • New scopes biomarkers:read/biomarkers:write for the practice's biomarkers (profiles with reference values). They are prepared for the endpoints that follow; until then they grant no access. Existing keys and OAuth grants do not receive them automatically.

v1.186.0 · October 18, 2026

  • New in the credits domain: billing runs (/credits/runs: preview, list, get, start, finalize, discard, cancel, send and regenerate statements; start, finalize and cancel run in the background, response 202), import (/credits/import-profiles: profiles, check, load, identifiers, carry-forward, master data; POST /credits/import-files/header; list as Base64, at most 600 KB), portal purchases (/credits/portal-purchases, invoices for them with invoices:write), commissions (/credits/commissions, reconcile) and supervisions (PUT /credits/accounts/{id}/supervision, DELETE /credits/supervisions/{id}).

v1.185.0 · October 18, 2026

  • New: credits domain (credits program, only with the organization’s CREDITS right): programs GET/POST /credits/programs, GET/PATCH /credits/programs/{id}, PUT/DELETE …/{id}/logo; accounts GET/POST /credits/accounts (list with from/to), GET/PATCH /credits/accounts/{id}, POST …/{id}/entries (manual grant or correction), PUT …/{id}/bonus-rules. Writing needs an acting person with ORG_ADMIN or ORG_ACCOUNTANT. Values in English (WEEKLY, PREPAID, USAGE, GRANT …).

v1.184.0 · October 18, 2026

  • New: time reports in the time domain: GET /time-reports (filter by project and status), GET /time-reports/preview, POST /time-reports (freeze a project’s times in a period), GET /time-reports/{id} (with the times), POST …/{id}/discard, POST …/{id}/pdf and POST …/{id}/bill (invoice draft; needs time:write and invoices:write and an acting person, emits invoices.invoice.created). Billing rejects times another report has billed in the meantime (entries-already-billed).

v1.183.0 · October 18, 2026

  • New: billing templates in the templates domain: payment terms (/payment-terms) and header and footer texts (/text-blocks), each with list, get, create, update, delete and POST …/{id}/default; informal versions under informal. Deleting archives a template still used on documents, contacts or credit-note defaults (mode: archived). Plus GET/PATCH /contacts/{id}/billing-defaults (contacts domain).

v1.182.0 · October 18, 2026

  • New: GET /payments/events (payment events of the Stripe connection, filter by severity and kind, onlyProblems), damage settlements GET/POST /settlements and GET /settlements/{id} (domain invoices; create requires an acting person and confirmGenuineDamage: true) and POST /files/rich-images (signed upload address for images in rich-text descriptions; first endpoint in the files domain).

v1.181.0 · October 18, 2026

  • Articles complete: DELETE /articles/{id} (unused only; otherwise 409 conflict with in-use and usage, then archive), icon via POST /articles/{id}/icon-upload, POST /articles/{id}/icon and DELETE /articles/{id}/icon, GET /articles/catalog-range (price range of a catalog code). Create and update now take groupName, isSelectable and catalog; reads additionally return usageCount. New event articles.article.deleted.

v1.180.0 · October 18, 2026

  • Invoices complete: POST/DELETE /invoices/{id}/service-rendered (service rendered with resolution booking, exactly once), correction notes under § 31(5) UStDV (GET/POST /invoices/{id}/correction-notes, GET …/correction-notes/{correctionId}/email, POST …/send), installment plan (GET /invoices/{id}/installment-plan, POST …/installment-plan/collect, POST …/installment-plan/accelerate), GET /invoices/{id}/fee-schedule-check (GebüH), dispatch release (POST /invoices/release-dispatch) and plan runs (GET /invoices/plan-runs, POST /invoices/plan-runs/release, POST /invoices/plan-runs/direct-debit; release and switch ORG_ADMIN only) as well as invoice for Stripe payments (GET /invoices/stripe-payments, POST /invoices/stripe-payments/prepare, POST /invoices/stripe-payments/invoice; ORG_ADMIN and ORG_ACCOUNTANT only).

v1.179.0 · October 18, 2026

  • Invoices: DELETE /invoices/{id} (drafts only; otherwise 409 conflict with not-draft, drafts of a credits run with credits-run), POST /invoices/{id}/duplicate, GET /invoices/{id}/email (suggestion), POST /invoices/{id}/send (does not issue by itself: 409 conflict with not-issued; invoices issued afterwards awaiting-release), POST /invoices/{id}/mark-sent (dispatch outside claritos, always now), GET /invoices/{id}/refund-preview, POST /invoices/{id}/pdf (render the preview and wait) and POST /invoices/{id}/pdf/regenerate (re-render the official PDF). Cancelling via POST /invoices/{id}/correct now takes refundDays (refund period).
  • Behaviour change: POST /invoices, POST /invoices/{id}/issue and POST /invoices/{id}/correct require an acting person (no-acting-user), previously 500 internal for a key without a creator. GET /invoices/{id}/pdf and POST /quotes/{id}/convert need one only when rendering or when the quote must be issued first; the e-mail suggestions (GET …/email for invoices, orders and quotes) work without a person, with the organization’s signature and sender. Duplicating an invoice now emits invoices.invoice.created.

v1.178.2 · October 18, 2026

  • Behavior, same specification: POST /open-items/{id}/payments now requires an acting person whenever a booking is created and answers 403 no-acting-user without one. Previously a key without a creator failed there with 500 internal. markOnly: true (no booking) still works without a person.

v1.178.1 · October 18, 2026

  • Behavior, same specification: POST /tasks, POST /tasks/{id}/comments and POST /time-entries (without userId) now answer 403 no-acting-user instead of 500 for an API key without a recorded creator. Before, an empty user reached the core. Nothing changes for OAuth access or keys with a creator; for POST /time-entries, an explicitly passed userId stays valid.

v1.178.0 · October 18, 2026

  • Orders complete: POST /orders (draft with the contact’s defaults, lines and sections included), PATCH /orders/{id} (until the first billing, otherwise 409 conflict with locked), DELETE /orders/{id} (drafts without number only, otherwise not-draft), POST /orders/{id}/issue (order number and PDF), POST /orders/{id}/send (order confirmation by email), GET /orders/{id}/email (suggestion), POST /orders/{id}/duplicate, POST /orders/{id}/pdf (render the preview or the issued version and wait for it), POST /orders/{id}/invoices (partial, final or deposit invoice as draft; also requires invoices:write), POST /orders/{id}/lines/{lineId}/drop and …/restore (drop a line and undo it; if the quantities changed meanwhile, 409 conflict with line-changed). Create, duplicate, issue, send and PDF require an acting person.
  • New event orders.order.sent: the order confirmation went out by email, from the app or through the API, with sentTo.
  • Behaviour change for quotes: POST /quotes, POST /quotes/{id}/issue, POST /quotes/{id}/send and GET /quotes/{id}/pdf (when a preview is rendered) now require an acting person and answer no-acting-user without one. Previously a key without a creator failed there with 500 internal.

v1.177.0 · October 18, 2026

  • Quotes complete: GET /quotes/{id}/email (proposal for the quote email with sender and whether it can be sent), POST /quotes/{id}/remind (remind now, SENT only), POST /quotes/{id}/duplicate (deep copy as draft; requires an acting person), DELETE /quotes/{id} (drafts without number only, otherwise 409 conflict with not-draft) and attachments: GET and POST /quotes/{id}/attachments, DELETE /quotes/{id}/attachments/{documentId}, PUT /quotes/{id}/attachment-order.

v1.176.0 · October 18, 2026

  • New: collection cases. GET /dunning/collection-cases (filter status: pending, released, withdrawn, all), GET /dunning/collection-cases/{id}, POST …/release (recipientEmail, coverLetterHtml; claritos compiles the case file from invoice, proof of service and reminder PDFs and sends it to the collection agency; requires an acting person) and POST …/withdraw (as long as not handed over). Release and withdraw are protected against concurrent calls (409 conflict with wrong-status).

v1.175.0 · October 18, 2026

  • New: writing reminders. POST /dunning/reminders/{id}/finalize (number, booking, PDF), …/regenerate, …/discard (drafts only), GET …/email (proposal for the reminder email) and POST …/send (missing fields from the proposal; 409 conflict with sender-reconnect-required if the mailbox must be reconnected), POST /dunning/reminders/regenerate-unsent, POST /dunning/open-items/{openItemId}/extension (deadline extension with dueDate and reason) and POST /dunning/run (dunning run, 202). Finalizing, regenerating, email and sending require an acting person (no-acting-user). New event dunning.reminder.finalized, also as an automation trigger.

v1.174.0 · October 18, 2026

  • New: dunning sets and levels, the first write endpoints in the dunning domain. GET and POST /dunning/profiles (seedPreset creates the standard levels), GET, PATCH (isDefault: true makes a set the default) and DELETE /dunning/profiles/{id} (archives), POST /dunning/profiles/{id}/duplicate; levels POST /dunning/profiles/{id}/levels, PATCH and DELETE /dunning/levels/{id}, PUT /dunning/profiles/{id}/level-order, PUT …/sepa-return-level and PUT …/extension-levels/{variant} (pre-final, post-final; without fields the template). A contact's set: GET and PUT /dunning/contacts/{contactId}/profile. Level texts with informal versions (…Informal). Scopes dunning:read and dunning:write.

v1.173.0 · October 18, 2026

  • New: event subscriptions.subscription.ended when a subscription has actually ended: on the day after the last paid day, on every path (cancellation, scheduled end, subscription switch, exhausted term), once per end. Payload subscription, endedAt (start of the day after the last paid day) and reason (cancelled or completed). Meant for “revoke access”; it is tied to the end, not to the cancellation. In addition, subscriptions.subscription.cancelled now also reports a scheduled end of contract (marketplace at the end of the term); there status stays ACTIVE until the end, cancelEffectiveDate is what counts.

v1.172.0 · October 18, 2026

  • New: subscriptions. GET /subscriptions (filters status, contactId, due), GET and PATCH /subscriptions/{id} (autoSend, ownDirectDebitOffered), POST /subscriptions/{id}/pause, /resume and /cancel (as of the end of the last invoiced period, without refund), PUT /subscriptions/{id}/payment-method (pin a Stripe payment method or switch to bank transfer with null; with MOLLIE this ends the mandate, mandateOutcome) and POST /subscriptions/generate-due (generate due follow-up invoices now). New events subscriptions.subscription.paused, .resumed and .cancelled (also when cancelled in the customer portal), also as automation triggers. Scopes subscriptions:read and subscriptions:write.

v1.171.1 · October 18, 2026

  • Access hooks now only accept public https addresses: no credentials in the address, no internal host name, no private IP address, also not after DNS resolution. POST /checkout/hooks, PATCH /checkout/hooks/{id} and POST /checkout/hooks/{id}/test otherwise answer 422 validation-failed with url-not-allowed (or dns-failed if the name does not resolve). Deliveries follow no redirects and only go to an address checked when connecting.

v1.171.0 · October 18, 2026

  • New: billing access hooks. A hook notifies an external system about payments (onIntentSucceeded, onPaymentCompleted, onPaymentFailed), e.g. to grant or revoke a course. GET and POST /checkout/hooks, GET, PATCH and DELETE /checkout/hooks/{id}, POST /checkout/hooks/{id}/rotate-secret, DELETE /checkout/hooks/{id}/secret, POST /checkout/hooks/{id}/reactivate and POST /checkout/hooks/{id}/test (202). The secret is only returned when claritos generates it (generateSecret on create, rotate-secret without your own), and only in that response; otherwise hasSecret. Assign per target: GET and PUT /checkout/hook-assignments/{targetType}/{targetId} with checkout-link, article, quote or order. Managing requires a person with ORG_ADMIN (no-acting-user or forbidden), reading and assigning do not.

v1.170.0 · October 18, 2026

  • New: checkout discount codes. GET and POST /checkout/discount-codes, GET, PATCH and DELETE /checkout/discount-codes/{id}: percentage (PERCENT, percent) or fixed deduction in cents (FIXED, amountCents), optional period, maximum redemptions, affiliate and binding to individual checkout links (checkoutLinkIds, empty = all). Without code, claritos generates a readable code, optionally with codePrefix. Filter code shows whether a code is taken, checkoutLinkId the codes that apply to a link. A redeemed code cannot be deleted (409 conflict with redeemed; use active: false instead). Scopes checkout:read and checkout:write.

v1.169.0 · October 18, 2026

  • New: checkout links. GET and POST /checkout-links, GET, PATCH and DELETE /checkout-links/{id}: links with article, price in cents, audience, requested details, payment provider (STRIPE or MOLLIE), own direct debit, add-on offers (bumps), payment plans (plans) and post-purchase offers (upsells); on write, lists replace the existing ones. Deleting only works without invoices (otherwise 409 conflict with has-invoices; use active: false instead). POST /checkout-links/{id}/personal-links creates a personal link for a contact, valid for seven days. GET and PATCH /checkout/settings: the organization's default invoice author. Scopes checkout:read and checkout:write; BUSINESS and HOLDING organizations only.

v1.168.0 · October 18, 2026

  • New scopes for billing: checkout:read/checkout:write (checkout links, discount codes, personal links, access hooks), subscriptions:read/subscriptions:write (subscriptions), credits:read/credits:write (credits program) and dunning:write (dunning). They are prepared for the endpoints that follow; until then they grant no access. Existing keys and OAuth grants do not receive them automatically.

v1.167.0 · October 17, 2026

  • New: settings for the claritos live room. On the appointment type liveRoom with classId (class for breakouts by subgroups) and summarizeBreakouts, in POST /appointment-types and PATCH /appointment-types/{id} and in every appointment type response. On the appointment GET and PUT /appointments/{id}/live-room: override class, recording and breakout summary, or reset them to the appointment type with TYPE, plus what applies (effective).

v1.166.1 · October 16, 2026

  • API MCP (/api/mcp/v1, /api/mcp/v1/compact, each also /o/{orgId}): GET now answers 405 Method Not Allowed with Allow: POST, OPTIONS. The server is stateless and sends nothing on its own; until now GET opened a stream that stayed open until the time limit. MCP clients treat 405 as intended as “no stream” and continue with POST. Without access it stays 401 with WWW-Authenticate.

v1.166.0 · October 15, 2026

  • New: check.overallScore, a campaign's overall spam score in percent (0 to 100, null without a check): technology from Rspamd's points at its thresholds (4 points 25 %, 6 points 50 %, 15 points 100 %, linear in between) and content from the AI check, combined as 1 − (1 − technology)(1 − content), with two versions the worse one. New in spamReports[].report.symbols[].origin: testSend for rules produced only by the test send to claritos; they do not count towards the overall score. Behaviour: red findings no longer block the start. POST /email-campaigns/{id}/start requires confirmWarnings: true for red as for yellow findings (otherwise 422 precondition-failed with campaign-check-warnings); campaign-check-red no longer occurs. A scheduled campaign only pauses before its time if the content changed since the check and the new check has notes.

v1.165.1 · October 15, 2026

  • Text: In GET /email-campaigns/setup, a subgroup of a class is now named “Class › Group” in smartLists[].name, so that groups with the same name in different classes can be told apart. The ID and the recipients stay the same.

v1.165.0 · October 15, 2026

  • New: assembled lists (such as classes) under /contact-lists. A list consists of individually chosen person contacts and can be divided into named subgroups; each person is in at most one subgroup. GET /contact-lists (paginated, with memberCount and subgroups), GET /contact-lists/{id} (subgroups with contactIds, plus withoutSubgroup), POST, PATCH, DELETE /contact-lists/{id}; subgroups via POST /contact-lists/{id}/subgroups, PATCH/DELETE /contact-lists/{id}/subgroups/{subgroupId} and PUT /contact-lists/{id}/subgroups/order; members via POST /contact-lists/{id}/members (with subgroupId), POST /contact-lists/{id}/members/from-selection (tags, smartListIds), PUT /contact-lists/{id}/members/subgroup and POST /contact-lists/{id}/members/remove. Reading needs contacts:read; the person who created the list or ORG_ADMIN may change it (otherwise forbidden, without an acting person no-acting-user). Reasons: 409 conflict with subgroup-name-taken, 422 precondition-failed with too-many (over 2,000 members or 100 subgroups). Companies do not become members (notPerson).

v1.164.0 · October 15, 2026

  • New: check.contentReports per version, the report of the AI content check: score (0 to 100, not a percentage), zone (none, low, elevated, high) and findings with category, strength (slight, clear, strong) and quote (verbatim from subject or text). claritos calculates the score from the findings using a fixed rubric. New in check.findings[].rule: kiRisiko (yellow, from elevated, value = score) and kiGering (info, value = score); the rules kiGewinn to kiUnserioes from 1.162.0 are no longer produced, older checks keep them. Also new in the quick check: betreffAntwort (yellow, subject starts with “Re:” or “Fwd:”) and linkTextTaeuscht (yellow, link text names a different domain than its target).

v1.163.0 · October 15, 2026

  • New: GET and PUT /organization/security-txt read and set the address for reports about security vulnerabilities (email). When set, the organization's own domains serve /.well-known/security.txt following RFC 9116; null removes it. Setting requires a person with ORG_ADMIN; an invalid address returns 422.

v1.162.0 · October 14, 2026

  • New: seven values for campaign check.findings[].rule. kiGewinn, kiGesundheit, kiDruck, kiUebertreibung and kiUnserioes (always level yellow, value is the quote from the text) report promises of money or health effects, pressure, exaggeration and unprofessional wording that an AI content check found in the template's subject or text; kiOk and kiFehler (info) say it found nothing or did not run. On production only once the privacy policy says so; until then these values do not occur there.

v1.161.0 · October 14, 2026

  • New: “My mailboxes”. GET /mailboxes/mine lists the mailboxes the acting person may open (personal and shared ones with access). GET /mailboxes/{key}/messages lists a folder (inbox, sent, archive, spam, trash), GET /mailboxes/{key}/messages/{folder}/{uid} reads a message, POST /mailboxes/{key}/messages/update sets flags, moves or removes from the mailbox. POST /mailboxes/attachments returns a signed address for an attachment, POST /mailboxes/{key}/send sends from this mailbox (personal or shared) via the organization's SendGrid account, with a record in the outbox. Reasons with 422 precondition-failed: invalid-recipients, attachment-not-uploaded, send-failed.

v1.160.0 · October 14, 2026

  • Behaviour, spec unchanged: mail from mailboxes the user behind the credential may not see (rule from GET /mailboxes) is now missing from GET /inbox/threads and the other inbox endpoints, from the contact conversation (/contacts/{id}/conversation, including mailboxes, entry and reply) and from the outbox (GET /outbound-emails, GET /outbound-emails/{id}, POST /outbound-emails/{id}/resend). A thread without a visible message and such a record count as not existing (404). A key without an acting user only sees mailboxes visible to all roles. Without restricted mailboxes nothing changes.

v1.159.0 · October 14, 2026

  • New: mailboxes. GET /mailboxes lists personal and shared mailboxes on the domain for personal emails with address and access rule (access.roles, access.rolesWithRecordAccess, access.users); POST /mailboxes, PATCH /mailboxes/{id} and DELETE /mailboxes/{id} create, change and remove shared mailboxes such as info@ (ORG_ADMIN only). GET /mailboxes/personal/me returns your own personal mailbox, PUT /mailboxes/personal/{userId}/access sets who sees its mail (your own: anyone; someone else's: ORG_ADMIN only). Reasons with 422 precondition-failed: no-personal-domain, invalid-local-part, display-name-required, not-a-member; a taken address is 409 conflict with address-taken. The rule only takes effect on inbox, outbox and conversation with one of the next versions; until then everyone sees everything as before.
  • Text: mood on inbox threads now describes the mood of the most recently classified incoming email, not only of a reply. Every genuine email will be classified, except spam and bulk mail (on production only once the privacy policy says so).

v1.158.0 · October 13, 2026

  • POST /organization/invitations accepts deliverTo: if email is on the organization's domain for personal emails, the mailbox only exists after acceptance; the invitation then goes to deliverTo (required, otherwise 422 at the field), and the name before the @ must be free (409 conflict, reason: mailbox-taken). Invitations carry deliveredTo (otherwise null).

v1.157.0 · October 13, 2026

  • Behaviour, spec unchanged: entries someone creates on a calendar device (Thunderbird, iPhone, CalDAV) are now the person's own appointments, no longer absences, unless their category is vacation, sick, training or away. A resource's absences (GET /appointment-resources/{id}) therefore no longer include own appointments; they still block the time (unless marked free). Changing an own appointment via PUT /appointment-resources/{id}/absences/{absenceId} turns it into an absence.

v1.156.0 · October 13, 2026

  • New: projectId on POST /appointments. Appointment types billed as QUOTA can now be assigned in-house (owner rule: from outside, only the customer books them in the portal). The customer's project whose free time budget covers the duration is then required; the duration is reserved on creation. If the project is missing, does not belong to the customer or the budget is insufficient, 400 on body.projectId. As a recurrence, group appointment or series the API answers 422 with precondition-failed and reason quota-single-only (previously quota-portal-only, which remains for booking links).

v1.155.0 · October 13, 2026

  • GET/PATCH /organization/letterhead carry cancellationRefundDays: the period in days (0 to 365) a cancellation invoice states for refunding an invoice already paid. Default of the cancellation dialog; outside the range 422 at the field.

v1.154.0 · October 13, 2026

  • Cancellation invoices (kind: CANCELLATION), also via POST /invoices/{id}/cancel: only the behaviour changes, the fields stay. A new cancellation invoice has bankTransferEnabled: false instead of the original invoice's value. paymentTermsText carries a fixed sentence in the invoice's language and form of address: if the invoice had not been paid, that nothing needs to be done; otherwise by which day the amount paid will be refunded. The open item for the refund to the customer falls due on that day instead of immediately. The period comes from the organization's default (14 days if nothing is set); there is no parameter on the endpoint for it. Older cancellation invoices stay unchanged.

v1.153.0 · October 13, 2026

  • finAPI: PUT /finapi/accounts/{externalAccountId}/connection returns precondition-failed with reason: finapi-terms-consent as long as the organization has not yet accepted section 11 (5) of the terms of use (bank connection via finAPI). This only concerns customers who signed up before 2026-10-13, until the change takes effect for them (FI.134). Consent is given in claritos when connecting the bank (setupUrl of GET /finapi); the API does not accept consent.

v1.152.0 · October 13, 2026

  • New GET /documents/{id}/related (scope documents:read): the related documents of a document, as under “Related documents” in the viewer. Each entry has id, title, mimeType, createdAt and relation: session (meeting document), recording (recording of the meeting), split-original/split-part (original and part of a split), signed (signed version), signing-original (original before signing), same-email (attachment of the same e-mail), same-appointment (document of the same appointment). Each document once; what the key may not see is left out (as with GET /documents).

v1.151.0 · October 13, 2026

  • SendGrid: the domain of the appointment accounts may be the one for personal mails (SV.147). Then names of people and handles of resources must be unique together; otherwise conflict with reason: address-taken (on PUT /sendgrid/domains/{id}/calendar and PUT /sendgrid/domains/{id}/personal with localParts, on PUT /sendgrid/my-sender-name without). The reasons sendgrid-domain-is-personal and sendgrid-domain-is-calendar are gone.
  • SendGrid: field automaticSecurity on each domain, receiveOnDomain when creating (POST /sendgrid/domains) and new endpoint POST /sendgrid/domains/{id}/recreate (SV.148). The domain for personal mails and appointment accounts receives on itself; replies go to the same address the mail was sent from. At SendGrid this works only without “Automatic Security” (MX and TXT records instead of CNAME; MX records carry priority), otherwise precondition-failed with reason: sendgrid-domain-automatic-security.
  • SendGrid: POST /sendgrid/domains/{id}/replies on any domain (SV.149). On a domain that carries neither personal mails nor appointment accounts the host lies below the domain, and replies, for example to campaigns, land in the organization's inbox; campaigns then give this address as reply address. In production only once the privacy policy names it (precondition-failed, reason: sendgrid-replies-not-released).

v1.150.0 · October 12, 2026

  • New: guests when creating a single appointment (POST /appointments, POST /appointment-recurrences): name and email per guest, at most the appointment type's maxGuests. Guests are created in the same operation and receive their own invitation naming the customer as the one who invited them; for a recurrence also on the following appointments. Without guests on the appointment type or for a group appointment 400.

v1.149.0 · October 12, 2026

  • New: accountEmail in a resource's calendar feed (/appointment-resources/{id}/calendar-feed): the email address of its appointment account (staff member, room, equipment), otherwise null. Rooms and equipment answer invitations to this address on their own; where there is an appointment account, appointment emails are sent from it.

v1.148.0 · October 12, 2026

  • SendGrid: calendar domain for the appointment accounts. Field calendar on each domain, calendarAvailable on the setup (GET /sendgrid) and PUT /sendgrid/domains/{id}/calendar (enabled): at most one domain per organization, never the one for personal mails, confirmed only and without an MX pointing elsewhere. POST /sendgrid/domains/{id}/replies sets up receiving on this domain on the domain itself (host is then not read). New reasons for precondition-failed: sendgrid-calendar-not-released, sendgrid-domain-is-personal, sendgrid-domain-is-calendar, sendgrid-domain-foreign-mx, dns-unavailable. Switchable only with the permissions for appointment accounts and email campaigns, not yet in production (calendarAvailable: false).

v1.147.0 · October 12, 2026

  • New: calendar feed per resource. GET/POST/PATCH/DELETE /appointment-resources/{id}/calendar-feed: state, a new secret ICS address (only in the POST response; a previous one stops working), customer names on or off, end. Without the right 412 with calendar-feed-not-enabled.

v1.146.0 · October 12, 2026

  • GET /organization/entitlements knows the new right TERMINKONTEN (subscription feed, CalDAV and own addresses for resources). It only applies together with E_MAIL_KAMPAGNEN; without it, effective is false.

v1.145.0 · October 12, 2026

  • New: reschedule appointments of a series without breaking the chain. POST /appointments/{id}/series-proposal says whether a new time fits, otherwise the allowed window and the booked following steps placed anew; POST /appointments/{id}/reschedule-with-series moves them all according to the proposal. Changed: POST /appointments/{id}/reschedule rejects a time that breaks the chain with 412 and series-chain-broken (previously it moved without checking).

v1.144.0 · October 12, 2026

  • New: GET /appointment-series lists running series with their state (open steps first, openStep.passed, next appointment) and POST /appointment-series/{id}/cancel-from cancels an appointment and all following steps; the series ends, the customer gets one cancellation naming the other appointments.

v1.143.0 · October 12, 2026

  • New: customers start an appointment series themselves. POST /appointment-series-templates/{id}/start-links with contactId returns the personal link (/t/serie/…), one per customer and template; there the customer sees a proposal (with STEPWISE only step 1) and books with one click. Changed: clientBookable now also applies to ADVANCE and is stored as sent (previously stored as false with ADVANCE). Without clientBookable 412 with series-not-client-bookable.

v1.142.0 · October 12, 2026

  • New: clients book the follow-up steps of a series themselves. Templates accept and return clientBookable (effective only together with bookingMode STEPWISE, stored as false with ADVANCE); series return it too. When a step opens, the customer gets an email with a booking link that only shows times within the step's window, and a reminder before it ends.

v1.141.0 · October 12, 2026

  • New: step-by-step appointment series. Templates and series carry bookingMode (ADVANCE as before, STEPWISE: only step 1 at first, each further step opens once the previous one has taken place). With STEPWISE, POST /appointment-series takes exactly one entry (previously at least two); POST /appointment-series/proposal then proposes only step 1. GET /appointment-series/{id} additionally returns contactId, progress and openStep (window of the open step). New POST /appointment-series/{id}/steps/{step}/proposal (free times within the window) and POST /appointment-series/{id}/steps/{step} (books the open step; not open 412 with series-step-not-open, outside the window 422 at body.startsAt).

v1.140.0 · October 12, 2026

  • New: appointment series (a sequence of different appointment types with windows). GET/POST /appointment-series-templates, PATCH /appointment-series-templates/{id} (steps with appointmentTypeId, durationMinutes, fromDay/toDay after the previous step, samePersonAsStep), POST /appointment-series/proposal (earliest complete sequence from from, books nothing; without room 412 with series-no-slots), POST /appointment-series (in advance, all or nothing) and GET /appointment-series/{id}.

v1.139.0 · October 12, 2026

  • New: GET /appointments/{id}/waitlist (waiting list of an event: state WAITING, OFFERED, ACCEPTED, EXPIRED, DECLINED, REMOVED, plus position and offerExpiresAt). Behaviour: when a seat becomes free in an event with a waiting list, the first person on the list gets an offer with a deadline; while it is open it holds the seat, also against bookings through the link.

v1.138.0 · October 12, 2026

  • Recurring series: POST /appointment-recurrences/{id}/change-from (appointmentId, startsAt, rule, end, optional duration, place, service, phone, person, skipping): a new series from a new first time with the customers of the given appointment; it and the following old appointments are cancelled; the response is the new series. Behaviour: with cancel-from and change-from, appointments are only cancelled without their own cancellation when every one of their customers gets the combined mail; for events each appointment gets its own cancellation.

v1.137.0 · October 12, 2026

  • Recurring series: POST /appointment-recurrences/{id}/end (end; the created appointments stay), POST /appointment-recurrences/{id}/cancel-from (appointmentId, optional reason: cancel this and all following; the customer gets ONE cancellation listing the others) and PATCH /appointment-recurrences/{id} (change end, e.g. to extend; not before created appointments, otherwise 422 with too_small). Behaviour: the confirmation of a series' first appointment states the rule in words.

v1.136.0 · October 12, 2026

  • New: recurring series (recurring appointments, any appointment type). POST /appointment-recurrences creates one: fields of the first appointment as for POST /appointments, plus rule (weekly with an interval of 1 to 4 and days with a time, monthlyWeekday with the nth or last weekday, monthlyDay), end (count 2 to 200, until up to two years, open) and skipHolidays/skipClosures (on by default). Computed in the appointment type's time zone; the further appointments are created in the background without their own confirmation. GET /appointment-recurrences/{id} returns rule, state, upcoming appointments and skipped ones with their reason. Appointments now carry recurrenceId. Invalid rule or end: 422 at body.rule or body.end.

v1.135.0 · October 12, 2026

  • Events (group types with internalOnly: false, not a lesson): POST /appointments may be called without participants for an event; the appointment is then created with all seats free. A selection that resolves to nobody still answers 422 with too_small. DELETE /appointments/{id}/participants/{contactId} removes the last participant of an event too (no last-participant). Customers book a seat in an existing appointment through the booking link; /appointment-types/{id}/slots still shows when the team can create an appointment.

v1.134.0 · October 12, 2026

  • Appointment types: new fields minParticipants, minParticipantsHours, minParticipantsAction (NOTIFY, CANCEL), waitlistEnabled, waitlistOfferHours (read and write; minimum and waiting list for group types, the waiting list for events only). internalOnly now returns the stored value for groups: false means event (customers book a seat), lessons stay internal. Quota only for one-to-one types (422 with quota_group). Invalid values: 422 with minimum_invalid, minimum_hours_invalid, waitlist_hours_invalid.

v1.133.0 · October 12, 2026

  • Quota appointments: new field quota on the appointment (projectId, minutes, state: HELD, CONSUMED, RELEASED; null without a quota) and POST /appointments/{id}/quota/release (reason 3 to 500 characters) releases reserved time with a record; without an open reservation 422 with quota-not-held. After the meeting the actual Zoom time becomes a time entry in the project, and the reservation turns CONSUMED.

v1.132.0 · October 12, 2026

  • Quota appointments are booked only by the customer in the portal (owner rule): POST /appointments with an appointment type in QUOTA mode now answers 422 with precondition-failed and reason quota-portal-only instead of creating an appointment without a project. A cancellation (POST /appointments/{id}/cancel) releases the reserved project time; a reschedule with a different duration adjusts the reservation.

v1.131.0 · October 12, 2026

  • Appointment types in QUOTA mode: on write (POST/PATCH /appointment-types) places are now online only (places: ["ONLINE"]) and both Zoom switches are on (recording.autoRecord, recording.fetchZoomRecordings), regardless of the input. The staffing (PUT /appointment-types/{id}/staffing) of such a type requires meetingProvider: "ZOOM" for every person and no partner role; otherwise 422 with code quota_zoom_required or quota_partner. Quota booking through the portal follows in a later version.

v1.130.0 · October 12, 2026

  • Invoices and quotes: new field contactEmail (string or null), the email address of the linked contact; null without a contact or without an address. In GET /invoices, GET /quotes, the single reads and responses and the invoices.invoice.* and quotes.quote.* events.
  • payments.checkout.* events: new fields in the checkout object: checkoutLinkName (title of the checkout link, i.e. the product; null without a title), customerName (contact of the invoice, otherwise the name entered at checkout), orderId and orderNumber (order of the invoice, otherwise null) and, only on payments.checkout.failed, failureReason: direct_debit_failed, chargeback, no_mandate or payment_failed (other reason). Existing fields stay.

v1.129.0 · October 12, 2026

  • Tasks: new field contactEmail (string or null), the email address of the linked contact; null without a contact or without an address. In GET /tasks, GET /tasks/{id}, the create and update responses and the tasks.task.* events. Workflows without a contact ID can find the contact by its address.

v1.128.0 · October 12, 2026

  • API MCP for language models: on connecting, the server sends an overview of claritos (instructions: areas in groups with one sentence each and the number of endpoints the access may use, rules, typical flows). New tool guide (overview, an area with its endpoints, or a guide from /developers). The tools' field descriptions now arrive as text; before, they carried translation keys such as apiDocs.fields.common.limit. New address /api/mcp/v1/compact (per organization /api/mcp/v1/compact/o/{orgId}) with four tools instead of one per endpoint: guide, search_endpoints, describe_endpoint, call_endpoint; same sign-in, scopes, limits and log. /api/mcp/v1 and /api/v1 stay unchanged.

v1.127.0 · October 12, 2026

  • New: GET /call-guides/options (callguides.options, ORG_ADMIN only) returns in one call everything the call guide editor offers for actions and fields: templates (sms, promotional), members, personal checkout links, forms, marketing assets, appointment types with holders and contact fields (fixed, standard, custom) with options. The IDs and keys go into the content of POST /call-guides and PATCH /call-guides/{id}.

v1.126.0 · October 12, 2026

  • New: read calls (scope calls, read only, every member). GET /calls lists calls newest first (filter missed, messages, withoutContact, contactId for owner of the number or speaker, search q, updatedSince), GET /calls/{id} reads one. The fields match the calls.call.ended event, plus voicemail and call note status. Note (note) and automatic call note (callNote) are client data: their text only with the organization's consent and a clients: permission, otherwise null with hasNote/hasCallNote.

v1.125.0 · October 12, 2026

  • Letters: POST /letters/{id}/finalize (finalize without dispatch), POST /letters/{id}/duplicate (copy as a draft), DELETE /letters/{id} (not once a number is assigned, 409 numbered-no-delete), POST /letters/{id}/cancel-signature (cancel a running signature, 409 signature-completed once completed) and POST /letters/{id}/number (assign the running number, 202, the PDF is re-rendered). Outbox: POST /outbound-emails/{id}/resend sends an email again, optionally to another address or with changed text, with its own record; not for code records, redacted content, campaigns and anonymized records (409 not-resendable).
  • Issued documents from PDF templates (certificates): GET /issued-documents, GET /issued-documents/{id}, POST /issued-documents, DELETE /issued-documents/{id} (drafts only), POST /issued-documents/{id}/finalize, POST /issued-documents/{id}/retry-file, POST /issued-documents/{id}/cancel (ORG_ADMIN only) and POST /issued-documents/{id}/letter (prepare a letter with the document attached). Issuing is open to those who write letters (ORG_ADMIN, ORG_USER), as in the app.
  • Inbox: GET /inbox/threads, GET /inbox/threads/{id}, PATCH /inbox/threads/{id} (read, archived, responsible person, contact, tags), GET /inbox/tags, GET /inbox/counts and POST /inbox/threads/{id}/task (task from the thread, additionally needs tasks:write). Attachments as document IDs (documents.downloadUrl). Threads of a contact with a client record only with client data enabled and clients:read.
  • Conversation with a contact: GET /contacts/{id}/conversation (history across email, SMS, portal and client-file posts, phone calls), GET /contacts/{id}/conversation/{source}/{entryId} and …/reply-basis, GET /contacts/{id}/conversation/compose (senders, templates, permission), GET /contacts/{id}/conversation/permission, POST /contacts/{id}/conversation/email, POST /contacts/{id}/conversation/portal-post (clients:write), POST /contacts/{id}/conversation/sms and POST /contacts/{id}/conversation/sms-preview. Reading marks nothing as read; marketing only with consent. New reason for precondition-failed: client-record-missing.

v1.124.0 · October 12, 2026

  • Appointment types: new field startWindows (read, and write in POST/PATCH /appointment-types): when an appointment of this type may begin, each entry with days (1 = Monday to 7 = Sunday), earliest and latest (HH:MM in the appointment type's time zone, both inclusive), at most 14; null or [] removes them. /appointment-types/{id}/slots then only offers times inside them, and booking and rescheduling by the customer keep to them. Invalid: 422 with path body.startWindows.

v1.123.0 · October 12, 2026

  • Logos and type of the organization: GET /organization/logos, POST /organization/logos/{kind}/upload (check format and size, signed address for the direct upload), POST /organization/logos/{kind}/confirm and DELETE /organization/logos/{kind}, each for logo and invoice-logo; for SVG and WebP a PNG version for mails is created as in the app. PATCH /organization additionally takes type (BUSINESS, HOUSEHOLD, HOLDING); a private organization keeps its type (409 conflict, reason: private-organization). Changes with organization:write and a person who is ORG_ADMIN.

v1.122.0 · October 12, 2026

  • Guests of a one-to-one appointment: POST /appointments/{id}/guests (name, email) invites a guest on behalf of the booker, DELETE /appointments/{id}/guests/{contactId} uninvites them (they get “Invitation withdrawn”, the appointment stays). Scope appointments:write and a person with “Manage scheduling”. New field isGuest on participants. New reasons for precondition-failed: group-appointment-has-no-guests, guest-limit-reached.

v1.121.0 · October 12, 2026

  • Entitlements, integrations and own domains of the organization: GET /organization/entitlements (every right with license, release, effect), GET /organization/integrations (state of every integration with the page for connecting; LeadConnector is called leadconnector there), GET/POST /organization/domains, POST /organization/domains/{purpose}/verify and DELETE /organization/domains/{purpose} (purpose app, finder, marketplace; the answer names the missing DNS records). All with a person who is ORG_ADMIN; own domains need the release by claritos, a domain of another organization answers 409 conflict with reason: taken.

v1.120.0 · October 12, 2026

  • Documents: every document carries extracted.counterpartyDetails (address with street, postalCode, city, country as ISO code, plus email, phone, website and contactPerson with name, email, phone, position) as read from the document by the AI; null if nothing was recognised. New POST /documents/{id}/counterparty-contact (scopes documents:write and contacts:write): links the document to the contact of its counterparty, like “Create contact” in the app. An already linked contact stays; otherwise a contact with exactly this name, a matching company (VAT ID, register, domain, name) or a new one with the address. Response { contactId, created }; without a counterparty 409 conflict with reason: no-counterparty.

v1.119.0 · October 12, 2026

  • New: read inbound SMS. GET /inbound-sms lists the SMS sent to the organization's number (newest first, pages like GET /sms, filter contactId, updatedSince means received since here), with contact, kind of assignment (number, personBeforeCompany, ambiguous, unknown, manual) and Twilio's opt-out keyword; GET /inbound-sms/{id} reads one. Scope sms, permission sms:read.

v1.118.0 · October 12, 2026

  • Salutation and legal texts of the organization: GET/PATCH /organization/salutation (formal or informal by default, informal for individual contacts, formal required per document type, greeting), GET/PATCH /organization/legal-texts (all legal texts including defaults, data protection officer and supervisory authority), PUT/DELETE /organization/legal-texts/{kind} (set the organization's own text, the version increases; back to the default). Read with organization:read, change with organization:write and a person who is ORG_ADMIN. A private organization has no legal texts (403 feature-not-available).

v1.117.0 · October 12, 2026

  • Contact, opening hours and letterhead of the organization: GET/PATCH /organization/contact (visiting address, phone, e-mail for website and portal), GET/PUT /organization/opening-hours (up to two spans per weekday) and GET/PATCH /organization/letterhead (business stationery: legal name, legal form, address, tax and register data, managing directors, bank, letterhead form, articles for time billing and returned direct debits). Read with organization:read, change with organization:write and a person who is ORG_ADMIN; PATCH changes only what is sent, checked as in the settings (422 with field).

v1.116.0 · October 12, 2026

  • Presentation only, no endpoint changed: the spec groups the areas (x-tagGroups, such as “Contacts and clients”, “Sales and invoicing”). Every tag carries a display name (x-displayName) and, as its description, a sentence on what the area is for. The tag names themselves (contacts, invoices …) stay as they are.

v1.115.0 · October 12, 2026

  • Appointment types: new field maxGuests (read, and write in POST/PATCH /appointment-types): how many more people the booker may invite to their appointment, 0 to 20, only with one seat (otherwise always 0). Invalid: 422 with code guests_invalid.

v1.114.0 · October 12, 2026

  • Write members and invitations (scope members:write, a person with ORG_ADMIN as in the Members tab): PATCH /organization/members/{userId} (role ORG_ADMIN/ORG_USER, visibility, access to client records, translator languages), DELETE /organization/members/{userId}, POST /organization/invitations (invitation by e-mail, link valid for seven days) and DELETE /organization/invitations/{id}. The acting person never changes or removes themselves (403 forbidden, reason: self), the last ORG_ADMIN stays (409 conflict, reason: last-admin); already a member or already invited answers 409 conflict with reason: already-member or already-invited.

v1.113.0 · October 12, 2026

  • Postal accounts through the API (area letters): GET /postal-account (which provider the queue sends through, its balance, pause, waiting letters; ORG_ADMINs also see LetterXpress and Pingen in detail in accounts) and POST /postal-account/resume-queue (lift the pause, send the waiting letters, 202). LetterXpress and Pingen are connected and disconnected only in the app; the API does not accept their credentials.

v1.112.0 · October 12, 2026

  • Read Meta datasets: GET /organization/meta-datasets (pixel and Conversions API: name, pixel ID, test code, hasToken), with organization:read and a person who is ORG_ADMIN. The API never returns the token; creating and changing them stays in the app, as with SendGrid.

v1.111.0 · October 12, 2026

  • The brand board through the API (area sites): boards with GET/POST /sites/brands, GET/PATCH/DELETE /sites/brands/{id}, POST /sites/brands/{id}/default and POST /sites/brands/{id}/publish; fonts with GET/POST /sites/brands/{id}/fonts (own font, upload address), POST /sites/brands/{id}/fonts/google (import a Google font, search via GET /sites/google-fonts) and DELETE /sites/brands/{id}/fonts/{fontId}; logos with GET /sites/brands/{id}/logos, POST/DELETE /sites/brands/{id}/logos/{slot}. PATCH changes only what is sent (objects are merged). Reading with sites:read, writing with sites:write and a person who is ORG_ADMIN (as in the brand board). The last board cannot be deleted (409, last-board); a font already imported answers 409 with font-already-imported. The brand board's AI advisors stay in the app.

v1.110.0 · October 12, 2026

  • Bank connections (scope banking): GET /bank-connections and GET /bank-connections/{id} (with the public key for WISE), POST /bank-connections/{id}/sync (fetch statements), GET /revolut (setup status including the address in claritos), GET /revolut/accounts and PUT /revolut/accounts/{externalAccountId}/connection (connect an account of a released access), GET /finapi, PUT /finapi/accounts/{externalAccountId}/connection and POST /finapi/banks/{bankConnection}/refresh. Connecting with a key, signing in at Revolut or finAPI and disconnecting stay in claritos; no key and no bank sign-in goes through the API.

v1.109.0 · October 12, 2026

  • New: set up telephony and the SMS sender (scope telephony, ORG_ADMIN only). GET /telephony shows account, voice setup, all numbers and the settings of the active ones; POST /telephony/setup sets up voice; POST /telephony/numbers activates a number (asking back with activated: false if another system is already there, confirmed with overwrite: true); GET/PATCH/DELETE /telephony/numbers/{id} read, update (strict, call notes only with callNotesNoticeConfirmed: true) and deactivate; greeting via POST /telephony/numbers/{id}/greeting/upload, PUT and DELETE /telephony/numbers/{id}/greeting. Twilio: GET /telephony/twilio, GET /telephony/twilio/numbers, PUT /telephony/twilio/sender, POST /telephony/twilio/inbound. Only the interface connects and disconnects the Twilio account (settingsUrl); foreign addresses on a number are given as host only.

v1.108.0 · October 12, 2026

  • Organization affiliate settings through the API (area affiliates): coupon codes with GET/POST /affiliate-coupons, GET/PATCH/DELETE /affiliate-coupons/{id} (switch on and off with active), attribution tracking with GET /affiliate-tracking (address of the conversion webhook, credentials only masked) and DELETE /affiliate-tracking/webhook (switch off), climate contribution with GET/PUT /affiliate-climate-contribution (0, 50, 100 or 150 basis points). Reading with affiliates:read, writing with affiliates:write and a person who is ORG_ADMIN (as in the tab). The API does not create or show conversion webhook credentials: that is only possible in the app. A coupon code already in use answers 409 with the reason coupon-code-taken.

v1.107.0 · October 12, 2026

  • The organization's backup and consent log: GET /backups (settings and the last 20 runs), PATCH /backups/settings (interval, coverage, recipients), POST /backups/runs (start a backup, 202 with the run), GET /backups/runs/{id} and PUT /backups/password (set the archive password or remove it with null; it is never returned). Plus GET /consent-log, GET /consent-log/summary and GET /consent-log/export (CSV), read-only. Scopes backups:read/backups:write and consentlog:read, all only for a person with ORG_ADMIN, as in the tab. New reasons for precondition-failed: backup-running and backup-recipients-required.

v1.106.0 · October 12, 2026

  • Update the organization: PATCH /organization (scope organization:write, a person with ORG_ADMIN as in the settings) for name, base currency, country, price mode, practice profile, industry, inbox address (inboxSlug), reply alias (replyAlias) and e-mail signature; all or nothing, the same checks as in the app. Invalid input answers 422 with field and code, an inbox slug or reply alias already in use 409 conflict with reason: taken, a practice profile without the practice module 403 feature-not-available. GET /organization additionally returns inboxSlug, replyAlias, replyAddress, industryCode, defaultPriceMode and emailSignatureHtml.

v1.105.0 · October 12, 2026

  • Appointment mailbox: GET /appointment-mailbox (connected Gmail mailbox, state, reply address; every member) and DELETE /appointment-mailbox (disconnect, with the “Manage scheduling” permission; appointment mail then continues with the business paper address). Connecting happens only in claritos (consent at Google).

v1.104.0 · October 12, 2026

  • New scopes for the organization's settings (endpoints follow in the next versions): members:write (members, roles, invitations; members was read-only so far), backups:read/backups:write (backups), consentlog:read (website consent log, read-only) telephony:read/telephony:write (telephony and SMS sender setup) and banking:read/banking:write (bank connections). Through OAuth the first four are granted only to ORG_ADMINs of the organization, as with webhooks:manage; banking:read is open to every member, as in the user interface.
  • LeadConnector app: three new payment triggers, checkout_pending (payment started; with SEPA no money yet), checkout_completed (payment received) and checkout_failed (failed, charged back or instalment missed), on the payments.checkout.* events; and the action invoice-issue (finalize an invoice, invoices:write), whose response carries documents with PDF status and URL and the URL of the ZUGFeRD XML, with pending: xml-not-ready while it is generated. The /api/v1 interface does not change.

v1.103.0 · October 12, 2026

  • Appointment groups, partner release and calendars: GET/POST /appointment-groups, GET/PATCH/DELETE /appointment-groups/{id} (several appointment types on one page; as in the tab, reading also needs the “Manage scheduling” permission), GET/PUT /appointment-types/{id}/partner-release (visibility in the partner program) and GET /appointment-resources/{id}/calendars (a resource's chosen Google calendars, read-only; the API does not give out the calendar lists of Google accounts). With this the appointments area can be fully set up through API and MCP.

v1.102.0 · October 12, 2026

  • Set up reminder plans: GET/POST /appointment-reminder-plans, GET/DELETE /appointment-reminder-plans/{id} (removing archives), POST /appointment-reminder-plans/{id}/steps, PATCH/DELETE /appointment-reminder-steps/{id}, POST /appointment-reminder-steps/{id}/move and POST /appointment-reminder-preview (sample values filled in, unknown variables named). The list states the language of the texts and the catalog of variables. Reading with appointments:read, setting up with appointments:write and a person who is ORG_ADMIN (as in the tab). A text with an unknown variable answers 422 with the code unknown_variable.

v1.101.0 · October 12, 2026

  • Set up closures and places: GET/POST /appointment-closures, PATCH/DELETE /appointment-closures/{id} (public holiday, bridge day, company closure, other; all day or with a time window; affectedAppointments counts existing appointments in the period, which stay), PUT /appointment-bridge-day-rule (closed on all bridge days), POST /appointment-closures/{id}/keep-open and DELETE /appointment-bridge-day-rule/kept-open/{date} (keep a bridge day open or close it again), GET /appointment-places, POST/PATCH/DELETE /appointment-phones[/{id}], POST/PATCH/DELETE /appointment-venues[/{id}] and PUT /appointment-venues/{id}/groups (rooms and devices that must be free at an address). Reading with appointments:read, writing with appointments:write and the “Manage scheduling” permission. Deleting a number or address that is still chosen answers 409 with in-use. New reason for precondition-failed: closure-automatic.

v1.100.0 · October 12, 2026

  • Set up SendGrid through the API (area campaigns): GET /sendgrid (right, connection, missing key scopes, events and, per sender domain, DNS records, DMARC, personal mails, replies), POST /sendgrid/events, POST /sendgrid/domains (returns the DNS records to set), POST /sendgrid/domains/{id}/verify, DELETE /sendgrid/domains/{id}, PUT /sendgrid/domains/{id}/personal, POST/DELETE /sendgrid/domains/{id}/replies and POST /sendgrid/domains/{id}/replies/verify (replies through Inbound Parse, with the MX record in replies.mxRecord) and GET/PUT /sendgrid/my-sender-name (your own name before the @, for every member). The API does not accept the SendGrid key: connecting and disconnecting happen only in the app. Everything on the organization requires ORG_ADMIN; setting up also requires the “Email campaigns” right, viewing and removing work without it. New reasons in 422 precondition-failed: sendgrid-domain-not-in-account, sendgrid-key-invalid, sendgrid-unreachable, sendgrid-rejected, sendgrid-events-failed, sendgrid-personal-not-released, sendgrid-domain-not-confirmed, sendgrid-domain-not-personal, sendgrid-parse-scopes-missing (with missingScopes), replies-not-configured, sendgrid-policy-forbidden, sendgrid-parse-failed, sendgrid-replies-not-set-up.

v1.99.0 · October 12, 2026

  • Write automations (scope automations:write, acting person ORG_ADMIN): POST /automations (created switched off), PATCH /automations/{id} (missing parts stay, new version), DELETE /automations/{id}, POST …/activate and POST …/deactivate as well as POST /automation-runs/{id}/resume for failed runs. Flow errors come as 422 validation-failed with location (body.flow.nodes.‹node›.fields.‹field›) and code. New for reading: GET /automation-catalog with triggers (filters, placeholders), date sources and the actions with their fields.

v1.98.0 · October 12, 2026

  • Set up resources: POST /appointment-resources and PATCH /appointment-resources/{id} (the same checks as the resource dialog), GET …/availability, PUT …/schedule (schedule in a cycle of 1 to 4 weeks), POST …/absences plus PUT and DELETE …/absences/{absenceId} (vacation, training, sickness, extra consultation), GET and POST …/closure-overrides plus DELETE …/closure-overrides/{overrideId} (working on a closed day after all), GET …/working-hours (preview of the coming weeks), GET and PUT …/meeting-defaults (Zoom user, own number) and GET …/zoom-users. Rights as in the app: whoever manages appointments, at any resource; the person at their own (time zone only, not name, slug and active; as Zoom user only the one with their own address); every member creates their own availability. A person who already is a resource answers 409 with already-resource. New reason for precondition-failed: zoom-unavailable.

v1.97.0 · October 12, 2026

  • New: read automations (area automations, scope automations:read): GET /automations, GET /automations/{id} with flow (flow: nodes with kind and next, conditions, waits; an action is named after its endpoint, such as tasks.create), GET /automations/{id}/runs (last 100 runs with steps, failedOnly) and GET /automations/{id}/stats (90 days, per node reached, failed, exits, waiting). Creating and updating follow.

v1.96.0 · October 12, 2026

  • Set up appointment types: POST /appointment-types and PATCH /appointment-types/{id} (the same checks as the appointment type dialog; PATCH changes only the given fields), GET and PUT /appointment-types/{id}/staffing (staffing: roles, candidates, distribution, presence, video tool per person), GET and POST /appointment-types/{id}/links plus POST /appointment-links/{id}/revoke (booking links). Reading with appointments:read, writing with appointments:write and a person with the “Manage scheduling” permission. A taken slug answers 409 with slug-taken. New reasons for precondition-failed: appointment-type-not-public, quota-portal-only.

v1.95.0 · October 12, 2026

  • Email campaigns through the API (area campaigns, path /email-campaigns because /campaigns are affiliate campaigns): GET /email-campaigns/setup (SendGrid connected, events, confirmed domains, marketing templates, smart lists, tags, own addresses for the test email), GET/POST /email-campaigns, GET/PATCH/DELETE /email-campaigns/{id}, POST /email-campaigns/recipient-count, POST /email-campaigns/{id}/check (check with Rspamd and a test send in the background, 202), POST /email-campaigns/{id}/test-email (only to the acting person's own addresses, at most ten per hour, otherwise 429), POST /email-campaigns/{id}/start (now or with scheduledAt; yellow only with confirmWarnings) and /pause, /resume, /cancel. Every endpoint, reading included, requires ORG_ADMIN (403 forbidden, a key without a creator 403 no-acting-user) and the organization's “Email campaigns” right (403 feature-not-available). New reasons in 422 precondition-failed: campaign-check-missing, campaign-check-outdated, campaign-check-red, campaign-check-warnings, sendgrid-not-connected, sendgrid-events-missing, sendgrid-not-ready, campaign-template-missing, campaign-template-not-marketing, campaign-selection-empty, campaign-smart-list-unknown; a transition the state does not allow answers 409 with wrong-status.

v1.94.0 · October 12, 2026

  • Webhook targets fully through the API (scope webhooks:manage): POST /webhook-targets (secret in the response), PATCH and DELETE /webhook-targets/{id}, POST …/rotate-secret, GET …/secret, POST …/test (synchronous, with sample data or a contact; with a contact also contacts:read), GET …/deliveries/{deliveryId}/body (also contacts:read) and POST …/deliveries/{deliveryId}/retry.
  • New: inbound hooks through the API (/inbound-hooks, scope webhooks:manage): list, create (state LEARNING, optionally with a required Authorization header), read, update (name, recordTypes, mapping, state), delete, rotate the URL, read the required header, sample with a list of paths (GET …/sample, also contacts:read), deliveries, body of a delivery (also contacts:read) and reprocess.

v1.93.0 · October 12, 2026

  • Write appointments (scope appointments:write): POST /appointments (assign; one-to-one with contactId, group with participants from smart lists, tags and contacts), POST /appointments/{id}/cancel, /reschedule, /host, /type, /no-show, /participants, DELETE /appointments/{id}/participants/{contactId} and POST /appointments/{id}/meeting (renew the video link). The same checks and the same appointment messages as in-house. Each of these calls requires a person with the “Manage scheduling” permission (owner, ORG_ADMIN or individual permission): without a person no-acting-user, without the permission forbidden. A taken time answers 409 with slot-taken. New reasons for precondition-failed: contact-without-phone, appointment-not-open, appointment-not-started, not-a-group-appointment, last-participant.

v1.92.0 · October 12, 2026

  • Number circles and PDF templates in the templates area: GET/POST /number-circles, GET/PATCH /number-circles/{id} (prefix, 6 to 12 digits, yearly reset, plus issued and the next number; once a circle has issued numbers, prefix, digits and yearly reset are fixed, 409 with format-locked), GET/POST /pdf-templates, GET/PATCH /pdf-templates/{id} (name, number circle, validity in months, up to four signer slots) and PUT /pdf-templates/{id}/fields (the complete field list, checked as in the app; the first error comes as 422 validation-failed with the reason in the code, e.g. bindingUnknown or numberWithoutCircle). A PDF template is created on a PDF that was uploaded and confirmed through documents first. Writing only if the person behind the credential is an ORG_ADMIN. Neither a circle nor a template is deleted: active: false retires.

v1.91.0 · October 12, 2026

  • OAuth: an OAuth credential now receives the webhooks:manage scope only if its user is ORG_ADMIN in the bound organization, as in the user interface. It is checked at consent and on every call; if the user loses the role, the scope is missing from the next call on (403 insufficient-scope). The consent page shows it locked for non-admins. API keys are not affected; only an ORG_ADMIN creates them. The endpoint description is unchanged.

v1.90.0 · October 12, 2026

  • Read appointments (scope appointments:read): GET /appointments (list by start, filters for period, status, appointment type, resource and contact), GET /appointments/{id} (the same shape as the appointments.appointment.* webhooks, plus seats, participants and hosts), GET /appointment-types and GET /appointment-types/{id} (all settings including kind one-to-one, group or lesson, and services), GET /appointment-resources and GET /appointment-resources/{id}, GET /appointment-types/{id}/slots (free times as when assigning in-house, at most 62 days per request). Appointments with a lab request appear only with client data access; otherwise they are missing and the single read answers 404. Writing and setup follow in the next versions.

v1.89.0 · October 12, 2026

  • Templates through the API (area templates): GET/POST /message-templates, GET/PATCH /message-templates/{id} for email and SMS templates (formal and informal version, usage contacts or partnerPortal, purpose transactional or marketing), plus GET/POST /letter-templates, GET/PATCH /letter-templates/{id} for letter templates (with number circle for {{brief.nummer}}). Read with templates:read, write with templates:write, and only if the person behind the credential is an ORG_ADMIN (otherwise 403 forbidden, a key without a creator 403 no-acting-user). There is no deletion: active: false retires. Unknown placeholders in contact templates reject the save with 422.

v1.88.0 · October 12, 2026

  • Video rooms (/rooms, scopes rooms:read/rooms:write): GET /rooms and GET /rooms/{id} (with host and guest link while the room is open), POST /rooms/instant (instant meeting with a contact; the host is the key's creator), POST /rooms/{id}/participant-links (personal link for the invited contact or an appointment participant), POST /rooms/{id}/close (instant meetings only; rooms of appointments close when the appointment is cancelled, otherwise 409 with appointment-room), GET /rooms/{id}/recordings (video recordings and calls with documentId) and GET/PATCH /rooms/settings (the “Summary” switch, changed by ORG_ADMINs only). Visibility as for conference documents (1.85.0): ORG_ADMINs see all rooms, others only those they host; a key without a creator sees none. New reason room-not-configured in 422 precondition-failed; without the organization's “Live room” right, 403 feature-not-available.

v1.87.0 · October 12, 2026

  • Three new areas with read and write scopes: rooms (video rooms), templates (letter, email, SMS and PDF templates including number ranges) and campaigns (email campaigns). The endpoints follow in the next versions; until then the scopes grant no access yet. Templates and campaigns have their own scopes because email:write only allows sending, not setting up or bulk sending.
  • Two new error types, both 403: no-acting-user when an action requires an acting person (role, individual permission, author) and the credential has none (API key without a creator), and forbidden when the credential's person lacks the permission the user interface requires in the organization. For a key the person is whoever created it; for OAuth access it is the signed-in user. Existing endpoints do not change their responses.

v1.86.0 · October 12, 2026

  • New area appointments with the scopes appointments:read and appointments:write. The endpoints follow in the next versions; until then the scope grants no access yet. Appointments with a lab request attached count as client data, as in webhooks: they appear only if the organization has enabled client data for the API and the credential carries a clients: scope.

v1.85.0 · October 12, 2026

  • Documents: conference documents (recordings and summaries of the live room) are visible only to ORG_ADMINs of the organization and to the host of the call. For an API key, the user who created it counts; a key without a creator sees none. They are then missing from GET /documents, and GET /documents/{id} answers 404. The endpoint description is unchanged, which is why it is noted here. documents.* events still go to the organization's webhooks, which only an ORG_ADMIN sets up.

v1.84.0 · October 11, 2026

  • New event letters.email.received: an email arrived through the organization's SendGrid reply address and was rated. email carries id, conversationId, from, subject, receivedAt, sentiment (positive, neutral, negative, null if rating failed), contactId (or null) and campaignId if the email replies to a campaign (otherwise null). Without the email body. Sent only after rating; emails through the Resend inbox (receipts, forwards) do not send it. In automations it is the trigger “Email received” with filters by rating and campaign.

v1.83.0 · October 11, 2026

  • Call guides (/call-guides): content.results defines results, named endings with id, name and optionally color (at most 20, name at most 80 characters), and result on a step (type: point) or an answer refers to one. It only applies at an ending; elsewhere it is kept and ignored, and an unknown ID is dropped when reading. A result without a name is rejected on save with 422 and the code ergebnis-ohne-name. Until now, results created in the editor were lost on an update through the API.

v1.82.0 · October 11, 2026

  • callguides.run.completed now carries guideRun.resultId and guideRun.resultName: the named outcome of the ending the run reached (for example “Meeting booked”). The organization defines outcomes in the guide and assigns them to a step without a successor or to an answer that leads to the end. ID and name come from the version the call used. Without an outcome at that ending both are null; outcome (the last step) is unchanged.

v1.81.0 · October 11, 2026

  • leads.lead.created now carries consentPurposes next to consent (element → ticked): the purpose of each consent as in forms (1.79.0). INQUIRY is the required box “contact about my inquiry” and does not allow marketing, MARKETING the optional box “marketing”, null a custom box or an older one that combines inquiry and marketing. Anyone deriving marketing consent from the event takes only MARKETING (or null) with consent = true. Leads without a form (finder, manual) have an empty object.

v1.80.0 · October 10, 2026

  • kind on SMS (GET /sms, GET /sms/{id}, sms.message.* events) has the new value EINWILLIGUNG: the non-promotional request to confirm consent given in a form via a link. It is sent through the organization's Twilio account to the contact, with the organization's name as footer.

v1.79.0 · October 10, 2026

  • Forms: every consent now carries purpose, in the form definition (GET /forms/{id}) and in submissions (GET /forms/{id}/responses). INQUIRY is the required checkbox “contact about my request”, MARKETING the voluntary checkbox “advertising”, null a custom checkbox or an older one that combines request and advertising. Submissions from before this version have null. Only MARKETING (or an older combined checkbox) is a consent to advertising; INQUIRY does not permit advertising.

v1.78.0 · October 10, 2026

  • New event contacts.webhook.received: an inbound hook of the organization has accepted and processed a record from another system. hook gives ID and name, company the company (existing or newly created, otherwise null), contact the person, or without a person the company itself; contactStatus and companyStatus are new or existing. Inbound hooks are created in settings under Integrations → Interfaces: an address of their own, POST /api/hooks/‹id› (outside /api/v1, optionally requiring Authorization: Bearer …), which accepts JSON or forms up to 256 KB immediately with 202 and processes them in a queue per hook (at most 60 per minute; above 600 per minute it answers 429). In learning mode the next delivery is only captured as a sample on which the fields are mapped.

v1.77.0 · October 10, 2026

  • Handovers to other organizations: new area handovers with the scopes handovers:read and handovers:write (existing keys do not have them). GET /handover-connections lists the active connections through which this organization may hand over (id, name, recipientName). POST /handovers with connectionId and contactId (plus contacts:read) copies the contact with its company into the receiving organization and responds 201 with handoverId, never with created or merged. Errors: 404 (connection-unknown, not-your-connection, contact-unknown), 422 precondition-failed (connection-revoked, connection-not-active), 500 (copy-failed). At the recipient, the handover triggers contacts.handover.received (since 1.75.0); automations get a filter by connection for it and the action “Hand over to organization”.

v1.76.0 · October 10, 2026

  • Webhook targets: named addresses of other systems to which a contact with its company is sent, for example by the new action “Send webhook” in automations. Unlike /webhooks, targets do not subscribe to events. New: GET /webhook-targets, GET /webhook-targets/{id}, GET /webhook-targets/{id}/deliveries (log, 30 days, with the beginning of the response) and POST /webhook-targets/{id}/send with contactId (202, scopes webhooks:manage and contacts:read; 409 conflict with reason: target-inactive if the target is off). The body uses the event envelope with type: contacts.contact.sent and data = { contact, company, automation, test }, signed per Standard Webhooks with the target's secret, retried after 1 min, 5 min, 30 min, 2 h and 12 h, and switched off after five dead deliveries in a row. Creating, editing, the secret and tests are in settings under Integrations → Interfaces.

v1.75.0 · October 10, 2026

  • New event contacts.handover.received: another organization has handed a contact over to this one through a handover connection. contact is the contact in this organization (newly created or merged with an existing one), company its company or null, handover names the handover, the connection (connectionId, connectionName) and the outcome (created or merged). It can be subscribed to like any event and is a trigger in automations. The handover connections themselves follow in a later version.

v1.74.0 · October 9, 2026

  • Correspondence: POST /outbound-emails and POST /sms optionally take vorlageId, the ID of a template from the shared library (use “Contacts”). Subject, text, informal (Du) version and send type then come from the template, read at sending time, with its placeholders (such as {{person.firstName}}, {{anrede}}); whoever changes the template changes the next send. Either vorlageId or free text: for email, subject and bodyHtml are now only required without vorlageId, for SMS body and art; with vorlageId they must not be sent, and for SMS contactId is then required. An email from a template is sent like one from the contact's conversation (kind: gespraech, footer with the conversation ID; promotional templates only with email consent and with an unsubscribe link). New reasons in 422 precondition-failed: message-template-not-found, message-template-archived (fixable), message-template-without-sms (fixable, SMS only), email-ohne-einwilligung.

v1.73.0 · October 8, 2026

  • Forms: a consent for email or phone now only counts as asked when a field of its channel has a value. If it is empty, the consent no longer appears in a submission's consents (GET /forms/{id}/responses, forms.response.submitted) or in consent of leads.lead.created, not even as declined; a true sent in POST /forms/{id}/responses is then not stored. Until now it was always listed, with accepted: false or even true for an address that did not exist. Free-text consents (channel CUSTOM) are unchanged.

v1.72.0 · October 8, 2026

  • Contacts: new field dateOfBirth (“YYYY-MM-DD”, PERSON only, between 1900 and today) in all contact responses and events, settable via POST /contacts and PATCH /contacts/{id} (null clears). Same format as clients.dateOfBirth, but on the contact; an invalid date or a date on a company returns 422 validation-failed (body.dateOfBirth).

v1.71.0 · October 8, 2026

  • New appointment events: appointments.appointment.booked (confirmed; with mandatory payment, after the payment), appointments.appointment.rescheduled (with previousStartsAt, previousEndsAt and by: customer or provider), appointments.appointment.cancelled (with by and reason) and appointments.appointment.noShow (marked by the team, with markedByUserId). The payload carries the appointment under appointment, the contact under appointment.contactId; automations can use these events as triggers. Only confirmed appointments are reported. An appointment with a lab request is only sent to endpoints with client data access.

v1.70.0 · October 8, 2026

  • New event calls.call.ended: a call has ended, exactly once per call. call carries direction (inbound, outbound), outcome (answered, missed, voicemail for our voicemail, failed), contact (contactId, null for an unknown number), speaker, numbers, times and durationSeconds. Call notes, recordings and transcripts are never included.
  • New event callguides.run.completed: a call guide was completed during a call (main path reached an end, no required step open), exactly once per run; later edits do not trigger it again. guideRun carries the guide (guideId), contact (contactId, the speaker or otherwise the call's contact), outcome (ID of the last step), answers (question → answer as IDs), objections used and the path. Notes are never included.

v1.69.0 · October 8, 2026

  • Contacts, new endpoints for single changes (automation actions): POST /contacts/{id}/tags (tagId from the tag pool or tag as text) and DELETE /contacts/{id}/tags/{tag} (id or text) add or remove one tag without sending the whole list; an existing or missing tag changes nothing and sends no second event. POST /contacts/{id}/notes creates a note (plain text, stored as escaped HTML). PUT /contacts/{id}/custom-fields/{slug} sets a custom field (value: text, list of option keys or null; not client-record-only fields or consents). PUT /contacts/{id}/owner sets the owner (userId of a member or null). Du/Sie and standard fields still via PATCH /contacts/{id}.

v1.68.0 · October 8, 2026

  • New event funnels.funnelLead.created: a lead from a funnel or website form, with the submission (lead.id), the site (lead.funnelId, lead.funnelName, lead.funnelKind), the page of the form (lead.stepId, lead.stepName, lead.stepPath), the form and the contact (lead.contactId). Identifiers and names only, no personal details. It is sent in addition to leads.lead.created and is available in automations as the trigger “Lead from a funnel or website”.
  • leads.lead.created from a funnel now carries contactId also when the submission created a prospect (the prospect's contact); previously it was null.

v1.67.0 · October 8, 2026

  • Contracts from template (POST /contracts): new field send (default false, draft only as before). With true the contract is sent as soon as its PDF has been rendered; the response still shows the draft, the event esign.request.sent reports the sending. Optionally reminderPolicy and locale as on POST /signature-requests/{id}/send. If rendering fails or takes longer than ten minutes, the draft stays.

v1.66.0 · October 8, 2026

  • Form responses (GET /forms/{id}/responses, GET /forms/responses/{id}, event forms.response.submitted): new field contactId, the contact the submission belongs to; null while there is none, and always for client record forms. Automations triggered by “Form submitted” can now use contact actions.
  • Form responses: new value booking for source, submitted through an appointment booking flow. Previously these responses appeared as api.

v1.65.0 · October 5, 2026

  • Call guides: new action type consent ({ type: "consent", channel: "EMAIL" }) to record consent to email on the phone; the wording comes from contacts at runtime. channel is currently only EMAIL; any other value returns 422 validation-failed.

v1.64.0 · October 5, 2026

  • Call guides (/call-guides) with actions and inputs, all optional: a point can be an action (email, sms, callback, handover, checkout, appointment, form) or use field to write an input into a field of the call partner; a question uses field to write the chosen answer, or the answer's value if set (such as the key of a choice); mandatory: true makes a step mandatory; actions places actions at the side of the call. New check reasons on body.content: aktion-unvollstaendig (template or link missing, side action without a name) and action-and-field (a point with both). Reading a guide and writing it back keeps these parts.

v1.63.1 · October 5, 2026

  • Clarification of 1.63.0 (not yet released): contactFields on call guides only accepts keys the mini window at the side of the call can show: title, website, addressStreet, addressPostalCode, addressCity or cf:<slug> (lowercase letters, digits, _). Any other key returns 422 validation-failed instead of being dropped silently.

v1.63.0 · October 5, 2026

  • Call guides (/call-guides) can do more, all optional: per step hint (a hint only for the person on the phone) and cards (hint cards with title, text, color); per guide cards (always visible), objections (with name and start, the first step of their own path) and contactFields (extra fields for the mini window at the side of the call). Placeholders also work in hints and cards. New check reasons on body.content: karte-leer and einwand-unvollstaendig.

v1.62.0 · October 5, 2026

  • New: call guides of the telephony feature (branching checklists for phone calls). GET /call-guides, GET /call-guides/{id}, POST /call-guides and PATCH /call-guides/{id}, new scopes callguides:read and callguides:write; in the API MCP as tools callguides_list, callguides_get, callguides_create and callguides_update. A guide has a start and nodes: point to tick off or question with answers; next leads on (missing: next node in the list, null: end, ID: to that node). Only content without errors is saved, otherwise 422 with the reasons on body.content. Every change to name, description or content is a new version (version); active switches without a new version.

v1.61.0 · October 4, 2026

  • Required field art on POST /sms (also MCP letters_sendSms and the LeadConnector action sms-send): notwendig (necessary) or werblich (promotional), no default; a request without art returns 422 validation-failed on body.art. This is stricter than before but affects nobody: there was not a single POST /sms request in production. The send type determines the SMS footer (necessary: the organization's name; promotional: the name and “Keine SMS mehr? STOP antworten”), which is appended to body and counts towards the segments, and a promotional SMS only goes to a contact (contactId) with SMS consent: without a contact 422 precondition-failed with reason = sms-werblich-ohne-kontakt, without consent for the number reason = sms-ohne-einwilligung (both fixable: false).

v1.60.2 · October 4, 2026

  • Fixed: POST /documents with contactId links the document to that contact, and the link now survives the analysis of the document. Previously the automatic assignment could overwrite it, with the hit of a name search or with nothing, so that GET /documents/{id} showed a different contact or none. The automatic assignment now only fills what is empty; the same applies to PATCH /documents/{id} with contactId followed by a new analysis.

v1.60.1 · October 4, 2026

  • Clarification of 1.60.0, which had not yet been released: the SMS to a member (channel: sms) falls back to the default number in their profile if they have not entered a number for SMS confirmation in this organization, as for signing and appointment reminders. member-without-phone now only occurs if both are missing.

v1.60.0 · October 4, 2026

  • POST /organization/members/{userId}/notifications can now also send an SMS: channel: sms goes to the mobile number the member entered for SMS confirmation in this organization, otherwise the default number in their profile (the same order as for signing and appointment reminders), through the organization's Twilio account; the text is title and body. If both are missing: 422 precondition-failed, reason = member-without-phone, fixable: true; if it is invalid: member-phone-invalid. The SMS sending reasons (twilio-*) apply as for POST /sms (1.58.0), network errors 500. The SMS appears in GET /sms with kind: API.

v1.59.0 · October 4, 2026

  • kind on SMS (GET /sms, GET /sms/{id}, sms.message.* events) has the new value GESPRAECH: an SMS a team member wrote by hand in a contact's conversation. If you evaluate kind, allow for unknown values.

v1.58.0 · October 4, 2026

  • POST /sms now only sends through the organization's own Twilio account (Organization → Integrations); this also applies to automations and the LeadConnector action sms-send. Without a connected account, without a sender number or with invalid credentials the request returns 422 precondition-failed with reason = twilio-nicht-verbunden, twilio-keine-nummer or twilio-zugang-ungueltig and fixable: true; no SMS is created in that case (previously a row with FAILED and 403 feature-not-available). If the recipient sent STOP: 422 precondition-failed, reason = twilio-empfaenger-gesperrt, fixable: false (often only in the callback, then FAILED with errorCode on the SMS). Number invalid according to Twilio: 422 validation-failed on body.to. Other rejection: 409 conflict, reason = twilio-abgelehnt. Network error: 500, retryable.
  • The SMS quota of 300 per organization and month is removed, because each organization pays for its own SMS as of this version. 429 sms-limit-reached no longer occurs; the code stays in the catalog until v2.

v1.57.0 · October 4, 2026

  • POST /organization/members/{userId}/notifications can now also send emails: channel: email goes to the member's address, with title as subject, body as text and link as an address in the application. If sending fails, the request returns 500 and may be retried. The response carries the channel used.
  • Documents of a client record now also include the attachments of record mail (portal messages in the record area). The same rules apply as for lab sheets and contracts with clients (1.54.0): without client-data enablement and a clients: scope they are missing from GET /documents, a request by ID (including …/download-url and PATCH) returns 404, and documents.document.* events about them only go to endpoints with clientsData: true.

v1.56.0 · October 4, 2026

  • New: POST /organization/members/{userId}/notifications sends a member of the organization a message in the bell (with browser push if enabled): title, optional body and link (a path in the application). New scope members:notify; members otherwise stay read-only. A user who is not a member returns 404. The channel is for now only channel: notification; email and SMS will be added as further values.

v1.55.0 · October 4, 2026

  • POST /outbound-emails accepts an informal (Du) version: subjectDu and bodyHtmlDu, both optional and only effective together. claritos then picks per recipient according to the salutation rule (formal-only for letters, personal Du with OAuth, setting on the contact, otherwise the organization's default), and placeholders such as {{ansprechpartner.anrede}} follow the same choice. If either is missing, the email goes out entirely in the formal version, as before. The per-recipient choice is prepared and will be switched on for all organizations at once; until then every email goes out in the formal version, but the informal version can already be sent along.
  • The description now lists every error response the framework can return: 409 on write requests (conflict, a request with the same Idempotency-Key still running), 413 on requests with a body (over 1 MB) and 500 everywhere. Behaviour is unchanged; these codes were only missing from the description.

v1.54.0 · October 3, 2026

  • Webhooks with client data now only go to endpoints that are enabled for it. New field clientsData on GET/POST/PATCH /webhooks: only an endpoint with clientsData: true receives events containing client data, that is clients.record.created, clients.record.updated, clients.message.received and the esign.request.* events of a contract with a client, and only while the organization has enabled client data for the API. clientsData: true can only be set with clients:read or clients:write (otherwise 403 insufficient-scope) and only while enabled (otherwise 403 clients-data-not-enabled). The check runs on every delivery attempt; if the enablement is withdrawn, a pending delivery ends as FAILED with lastError = clients-data-not-allowed. A replay skips such events for an endpoint that is not enabled, and GET /webhooks/events/{type}/recent only shows them to a key with a clients: scope. Until now clients.* events went to every endpoint of the organization.
  • Documents of a client record (lab sheets, contracts with clients) are only returned by /documents while the organization has enabled client data for the API and the key carries a clients: scope; otherwise they are missing from GET /documents, and a request by ID (including …/download-url and PATCH) returns 404. For a contract the same exception as in 1.53.0 applies: the user behind the key created or sent it.
  • The events documents.document.ready, documents.document.analyzed and documents.document.updated for documents of a client record (lab sheets, documents of a contract with a client) count as client data: they only go to endpoints with clientsData: true and only while the organization has enabled client data. Unlike for requests, there is no exception for the creator or sender here, because a webhook does not belong to a user.

v1.53.0 · October 3, 2026

  • Contracts with clients only with client-data release: if a contact with a client record (or their representative) takes part in a contract or signature request, GET /contracts, GET /signature-requests, the single reads, …/events, …/pdf, …/send and …/cancel return it only if the organization has released client data for the API and the key carries a clients: scope; otherwise it is missing from lists, and a read by ID answers 404. Exception: contracts created or sent by the user behind the key. Lists stay full and hasMore is accurate.

v1.52.0 · October 3, 2026

  • Client-record fields in contract templates: if the organization runs a practice, templates also know fields of the client record as <party>.akte.<field> (date of birth dateOfBirth, record number recordNumber, start of care careStartedAt and end careEndedAt, custom fields on the record and practice-only fields as <party>.akte.custom.<slug>). variables lists them. POST /contracts fills them only if the organization has released client data for the API and the key carries a clients: scope; otherwise ••• appears and the record is not read.

v1.51.0 · October 3, 2026

  • Contract templates know more variables: for each company, contact person and person, all fields of the contact are available (for example company.1.email, company.1.legalFormName, company.1.contact.1.firstName, person.1.customerNumber) as well as the organization's custom fields as <party>.custom.<slug> (for example company.1.contact.1.custom.jahrgang). variables in GET /contract-templates lists them, and warnings no longer reports them as unknown-variable. POST /contracts fills them from the contacts. Also new is countryName (country spelled out, in the template's language) next to country (country code such as DE, unchanged). All existing variables remain.

v1.50.1 · October 2, 2026

  • POST /contract-templates/{id}/archive responds with 200 instead of 201: archiving creates nothing. The other actions that create nothing, for example on quotes and documents, respond the same way.

v1.50.0 · October 2, 2026

  • Contract templates can now be created, updated and archived: POST /contract-templates, PATCH /contract-templates/{id} and POST /contract-templates/{id}/archive, scope contracts:write, with the same fields and the same checks as the template editor. bodyHtml is cleaned on save: the editor's markup remains; scripts, event attributes, links other than http, https, mailto and tel, and images outside the organization's own storage are removed. The response carries warnings listing what was removed and placeholders that neither the party plan nor the fixed variables know (unknown-variable). An invalid party plan returns 422, updating an archived template 409 (archived), a non-business organization feature-not-available. New when reading any template: anrede (AUTO, SIE, DU) and isFeeAgreement; formal remains.

v1.49.0 · October 2, 2026

  • A contact of type PERSON with a VAT ID is rejected (422 validation-failed, path body.vatId, code invalid_combination): anyone with a VAT ID is a company. This applies to POST /contacts and to PATCH /contacts/{id} when the change gives a person a VAT ID. Instead, create a company (type: COMPANY, legal form sole proprietorship) with the VAT ID and attach the person to it as contact person via worksAtId. Changes to existing contacts still stored as a person with a VAT ID remain possible as long as they do not set the VAT ID.

v1.48.0 · October 1, 2026

  • Payment reminders (GET /dunning/reminders, GET /dunning/reminders/{id}) can have the new status SUPERSEDED: they have been replaced by a later reminder for the same receivable and no longer accept payment. This happens as soon as the next level is finalized; until now the earlier one stayed SENT. In addition, reminders that were sent outside claritos before it took over can now be recorded afterwards as a link in the chain. They appear with status: SENT, number: null and feeCents/interestCents 0. The portalUrl of a superseded or recorded reminder leads to the current reminder or to the invoice. If you evaluate the status, treat SUPERSEDED as a completed level, not as an open request for payment.

v1.47.0 · September 27, 2026

  • Documents have the new field access with public or protected (GET /documents, GET /documents/{id}, PATCH /documents/{id} and the webhooks documents.document.ready, .analyzed and .updated). Protected documents are not publicly available: for them url and previewUrl are always null, even when the document is ready. Retrieve the file via the signed link from GET /documents/{id}/download-url. Today this only applies to newly added Zoom recordings. url is marked deprecated as of this version: it will later become null for all documents, and GET /documents/{id}/download-url will then be the only way to the file. If you store url, switch to download-url now.

v1.46.0 · September 26, 2026

  • addressForm on forms (GET /forms, GET /forms/{id}) can now also return AUTO, alongside DU (informal) and SIE (formal). AUTO means the form has no fixed form of address; it addresses people the way the organization or the contact specifies. Which form of address a person actually sees is decided by claritos when the form is shown. New forms default to AUTO, and existing forms set to DU were switched to AUTO, except the anamnesis templates, whose questions themselves use the informal form. If you have treated everything other than SIE as informal, do not treat AUTO as informal.

v1.45.0 · September 26, 2026

  • Changed behaviour of POST /signature-requests with send: true and of POST /signature-requests/{id}/send: invitations are now always sent. If the sender's Gmail connection has expired, they go out from the claritos address, and replies still reach the sender. Until now they were held back in that case and senderInvalid was true. As a result senderInvalid is always false since 1.45.0, is marked deprecated and will be removed in v2. If you reacted to it, for example with "reconnect mailbox", you will no longer receive that signal; the connection is marked invalid in claritos and its owner is asked there to reconnect.

v1.44.0 · September 26, 2026

  • Contacts carry the new field anrede: STANDARD (as set for the organization), DU (informal) or SIE (formal). Readable on all contact endpoints and in the webhooks contacts.contact.created and contacts.contact.updated, writable on create and update. It only applies to people: for companies the contact person counts, the value there is always STANDARD, and DU or SIE on a company is rejected with 422 (validation-failed, path body.anrede).

v1.43.0 · September 25, 2026

  • New field paymentProvider on invoices, quotes and orders and on their sections: MOLLIE when paid online via the payment layer, otherwise null. Readable everywhere, writable on invoices and quotes (head and sections). It excludes stripeEnabled (one online provider); to switch from Stripe to Mollie, set stripeEnabled: false in the same call. It can only be set if the organization has connected Mollie, otherwise validation-failed. When writing sections, omitting it means no provider. The invoices.invoice.* events carry the field as well.

v1.42.0 · September 25, 2026

  • New event letters.certificate.expired for documents from PDF templates with an expiry date (for example a certificate valid for three years). It is sent once, on the day after the last valid day; if a daily run was missed, it is caught up for up to three days. It carries certificate (id, template, number, contact, validUntil, signed, verification code) and contact. Revoked documents and those still awaiting signature send nothing. A reminder before expiry is not an event but a date trigger of automations.

v1.41.0 · September 24, 2026

  • POST /letters/{id}/send now refuses to send with 409 conflict and reason = certificate-attachment-invalid when an attachment is an issued document (a certificate from a PDF template) in a version that is not valid: cancelled, not yet signed or superseded by the signed version. Until now such an attachment was sent. The same check applies to letters from the "letter from template" action.

v1.40.0 · September 24, 2026

  • New endpoints for automations and integrations. POST /letters/from-template creates a letter from a letter template for a contact and delivers it once its PDF is ready (channel: EMAIL, POSTAL or BOTH; response 202 with the letter as DRAFT). POST /outbound-emails sends a free-form email to a contact; subject and body may carry the same placeholders as letter templates, and the record then appears under GET /outbound-emails with kind = message. If the contact lacks the required detail, both respond with precondition-failed and a reason such as contact-without-email, contact-without-address, postal-not-connected, template-archived or sender-invalid. There is no fallback to another delivery channel.
  • When called from an automation, both endpoints recognise a resumed run: the same step finds the same letter or email again instead of creating a second one. If a letter fails to be delivered only after it was accepted (202), the acting user receives a notification; the caller is not yet informed of this.

v1.39.0 · September 24, 2026

  • New error code precondition-failed (422): a precondition on the object is not met, for example a contact without an email address. The response carries reason (a stable code such as contact-without-email) and fixable (whether changing the data resolves it). Retrying after fixing the data needs a new Idempotency-Key: the store also remembers this error response.

v1.38.0 · September 24, 2026

  • New events contacts.tag.added and contacts.tag.removed: one event per tag set on or removed from a contact, carrying contactId and tag in the same shape as tagDetails (id, text, label, source, group). The event is sent only once the change is stored. A different spelling of the same tag is not a change. Renaming, merging and deleting in tag management do not trigger events, nor does merging contacts.

v1.37.0 · September 24, 2026

  • kind on SMS (GET /sms, GET /sms/{id}, sms.message.* events) has the new value APPOINTMENT_REMINDER for appointment reminders. Until now reminders carried API although they were not sent through the API; older reminders keep API. Appointment reminders do not count toward the SMS quota (sms-limit-reached).
  • Added retroactively: two values entered the contract without an entry of their own. (1) Since 13 September, the type of a form field (GET /forms/{id}) can be UPLOAD; the answer to such a field is the ID of a document. (2) Since 24 September, taxCategory on articles and on the items of quotes, orders and invoices can be OUTSIDE_SCOPE (not taxable domestically, section 3a German VAT Act). Clients that evaluate these fields exhaustively should know both values.

v1.36.0 · September 24, 2026

  • Signature requests now know the source PDF_TEMPLATE: a document created from a PDF template, such as a certificate with a running number. The value appears in the sourceKind field of requests under /esign, as the filter ?sourceKind=PDF_TEMPLATE and in the payload of the esign.request.* events. If you handle sourceKind exhaustively, for example in a switch, add the new value.

v1.35.0 · September 24, 2026

  • New error code sms-limit-reached (429) on POST /sms: through the API, the LeadConnector action and automations, an organization sends at most 300 SMS per calendar month (German time); the value can be set per organization. The response includes limit, used and resetsAt and carries Retry-After until the start of the next month. Appointment reminders do not count.

v1.34.0 · September 24, 2026

  • Changed behaviour for document tags: PATCH /documents/{id} no longer stores tags lowercased and with - instead of spaces. Each tag comes back spelled as in the organization's tag vocabulary; sending VIP while vip already exists returns vip. Tags that differ only in upper and lower case, spaces or hyphens count as the same tag. An unknown tag is created as sent; spaces and special characters are kept, previously spaces became - and special characters were removed.
  • The GET /documents?tag= filter now matches regardless of case, spaces or hyphens; previously it compared exactly.

v1.33.0 · September 24, 2026

  • Contacts now carry tagDetails next to tags: for each tag the stable id (id), the text (tag), the explanatory label (label), the source (source) and the group (group, or null). The planned events for a tag being added or removed will use the same shape. The webhooks contacts.contact.created and contacts.contact.updated include the field as well. The id stays the same when a tag is renamed; if you map tags, use it instead of the text.
  • Changed behaviour for tags: contact tags are no longer lowercased. They come back spelled as in the organization's tag vocabulary; sending VIP while vip already exists returns vip. Tags that differ only in upper and lower case count as the same tag. Spaces and special characters are kept; previously spaces became - and special characters were removed. The ?tag= filter now matches regardless of case; previously it did not find capitalised tags.

v1.32.1 · September 15, 2026

  • Open items (/open-items) are now available for every organization type, including personal spheres and households. Previously the API answered with feature-not-available there although the app keeps the items. Unchanged: reminders (/dunning/reminders) remain limited to business organizations.

v1.32.0 · September 7, 2026

  • OAuth foundation moved to Better Auth 1.7 (new oauth-provider plugin). New: token revocation and token introspection as their own endpoints, resource-bound tokens, public clients without a secret, stronger client authentication. Two security advisories affecting the previous version are resolved. Existing OAuth connections have to be re-established once — clients, consents and tokens from the old version cannot be carried over. API keys (capi_) are unaffected.

v1.31.0 · September 7, 2026

  • Website-builder MCP: the tool list is now filtered by permission — an access with sites:read no longer sees the writing tools at all. Calling a disallowed tool directly still answers with 403 insufficient_scope.

v1.30.0 · September 7, 2026

  • Connected apps in the profile: users see every OAuth grant (application, organisation, permissions in plain words, valid accesses, last sign-in) and can revoke it themselves. Revoking removes the organisation binding, the issued tokens and the consent — the application loses access immediately and asks again on the next connection.

v1.29.0 · September 7, 2026

  • LeadConnector menu entry: claritos can appear as a custom menu link in LeadConnector (/embed/leadconnector in an iframe). The encrypted location context from LeadConnector is read with the app's SSO key and shows the linked organisation, active triggers and available actions. The context proves the location, not a claritos identity — it creates no sign-in and the page shows no business data.

v1.28.0 · September 7, 2026

  • Zapier app: sign-in now uses OAuth 2.1 (authorization code + PKCE, automatic token refresh) instead of an API key — a prerequisite for public listing. On connect users pick the organisation and permissions in the claritos consent; the requested scope list is generated from the spec and leaves clients data out. Missing permissions surface as 403 on the affected action.

v1.27.0 · September 7, 2026

  • Checkout events in the standard format: payments.checkout.pending / .completed / .failed (payment-link sales) now also run through the API webhook service — with standard signature, retries, delivery log, replay and alerts. The existing payment-link webhooks on the link stay unchanged; to migrate, subscribe to the new types and switch the old target off.

v1.26.0 · September 7, 2026

  • OAuth consent: permissions can be deselected individually (least privilege). The client only receives the selected scopes — even if it requested all of them; clients-data scopes are deselected by default. Consent without any selected permission is no longer possible; an empty grant means “no API rights”.

v1.25.0 · September 6, 2026

  • Website-builder MCP (POST /api/mcp) now also accepts OAuth 2.1 access tokens (login + consent, scopes sites:read/sites:write) — chat connectors (claude.ai, ChatGPT) no longer need a cmcp_ token; cmcp_ tokens stay valid. Scopes are enforced per tool (get_/list_/verify_/suggest_ = read, everything else = write; 403 insufficient_scope). Protected-resource metadata per MCP server: /.well-known/oauth-protected-resource/api/mcp and …/api/mcp/v1.

v1.24.0 · September 6, 2026

  • Make custom app (integrations/make): app tree generated entirely from the spec — connection API key + environment, webhook (attach/detach via /webhooks), one instant trigger per event type, action/search/get/delete modules per endpoint (search with cursor pagination, actions with Idempotency-Key), Problem-Details error mapping; upload script for the Make Apps SDK API. “Make” guide. All four platform apps (LeadConnector, Zapier, n8n, Make) are now in the repository.

v1.23.0 · September 6, 2026

  • n8n community node (integrations/n8n, npm n8n-nodes-claritos): regular node with resource = domain and operation = endpoint (declarative, generated from the spec; lists unwrapped to data), trigger node subscribing via POST /webhooks with signature verification and cleanup on deactivation, credential API key + environment. “n8n” guide.

v1.22.0 · September 6, 2026

  • Zapier app (integrations/zapier): one REST-hook trigger per event type (subscription via POST /webhooks, signature verification, “Load sample” from /webhooks/events/{type}/recent), actions for every write endpoint, searches for every list — generated entirely from the spec. New snapshot docs/api/events.v1.json (event catalog with samples). “Zapier” guide.

v1.21.0 · September 6, 2026

  • LeadConnector marketplace app (route C): one install per location (OAuth from the organisation settings or External Authentication with an API key), custom workflow actions (contact-create, task-create, sms-send, quote-create, invoice-create, form-response — routed through the API framework with the user's key), custom workflow triggers (lead_created, contact_created, invoice_paid, invoice_issued, quote_accepted, esign_completed, form_submitted, task_done — webhook endpoints internally). “LeadConnector” guide.

v1.20.0 · September 6, 2026

  • MCP over the API: POST /api/mcp/v1 (Streamable HTTP) — one tool per endpoint (name <domain>_<action>, input params/query/body as in the reference, optional idempotencyKey on write calls). Same auth (API key or OAuth 2.1), same scopes, clients-data gate, rate limits and log as HTTP; the tool list shows only what the access is allowed to do. “MCP” guide.

v1.19.0 · September 6, 2026

  • OAuth 2.1: Besides API keys the API now accepts OAuth access tokens (authorization code + PKCE, refresh tokens, dynamic client registration). The user grants exactly one organization in the consent screen; scopes are the same as for keys. Discovery at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource. “OAuth” guide (flows, consent, Zapier/n8n).

v1.18.0 · September 6, 2026

  • Finder + foods (read-only): GET /finder/practitioners (radius, place, language, qualification and topic filters; the same search as the organization’s public finder page), GET /finder/practitioners/{slug} (profile with locations, focuses, qualifications; old slugs are resolved), GET /finder/places (place suggestions). GET /foods/search (hits grouped by category), GET /foods (list per category), GET /foods/{id} (by ID or slug) — global, nutrients per 100 g, portion data, source and attribution in every response.

v1.17.0 · September 6, 2026

  • Organization (read-only): GET /organization (master data, address, tax/register data, bank, logo, inbox address, branding domain, e-sign level, API settings), GET /organization/members (members with role, visibility, client access), GET /organization/invitations (invitations; expired ones are reported as EXPIRED), GET /organization/api-keys (own keys — metadata only, never hash/plaintext; isCurrent marks the calling key). Event organization.member.joined (invitation accepted, organization created).

v1.16.0 · September 6, 2026

  • Finance (read-only): GET /accounts, GET /accounts/{id} (chart of accounts with kind, subtype, hierarchy, postability, bank data and balance — canonical debit − credit plus display balance), GET /bookings, GET /bookings/{id} (journal with lines per account/contact/cost category, documents, open-item links, reversal reference; filter by period, status, account, contact, document), GET /statements, GET /statements/{id}, GET /statements/{id}/lines (bank statements with line states, assigned bank account and credit-card summary). Events finance.booking.created (all creation paths) and finance.booking.reversed. No write paths in v1.

v1.15.0 · September 6, 2026

  • Post/SMS/e-mail: GET/POST /letters (create a letter, optionally generate the PDF right away), GET/PATCH /letters/{id}, POST /letters/{id}/generate (PDF asynchronously, pdfState), POST /letters/{id}/send (channel EMAIL, POSTAL or BOTH — postal dispatch via the connected provider is charged), GET /letters/{id}/pdf, GET /postal-letters, GET /postal-letters/{id} (queue with status, pages, cost, tracking), GET/POST /sms, GET /sms/{id} (send SMS — charged — and read delivery status), GET /outbound-emails, GET /outbound-emails/{id} (outbound e-mails of all areas; client-record e-mails excluded). Events letters.letter.sent, letters.postal.submitted/sent/delivered/failed, sms.message.sent/delivered/failed.

v1.14.0 · September 6, 2026

  • Contracts/e-sign: GET /contract-templates, GET /contract-templates/{id} (template with party plan, variable slugs and HTML), GET/POST /contracts (contract from template: parties per slot, title/place/date, extra variables; the worker renders the PDF asynchronously — renderState), GET /contracts/{id}, GET/POST /signature-requests (signature request from a PDF document with parties, optional field placement, signature level, consent; sent immediately by default), GET /signature-requests/{id}, POST …/send (sends or resends; contracts only after rendering), POST …/cancel, GET …/events (hash chain), GET …/pdf (sealed copy or original, short-lived URL). Events esign.request.sent/completed/sealed/expired/declined/cancelled. Signing links are never exposed.

v1.13.0 · September 6, 2026

  • Affiliates: GET /affiliates, GET /affiliates/{id} (partner with status, contract kind, ref code, primary contact; no bank/tax data), GET /campaigns, GET /campaigns/{id} (campaign with depth, model, attribution window, articles, landing pages, ref parameter), GET /affiliate-links (enrollments partner × campaign with clicks and ready-made share links per landing page), GET /conversions, GET /conversions/{id} (conversion with gross/fee/climate contribution/base, status, payment state, payout dates and commission entries per level/role), POST /conversions (register an external conversion — by ref code or coupon code, idempotent via externalRef; same semantics as the conversion webhook), GET /commissions (commission entries, read-only). Events affiliates.conversion.registered (from all ingestion paths: Stripe, coupon, webhook, manual, API) and affiliates.conversion.settled. No payouts, no credit notes.

v1.12.0 · September 6, 2026

  • Clients (practice management, health data): GET/POST /clients, GET/PATCH /clients/{id} (record with record number, status, channel overrides, care period, retention), GET/PATCH /clients/{id}/fields (all record fields with current value; write several fields with measured-at/measured-by/reason), GET/POST /clients/{id}/measurements (value history with correction chain; record a single measurement), GET/POST /clients/{id}/messages (conversation with the client, practice side), GET /clients/{id}/files. All only with clients-data enablement (data processing agreement) + clients:read/clients:write; every access is logged per record (IDs only). Events clients.record.created, clients.record.updated, clients.message.received (references only, no health data in the webhook).

v1.11.0 · September 6, 2026

  • Forms: GET /forms, GET /forms/{id} (definition: pages, fields with key/type/options/required/conditions, matrix/repeater blocks, consents), GET /forms/{id}/responses, GET /responses/{id}, POST /forms/{id}/responses (server-side submit without OTP; same validation as the public form; optional affiliateId for attribution; creates prospect + lead event). Responses of client-record forms only with clients-data enablement + clients:read. Event forms.response.submitted (also for public forms and funnel forms; client-record forms as reference only).

v1.10.0 · September 6, 2026

  • Documents: GET /documents (status, type, taskId/none, contactId, tag, financeRelevant, q, updatedSince), GET /documents/{id}, POST /documents (presigned PUT URL for direct upload to R2, 5 min) + POST /documents/{id}/confirm (READY, starts OCR/AI or statement parser), GET /documents/{id}/download-url (short-lived URL with filename), PATCH /documents/{id} (title, type, task, contact, tags). AI-extracted fields under extracted. Events documents.document.ready/analyzed/updated.

v1.9.0 · September 6, 2026

  • Time tracking: GET/POST /time-entries, GET/PATCH/DELETE /time-entries/{id}, POST /time-entries/{id}/stop. POST without endTime starts a running timer (one per user; stops others, sets the task to IN_PROGRESS). Billed entries are immutable (409 billed). Filters taskId, userId, projectId, from/to, isBillable, isBilled, running, updatedSince. Events time.timeEntry.created/updated/deleted.

v1.8.0 · September 6, 2026

  • Projects: GET/POST /projects, GET/PATCH/DELETE /projects/{id} — multilingual name like tasks, customer + contact person, parent project (cycle-free), time budget (minutes, prepaid), period; metrics open tasks, booked and billable minutes. Filters q, customerContactId, parentId (none = top level), activeOn, updatedSince. Events projects.project.created/updated/deleted.

v1.7.0 · September 6, 2026

  • Tasks: GET/POST /tasks, GET/PATCH/DELETE /tasks/{id}, POST /tasks/{id}/status, GET/POST /tasks/{id}/comments. Multilingual title/description: read in the request language (?locale or Accept-Language) plus the full titleI18n; write as string or object {de,en,ru}, the organization language is translated automatically. Completing stops running timers, closes watchers and spawns the next recurrence like in the app. Events tasks.task.created/updated/completed/deleted, tasks.comment.created.

v1.6.0 · September 6, 2026

  • Open items: GET /open-items (direction, status incl. open/overdue, contactId, invoiceId, q, updatedSince), GET /open-items/{id} (amounts in cents, cash discount, dunning state, payments = linked bookings), POST /open-items/{id}/payments (payment as booking “bank to personal account” incl. § 367 allocation of outstanding dunning costs; partial via amountCents; markOnly for a plain status flip). Dunning: GET /dunning/reminders and GET /dunning/reminders/{id} (level, claim/fee/interest/total in cents, PDF, portal link). Events payments.payment.recorded (all payment paths), dunning.reminder.sent, invoices.invoice.overdue (when a dunning level is created).

v1.5.0 · September 6, 2026

  • Invoices: GET /invoices (filters status incl. open/overdue, kind, contactId, orderId, q, updatedSince), GET/POST /invoices, PATCH /invoices/{id} (drafts only — GoBD), POST …/issue (number, booking, open item, PDF + ZUGFeRD), POST …/correct (mode cancel = cancellation document, mode value = value correction KOR-…), GET …/pdf (final or preview), GET …/xml (ZUGFeRD XML as application/xml). Amounts as cents + exact decimal strings; gross mode (priceMode GROSS) with gross unit prices. Events invoices.invoice.created/issued/sent/paid/cancelled/corrected — also for payments via Stripe/checkout/installments/open-item settlement.

v1.4.0 · September 6, 2026

  • Orders: GET /orders (filters status/draft, contactId, sourceQuoteId, q, updatedSince), GET /orders/{id} (lines with billed/dropped/open quantity, sections, linked invoices, confirmation PDF), GET /orders/{id}/pdf. POST /quotes/{id}/convert: issue and accept the quote and turn it into an order via the acceptance router (order number, PDF, automatic sending, possibly advance/deposit invoice); waits up to 25 s, otherwise routing-pending. Event orders.order.created (source quote|manual|duplicate).

v1.3.0 · September 6, 2026

  • Quotes: GET/POST /quotes, GET/PATCH /quotes/{id} (head, items, sections; article reference fills name/unit/price/tax), POST …/issue (number + portal link + PDF), POST …/send (e-mail with PDF; waits up to 25 s for rendering, otherwise pdf-pending), POST …/accept and …/decline (on the customer's behalf; acceptance triggers order/advance invoice), GET …/pdf (status + URL). Amounts as cents + exact decimal string. Events quotes.quote.created/updated/sent/accepted/declined — also when accepted in the customer portal.

v1.2.0 · September 6, 2026

  • Articles: GET/POST /articles, GET/PATCH /articles/{id} — search q, filters kind/archived, updatedSince; prices as unitPriceCents + unitPriceExact (four fraction digits), currency = the organization's base currency; archive via PATCH archived (no DELETE). Events articles.article.created/updated. New error code feature-not-available (403) when a feature is unavailable for the organization type.

v1.1.0 · September 6, 2026

  • Webhooks: GET/POST /webhooks, GET/PATCH/DELETE /webhooks/{id}, POST …/rotate-secret, POST …/test, GET …/deliveries, POST …/replay; catalog GET /webhooks/events with …/{type}/sample and …/{type}/recent. Standard Webhooks signature (webhook-id, webhook-timestamp, webhook-signature), retries after 1 min/5 min/30 min/2 h/12 h, endpoint disabled after five consecutive failures. Scope webhooks:manage.
  • Events: contacts.contact.created/updated/deleted, leads.lead.created, webhooks.test.

v1.0.0 · September 6, 2026

  • First release of the public API: keys (capi_…), scopes, RFC 9457 errors, cursor pagination, Idempotency-Key, rate limits, GET /me.
  • Contacts: GET/POST /contacts, GET/PATCH/DELETE /contacts/{id} — search (q), filters type/tag, updatedSince; gender resolved by AI when omitted.