Delete Project

Beta
Delete a project. With no body it deletes a project that holds nothing, and refuses one that does; `mode` is how you say what should happen to what it holds. **Empty** (no body): the project is removed only while it holds no resources. A project that holds any is refused with 409 `project_not_empty`, and the refusal enumerates what is inside: `error.details.resource_count` is the total, and `error.details.contents` names each kind with a count and up to five names. Every project row also carries that total as `resource_count`, so an application can find the projects it may delete in one list call. Records of work - conversations, runs, calls, callers, memories - never hold a project open and are not counted. **Detach** (`mode: detach`): only the grouping row is removed; every resource in the project moves to the implicit Default project, where it stays readable and is listed by `?project_id=default`. This is what an unqualified delete used to do silently. Refused with 409 `project_has_scoped_credentials` while an API key, service account, vault credential, webhook endpoint, member grant or pending invite is scoped to the project, because detaching any of those would silently widen it. **Purge** (`mode: purge` with `confirm` equal to the project's name): available only on an ARCHIVED project, because a teardown needs a state you can sit in and reverse first; a live project is refused with the coded `409 project_not_archived`. Archive the project, confirm it is the one you mean, then purge. The project is removed WITH its contents in one transaction. Agents (with their tests), knowledge bases (with their documents), tools, audio assets, scoped webhook endpoints and scoped vault credentials are deleted; API keys and service accounts pinned to the project are revoked; member grants and pending-invite scopes on the project are cleared. The runs and conversations of a deleted agent go with that agent, transcripts and recordings included, and stop being readable the moment the purge lands - a detach leaves them alone, because a detached project's agents are still live. Callers, suite runs and memories are operational records and survive either mode, moving to the Default project; a batch call survives the project the same way, but not the agent it dialled for, so a purge's agents take their campaigns with them once they are permanently removed. External brains, skills, teams, channels, stores, hosted APIs and files are resources with their own lifecycle and their own delete, so a purge does NOT remove them either: they move to the Default project too, the teardown preview lists every one of them under `retains`, and because they DO hold a project open an unqualified delete refuses while any of them is in the project. Refused with 409 while a phone number is attached (release or move it first), while a member's only project grant is this one, or while a live invite carries only this project (clearing either would widen that person to the whole workspace, the invite one acceptance earlier). Preview either mode with `GET /v1/projects/{project_id}/teardown`. **A purge is recoverable for 30 days.** The project disappears from every list and read immediately, and its name is freed for reuse, but the project and its resources are kept and permanently deleted only once the window closes. `POST /v1/projects/{project_id}/restore` brings the project and its resources back inside that window; the credentials the purge revoked and the grants it cleared stay that way. The 409 carries the blockers under `error.details.blockers` (`kind`, typed `id`, `name`, and the `blocks` modes each refuses), their total under `error.details.blocker_count`, and, for existing clients, the same rows under `error.details.credentials`. The lists are capped at 50 rows; the counts are not, and the refusal is decided on the count.

Authentication

AuthorizationBearer

Enter your API key with the Bearer prefix, e.g. ‘Bearer sk_…’.

Path parameters

project_idstringRequired

Project id (prefixed external id, proj_...).

Headers

Speechify-VersionstringOptional

Request

This endpoint expects an object.
modeenumOptional

detach removes the grouping row only and moves every resource to the Default project; purge removes the project with its contents. Omitted, the delete removes only an empty project.

confirmstringOptional

Required for purge: the project’s name, exactly as returned by GET. A mismatch answers 400 validation_failed naming this field.

Response

Project deleted. With no mode it held nothing; in detach mode its resources moved to the Default project; in purge mode they went with it.

Errors

400
Bad Request Error
401
Unauthorized Error
404
Not Found Error
409
Conflict Error