Skip to main content
POST
Error

Authorizations

Authorization
string
header
required

A contact session token, uk_ct_…. Belongs to one of the developer's own users, and reads only that user's data.

Headers

X-Customer-Id
string<uuid>

The customer this call is acting inside — the same arrangement as X-Organization-Id, one plane down. Switching customers is navigation, not a mutation: nothing is stored, you send a different header, and the membership JOIN behind it decides what you may do there. An id you are not a member of matches no row and answers 404. Absent, the contact's oldest membership answers.

Body

application/json
reason
enum<string>
required

Required. Why this team is leaving.

Available options:
too_expensive,
missing_feature,
not_using,
switching,
temporary,
other
comment
string

What they typed, up to 2000 characters.

subscription_id
string<uuid>

Which subscription, when the team holds several.

Response

The record, the offer to make, and the date access ends.

cancellation
object

One person's answer to "why are you leaving", and what happened next.

It is recorded before any gateway is asked anything, so a record exists whether or not the cancellation was ever carried out — and a record nobody carried out is the only churn signal that arrives while the customer is still a customer.

offer
object | null

The one offer worth making to somebody who just gave this reason, or null.

At most one: a screen that answers "I am leaving" with three counter-offers is a negotiation and reads as one. The extra fields depend on kinddowngrade carries plan and price, pause carries months and resumes_at, discount carries coupon.

access_until
string<date-time> | null