Audiences & Languages API
Full REST reference for the audiences and languages domain. All routes require a
Cognito JWT (Authorization: Bearer <token>) and are backed by
services/backend/lambda/audiences_handler.py /
audiences_service.py. See specs/api/audiences.md in the repo for the underlying
spec this page is based on, and the
Audiences & Languages feature guide for the product-level
behavior.
Unlike most of the Workspaces API, no endpoint here
checks the caller's membership role. Any member — owner, editor, or
viewer — can read and overwrite both lists.
Endpoints at a glance
| Method | Path | Description |
|---|---|---|
GET | /api/audiences?workspaceId= | Get audiences |
PUT | /api/audiences | Update audiences |
GET | /api/languages?workspaceId= | Get languages |
PUT | /api/languages | Update languages |
Every error response has the same shape:
{ "error": "human-readable message" }Get Audiences
GET /api/audiences?workspaceId={workspace_id}Returns the workspace's saved audience list, or the 6 built-in defaults if it has never saved one.
// 200 Response — defaults, never-saved workspace
{
"items": [
{ "id": "CEO", "name": "CEO" },
{ "id": "CTO", "name": "CTO" },
{ "id": "System Admins", "name": "System Admins" },
{ "id": "Architects", "name": "Architects" },
{ "id": "Developers", "name": "Developers" },
{ "id": "Business People", "name": "Business People" }
]
}| Status | Reason |
|---|---|
| 400 | workspaceId query parameter missing/empty |
| 403 | Caller is not a member of workspaceId |
Update Audiences
PUT /api/audiencesReplaces the workspace's entire audience list — full overwrite, not a merge. Any item not included in this request is dropped from the workspace's list.
// Request
{
"workspace_id": "ws_123",
"audiences": [
{ "id": "dev", "name": "Developers" },
{ "id": "cto", "name": "CTO" }
]
}Validation: at most 30 items, each with an id and a name, each name ≤ 100
characters. Duplicate names/ids and empty names are not rejected — see
Validation for the full picture.
// 200 Response — echoes exactly what was saved
{
"items": [
{ "id": "dev", "name": "Developers" },
{ "id": "cto", "name": "CTO" }
]
}| Status | Reason |
|---|---|
| 400 | workspace_id missing/empty |
| 400 | audiences isn't a list, has more than 30 items, an item is missing id/name, or a name exceeds 100 characters |
| 403 | Caller is not a member of workspace_id |
Get Languages
GET /api/languages?workspaceId={workspace_id}Same contract as Get Audiences, for the languages list.
// 200 Response — defaults, never-saved workspace
{
"items": [
{ "id": "German", "name": "German" },
{ "id": "SwissGerman", "name": "SwissGerman" },
{ "id": "English", "name": "English" },
{ "id": "French", "name": "French" },
{ "id": "Italian", "name": "Italian" },
{ "id": "Spanish", "name": "Spanish" }
]
}| Status | Reason |
|---|---|
| 400 | workspaceId query parameter missing/empty |
| 403 | Caller is not a member of workspaceId |
Update Languages
PUT /api/languagesSame contract as Update Audiences, for the languages list — full overwrite, same validation rules.
// Request
{
"workspace_id": "ws_123",
"languages": [
{ "id": "en", "name": "English" },
{ "id": "de", "name": "German" }
]
}// 200 Response — echoes exactly what was saved
{
"items": [
{ "id": "en", "name": "English" },
{ "id": "de", "name": "German" }
]
}| Status | Reason |
|---|---|
| 400 | workspace_id missing/empty |
| 400 | languages isn't a list, has more than 30 items, an item is missing id/name, or a name exceeds 100 characters |
| 403 | Caller is not a member of workspace_id |
See also
- Audiences & Languages feature guide — storage shape, authorization rationale, and the Settings page editor UI.
- Prompts API —
default_audience/default_languageon a saved prompt (free text, not validated against these lists). - GenAI API — where a generate-post request's
audience/languagereach the prompt template.