Bolta Review Queue
Triage and clear what's waiting for a human decision. Prefer list-inbox-items —
the unified inbox that returns everything pending review in one call (each item is
labeled with its source: team, recurring, hunter, or report). Hunter rows
carry the mention/lead context they respond to and are fully actionable here —
edit the draft (update-hunter-reply) and send it (send-hunter-reply). Report rows
carry the agent report and its download link. Pass agent_id to scope the inbox to
one agent's output. The two per-queue tools remain available when you need one queue
in isolation: the standard review queue (list-reviews) and the agent-produced
recurring queue (list-recurring-reviews). Show what's waiting and act — approving,
rejecting, or sending each item, with rejection reasons that feed Bolta's voice
learning.
When to use
Any time the user wants to see, triage, or clear pending approvals — or to push their own
drafts into review for someone else to approve. If the user wants to trigger a run first
and then review what it produced, kick the routine off with run-routine-now and come back
here — this skill works the queue as it stands.
Tools this skill uses
| Tool |
Why |
list-workspaces |
Resolve workspace_id if unknown. |
list-inbox-items |
Preferred: unified inbox of everything pending (team + recurring + hunter + report), filterable by source/status, scopable to one agent via agent_id. |
list-reviews |
Review queue — defaults to BOTH workflows (team + recurring). Pass workflow_type="team" for the standard queue in isolation. |
list-recurring-reviews |
Automation-produced pending drafts (the routine → human queue); scope to one producer via agent_creator_id (the id is echoed on inbox rows). |
get-post |
Optional — pull full detail for a queued item before deciding. |
approve-post |
Approve a standard-queue post (optionally schedule at approval). Echo the row's content_fingerprint as expected_fingerprint. |
approve-recurring-review |
Approve an agent draft (optionally schedule at suggested time). |
reject-recurring-review |
Reject an agent draft with a reason (feeds voice learning). |
update-hunter-reply |
Edit a hunter reply draft without sending it (already-sent replies 409). |
send-hunter-reply |
Approve + send a hunter reply; optional content overrides the draft in the same call. Double-send prevented server-side. |
submit-for-review |
Push the user's own drafts into the review queue. |
Prerequisites
workspace_id — resolve once via list-workspaces, reuse for every call. Auth is automatic
via the Bolta connector's OAuth grant — never ask for an API key. Default new content to
Draft; confirm before publish/delete.
- Approving/rejecting requires an owner/admin/creator role (viewers are read-only;
workspace roles are owner/admin/creator/viewer). If a call returns a permission error,
run
get-my-capabilities and explain the missing role plainly rather than retrying.
Workflow
1. Resolve the workspace
Call list-workspaces and use the active workspace's id. Never guess a UUID.
2. Pull the inbox
Prefer one call: list-inbox-items(workspace_id) — the unified inbox. Each item carries a
source (team, recurring, hunter, report); filter with source/status when asked
for one slice, and pass agent_id when the user asks about ONE agent's output ("what did
Hunter produce that needs me?"). Fall back to the per-queue tools only when you need
queue-specific filters:
list-reviews(workspace_id, workflow_type="team") — standard queue (reviewer_id filter
also available). Without workflow_type, list-reviews returns BOTH workflows (team +
recurring), so calling it bare alongside list-recurring-reviews double-counts the agent
drafts. Always pass workflow_type="team" when segmenting the two queues.
list-recurring-reviews(workspace_id) — agent drafts (status, template_id filters;
pass agent_creator_id — the producer id echoed on the inbox row — to triage one
producer's drafts).
Present a single combined summary: how many from each source, and a one-line preview per item
(content snippet, target account/platform, for agent items the suggested schedule time, and
for hunter items the mention/lead being replied to). For report items, surface the report
summary and its download link — reports are read-and-download, not approve/reject. Make clear
which source each item belongs to, since they're actioned through different tools.
Two extra fields on team rows matter:
workflow_run_id — items sharing one came from the same run; group them as a batch
("3 drafts from your launch routine"). For the run's overall status, use
list-routine-runs on the routine that produced them.
- Status
autonomous — the post was scheduled by the autonomy policy, not approved by
a human. Never describe an autonomous row as human-approved; say it was auto-scheduled
under the workspace's autonomy settings.
3. Inspect (optional)
For any item the user wants to see in full before deciding, call get-post(post_id) for the
complete content, media, and target accounts. Do this when a snippet isn't enough to judge.
4. Act on each item
- Standard-queue item →
approve-post(workspace_id, post_id). Always pass the item's
content_fingerprint (from the inbox/workflow-run read) as expected_fingerprint — it
guarantees you approve exactly the revision the user just saw, not whatever the post
contains now. Optionally pass schedule_mode / fixed_time to schedule it on approval,
and comments for approver notes.
- Agent (recurring) item, approve →
approve-recurring-review(review_id). Pass
approveWithSchedule + useSuggestedTime to schedule at the agent's suggested time, and
approvalComments for notes.
- Agent (recurring) item, reject →
reject-recurring-review(review_id, rejectionReason, rejectionCategories). ALWAYS also pass rejectionCategories when the objection fits a code — structured categories train the voice far better than free text. Valid codes: too_casual, too_formal, wrong_tone, off_brand, too_long, too_short, wrong_format, factual_error, spelling_grammar, missing_cta, wrong_cta, wrong_emoji, wrong_hashtag, not_engaging, platform_mismatch, too_salesy, off_topic, repetitive, other (anything else is silently dropped).
Always include a concrete reason — rejections and edits are what teach Bolta the brand's
voice, so a specific reason ("too hypey", "wrong CTA") improves future drafts more than a
bare reject.
- Hunter reply draft (source=
hunter; reply_id from the inbox row) → show the draft
alongside the mention/lead it responds to, then:
- Send as-is →
send-hunter-reply(workspace_id, reply_id).
- Send with a tweak →
send-hunter-reply(workspace_id, reply_id, content=<revised text>) —
one call edits and sends.
- Edit but hold →
update-hunter-reply(workspace_id, reply_id, content) (only unsent drafts;
already-sent replies 409). Confirm the final text with the user before sending — replies go
out publicly on the platform. Double-send is prevented server-side, so a retry is safe.
- Report item (source=
report) → nothing to approve; present the summary and download link.
Approving finalizes content toward publishing. Confirm the batch with the user before mass
approvals, and never publish outside these approve paths without an explicit ask.
5. Push drafts into review (when asked)
If the user wants their own drafts routed for someone else to approve, call
submit-for-review(workspace_id, post_ids, note) with the draft ids and an optional note.
This lands them in the standard queue.
6. Report
Summarize what was approved, scheduled, rejected (with reasons), and what remains in each
queue. Note that rejection reasons feed the voice-learning loop.
Failure handling
approve-post returns 409 stale_review → the post changed (content, media,
destination, or scheduled time) after the user last saw it. NEVER blindly retry — the
409 deliberately carries no fingerprint, so a blind retry cannot succeed. Recovery flow:
re-read the item (list-inbox-items or get-post), SHOW the user the current content,
get a fresh explicit decision, then approve
again passing the fresh content_fingerprint as expected_fingerprint. (Alternative:
submit-for-review re-stamps the reviewed revision.)
- Empty queues → say both are clear; offer to push drafts in via
submit-for-review.
- Permission error on approve/reject → run
get-my-capabilities, report the missing role,
do not retry.
- Wrong tool for the queue (e.g.
approve-post on an agent item) errors — route standard
items through approve-post and agent items through the *-recurring-review tools.
update-hunter-reply returns 409 → the reply was already sent; report that and re-pull the
inbox rather than retrying.
get-post not found → the item may have been actioned elsewhere; re-pull the queues.
Example
User: "What needs my review?"
list-workspaces → workspace_id.
list-inbox-items(workspace_id) → 2 team posts + 3 agent drafts (Hype Man, each with a
suggested time), each labeled by source.
- Present: "5 waiting — 2 in your review queue, 3 agent drafts. Approve all, or review each?"
- User: "Approve the agent ones at their suggested times, reject the standard LinkedIn one —
too salesy." →
approve-recurring-review(review_id, approveWithSchedule=true, useSuggestedTime=true) ×3.
approve-post(workspace_id, post_id) for the good standard post; for the LinkedIn one,
it's an agent draft? No — standard, so it can only be approved or left. Confirm the user
wants it rejected; agent-style rejection with a reason isn't available for standard posts,
so leave it pending and note that.
- Report: 3 agent drafts approved + scheduled, 1 standard approved, 1 held. Rejection reasons
captured feed voice learning.
1---2name: bolta-review-queue3description: Work the Bolta review and approval queues. Use this skill when the user asks "what needs my review", "show the approval queue", "approve pending posts", "review my content", "what's waiting for approval", "clear my review queue", "anything to approve", "approve the agent drafts", "any replies to send", "send that reply", or wants to triage, approve, reject, edit-and-send, or push content into review. Handles ALL inbox sources: the standard review queue, the agent-produced recurring queue, hunter reply drafts (edit + send), and agent reports. This skill is the standing inbox — triage whatever is already waiting. To trigger a run and then review its output in one loop, run the routine first with bolta-setup's routine flow. Not for writing new content (use bolta-draft-post) or reading analytics (use bolta-analytics-report).4---56# Bolta Review Queue78Triage and clear what's waiting for a human decision. **Prefer `list-inbox-items`** —9the unified inbox that returns everything pending review in one call (each item is10labeled with its `source`: `team`, `recurring`, `hunter`, or `report`). Hunter rows11carry the mention/lead context they respond to and are fully actionable here —12edit the draft (`update-hunter-reply`) and send it (`send-hunter-reply`). Report rows13carry the agent report and its download link. Pass `agent_id` to scope the inbox to14one agent's output. The two per-queue tools remain available when you need one queue15in isolation: the **standard review queue** (`list-reviews`) and the **agent-produced16recurring queue** (`list-recurring-reviews`). Show what's waiting and act — approving,17rejecting, or sending each item, with rejection reasons that feed Bolta's voice18learning.1920## When to use21Any time the user wants to see, triage, or clear pending approvals — or to push their own22drafts into review for someone else to approve. If the user wants to *trigger a run first*23and then review what it produced, kick the routine off with `run-routine-now` and come back24here — this skill works the queue as it stands.2526## Tools this skill uses27| Tool | Why |28|-|-|29| `list-workspaces` | Resolve `workspace_id` if unknown. |30| `list-inbox-items` | **Preferred**: unified inbox of everything pending (team + recurring + hunter + report), filterable by `source`/`status`, scopable to one agent via `agent_id`. |31| `list-reviews` | Review queue — **defaults to BOTH workflows** (team + recurring). Pass `workflow_type="team"` for the standard queue in isolation. |32| `list-recurring-reviews` | Automation-produced pending drafts (the routine → human queue); scope to one producer via `agent_creator_id` (the id is echoed on inbox rows). |33| `get-post` | Optional — pull full detail for a queued item before deciding. |34| `approve-post` | Approve a standard-queue post (optionally schedule at approval). Echo the row's `content_fingerprint` as `expected_fingerprint`. |35| `approve-recurring-review` | Approve an agent draft (optionally schedule at suggested time). |36| `reject-recurring-review` | Reject an agent draft with a reason (feeds voice learning). |37| `update-hunter-reply` | Edit a hunter reply draft without sending it (already-sent replies 409). |38| `send-hunter-reply` | Approve + send a hunter reply; optional `content` overrides the draft in the same call. Double-send prevented server-side. |39| `submit-for-review` | Push the user's own drafts into the review queue. |4041## Prerequisites42- `workspace_id` — resolve once via `list-workspaces`, reuse for every call. Auth is automatic43 via the Bolta connector's OAuth grant — never ask for an API key. Default new content to44 Draft; confirm before publish/delete.45- Approving/rejecting requires an **owner/admin/creator** role (viewers are read-only;46 workspace roles are owner/admin/creator/viewer). If a call returns a permission error,47 run `get-my-capabilities` and explain the missing role plainly rather than retrying.4849## Workflow5051### 1. Resolve the workspace52Call `list-workspaces` and use the active workspace's `id`. Never guess a UUID.5354### 2. Pull the inbox55Prefer one call: `list-inbox-items(workspace_id)` — the unified inbox. Each item carries a56`source` (`team`, `recurring`, `hunter`, `report`); filter with `source`/`status` when asked57for one slice, and pass `agent_id` when the user asks about ONE agent's output ("what did58Hunter produce that needs me?"). Fall back to the per-queue tools only when you need59queue-specific filters:60- `list-reviews(workspace_id, workflow_type="team")` — standard queue (`reviewer_id` filter61 also available). **Without `workflow_type`, list-reviews returns BOTH workflows** (team +62 recurring), so calling it bare alongside `list-recurring-reviews` double-counts the agent63 drafts. Always pass `workflow_type="team"` when segmenting the two queues.64- `list-recurring-reviews(workspace_id)` — agent drafts (`status`, `template_id` filters;65 pass `agent_creator_id` — the producer id echoed on the inbox row — to triage one66 producer's drafts).67Present a single combined summary: how many from each source, and a one-line preview per item68(content snippet, target account/platform, for agent items the suggested schedule time, and69for hunter items the mention/lead being replied to). For `report` items, surface the report70summary and its download link — reports are read-and-download, not approve/reject. Make clear71which source each item belongs to, since they're actioned through different tools.72Two extra fields on team rows matter:73- **`workflow_run_id`** — items sharing one came from the same run; group them as a batch74 ("3 drafts from your launch routine"). For the run's overall status, use75 `list-routine-runs` on the routine that produced them.76- **Status `autonomous`** — the post was **scheduled by the autonomy policy, not approved by77 a human**. Never describe an autonomous row as human-approved; say it was auto-scheduled78 under the workspace's autonomy settings.7980### 3. Inspect (optional)81For any item the user wants to see in full before deciding, call `get-post(post_id)` for the82complete content, media, and target accounts. Do this when a snippet isn't enough to judge.8384### 4. Act on each item85- **Standard-queue item** → `approve-post(workspace_id, post_id)`. **Always pass the item's86 `content_fingerprint` (from the inbox/workflow-run read) as `expected_fingerprint`** — it87 guarantees you approve exactly the revision the user just saw, not whatever the post88 contains now. Optionally pass `schedule_mode` / `fixed_time` to schedule it on approval,89 and `comments` for approver notes.90- **Agent (recurring) item, approve** → `approve-recurring-review(review_id)`. Pass91 `approveWithSchedule` + `useSuggestedTime` to schedule at the agent's suggested time, and92 `approvalComments` for notes.93- **Agent (recurring) item, reject** → `reject-recurring-review(review_id, rejectionReason, rejectionCategories)`. ALWAYS also pass `rejectionCategories` when the objection fits a code — structured categories train the voice far better than free text. Valid codes: too_casual, too_formal, wrong_tone, off_brand, too_long, too_short, wrong_format, factual_error, spelling_grammar, missing_cta, wrong_cta, wrong_emoji, wrong_hashtag, not_engaging, platform_mismatch, too_salesy, off_topic, repetitive, other (anything else is silently dropped).94 Always include a concrete reason — rejections and edits are what teach Bolta the brand's95 voice, so a specific reason ("too hypey", "wrong CTA") improves future drafts more than a96 bare reject.97- **Hunter reply draft** (source=`hunter`; `reply_id` from the inbox row) → show the draft98 alongside the mention/lead it responds to, then:99 - Send as-is → `send-hunter-reply(workspace_id, reply_id)`.100 - Send with a tweak → `send-hunter-reply(workspace_id, reply_id, content=<revised text>)` —101 one call edits and sends.102 - Edit but hold → `update-hunter-reply(workspace_id, reply_id, content)` (only unsent drafts;103 already-sent replies 409). Confirm the final text with the user before sending — replies go104 out publicly on the platform. Double-send is prevented server-side, so a retry is safe.105- **Report item** (source=`report`) → nothing to approve; present the summary and download link.106107Approving finalizes content toward publishing. Confirm the batch with the user before mass108approvals, and never publish outside these approve paths without an explicit ask.109110### 5. Push drafts into review (when asked)111If the user wants their own drafts routed for someone else to approve, call112`submit-for-review(workspace_id, post_ids, note)` with the draft ids and an optional note.113This lands them in the standard queue.114115### 6. Report116Summarize what was approved, scheduled, rejected (with reasons), and what remains in each117queue. Note that rejection reasons feed the voice-learning loop.118119## Failure handling120- `approve-post` returns **409 `stale_review`** → the post changed (content, media,121 destination, or scheduled time) after the user last saw it. **NEVER blindly retry** — the122 409 deliberately carries no fingerprint, so a blind retry cannot succeed. Recovery flow:123 re-read the item (`list-inbox-items` or `get-post`), SHOW the user the current content,124 get a fresh explicit decision, then approve125 again passing the fresh `content_fingerprint` as `expected_fingerprint`. (Alternative:126 `submit-for-review` re-stamps the reviewed revision.)127- Empty queues → say both are clear; offer to push drafts in via `submit-for-review`.128- Permission error on approve/reject → run `get-my-capabilities`, report the missing role,129 do not retry.130- Wrong tool for the queue (e.g. `approve-post` on an agent item) errors — route standard131 items through `approve-post` and agent items through the `*-recurring-review` tools.132- `update-hunter-reply` returns 409 → the reply was already sent; report that and re-pull the133 inbox rather than retrying.134- `get-post` not found → the item may have been actioned elsewhere; re-pull the queues.135136## Example137User: "What needs my review?"1381. `list-workspaces` → workspace_id.1392. `list-inbox-items(workspace_id)` → 2 team posts + 3 agent drafts (Hype Man, each with a140 suggested time), each labeled by `source`.1413. Present: "5 waiting — 2 in your review queue, 3 agent drafts. Approve all, or review each?"1424. User: "Approve the agent ones at their suggested times, reject the standard LinkedIn one —143 too salesy." →144 - `approve-recurring-review(review_id, approveWithSchedule=true, useSuggestedTime=true)` ×3.145 - `approve-post(workspace_id, post_id)` for the good standard post; for the LinkedIn one,146 it's an agent draft? No — standard, so it can only be approved or left. Confirm the user147 wants it rejected; agent-style rejection with a reason isn't available for standard posts,148 so leave it pending and note that.1495. Report: 3 agent drafts approved + scheduled, 1 standard approved, 1 held. Rejection reasons150 captured feed voice learning.