Get Outreach Review
Default tool for outreach queue triage — pending messages with full context for review.
Start here when reviewing or managing the outreach queue. Returns pending messages — both 'needs_draft' (unauthored, awaiting harness authoring: write via manage_messages edit) and 'draft' (authored, awaiting approve/reject), disambiguated by each item's status — enriched with: person context, objective instructions (tone rules, selling strategy, touch sequence), match analysis (summary, alignment points, recommended approach), company research summary, recent LinkedIn posts, conversation thread, and outreach plan state. One call gives you everything needed to author, approve, or reject.
channel_holds reports LinkedIn sender blocks such as daily quota, provider throttling, or reconnect-required state. If channel_holds_degraded is true, an empty hold list is unknown rather than proof that the channel is healthy.
Use content_length='full' for detailed review (capped at 5 items to prevent connection drops from oversized payloads — use offset to paginate), or 'preview' (default) for quick scanning with truncated content.
Filter by objective name or ID to review a specific queue (e.g. objective='DFW CFOs').
Use message_ids to fetch specific messages by ID (comma-separated UUIDs, max 20). Bypasses sorting/pagination — returns full context for exactly those messages. Useful for subagent dispatch: pull the lightweight queue first, split into batches, then each subagent calls with its assigned message_ids.
Operators: pass for_company parameter to review a specific client company.
Returns (units in parentheses; scope = messages.status IN ('draft','needs_draft') for this tenant unless message_ids is set): items (list of ReviewItem, unit=messages): one entry per pending message (not per person — a person with two pending messages shows up twice). Each item: - message_id, status ('needs_draft' = author it, 'draft' = approve it), channel, subject, content, category (initial / followup / reply_response), priority_score, created_at - expires_at (needs_draft only): when the nightly sweep auto-rejects this row if still unauthored (the action's expires_at — regenerate grants a fresh window). Author nearest-deadline-first. An expired touch shows up later as status='rejected' with blank content and ai_decision_context.expired_signal — that is GC, NOT an operator rejection; revive via manage_messages action=regenerate, then author and edit as normal. - person_id, person_name, person_title, person_company, match_score, stage (the company_people stage) - campaign_name, campaign_tone_instructions, campaign_selling_strategy, campaign_touch_sequence (per-touch instructions): VRU-878 — sourced from the message's PLAN OBJECTIVE (name / policy_envelope.tone_rules / sequence pin), not a campaign row. Field names are fixed by the shared ReviewItem schema (app/shared/schemas/mcp_compound.py, out of scope here). - match_summary, alignment_points, recommended_approach - company_summary (recent company research), recent_linkedin_posts (last 3 posts; unit=posts) - manual_notes (full content only): up to 10 newest-first person timeline notes. Each note is capped at 4,000 characters, each person at 8,000, and all repeated item payloads at 30,000 total. A cut note ends with ...[truncated]. When objective instructions name a saved per-person draft, use it instead of the 200-character activity summary. - conversation_thread (list of outbound+inbound rows, unit=messages, ordered by created_at; truncated to 200 chars when content_length='preview') - prior_reply (cold touches only: category initial/followup): the person's newest human reply {message_id, received_at, channel, intent, excerpt}. The prospect already wrote back, so the draft is a re-pitch: read the reply, and hold the draft for the operator unless they chose to continue the sequence. None when the person never replied. - outreach_plan_id (the linked plan's id — pass straight to manage_outreach pause/resume/stop; no get_person_360 needed), plan_status, plan_strategy, touches_completed, max_touches, plan_next_action_at (when the plan's next touch fires — an approved-but-deferred send happens at this time), connection_status (the plan's LinkedIn connection state) (from the linked outreach_plan; unit=plans) - PRIORITIZE WARM ITEMS: a linkedin_message item with connection_status='connected' is a follow-up to someone who ACCEPTED the connection request — author/approve these before any cold lane; they are the highest-EV rows in the queue. total_pending (int, unit=messages): EXACT count of actionable pending messages matching the objective / message_ids filter for the tenant, BEFORE pagination. Filters: status IN ('draft','needs_draft'), excludes externally scheduled/reservation-protected rows, user_company_id, and the objective filter when set. Without message_ids, a cold touch (initial/followup) is listed only while approving it can send it: its plan is active and still runs the touch's objective, that objective is active, and its person is not archived. A hidden draft keeps its state and returns when its plan or objective resumes; replies and retained emails are not narrowed. Does NOT date-filter — the queue is "everything currently pending." offset (int): echoes the request offset. limit (int, unit=messages): echoes the page size. When content_length='full' this is capped at 5 (regardless of the requested limit). approved_pending_send_count (int, unit=messages): approved rows that have NOT sent yet (they no longer show as items). Non-zero after a bulk approve means those sends are SCHEDULED (per-person cooldown / designed sequence timing) — they are not lost, not sent, and must not be re-drafted or manually re-sent. externally_scheduled_count (int, unit=messages): Gmail/provider-scheduled rows protected by an external-send reservation. They are excluded from actionable items and must not be approved or re-drafted.
Request
- Base URL: https://api.vruum.ai
- URL: https://api.vruum.ai/api/outreach/review
- Auth: HTTPBearer (a scheme the document does not define)
Query parameters
Max messages to review (up to 200)
Pagination offset
'full' for untruncated conversation content, 'preview' (default) for 200-char truncation. When 'full', limit is auto-capped at 5 to prevent oversized responses — use offset to paginate.
Filter by objective name or ID. Example: 'DFW CFOs' or a UUID. Returns only drafts for people on that objective.
Comma-separated message UUIDs to fetch specific messages. Bypasses sorting/pagination — returns full context for exactly these messages. Example: 'uuid1,uuid2,uuid3'. Max 20.
Response
Successful Response
Changes
No recorded changes to this operation across all 1 revision of this API.