# Workspace and rules (/docs/workspace)



A subscription owns one tenant-isolated research workspace. Its tenant identity and history stay
stable, while the research brief, subject seeds, competitors, display name, and rules are editable.
The workspace is derived from the bearer key; customer operations never accept an `accountId` or
another tenant's `workspaceId`.

## Set the workspace [#set-the-workspace]

Create the research brief once. Include the user's niche description and any exact App Store URL,
website, named competitors, or display name that they supplied:

```bash
curl -X POST https://api.viralquery.com/v1/workspace \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"description":"Calorie tracking apps and the organic videos that make them spread","appStoreUrl":"https://apps.apple.com/app/id6480417616","competitors":["MyFitnessPal","Lose It!"],"name":"Cal AI"}'
```

Repeating the same brief is idempotent. Use `PUT /v1/workspace` to update the fields of an existing
brief. The legacy `url` field remains accepted for compatibility, but new callers should use the
brief fields above.

Read the calling key's workspace with `GET /v1/workspace`.

## Change the subject URL [#change-the-subject-url]

To point an existing workspace at a different app or website, send the new `website` or `appStoreUrl`
with `PUT /v1/workspace`:

```bash
curl -X PUT https://api.viralquery.com/v1/workspace \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"website":"https://newsubject.example"}'
```

The change is atomic and does not clear your library. Videos gathered for the previous subject stay
until you archive them, so you decide what carries over (see
[Personalized results](/docs/library#curate-the-library)). Re-posting a different subject to
`POST /v1/workspace` returns `409 workspace_already_set` on purpose; use `PUT` to change the subject.

To clear the old subject's library in the same request, add `"archivePriorSubject": true`. It
soft-hides every currently-active library video (reversible) only when the subject actually changes,
and reports how many it hid:

```bash
curl -X PUT https://api.viralquery.com/v1/workspace \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"website":"https://newsubject.example","archivePriorSubject":true}'
# → { "workspace": { ... }, "archivedVideos": 181 }
```

## Research rules [#research-rules]

Rules are plain text that the internal research agent interprets when a scroll begins. Manage them
whichever way fits: replace the whole set at once, or curate individual rules.

Replace the entire ruleset with `PUT /v1/rules`:

```bash
curl -X PUT https://api.viralquery.com/v1/rules \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Watch calorie tracking, food scanner, and competitor videos. Ignore bodybuilding and restaurant reviews."}'
```

Or curate rules one at a time, so you can add and retire them without rewriting the rest:

```bash
# Append one rule
curl -X POST https://api.viralquery.com/v1/rules/items \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"text":"Ignore restaurant reviews."}'

# Archive (or restore) one rule by id
curl -X POST https://api.viralquery.com/v1/rules/items/archive \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"ruleId":"<id>","archived":true}'
```

`GET /v1/rules` returns the composed active `rules` text plus the individual `items`, each with its
`id`, `text`, and `archived` flag. The effective ruleset is the active items joined in order.

Each rules change creates an immutable **historical rules snapshot**, so past research runs retain
the exact rules they received even after the active rules are edited. The workspace brief itself is
editable with `PUT /v1/workspace`. Repeating identical rules text does not create a new snapshot.
Archiving a rule hides it from the active ruleset but keeps it restorable.
