Skip to content
DELETE /organization/{id}

**Schedules permanent deletion 30 days out; it does not erase the organization today.** Immediately and irreversibly, every connection is severed and its stored credential deleted (a restore returns the organization but not the connections; each must be re-authorized by hand), every SCIM token and MCP OAuth grant is revoked, and the Stripe subscription is canceled (immediately, not at period end). Everything else (members, roles, teams, toolboxes, templates, restrictions, conversations, audit history, the logo, API tokens) survives and returns on a restore. For the next 30 days the organization is read-only: every GET still works (the paginated read APIs are the export path, and existing API tokens keep reading through them, so an export script needs no new credential), and every other method answers `403 organization_pending_deletion` except `POST /organization/{id}/restore`. MCP, tool execution and new connections are refused outright. On day 30 the full teardown runs. Calling this twice is idempotent: the second call returns the same `purge_after` with an all-zero summary. Requires the `org:delete` permission, which only the Org Owner role holds (an Org Admin is refused with 403 `permission_required`), an interactive browser session (an org API token is refused with 403), and step-up reauthentication in the app: without a valid `X-Step-Up-Token` the call answers `428 step_up_required`. `confirm_slug` must equal the organization's own `slug`; the API re-checks it, so a client that skips its confirmation prompt does not skip the check. Unlike every other mutation here this does not require an active subscription, so a locked or expired organization can still leave. On `200` the `summary` describes only what this call severed: `api_tokens_revoked`, `conversations_purged` and `logo_objects_deleted` are absent and `residue` stays empty because this phase touches none of them (the day-30 purge reports those). A non-empty `failures` means a credential this call promised to revoke may still be live at the provider, so tell the user rather than repeat the promise.

Path Parameters

idstring
required·

Organization id (org_…).

Request Body

confirm_slugstring

Must equal this organization’s slug. The API re-checks it.

reasonstring

Optional note, recorded on the audit entry this deletion writes before it runs.

Response Body

deletedboolean
Possible values:
true
organization_idstring
pending_deletionboolean

Always true here: this route only schedules. The organization is read-only until purge_after and can be brought back with POST /organization/{id}/restore.

Possible values:
true
purge_afterstring · date-time

When the full teardown will run, 30 days out. The restore window closes at this instant. A repeat call on an already-scheduled organization returns the deadline already set, never a later one.

summaryobject

Only what this call severed. Counts are of items successfully removed. The purge-only counts (api_tokens_revoked, conversations_purged, logo_objects_deleted) are absent here, not zero: they appear only on the day-30 purge.

connections_deletedinteger
failuresobject[]

Steps that did not come off cleanly on this run, one entry per step. Empty on a clean run; a retry of the same delete may clear them. There are only a handful of possible steps, so the list stays short however large the organization is; a step that walks many items reports a count and a few sample ids in its single entry.

2 properties
detailstring
stepstring
oauth_grants_revokedinteger
residueobject[]

Stores a deletion cannot reach at all. Empty on this route, because scheduling touches none of them; the day-30 purge reports them, and that list is never a sign that anything went wrong. It is the list an erasure request is answered with.

2 properties
detailstring
stepstring
scim_tokens_revokedinteger
stripe_subscription_cancelledboolean
curl -X DELETE 'https://api.elaichi.ai/organization/<id>' \
  -H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
  -H 'Content-Type: application/json'
const response = await fetch('https://api.elaichi.ai/organization/<id>', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
    'Content-Type': 'application/json',
  },
});

const data = await response.json();
console.log(data);
import os
import requests

url = "https://api.elaichi.ai/organization/<id>"
headers = {
    "Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
    "Content-Type": "application/json",
}

response = requests.delete(url, headers=headers)
print(response.json())