---
title: "Disconnect"
method: DELETE
path: "/api/v1/integrations/{provider}/connection"
tags: ["integrations"]
---

# Disconnect

`DELETE /api/v1/integrations/{provider}/connection`

## Request

- Base URL: `https://api.aws.cognee.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.aws.cognee.ai/api/v1/integrations/{provider}/connection`
- Auth: API key in header `X-Api-Key`

Revoke this tenant's connection. Owner-only.

Local revocation is what actually cuts access off — it stops any token
from being minted or decrypted for this account. The remote call is
best-effort on top, and a no-op for providers where the only remote
equivalent is destructive (uninstalling an app from a whole
organization is not one tenant's decision to make).

``account_id`` picks one connection when the tenant holds several to
the same provider (CLO-528); omitted, this is the pre-existing
"most recently connected wins" behavior.

``delete_data`` empties the connector dataset in the tenant pod first
— every dataset this connection has ever landed in (CLO-1014 D2): its
current target, plus every earlier target it was switched away from
without deleting, recorded in ``previous_targets``. The delete gates
the revoke: a 409 (a sync is still in flight — a resource still
pending here, or the pod's dataset lock held) or a 502 (the pod could
not delete one of them) leaves the connection active and nothing
revoked, so the caller can retry or disconnect without deleting.

**The delete/switch race (CLO-1014).** The sweep below reads
``target_dataset``/``previous_targets`` once, then spends an
unbounded amount of time calling the pod before this route ever
touches the row again - long enough for ``set_connection_dataset``
to switch the target underneath it. Closed with a lease
(:func:`~.target_dataset.metadata_marking_disconnecting`), not a
recheck alone: taken under the row's own lock before the sweep
starts, checked by every other writer of these two keys before
*they* write (the switch routes' own ``_write_new_target``,
``dispatch_sync``'s ``pending_patch``), and verified again,
independently, right before the final revoke
(``revoke_credential_by_account``'s own ``verify_swept_target``) -
the lease stops another writer from landing a change, the final
verify is what stops this route from trusting that it did. Released
in a ``finally`` covering every exit from here, success or failure,
so a crash mid-sweep cannot wedge the connection - see
:func:`~.target_dataset.is_disconnect_lease_active` for the
staleness backstop that recovers one that outlives its own request.

## Path parameters

- `provider` string, required

## Query parameters

- `tenant_id` string, uuid, required
- `account_id` string, nullable
- `delete_data` boolean

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/cognee/apis/cognee-api.md) - [All operations](https://skmtc.dev/cognee/apis/cognee-api/llms.txt) - [OpenAPI document](https://skmtc.dev/cognee/apis/cognee-api/revisions/a7b6c6cb8212?raw)
