search_conversations
<usecase>
Search conversations with filters and get tabular data.
Returns individual conversations matching the given filters, with configurable
fields showing attribute values for each conversation.
IMPORTANT - choose the right tool AND approach based on scale:
- For "how many" questions, use group_conversations — group by the relevant attribute
and read the conversation_count per group, or use a single group to get the total. This avoids
fetching full conversation rows when only a count is needed.
- For breakdowns by attribute (e.g. by department, interviewer), use group_conversations.
- For time-series trends, use get_chart_data.
- Only use search_conversations when you need individual conversation rows.
SCALE-AWARE STRATEGY — pick the right fields based on how many conversations match:
- 1-5 conversations: Use fields=['default:transcript'] to read full transcripts.
You can analyze them in detail within your context window.
- 5-20 conversations: Use fields=['default:summary'] to get AI-generated summaries.
Good middle ground — key points without overwhelming context. Fetch individual
transcripts only for conversations you need to drill into.
- 20+ conversations: Do NOT fetch transcripts or summaries in bulk. Instead use
create_ai_field to extract specific data points per conversation, then
query the AI field here or in group_conversations to aggregate results.
This is the only way to analyze large numbers of conversations effectively.
- When unsure of scale, first run a query with just default fields (no transcripts/summaries)
to see total_count, then decide your approach.
IMPORTANT - transcript token cost: A single 1-hour transcript uses roughly
10,000-15,000 tokens. Be careful not to fetch too many transcripts or else you
may use up all your context. Prefer AI fields over raw transcripts when possible.
Transcript format is one line per monologue:
Speaker Name (Role): What they said...
IMPORTANT - AI fields: AI fields (field IDs starting with 'AI:') require per-conversation
analysis. Results are generated asynchronously and return faster with fewer conversations.
Always apply tight filters (date range, department, interviewer, etc.) BEFORE requesting
AI fields. If too many conversations need analysis, you will be asked to narrow your query.
IMPORTANT - summary generation: When the 'default:summary' field is included,
summaries are generated on the fly for conversations that don't have one yet.
Summary generation is SLOW (each summary analyzes the full transcript) and
produces roughly 2,000 tokens per hour of conversation. A maximum of
100 summaries can be triggered per request. To avoid long
waits, always narrow your query with tight filters (date range,
department, interviewer, etc.) BEFORE requesting summaries.
When both report_id and filters are provided, filters are applied on top
of the report's saved filters.
Each filter object has three keys: field_id (str), operation (str),
and value (format depends on attribute type, see below).
Use list_fields to discover available fields and their operations.
Use list_field_values to find valid values for a specific field.
</usecase>
<instructions>
Args:
report_id: ID of a saved report to use as the base filter set.
filters: Array of filter objects, each with field_id (str),
operation (str), and value (format depends on attribute type,
see "Filter value formats" below).
fields: Field IDs to include. If omitted, uses the report's configured
fields or defaults.
only_show_recorded_conversations: When true (default), only return recorded conversations. Set to false to also include unrecorded conversations (scheduled calls that were not recorded, or upcoming conversations that haven't happened yet).
sort_by: Field ID to sort by (default: default:start_time).
sort_ascending: Sort ascending (default: false — newest first when sorting by date).
offset: Pagination offset (default 0).
limit: Number of conversations per page (default 20, max 50).
Keep low when requesting 'default:transcript' (see transcript token cost above).
conversation_ids: Fetch specific conversations by ID (max 100). When provided,
returns these conversations directly instead of using report/filter-based
querying.
extended_candidate_information: When true, enriches each conversation's
default:candidate field values with a 'person' dict containing the full
candidate profile from the ATS: name, email, phone, LinkedIn URL,
location, summary, experience, education, skills, applications,
scorecards, feedback, and presigned download URLs for attached files
(resumes/CVs). File URLs expire after 2 hours. Use this when you need
candidate background information for summary generation or document
creation. Requires the default:candidate field in the response (added
automatically if not present).
Filter value formats by attribute type:
### DATE (DateAttribute)
Operations: before, after, between
values MUST be a dict with "scope" and "value" keys. Do NOT pass a bare date string.
Absolute (single): {"scope": "absolute", "value": "2024-01-01T00:00:00.000Z"}
Absolute (range, for between): {"scope": "absolute", "value": ["2024-01-01T00:00:00.000Z", "2024-06-01T00:00:00.000Z"]}
Relative (seconds from now; negative = past): {"scope": "relative", "value": -2592000}
Common relative values: -86400 (1 day), -604800 (7 days), -2592000 (30 days), -7776000 (90 days), -15552000 (180 days), -31536000 (1 year).
### STRING (StringAttribute)
Operations: is_one_of, is_none_of, like_one_of, not_like_any_of
values: list of strings. Example: ["Engineering", "Product"]
### PERSON (PersonAttribute)
Operations: is_one_of, is_none_of
values: list of person IDs (integers). Example: [123, 456]
### NUMBER (NumberAttribute)
Operations: is, less_than, greater_than
values: a number. Example: 30.0
### BOOLEAN (BooleanAttribute)
Operations: is
values: true or false.
### CONTENT (ContentAttribute)
Operations: references, does_not_reference, references_one_of, does_not_reference_any_of
values: dict with "scope" and "value" keys.
Scope: "anyone", "internal_participant", or "external_participant".
Value: a string or list of strings.
Example: {"scope": "anyone", "value": ["Python", "TypeScript"]}
### PARTICIPANT_SCOPED_NUMBER (ParticipantScopedNumberAttribute)
Operations: is, less_than, greater_than
values: dict with "scope" and "value" keys.
Scope: "internal" or "external". Value: a number.
Example: {"scope": "external", "value": 50}
### PARTICIPANT (ParticipantAttribute)
Operations: is_one_of, is_none_of
values: list of participant IDs (UUIDs). Example: ["550e8400-e29b-41d4-a716-446655440000"]
### STRING_LIST (StringListAttribute)
Operations: includes_one_of, excludes_all_of
values: list of strings. Example: ["Engineering", "Product"]
### PERSON_LIST (PersonListAttribute)
Operations: includes_one_of, excludes_all_of
values: list of person IDs (integers). Example: [123, 456]
### PARTICIPANT_LIST (ParticipantListAttribute)
Operations: includes_one_of, excludes_all_of
values: list of participant IDs (UUIDs). Example: ["550e8400-e29b-41d4-a716-446655440000"]
### JSON (JsonAttribute)
Operations: is_one_of, is_none_of, like_one_of, not_like_any_of
values: list of strings. Example: ["value1", "value2"]
Common filter examples:
Last 30 days:
[{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -2592000}}]
January 2024:
[{"field_id": "default:start_time", "operation": "between",
"value": {"scope": "absolute",
"value": ["2024-01-01T00:00:00.000Z", "2024-02-01T00:00:00.000Z"]}}]
Engineering department, last 90 days (get the field ID from list_fields):
[{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -7776000}},
{"field_id": "OSPT:<uuid>", "operation": "is_one_of",
"value": ["Engineering"]}]
My conversations (use participant_id from get_user_context):
[{"field_id": "default:contact", "operation": "includes_one_of",
"value": ["<participant_id from get_user_context>"]}]
Specific candidate (use contact UUID from list_field_values):
[{"field_id": "default:candidate", "operation": "includes_one_of",
"value": ["<candidate-contact-uuid>"]}]
Specific interviewer (use contact UUID from list_field_values):
[{"field_id": "default:interviewer", "operation": "includes_one_of",
"value": ["<interviewer-contact-uuid>"]}]
</instructions>
<response_format>
{"field_definitions": [{"field_id": "default:start_time", "name": "Start Time", "type": "date"}],
"conversations": [{"id": 12345,
"url": "https://<app-domain>/notes/12345",
"fields": {"default:start_time": [{"value": "2024-01-15", "label": "Jan 15"}]}}],
"total_count": 142,
"has_more": true,
"ai_processing": {"AI:<uuid>": {"pending_count": 20, "total_count": 100}}}
</response_format>
<notes>
Note: AI field values are processed asynchronously. If "ai_processing" is present in the response, some values are still being computed. Poll by retrying the same call every ~30 seconds until the data is complete.
IMPORTANT: Including AI fields triggers analysis for every matching conversation that hasn't been analyzed yet. Always apply tight filters (date range, department, interviewer, etc.) to keep the set small and get results quickly. Broad unfiltered queries will be slow and may hit evaluation limits that require narrowing your search.
</notes>
<examples>
Engineering conversations in the last 30 days with department and interviewer fields:
First, find the department field ID: list_fields(search_term="department")
Then use the returned OSPT:<uuid> field ID:
search_conversations(
filters=[
{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -2592000}},
{"field_id": "OSPT:<uuid>", "operation": "is_one_of",
"value": ["Engineering"]}],
fields=["default:start_time", "default:calendar_event_title", "OSPT:<uuid>"])
</examples>
search_reports
<usecase>
List saved reports the user has access to, or fetch full details for specific reports.
A report is a saved configuration — a named set of filters, fields,
grouping, and charts that defines a particular way to analyze interview
conversations. Pass a report's ID to search_conversations, group_conversations,
or get_chart_data to reuse its saved filters.
Use report_ids to fetch one or more specific reports by ID.
Set include_detail=true to get the full configuration (filters, fields,
grouping, charts) instead of just the summary.
BEST PRACTICE: Use search_term when looking for a specific report
by name instead of listing all reports and scanning.
</usecase>
<instructions>
Args:
report_ids: List of report IDs to fetch. Returns only these reports.
include_detail: When true, returns full report configuration (filters,
fields, grouping, charts) for each report. Default false (summary only).
search_term: Filter reports by name (case-insensitive). Supports substring
matching and regex patterns (automatically detected).
category: Filter by category. One of: createdByMe, createdByMetaview,
recentlyViewed, favorited.
sort_key: Sort field. One of: updated_at (default), name, created_at.
sort_order: Sort direction. One of: desc (default), asc.
offset: Pagination offset (default 0).
limit: Number of results per page (default 20, max 100).
</instructions>
<response_format>
{"reports": [
{"id": "abc-123", "name": "Engineering Interviews Q1",
"url": "https://<app-domain>/reports/abc-123",
"description": "All engineering interviews in Q1 2024",
"is_default": false,
"created_by": {"name": "Alice Smith"},
"created_at": "2024-01-01 00:00:00+00:00",
"updated_at": "2024-03-15 10:30:00+00:00"}],
"count": 1, "has_more": false}
</response_format>
<examples>
search_reports()
search_reports(search_term="engineering")
search_reports(category="createdByMe", sort_key="updated_at")
search_reports(report_ids=["abc-123"], include_detail=true)
search_reports(report_ids=["abc-123", "def-456"])
</examples>
create_report
<usecase>
Create a new report or update an existing one in the Metaview web-app.
IMPORTANT: Only use this tool when the user explicitly asks to create or edit
a saved report in Metaview. Do NOT use this tool for ad-hoc data analysis, answering
questions, or running queries — use search_conversations, group_conversations,
or get_chart_data for those. This tool persists a report that appears in
the user's Reports list in the web-app.
Before calling this tool, confirm with the user what they want the report to contain
(name, filters, grouping, fields). Do not create reports speculatively.
After creating or updating a report, share the `url` from the response with the user
so they can open it in the web-app.
</usecase>
<instructions>
Creating: Omit report_id. You MUST provide filters (can be an empty list for "all
conversations"). Optionally set name, fields, grouping, and other configuration in the
same call.
Updating: Provide report_id of an existing report. Only the fields you include will
be changed — omitted fields are left unchanged.
Use list_fields to find valid field IDs for filters, fields,
and grouping. Use list_field_values to find valid filter values.
Args:
report_id: ID of an existing report to update. Omit to create a new report.
filters: Array of filter objects (required for create, optional for update).
See search_conversations for the complete filter format reference. IMPORTANT: Date filter values must use a dict with scope and value, not a bare date string. Example: {"field_id": "default:start_time", "operation": "after", "value": {"scope": "relative", "value": -2592000}}
name: Human-readable report name (e.g., "Engineering Interviews Q1").
description: Report description.
group: Field ID to group conversations by (e.g., "OSPT:<uuid>").
Use list_fields to find field IDs.
remove_grouping: Set to true to remove grouping from a report. Required because
passing group=null is indistinguishable from omitting the parameter.
field_ids: List of field IDs to show as columns
(e.g., ["default:start_time", "OSPT:<uuid>"]).
sort_field: Field ID to sort by. Must be one of the field_ids.
sort_ascending: Sort ascending (true) or descending (false). Default true.
metrics: Metrics for grouped reports. Array of objects, each with:
metric_id (str), function (str: mean/median/max/min/sum),
footer_aggregation_function (str), metric_arguments (dict).
sort_metric: Which metric to sort groups by. Object with:
metric_id (str), function (str),
metric_arguments (dict). Pass null to sort by the group label.
sort_metric_ascending: Sort groups ascending or descending. Default true.
only_show_recorded_conversations: Include only recorded conversations. Default true.
expand_rows: Expand table rows. Default false.
min_group_conversation_count: Hide groups with fewer conversations than this.
</instructions>
<examples>
Common filter examples:
Last 30 days:
[{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -2592000}}]
January 2024:
[{"field_id": "default:start_time", "operation": "between",
"value": {"scope": "absolute",
"value": ["2024-01-01T00:00:00.000Z", "2024-02-01T00:00:00.000Z"]}}]
Engineering department, last 90 days (get the field ID from list_fields):
[{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -7776000}},
{"field_id": "OSPT:<uuid>", "operation": "is_one_of",
"value": ["Engineering"]}]
My conversations (use participant_id from get_user_context):
[{"field_id": "default:contact", "operation": "includes_one_of",
"value": ["<participant_id from get_user_context>"]}]
Specific candidate (use contact UUID from list_field_values):
[{"field_id": "default:candidate", "operation": "includes_one_of",
"value": ["<candidate-contact-uuid>"]}]
Specific interviewer (use contact UUID from list_field_values):
[{"field_id": "default:interviewer", "operation": "includes_one_of",
"value": ["<interviewer-contact-uuid>"]}]
Example — create a report:
create_report(
name="Engineering Last 30 Days",
filters=[{"field_id": "default:start_time", "operation": "after",
"value": {"scope": "relative", "value": -2592000}},
{"field_id": "OSPT:<uuid>", "operation": "is_one_of",
"value": ["Engineering"]}],
field_ids=["default:start_time", "default:interviewer",
"default:candidate"],
sort_field="default:start_time",
sort_ascending=false
)
Example — rename a report:
create_report(report_id="abc-123", name="New Report Name")
</examples>
get_enrichment_status
<usecase>
Get the workspace's enrichment credit status, usage breakdown, and optionally
list individual enrichment attempts.
Always returns:
- Monthly credit allowance and remaining balance
- Usage breakdown by enrichment type (email vs phone) for the requested month
- Active top-up credit purchases with remaining balances and expiry dates
Optionally returns:
- Per-user usage breakdown (include_usage_by_user=true)
- Individual enrichment attempts (include_enrichment_attempts=true)
</usecase>
<instructions>
Args:
person_id: Filter usage and attempts to a specific person (admin only).
Non-admins always see only their own data regardless of this parameter.
month: Month to report on as YYYY-MM (e.g. "2026-01"). When provided,
usage is scoped to that calendar month. When omitted, usage covers
the current month to date (no end boundary).
include_usage_by_user: When true, include per-user usage breakdown.
Default false.
include_enrichment_attempts: When true, append the list of individual enrichment
attempts. Default false.
enrichment_type: Filter attempts by type: "email" or "phone".
Only used when include_enrichment_attempts=true.
offset: Pagination offset for attempts (default 0).
limit: Number of attempts per page (default 50, max 100).
</instructions>
<response_format>
{"credits": {
"monthly_limit": 500,
"monthly_used": 450,
"monthly_remaining": 50,
"top_up_credits_available": 200,
"total_available": 250,
"warning_threshold_reached": false},
"usage": {
"email": {"enrichments_count": 50, "credits_used": 150},
"phone": {"enrichments_count": 30, "credits_used": 300},
"total_credits_used": 450},
"usage_by_user": [{...}],
"top_ups": [{...}],
"enrichment_attempts": [{...}],
"enrichment_attempts_total_count": 150,
"enrichment_attempts_has_more": true}
</response_format>
<notes>
credits reflects the current live balance regardless of the month parameter.
usage is scoped to the requested month.
All workspaces receive a base allowance of 500 credits per month.
usage_by_user is only present when include_usage_by_user=true.
enrichment_attempts fields are only present when include_enrichment_attempts=true.
</notes>
<examples>
Check credit status and usage:
get_enrichment_status()
Usage for January 2026:
get_enrichment_status(month="2026-01")
Per-user breakdown:
get_enrichment_status(include_usage_by_user=true)
Include individual enrichment attempts:
get_enrichment_status(include_enrichment_attempts=true)
</examples>
find_candidate_in_sequences
<usecase>
Check if a candidate is enrolled in any sequences.
Look up a candidate by ID, LinkedIn URL, email address, or phone number and
return all sequences they are (or were) enrolled in, including sequences created
by other users. Useful before adding someone to a new sequence to avoid duplicate
outreach.
Provide at least one lookup parameter. If candidate_id is given, it is used
directly. Otherwise, linkedin_url/email/phone_number are matched with OR logic.
</usecase>
<instructions>
Args:
candidate_id: Candidate ID for direct lookup (preferred when known).
linkedin_url: LinkedIn profile URL (normalized automatically).
email: Email address to match against candidate primary email or
the to_email used in the sequence.
phone_number: Phone number to match against candidate primary phone.
</instructions>
<response_format>
{"candidates": [
{"candidate_id": "...", "candidate_name": "John Doe",
"candidate_email": "
[email protected]", "candidate_phone": "+1234567890",
"candidate_linkedin_url": "https://www.linkedin.com/in/johndoe",
"sequences": [
{"sequence_id": "...", "sequence_name": "Outreach v2",
"status": "active",
"created_at": "2024-01-10T...",
"steps_sent": 2, "steps_total": 4}]}]}
</response_format>
<examples>
Check by LinkedIn:
find_candidate_in_sequences(linkedin_url="https://linkedin.com/in/johndoe")
Check by email:
find_candidate_in_sequences(email="
[email protected]")
Check by multiple identifiers:
find_candidate_in_sequences(linkedin_url="...", email="
[email protected]")
</examples>
manage_candidate_sequence
<usecase>
Add candidates to a sequence, or pause, resume, cancel, remove, or update a candidate's enrollment.
Dispatches based on the action parameter. Only the sequence creator can perform these actions.
IMPORTANT: Always confirm with the user before calling this tool. Describe the exact changes you plan to make and get explicit approval first.
</usecase>
<instructions>
Args:
action: Required. One of: add, pause, resume, cancel, remove, update.
- cancel: Stop sending further emails but keep the candidate visible in the sequence.
- remove: Delete the candidate from the sequence entirely (archive/soft-delete).
sequence_id: Required for add.
candidate_ids: Required for add. List of candidate IDs to enroll.
candidate_sequence_id: Required for pause, resume, cancel, remove.
candidate_sequence_step_id: Required for update. Get this from
list_sequence_candidates(sequence_id=..., include_detail=true).
subject_override: Optional for update. Custom subject for this candidate's step.
Supports {{variable_name}} placeholders filled in per-candidate by AI before sending.
template_override: Optional for update. Custom body for this candidate's step.
Supports {{variable_name}} placeholders filled in per-candidate by AI before sending.
clear_subject_override: Optional for update. Set true to revert subject to template default.
clear_template_override: Optional for update. Set true to revert body to template default.
schedule_override: Optional for update. JSON object to override the step's schedule.
Supported types: {"schedule_type": "instant"}, {"schedule_type": "next_business_day", "time_of_day": "HH:MM"}, {"schedule_type": "later", "delay_seconds": N}.
Setting a specific time is NOT supported.
clear_schedule_override: Optional for update. Set true to revert schedule to template default.
context_source_type: Optional for add. Must be one of 'search' or 'project'.
If provided, context_source_id is also required.
IMPORTANT: Leave both context_source_type and context_source_id null
if the source is unknown — do NOT guess or fabricate a value.
context_source_id: Optional for add. UUID of the search or project the candidates came from.
If provided, context_source_type is also required.
Leave null if context_source_type is null.
</instructions>
<response_format>
Add: {"added": N, "sequence_id": "...", "candidate_sequences": [...]}
Pause/resume/cancel/remove: {"action": "paused|resumed|cancelled|removed", "candidate_sequence_id": "..."}
Update: {"updated": true, "candidate_sequence_step_id": "..."}
</response_format>
<examples>
Add candidates:
manage_candidate_sequence(action="add", sequence_id="abc", candidate_ids=["c1", "c2"], context_source_type="search", context_source_id="search-uuid")
Pause:
manage_candidate_sequence(action="pause", candidate_sequence_id="xyz")
Resume:
manage_candidate_sequence(action="resume", candidate_sequence_id="xyz")
Cancel:
manage_candidate_sequence(action="cancel", candidate_sequence_id="xyz")
Remove (archive):
manage_candidate_sequence(action="remove", candidate_sequence_id="xyz")
Override step template for a candidate:
manage_candidate_sequence(action="update", candidate_sequence_step_id="step1", template_override="Custom body")
Override step schedule for a candidate:
manage_candidate_sequence(action="update", candidate_sequence_step_id="step1", schedule_override={"schedule_type": "later", "delay_seconds": 86400})
</examples>
manage_sequence
<usecase>
Create, update, duplicate, or delete a sequence.
Dispatches based on the action parameter. Only the creator of a sequence can update or delete it; admins and creators can duplicate.
Test sends, email previews, and send-now are NOT available via this tool. Direct users to the Metaview web app for these.
IMPORTANT: Always confirm with the user before calling this tool. Describe the exact changes you plan to make and get explicit approval first.
</usecase>
<instructions>
Args:
action: Required. One of: create, update, duplicate, delete.
sequence_id: Required for update, duplicate, delete.
name: Required for create, optional for update.
description: Optional for create and update.
set_enabled: Optional for create and update. Enable or disable the sequence.
steps: Optional for update. A JSON list of step objects to replace the current steps.
Steps not in the list are deleted. Order in the list determines step order.
Each step object has:
sequence_step_id: str | null (include the existing step ID to update it;
omit or set null for new steps — an ID will be generated automatically)
from_person_id: str | null (person ID of sender)
template: str | null (email body template; supports {{variable_name}} placeholders
that are filled in per-candidate by an AI call before sending)
subject: str | null (subject line — required for NEW_THREAD steps;
also supports {{variable_name}} placeholders)
step_type: str | null (NEW_THREAD or REPLY)
description: str | null
schedule: dict | null (e.g. {"schedule_type": "instant"}, {"schedule_type": "later", "delay_seconds": 86400}, {"schedule_type": "next_business_day", "time_of_day": "09:00:00"}.
Setting a specific time is NOT supported.
cc: list[str] | null
bcc: list[str] | null
step_execution_type: str | null (AUTOMATIC or MANUAL)
execution_timeout_seconds: int | null
</instructions>
<response_format>
Create/update/duplicate: {"sequence": {sequence detail object}}
Delete: {"deleted": true, "sequence_id": "..."}
</response_format>
<examples>
Create a sequence:
manage_sequence(action="create", name="Outreach v2")
Update name and enable:
manage_sequence(action="update", sequence_id="abc", name="New Name", set_enabled=true)
Duplicate:
manage_sequence(action="duplicate", sequence_id="abc")
Delete:
manage_sequence(action="delete", sequence_id="abc")
</examples>
list_send_on_behalf_permissions
<usecase>
List send-on-behalf-of permissions for the current user.
Two directions:
- 'granted_to': People who have permission to send sequence emails on my behalf.
- 'granted_by': People who have granted me permission to send sequence emails on their behalf.
The from_person_id field on a sequence step determines who the email is sent as. To send as someone else, that person must have granted you send-on-behalf permission.
</usecase>
<instructions>
Args:
direction: Required. One of: granted_to, granted_by.
granted_to: People who can send on my behalf (I granted them permission).
granted_by: People whose behalf I can send on (they granted me permission).
search_term: Optional. Filter results by name or email.
offset: Optional. Number of results to skip (default 0).
limit: Optional. Maximum number of results to return.
</instructions>
<response_format>{"persons": [{"person_id": N, "name": "...", "email": "..."}], "total_count": N}</response_format>
<examples>
Who can send on my behalf:
list_send_on_behalf_permissions(direction="granted_to")
Whose behalf can I send on:
list_send_on_behalf_permissions(direction="granted_by")
Search:
list_send_on_behalf_permissions(direction="granted_by", search_term="jane")
</examples>
list_sequence_candidates
<usecase>
List candidates enrolled in a sequence, or get a specific candidate's full journey.
Non-admins can only access sequences they created.
By default returns a summary per candidate. Use include_detail for per-step
delivery status, and include_messages to see the actual email content.
Pass candidate_sequence_id to jump straight to a specific candidate's full detail.
</usecase>
<instructions>
Args:
sequence_id: UUID of the sequence (required unless candidate_sequence_id is provided).
candidate_sequence_id: Fetch a specific candidate's full journey directly.
When provided, include_detail and include_messages are implied.
include_detail: When true, include per-step delivery status (sent, delivered,
opened, replied, bounced, skipped) and candidate_sequence_step_id for each
candidate. Required to get step IDs for updates via manage_candidate_sequence.
Default false.
include_messages: When true, include email content for all sent steps.
Requires include_detail. Default false.
status: Filter by status: "active", "paused", "cancelled", or "completed".
Omit to see all statuses.
search_term: Filter by candidate name (case-insensitive substring match).
offset: Pagination offset (default 0).
limit: Number of results per page (default 50, max 100).
</instructions>
<response_format>
{"sequence_id": "...", "sequence_name": "Outreach v2",
"candidates": [
{"candidate_sequence_id": "...",
"candidate_id": "...", "candidate_name": "John Doe",
"candidate_email": "
[email protected]", "candidate_phone": "+1234567890",
"to_email": "
[email protected]",
"status": "active",
"paused_reason": null, "cancelled_reason": null,
"outcome": null,
"created_by": {"name": "Alice Smith"},
"created_at": "2024-01-10T...",
"steps_sent": 2, "steps_total": 4,
"last_sent_at": "2024-01-15T...",
"has_reply": true,
"steps": [{"candidate_sequence_step_id": "...", "step_id": "...", ...}],
"messages": [{...}]}],
"total_count": 42,
"has_more": false}
</response_format>
<examples>
List all candidates in a sequence:
list_sequence_candidates(sequence_id="abc-123")
Active candidates with delivery detail:
list_sequence_candidates(sequence_id="abc-123", status="active", include_detail=true)
Full journey for a specific candidate (with emails):
list_sequence_candidates(candidate_sequence_id="xyz-789")
</examples>
list_sequences
<usecase>
List sequences the current user has access to, or get full details for a specific sequence.
Admins can see all sequences in the workspace. Non-admins can only see
sequences they created. Archived sequences are always excluded.
Returns summary data including per-sequence stats so the caller can compare
sequences without further round-trips. Pass sequence_id or include_detail=true
for full step configuration.
</usecase>
<instructions>
Args:
sequence_id: Fetch a specific sequence with full detail (steps, templates, etc.).
When provided, include_detail is implied.
created_by_person_id: Only return sequences created by this person.
Useful for admins who want to see just their own sequences.
search_term: Filter sequences whose name contains this substring
(case-insensitive). Also supports regex when the term contains
special characters like .*+?[]|().
include_detail: When true, include full step configuration for each sequence.
Default false (summary only).
include_disabled: Whether to include disabled sequences (default true).
offset: Pagination offset (default 0).
limit: Number of sequences per page (default 20, max 50).
</instructions>
<response_format>
{"sequences": [
{"id": "...", "name": "Outreach v2", "description": "...",
"is_enabled": true, "is_valid": true, "is_modifiable": false,
"created_by": {"name": "Alice Smith"},
"created_at": "2024-01-01T...", "updated_at": "2024-01-10T...",
"step_count": 3,
"stats": {"total_candidates": 42, "total_active": 10,
"total_completed": 20, "total_paused": 2,
"total_sent": 100, "total_replies": 15,
"total_bounced": 3, "total_interested": 8},
"steps": [{...}]}],
"total_count": 5,
"has_more": false}
</response_format>
<examples>
All enabled sequences:
list_sequences(include_disabled=false)
Search by name:
list_sequences(search_term="outreach")
Full detail for a specific sequence:
list_sequences(sequence_id="abc-123")
Only sequences created by a specific person:
list_sequences(created_by_person_id=123)
</examples>
get_user_context
<usecase>
IMPORTANT: Call this tool FIRST, before any other tool.
Returns your identity, role, what data you can access, and an overview
of the data model.
- participant_id: Your contact UUID — use this to filter for your own conversations.
- user_id: Your numeric user ID.
- is_admin: Whether you have admin access.
- is_paying_plan: Whether you are on a paid plan. Free users have limited access
to transcripts, summaries, and AI fields.
- data_access: Describes exactly which conversations you can see. Read this
before drawing conclusions about completeness of query results.
- data_model: Key concepts for understanding the data.
</usecase>
<instructions>No parameters needed.</instructions>
<response_format>
{"organization_id": 1,
"user_id": 123,
"participant_id": "550e8400-e29b-41d4-a716-446655440000",
"is_admin": true,
"is_paying_plan": true,
"data_access": "You can see all conversations in the organization.",
"data_model": "## Data model\n..."}
</response_format>