---
audience: developer
summary: Inspect, preview, and override prompt assembly.
title: Prompt Studio API
path: reference/api/prompt-studio
status: published
---

# Prompt Studio API

6 endpoints. Gated by tenant `features.prompt_studio.enabled=true`
and role allowlist.

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/v1/prompt-studio/access` | Whether the caller can use Studio. |
| `GET` | `/v1/rooms/{room_id}/prompt-studio/overrides` | Read live overrides for this room. |
| `POST` | `/v1/rooms/{room_id}/prompt-studio/preview` | Render the prompt with given overrides (no API call). |
| `POST` | `/v1/rooms/{room_id}/prompt-studio/run` | Sandbox-run with overrides; returns model output. |
| `POST` | `/v1/rooms/{room_id}/prompt-studio/apply` | Persist overrides for this room. |
| `POST` | `/v1/rooms/{room_id}/prompt-studio/clear` | Clear all overrides. |

## POST /preview

```json
{
  "participant_id": "ai-…",
  "system_prompt_override": "You are concise.",
  "temperature": 0.4,
  "top_p": 0.9,
  "max_tokens": 800,
  "frequency_penalty": 0.0,
  "presence_penalty": 0.0,
  "reasoning_effort": null,
  "response_mode": "conversational",
  "plugins_enabled": ["scaiwave.notes", "scaiwave.web_search"],
  "trigger_text": "Imagine the user just typed this."
}
```

Returns the rendered prompt as an ordered list of blocks:

```json
{
  "data": {
    "messages": [
      {
        "role": "system",
        "source": "system:participant",
        "priority": 100,
        "content": "..."
      },
      {
        "role": "system",
        "source": "plugin:scaiwave.notes",
        "priority": 80,
        "content": "You can call find_note, ..."
      },
      …
      {
        "role": "user",
        "source": "trigger",
        "priority": 0,
        "content": "Imagine the user just typed this."
      }
    ],
    "estimated_tokens": 2341,
    "budget": 8192,
    "would_be_trimmed": []
  }
}
```

## POST /run

Same request body. Executes one real model call with the overrides.
Returns the model's response inline. **Does not** persist anything
to the room.

## POST /apply

```json
{
  "participant_id": "ai-…",
  "system_prompt_override": "...",
  "temperature": 0.4,
  …
}
```

Persists the overrides in Redis under
`sw:{tenant_id}:ai_override:{room_id}:{participant_id}` with no TTL.
Apply with `system_prompt_override=null` to clear that one key
without clearing others.

## POST /clear

Removes every Studio override for the room+participant.

## Errors

- `SW_STUDIO_DISABLED` — tenant flag off.
- `SW_STUDIO_FORBIDDEN` — caller isn't in the allowlist.
- `SW_STUDIO_NO_PARTICIPANT` — no AI participant resolved (zero AIs in the room).
