> For the complete documentation index, see [llms.txt](https://docs.concurrence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.concurrence.com/developer-guide/platform-api/workspaces.md).

# Workspaces

Manage workspaces: tenant isolation, timezone, version reads, voice settings, speech recognition, and test caller numbers.

Workspaces are the top-level organizational unit in the Platform API. Every resource (agents, services, skills, phone numbers, integrations) belongs to a workspace. Workspaces provide tenant isolation and environment separation.

## Key Concepts

* **Workspace ID**: UUID used in all Platform API request paths
* **Slug**: URL-friendly name (e.g., `acme-production`)
* **Regional endpoint**: responses report the deployment serving the request; region is not an editable workspace placement policy
* **Backend Org ID**: Links to the Classic API organization, bridging the two API surfaces

{% hint style="info" %}
**Workspace vs Organization**: The Classic API scopes by `organization`. The Platform API scopes by `workspace`. A workspace maps to a Classic API organization via `backend_org_id`.
{% endhint %}

## Workspace Resource

### List Workspaces

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Get a Workspace

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Update a Workspace

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}" method="patch" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Workspace Timezone <a href="#workspace-timezone" id="workspace-timezone"></a>

`timezone` is the workspace's IANA timezone, such as `America/Chicago`. Set it with the update operation above, or send `null` to clear it; a name that is not a valid IANA zone returns `422`. Workspace reads return it. In the Developer Console, **Settings > General** has a **Timezone** field, and clearing it removes the setting.

The agent tells the caller's local time from one zone per session. A session opened with an `entity_id` uses the timezone of the patient's assigned clinic when one is recorded. Otherwise it uses the workspace `timezone`, then the deployment region's default zone, which the agent's instructions mark as a fallback. A caller matched only by phone number gets the workspace zone. An invalid stored value is skipped.

Set `timezone` on any workspace whose callers are outside the deployment region's default zone.

## Provisioning

After creating a workspace, call the provision endpoint to seed default integrations and mark the workspace as provisioned. This is idempotent: safe to call multiple times. Requires `Workspace.update` permission.

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/provision" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

## Archive

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/archive" method="post" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

Archiving removes a workspace from active access flows while preserving all underlying data. It requires the `owner` role and a slug confirmation in the request body to prevent accidental archival. Archived workspaces no longer appear in workspace listings and reject new API requests.

## Invitations

{% hint style="info" %}
Invitation creation and preview are Identity API operations and are not represented in the Platform API OpenAPI document. The embedded Platform operations on this page remain the source of truth for workspace resources, archiving, settings, and test configuration.
{% endhint %}

Workspace invitations let you invite users by email before they have an account.

* **Create**: `POST /workspaces/{workspace_id}/invitations` sends an invitation with a specified role and 7-day expiry. Resending to the same email reactivates the existing invitation.
* **Preview**: `GET /workspaces/invitations/{invitation_id}/preview` returns a safe public view of the invitation (workspace name, role, expiry, status) without requiring authentication. Used to render invitation landing pages before sign-in.
* **Accept or decline**: the invited user can accept or decline from their pending invitations list.
* **Revoke**: workspace admins can revoke pending invitations.

When a workspace admin creates or resends an invitation, an email notification is sent to the invited user with the workspace name, assigned role, and an accept link. Email delivery is asynchronous and fail-open - if delivery fails, the invitation is still created and returned to the admin for manual sharing.

Invited users who do not belong to an auto-provisioning domain can log in through Google OAuth. If pending invitations exist for their verified email, they receive a bootstrap token with no workspace scopes. The user must accept a specific invitation through the Developer Console before receiving a workspace-scoped token.

### Access Audit Logging

All workspace membership and invitation operations emit audit events:

| Event                           | When                          |
| ------------------------------- | ----------------------------- |
| `workspace.member_added`        | Member created or reactivated |
| `workspace.member_removed`      | Member deactivated            |
| `workspace.member_role_updated` | Member role changed           |
| `workspace.invitation_sent`     | Invitation created or resent  |
| `workspace.invitation_accepted` | Invitation accepted           |
| `workspace.invitation_declined` | Invitation declined           |
| `workspace.invitation_revoked`  | Invitation revoked by admin   |

Each event records the actor, target, role, and relevant metadata. These events are available through the audit log endpoints and the compliance export.

## Environment Separation

A workspace has no environment label, and the Platform API does not convert a workspace between staging and production. Use separately provisioned workspaces for development, testing, and production, with the appropriate access, integration, and retention policies.

The legacy region update field is accepted but ignored. Its presence in a request does not move data or change the serving deployment's reported region. See [Regions and Endpoints](/developer-guide/getting-started/regions-and-endpoints.md).

## Optional Data Exposure

Topic modeling and Delta Sharing are separate opt-in settings, disabled by default. Delta Sharing supports open sharing and a recipient identified by a sharing identifier. Use the embedded workspace update schema for the mode and identifier requirements.

Saving a setting and applying its data grants are separate steps. Enabling a capability can require asynchronous provisioning. Disabling exposure or changing an active recipient requests reconciliation; if it cannot be queued, the request reports failure after the setting has been saved. Retry and verify actual access rather than treating the stored setting alone as proof of revocation.

## Agent and Context Graph Versions

Version reads for [agents](/developer-guide/platform-api/workspaces/agents.md) and Context Graphs take `latest` or a positive version number in the path; any other value, including `0` or a negative number, returns `422`. Creating a version updates the parent agent's or Context Graph's `updated_at`, so `sort_by=-updated_at` on their lists ranks the newest version push first. The Console's Personas and Context Graphs lists, which hold agents and Context Graphs, show the later of the last edit and the latest version push, under **Persona updated** and **Updated**.

## Voice Settings

Voice settings control the workspace-level voice pipeline of platform-managed calls. A `gpt_realtime` call takes its voice from `realtime.voice` and its language from the agent's default language.

### Get Voice Settings

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/settings/voice" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Update Voice Settings

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/{workspace\_id}/settings/voice" method="put" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

{% hint style="info" %}
**Partial updates.** The `PUT` endpoint supports partial updates: omitted fields stay unchanged. You only need to send the fields you want to modify. Send `null` for a field to reset it to its default, which the response and later reads return.
{% endhint %}

In the Developer Console's workspace voice settings, an unset TTS provider shows as **Platform default**, which follows the [default TTS model](/developer-guide/platform-api/workspaces/voice-configuration.md#default-tts-model) rules. Choosing **Platform default** clears a saved provider, while each per-language route names Cartesia or ElevenLabs.

### Voice Identity & Style

| Field      | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                     |
| ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `voice_id` | string | Voice persona identifier (max 128 chars)                                                                                                                                                                                                                                                                                                                                                        |
| `tone`     | string | Explicit TTS tone override. Typical values: `calm`, `sympathetic`, `enthusiastic`, `content`, `curious`, `cheerful`, `serious`, `friendly`                                                                                                                                                                                                                                                      |
| `speed`    | float  | Speech rate (0.5-2.0, default 1.0). Not applied on ElevenLabs `eleven_v4_turbo`                                                                                                                                                                                                                                                                                                                 |
| `volume`   | float  | Volume level (0.0-1.0)                                                                                                                                                                                                                                                                                                                                                                          |
| `language` | string | The language platform-managed calls are spoken in when the caller's record names none: `en` (default), `es`, `ar`, `fr`, `de`, `pt`, `zh`, `ja`, `ko`, or `multilingual`, which starts each call in English and follows the language the caller speaks. Any other value, including a regional tag such as `en-GB`, returns `422` naming the allowed values; a stored value reads back as stored |

### Providers

| Field                | Type   | Description                                                                                                                                                                                                                                                                                                                                                                                               |
| -------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stt_provider`       | string | Speech-to-text provider: `deepgram`, `openai`, or `cartesia`. OpenAI recognition uses `gpt-transcribe`                                                                                                                                                                                                                                                                                                    |
| `tts_provider`       | string | Text-to-speech provider: `cartesia` or `elevenlabs`                                                                                                                                                                                                                                                                                                                                                       |
| `tts_config`         | object | Provider-specific TTS configuration; keys depend on `tts_provider`                                                                                                                                                                                                                                                                                                                                        |
| `language_providers` | object | Per-language TTS provider map, up to 10 entries. Each key is `en`, `es`, `ar`, `fr`, `de`, `pt`, `zh`, `ja`, `ko`, or `multilingual`, and any other key returns `422`. A call in a regional language such as `es-MX` uses the `es` entry; see [Default TTS Model](/developer-guide/platform-api/workspaces/voice-configuration.md#default-tts-model). Send `null` to clear it; an empty map returns `422` |

{% hint style="info" %}
**Tone vs emotional adaptation.** In the standard voice-context path, an explicit workspace `tone` overrides the tone computed from acoustic emotion, tone momentum, or sensitive-topic matching. Omit `tone` if you want the runtime to select a supported tone from those signals. Provider and runtime support still determine how a selected tone is rendered.
{% endhint %}

### Speech Recognition

| Field      | Type          | Description                                                                                |
| ---------- | ------------- | ------------------------------------------------------------------------------------------ |
| `keyterms` | list\[string] | Exact words for STT boost, up to 200 entries: `["Dr. Ramirez", "metformin", "amlodipine"]` |

Keyterms are merged with service-level keyterms and deduplicated. They improve recognition of domain-specific vocabulary: drug names, doctor names, insurance carriers, medical abbreviations. Keyterms are the recommended way to improve transcription accuracy for domain-specific terms.

### Pronunciation

| Field                   | Type   | Description                                                                |
| ----------------------- | ------ | -------------------------------------------------------------------------- |
| `pronunciation_dict_id` | string | Pronunciation dictionary identifier for domain-specific term pronunciation |

Links to a pronunciation dictionary for the voice engine. Use this when the TTS engine mispronounces domain-specific terms (drug names, medical procedures, proper nouns).

On Cartesia voices, the dictionary applies to every spoken message, including greetings and fillers. On the default Sonic 3.6 model, an entry matches any capitalization unless it sets `case_sensitive`.

### Proactive Intelligence

| Field              | Type          | Description                                                                                               |
| ------------------ | ------------- | --------------------------------------------------------------------------------------------------------- |
| `sensitive_topics` | list\[string] | Topics that trigger preemptive tone softening, up to 50 entries: `["test results", "billing", "surgery"]` |

When the voice agent's current action matches a sensitive topic, the voice tone preemptively shifts to sympathetic, **before** the caller shows distress. Falls back to healthcare defaults when not configured.

### Post-Call Intelligence

| Field                        | Type | Description                                                                                                                                                                                                                    |
| ---------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `post_call_analysis_enabled` | bool | Setting (default `true`); does not establish an active scoring job for each call. See [Call Intelligence](https://docs.concurrence.com/intelligence-and-analytics/intelligence/call-intelligence#optional-post-call-analysis). |

See [Voice Agent, Post-Call Intelligence](/developer-guide/platform-api/conversations/voice-agent.md#layer-5-post-call-intelligence) for the evidence available after a call.

### How Settings Interact with Emotional Adaptation

Voice settings define workspace-level defaults and overrides. In the standard voice-context path, explicit `tone` wins over computed emotion tone, while other settings can still be adapted where noted:

| Setting            | What You Control            | What the System Overrides                                                      |
| ------------------ | --------------------------- | ------------------------------------------------------------------------------ |
| `tone`             | Explicit workspace TTS tone | Overrides acoustic, momentum, and sensitive-topic tone selection when set      |
| `speed`            | Base speech rate            | Can be reduced by supported empathy pacing logic, subject to configured floors |
| `volume`           | Base volume                 | Passed through when supported by the selected TTS provider                     |
| `voice_id`         | Voice persona               | Per-agent `voice_config` can override for specific agents                      |
| `keyterms`         | Domain vocabulary           | Merged with service-level keyterms and deduplicated                            |
| `sensitive_topics` | Proactive tone softening    | Falls back to defaults when not set                                            |

## Test Caller Numbers

Manage which phone numbers are authorized for test calls in the workspace. Useful for restricting test/playground calls to known numbers.

Calls from these numbers, and text turns from the test credentials below, are tagged as test traffic and run tools in simulation mode: every tool call returns a `dry_run` result instead of reaching an integration, a world write, or a platform function. Use the Playground when a test needs live tool results. See [Write Isolation](/developer-guide/platform-api/safety/simulation-coverage.md#write-isolation).

### Get Test Caller Numbers

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/test-caller-numbers" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Update Test Caller Numbers

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/test-caller-numbers" method="put" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

## Test Credential IDs

Manage which credentials are authorized for workspace test flows.

A test credential writes only to conversations a test session started. A turn, a close, a delivery acknowledgement, a channel switch, or an approval decision on any other conversation returns `403`, and on the [sessions WebSocket](/developer-guide/platform-api/platform-api/sessions.md#reconnect-and-thread-semantics) the credential gets its own conversation thread for each entity and service. See [Test Credentials](/developer-guide/platform-api/conversations.md#test-credentials).

### Get Test Credential IDs

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/test-credential-ids" method="get" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}

### Update Test Credential IDs

{% openapi src="<https://platform.api-us.concurrence.com/v1/openapi.json>" path="/v1/workspaces/{workspace\_id}/test-credential-ids" method="put" %}
<https://platform.api-us.concurrence.com/v1/openapi.json>
{% endopenapi %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.concurrence.com/developer-guide/platform-api/workspaces.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
