Update Project

Beta

Edit a project in place - its name, its monthly spend limit, or its capacity ceilings - keeping the same id so every grouped resource follows the edit with no re-pointing. Names are unique per workspace (case-insensitive). The limit fields require billing.manage; a capacity ceiling above the workspace’s own is refused, since it could never apply.

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.
max_concurrent_runsinteger or nullOptional>=1

Sets the project’s concurrent-run ceiling; null removes it. Must be a positive integer at or below the workspace’s own run ceiling, otherwise the request is refused with 400 validation_failed naming the field and the ceiling. Requires the billing.manage permission. Takes effect on the next run start attributed to the project.

max_concurrent_callsinteger or nullOptional>=1

Sets the project’s active-call ceiling; null removes it. Must be a positive integer at or below the workspace’s own active-call cap, otherwise the request is refused with 400 validation_failed naming the field and the ceiling: a project can only narrow the workspace’s capacity, never raise it. Requires the billing.manage permission, like the spend limit beside it. Takes effect on the next call start.

max_requests_per_minuteinteger or nullOptional>=1

Sets the project’s request-rate ceiling in requests per minute; null removes it. Must be a positive integer at or below the workspace’s widest per-surface request rate over a minute, otherwise the request is refused with 400 validation_failed naming the field and the ceiling. Requires the billing.manage permission. Takes effect on the next request from a credential pinned to the project.

namestringOptional<=120 characters

New project name; unique per workspace (case-insensitive), surrounding whitespace is trimmed.

monthly_budgetdoubleOptional0-1000000000

Edits the project’s MONTHLY spend limit in US dollars: omit to leave it unchanged, send a positive value to set or change it, or an explicit 0 to remove it. Amounts are whole cents written as a plain decimal; a finer value, or exponent notation, is refused rather than rounded. Requires the billing.manage permission (owners/admins), like the workspace budget — a spend ceiling is a billing control, not a grouping edit. Once the project’s billed spend within the current calendar month (UTC) reaches the limit, new billable work attributed to that project is refused with the coded 402 project_spend_limit_exceeded until the month resets or the limit is raised.

Response headers

Speechify-Request-IdstringOptional
Unique identifier for this request, present on every response (2xx and non-2xx alike). If the caller sends a `Speechify-Request-Id` request header the server echoes it back (sanitized and length-capped) so one logical request can be traced end-to-end; otherwise the server generates a fresh value. Log it on every response and quote it in support requests - it is the stable handle that ties your observation to Speechify's server-side logs, and it matches the `request_id` field in the error envelope. The legacy alias `X-Request-ID` carries the same value and is still accepted on requests, until 2027-07-24. Prefer the un-prefixed name (RFC 6648).

Response

The updated project.
idstringformat: "^proj_[0-9a-hjkmnp-tv-z]{26}$"

Workspace-scoped project identifier (prefixed external id).

namestring

Human-readable label, unique per workspace (case-insensitive).

resource_countinteger>=0

How many resources this project holds: agents and their tests, knowledge bases, tools, audio assets, phone numbers, external brains, skills, teams, channels, stores, hosted APIs and files. Records of work that happened - conversations, runs, calls, callers, memories - are not counted, and never hold a project open.

It is the count the unqualified delete refuses on, so a project reading 0 is one DELETE /v1/projects/{project_id} accepts with no body. That is what makes an application’s own cleanup a single list call rather than a stats read per project. Use GET /v1/projects/{project_id}/stats for the per-kind breakdown.

created_atdatetime
updated_atdatetime
archived_atdatetime or nullOptional

When the project was archived; null while it is live. While set, nothing new starts or bills inside the project and every such attempt answers 409 project_archived.

Absent rather than null while a console runs ahead of an API that predates archiving, which is why it is not required: read absent and null alike.

purged_atdatetimeOptional

When this project was purged, present only on the rows returned by include_purged=true. A purged project is kept for 30 days from this stamp and permanently deleted after that, so the restore deadline is this value plus the window; it is absent on every project that still exists. Restore it with POST /v1/projects/{project_id}/restore.

max_concurrent_callsintegerOptional>=1

The most voice-agent calls this project may have active at once, present only when set. Checked after the workspace’s own active-call cap on every call start (web session, outbound call, batch dial, inbound SIP), keyed on the project the call’s agent lives in: a call over the ceiling is refused with the same 429 concurrency_limit_reached the workspace cap answers (an inbound caller hears the busy message), while sibling projects keep their headroom. Never higher than the workspace’s cap: a project can narrow the workspace’s capacity, not raise it.

max_concurrent_runsintegerOptional>=1

The most durable agent runs this project may have queued or running at once, present only when set. Checked after the workspace’s own run ceiling on every run start (a request, a team run, or an unattended trigger fire), keyed on the project the run is ATTRIBUTED to - its agent’s project, captured at creation - so a workspace-wide key starting a run in this project counts against it. A run over the ceiling is refused with the same 429 concurrency_limit_reached the workspace ceiling answers, carrying Retry-After, while sibling projects keep their headroom. A run parked on a human approval or on its children holds no slot and does not count. Never higher than the workspace’s own run ceiling: a project can narrow the workspace’s capacity, not raise it.

max_requests_per_minuteintegerOptional>=1

The most API requests per minute credentials pinned to this project may make across every surface, present only when set. Checked after the workspace’s own request-rate limit, in one bucket per project: a request over the ceiling is refused with the same 429 rate_limited the workspace limit answers, while other projects and unpinned credentials are untouched. Never higher than the workspace’s widest per-surface rate over a minute: a project can narrow the workspace’s capacity, not raise it. Console sessions and unpinned keys carry no project and are never subject to it.

monthly_budgetdoubleOptional<=1000000000

The project’s monthly spend limit in US dollars, present only when one is set. New billable work attributed to this project is refused with the coded 402 project_spend_limit_exceeded once monthly_spend reaches it; the limit resets at the calendar-month boundary (UTC).

Spend is attributed the same way it is billed: work from a project-pinned API key counts against that key’s project, and a voice-agent conversation counts against its agent’s project. The implicit Default project cannot carry a limit — it has no project record — so spend there is bounded by the workspace’s monthly_budget instead.

monthly_spenddoubleOptional>=0

The project’s billed month-to-date spend in US dollars, present whenever the billing plane answered - regardless of whether a spend limit is set.

monthly_budget_statusenumOptional

Where monthly_spend stands against monthly_budget, present only when both are: warning from 80% of the budget, reached once the spend has reached it and new billable work attributed to the project is refused with 402 project_spend_limit_exceeded, ok below 80%. These are the thresholds the project.spend_budget.warning and project.spend_budget.reached webhook events fire at, so polling this field and subscribing to the events give the same answer.

monthly_budget_remainingdoubleOptional

monthly_budget minus monthly_spend in US dollars, present only when both are. Negative once the spend has passed the budget, by the amount it overshot: enforcement trails billed usage by a couple of minutes, so work already under way can carry a project past its budget.

Errors

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