> This page is for Build.

> Append .md to any page URL for clean Markdown. Index: https://docs.speechify.ai/llms.txt.
>
> Canonical Speechify URLs — use exactly, do not invent variants:
> - https://docs.speechify.ai — this site (API reference, SDKs, quickstarts)
> - https://speechify.ai — marketing + product site
> - https://platform.speechify.ai — customer dashboard, signup, API keys, billing
> - https://api.speechify.ai — API base URL
> - https://github.com/Speechify-AI: GitHub org for the API (cookbook, demos, CLI). `github.com/speechify` does not exist.
> - https://status.speechify.ai — status + incidents
> - https://speechify.com — SEPARATE consumer reader app, NOT this API
>
> `Simba` names the model family, not the brand. Model ids: `simba-3.2` (English, recommended) and `simba-3.0` (English, German, Spanish, French, Italian and Portuguese; the default). `simba-english` and `simba-multilingual` are retired: a new workspace that sends either gets `400 model_retired`. `SimbaVoice` / `simbavoice.ai` are retired.
>
> Ask, don't scrape. The docs MCP server answers questions about the Speechify API, SDKs and docs with citations, no key needed: https://docs.speechify.ai/_mcp/server (Streamable HTTP, tool `searchDocs`). Setup: https://docs.speechify.ai/build/guides/get-started/connect-mcp

# Projects

> How Speechify projects work: what a project groups, how a project grant scopes a member, what archive and delete do, and what projects do and do not scope in SpeechifyAI Build.

A **workspace** is who you are: it holds your identity, your members, your plan, and one invoice.
A **project** is where work happens inside it. A project groups the resources you create in it and
the spend you incur from it, so a workspace can run several environments or several end customers
without splitting into several accounts.

Every workspace has an implicit **Default project**. It is not a row you create or delete: any
resource with no project lives there, which is where everything sits until you make your first
project.

> **Note**
>
> A project is a filter and a grouping, not a security boundary. It scopes what a credential may
> reach, what a scoped member sees, and where spend lands. If you need one team to be unable to
> see another team's data at all, use a separate workspace.

## Creating a project

#### cURL

```bash
curl -X POST "https://api.speechify.ai/v1/projects" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Production"}'
```

Names are unique per workspace, case-insensitively. A workspace holds at most 10 live projects on Free, 50 on Starter and 100 on Pro and above;
at the cap the create is refused with `409 project_limit_reached`.

## What a project groups

| Kind                                    | Belongs to a project                                                                                                              |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Audio assets                            | Yes, and the project can be changed later                                                                                         |
| API keys and service accounts           | Yes, as a pin fixed when the credential is created                                                                                |
| Vault credentials and webhook endpoints | Either one project, or workspace-wide                                                                                             |
| Usage and spend                         | Yes, attributed through the calling credential's pin                                                                              |
| Your cloned voices                      | Yes, taken from the pin on the credential that created the clone, except a consent-verified clone, which is always workspace-wide |
| The public voice and model catalog      | No, it is workspace-wide                                                                                                          |

A usage record keeps the project it was attributed to, because your usage grouping and your
invoice already report it that way.

On Build, the project travels with the credential: a synthesis request lands in the project its
API key or service account is pinned to, and so does the spend it incurs. The lists whose rows can
be shared across the workspace instead of living in one project - credentials, webhook endpoints
and cloned voices - accept a `project_id` query parameter whose literal `shared` selects the
workspace-wide rows, because an absent project there means workspace-wide rather than Default.

#### cURL

```bash
curl "https://api.speechify.ai/v1/voices?project_id=shared" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY"
```

## Pinning a credential

An API key or a service account can be **pinned** to one project when you create it. A pinned
credential reads and writes only inside that project, its requests are attributed to that project,
and it is subject to that project's limits.

The pin is fixed at creation and cannot be edited afterwards, so re-scoping means minting a new
credential and retiring the old one. A credential with no pin is workspace-wide.

## What a grant does

By default every workspace member sees the whole workspace. Granting a member a project **narrows
them to the projects they hold**: from their first grant onward, they see and work in those
projects only, in the console and through the API.

* A member with no grants anywhere is workspace-wide. That is the default state, not a gap.
* Removing a member's last grant returns them to workspace-wide access. To narrow someone, grant
  them the projects they should keep rather than revoking everything.
* Owners and billing admins cannot be scoped: both already hold workspace-wide access that a
  project grant would contradict without narrowing anything.
* A pending invite can carry projects, so an invitee is scoped from the moment they accept.

#### cURL

```bash
curl -X POST "https://api.speechify.ai/v1/projects/proj_01jqr8x9zg5k2m3n4p5q6r7s8t/members" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "user_kb3fim3yjnyto3kxli4g4ysdmyzgiuttjrudswlkgbawk"}'
```

## Limits and capacity

A project can carry its own ceilings, each sitting under the workspace's own plan limits so one
project cannot consume the whole allowance:

| Setting                 | Effect when reached                                                                                                                               |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Monthly spend limit     | New billable work attributed to the project is refused with `402 project_spend_limit_exceeded`, resetting at the calendar-month boundary (UTC)    |
| Max requests per minute | A request from a credential pinned to the project is refused with `429 rate_limited`, while other projects and unpinned credentials are untouched |

A project limit bounds work; it does not split the bill. The invoice stays workspace-level, and
per-project cost shows up as a grouping on the workspace usage breakdown.

When a project models one of your own customers, you can tell that customer they are near their allowance before a request is refused.
A project read carries `monthly_budget_status` (`ok`, `warning` from 80%, `reached` once refusing) and `monthly_budget_remaining` (negative by the overshoot once spend has passed the budget), and the `project.spend_budget.warning` and `project.spend_budget.reached` webhook events announce the same two thresholds as they are crossed.
An endpoint scoped to a project receives only that project's events; a workspace-wide endpoint receives every project's.
See [Spend Limits](/build/guides/concepts/spend-limits#project-budgets) for the payload.

## Archiving a project

Archiving suspends a project without removing anything. From then on nothing new starts or bills
inside it: any synthesis request on a credential pinned to the project
is refused with `409 project_archived`. Work already in flight is left to finish.

Everything in the project stays readable and its configuration stays editable. Archiving is
idempotent and reversible: unarchive the project and work resumes.

## Deleting a project

Deleting runs in one of two modes.

**Detach** is the default. Only the grouping is removed, and every resource in the project moves to
the Default project. It is 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** removes the project together with its contents in one transaction. It is available only
on an **archived** project, so a teardown always has a state you can sit in and reverse first; a
live project is refused with `409 project_not_archived`. A purge is recoverable for 30 days, after
which the project and its contents are permanently deleted.

#### cURL

```bash
# Detach (the default): the grouping row goes, every resource moves to Default.
curl -X DELETE "https://api.speechify.ai/v1/projects/proj_01jqr8x9zg5k2m3n4p5q6r7s8t" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY"

# Purge: archived projects only, and `confirm` must equal the project's exact name.
curl -X DELETE "https://api.speechify.ai/v1/projects/proj_01jqr8x9zg5k2m3n4p5q6r7s8t" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "purge", "confirm": "Production"}'
```

| Purge removes                                                             | Purge keeps                                  |
| ------------------------------------------------------------------------- | -------------------------------------------- |
| Audio assets                                                              | Usage records, with their frozen attribution |
| Webhook endpoints and vault credentials scoped to the project             |                                              |
| API keys and service accounts pinned to the project, which are revoked    |                                              |
| Member grants and pending-invite scopes on the project, which are cleared |                                              |

A purge is refused while a member's only grant is this project, or while a live invite carries
only this project, since clearing either would widen that person to the whole workspace.

Both modes have a preview that reports what the delete would do without doing it: whether a purge
is available right now, every row holding the project open and which mode each refuses, what a
purge would remove, and the operational records it would keep.

## Restoring a purged project

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.

List what is still recoverable with `include_purged=true`, the only read that returns a purged
project. Each row carries `purged_at`, and the restore deadline is that stamp plus 30 days; a
project past its window is never listed, because a restore would refuse it.

#### cURL

```bash
# What is still recoverable, with the stamp each deadline runs from.
curl "https://api.speechify.ai/v1/projects?include_purged=true" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY"

# Bring one back.
curl -X POST "https://api.speechify.ai/v1/projects/proj_01jqr8x9zg5k2m3n4p5q6r7s8t/restore" \
  -H "Authorization: Bearer $SPEECHIFY_API_KEY"
```

**What comes back:** the project and its resources, audio assets included, exactly the rows the
purge removed. A resource you had deleted yourself
before the purge stays deleted. The project returns **archived**, the state it was purged from, so
nothing dispatches or bills inside it until you unarchive it.

**What does not come back, on purpose:** every credential the purge revoked stays revoked and
every grant it cleared stays cleared. API keys and service accounts pinned to the project are not
re-issued, vault credentials and webhook endpoints scoped to it are not undeleted, and member
grants and pending-invite scopes are not restored. Bringing a credential or a grant back would
re-grant access somebody deliberately ended, so the response reports them under `still_revoked`
instead. Re-create the credentials and re-grant the members the project still needs.

A restore is refused with `409 project_not_purged` when the project was never purged,
`409 project_restore_window_expired` once the 30 days have passed, and `409 project_name_taken`
when another project has taken this one's name since the purge - rename the project holding it,
then restore.

> **Note**
>
> A purge is recoverable for 30 days, but a restore is not a full undo: it returns the project and
> its resources, while the credentials it revoked and the access it cleared stay that way. Preview
> a purge first, and read the list of records it keeps: a project teardown that reads as total and
> is not would be worse than none.

## Promoting a project

Promoting copies one project's configuration into another project in the same workspace: build in
staging, promote to production, tear staging down.

Copied: audio assets and the webhook endpoints scoped to the source. Never copied: vault
credentials, API keys and service accounts, usage history, member grants, spend limits, and every
secret. A copied item whose credential reference
was cleared, whose secret was minted fresh, or whose name collided in the target is listed for you
rather than silently half-configured.

## What projects scope in SpeechifyAI Build

The short answer: **projects scope what everything costs, and in Build they scope the one thing you
create there, a cloned voice. The public voice and model catalog stays workspace-wide.**

| In Build                                       | Does a project apply                                                                                                                                                 |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Spend and usage attribution                    | Yes, through the calling key's pin                                                                                                                                   |
| A project's monthly spend limit                | Yes, it can refuse a Build request outright with `402 project_spend_limit_exceeded`                                                                                  |
| A project's requests-per-minute ceiling        | Yes, for credentials pinned to that project                                                                                                                          |
| Your cloned voices                             | Yes, a clone is filed under the project of the credential that created it, and the list filters by it. A consent-verified clone is filed under the workspace instead |
| The public voice catalog and the model catalog | No, they are workspace-wide                                                                                                                                          |
| Text to speech and Dialogue                    | No resource is created, so there is nothing to group                                                                                                                 |

Two consequences are worth stating plainly, because they are the ones most often misread:

* **A project's budget can stop a Build request that creates nothing inside the project.** A
  synthesis call leaves no resource behind and is still attributed to, and bounded by,
  the project its key is pinned to. Per-project Build cost is a statement about your API traffic,
  not about your console use.
* **The pin belongs to an API key, so a console session never carries one.** Everything a person
  does in the Build UI is workspace-level spend, whichever project the console is showing, and a
  voice cloned from the console is shared with the whole workspace rather than filed in a project.

### Cloned voices and projects

A voice clone created by a project-pinned credential is filed under that project alongside your
workspace, and the project decides who is shown it:

* A clone **with a project** is listed for the callers who can reach that project: a credential
  pinned to it, a member granted it, and anyone whose access is workspace-wide. It is not in
  anyone else's voice list.
* A clone **with no project** is shared with the whole workspace and listed for everyone in it,
  a project-pinned credential included. That is every clone made before projects, every clone made
  by an unpinned credential or from the console, and every consent-verified clone.
* `GET /v1/voices` takes a `project_id` filter: pass a `proj_...` id for one project's clones, or
  the literal `shared` for the clones no project filed. It is `shared` rather than `default`
  because a clone with no project is shared across the workspace rather than sitting in the
  Default project, the same way a workspace-wide credential is. The public voice catalog and the
  model catalog are returned whatever you filter by, because nobody created them in a project.

The scope you are showing changes which clones you see. It does not change where a charge lands:
synthesis bills to the project pinned on the credential that made the request, and a console
session carries no pin.

> **Note**
>
> Filing a clone to a project scopes who is shown it, not who could ever reach your account. A
> project is not a security boundary: use a separate workspace when one team must not be able to
> see another's data at all.

## Managing projects

Projects are managed in the console under **Settings → Workspace → Projects**: create and rename
them, set their limits, grant members access, archive and unarchive, preview and run a delete, and
promote one project into another. The scope picker in the top bar chooses the workspace and the
project the console is showing.