Skip to content

Delete tenant API Reference

DELETE
/tenants/{tenant}
curl --request DELETE \
--url https://api.kupe.cloud/api/v1/tenants/acme \
--header 'Authorization: <Authorization>' \
--header 'Content-Type: application/json' \
--data '{ "cascade": false, "confirm": "acme" }'

Request deletion of the tenant. Only the tenant owner (the contactEmail on the tenant) may call this, and only with an OIDC bearer token — API keys are refused (403, code owner_required), as are other admins.

The body must repeat the tenant name in confirm. While the tenant has clusters that are not already terminating the request is refused with 409 (code clusters_exist, the message lists their names) unless cascade is true, in which case those clusters are deleted first.

Deletion is asynchronous: on 202 the Tenant enters status.phase=Terminating; GET /tenants/{tenant} reports that phase until the platform has finished tearing the tenant down, then returns 404. A tenant that was ever billable is held until its final invoice settles (up to 24h).

Rate limited to one request per minute per caller (429 with Retry-After). Every request is recorded as a Kubernetes Event (TenantDeletionRequested) on the tenant.

tenant
required
string

Tenant name

Confirmation (and optional cascade)

Media type application/json
object
cascade

Delete every ManagedCluster in the tenant first. Without it the request is refused (409 clusters_exist) while any cluster is not already terminating.

boolean
Example
false
confirm

Must equal the tenant name in the path; guards against accidental deletion.

string
Example
acme

Deletion accepted; tenant is Terminating

Media type application/json
object
name
string
status
object
phase

Always “Terminating” on acceptance; GET /tenants/{tenant} reports the same phase until the tenant is gone (then 404).

string
Example
{
"name": "acme",
"status": {
"phase": "Terminating"
}
}

Confirm does not match the tenant name (code confirm_mismatch) or invalid body

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Missing or invalid authentication

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

API key or non-owner caller (code owner_required); not a member of this tenant

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Tenant not found (already gone)

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Active clusters without cascade (code clusters_exist) or already terminating (code already_terminating)

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}

Rate limit exceeded (one deletion request per minute per caller; see Retry-After)

Media type application/json
object
code
string
error
string
field
string
message
string
severity
string
Example generated
{
"code": "example",
"error": "example",
"field": "example",
"message": "example",
"severity": "example"
}