Trainual
Find how your company works
- Category
- Operations
- Primary Subcategory
- Shared Team AI Workspaces & Skill Libraries
Integration details
Description
Trainual is where growing companies run the operating side of the business — how work should be done, and how it is actually going. This plugin provides read access to your Trainual account so answers are grounded in your company’s own documented practice and current operating context rather than generic advice. From the Training suite: search documented processes, policies, and role expectations. See what training has been assigned and who has completed it. Look up what a role is responsible for and which tools a team uses. From the Operations suite: pull goals and progress against them, scorecard metrics and trends, meeting records and action items, and recurring team updates. Together that means you can ask how something is supposed to work and how it is actually going in the same conversation — the connection Trainual is built around. Common uses include onboarding support, answering "how do we do this here" without interrupting a colleague, preparing for a meeting or a one-on-one, checking training completion across a team, and drafting content that stays consistent with documented process. Access follows Trainual’s existing permission model. Users only reach content their Trainual account already permits, and the plugin never modifies data.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Shared Team AI Workspaces & Skill Libraries
- Secondary Subcategories
- None listed
- Brand
- Trainual
- Access
- Account required
- First tracked
- 2026-09-22
- Tool count
- 21
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Get alerts for Trainual
Get updates when Trainual’s Discoverability Score or category rank changes.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT Shared Team AI Workspaces & Skill Libraries
View Category21 tools agents can invoke
Read-only. Search the credentials uploaded to user profiles — certifications, licenses, assessments, and professional records. Call this tool even if the question mentions a specific person - profile documents are searchable by user name. Works at any scope: one named person's documents, or an account-wide sweep across everyone's uploaded credentials (queries search the parsed document text, so "anything mentioning X" sweeps need no person filter). NOT for skills or certifications mentioned only in a user's bio text (fetch_users' queries also searches skills - try both if the first comes up empty). NOT for files uploaded into training content — course attachments and the like (search_content's uploaded_file type). The word "uploaded" alone does not mean training content: a credential, license, or certification file — person-scoped or account-wide — is a profile document and belongs here. NOT for a file the user attached to the current Assistant conversation — read_attached_file. Common use cases: - "Show me John's certifications." - "Who has a PMP certification?" - "Find expired licenses." - "What assessments has Sarah completed?" - "Search for AWS certificates." - "Does [user] have [certification]?" - "Search everyone's uploaded credentials for [a qualification]." FILTERS: You can provide ids, queries, both, or neither: - ids only: Fetch specific profile documents by ID - queries only: Search documents by user name, filename, document content (plain_text), or document type (multiple queries use OR logic — matches ANY term) - Both ids AND queries: First filters to the provided IDs, then searches within that filtered set (INTERSECTION: must match at least one query term AND be in the ids list) - Neither: Returns all accessible profile documents The queries parameter searches the following fields: - user name - filename - plain_text (parsed document content including certifications, assessments, licenses, etc.) - document_type (e.g., certification, assessment, license) **Optional includes**: • user - the document's owner (name and ID), always returned regardless of include. Passing include: ['user'] is accepted but has no effect — this class eager-loads the user association unconditionally, so the parameter changes neither the response shape nor the query plan. Returns the following fields: {"id":"The profile document's internal identifier","filename":"The filename of the profile document","plain_text":"The extracted plain text content from the profile document","document_type":"The type of the profile document (e.g., certification, assessment, license)","user":"The user that owns the profile document, with the following fields: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","__typename":"The type of the object (always 'ProfileDocument')"}
fetch_profile_documents
Read-only. Search inside training content — the primary tool for finding answers within an organization's written training material. Most answers to policy, process, and procedure questions live in training pages (steps), which make up the majority of content in any account. Domain: - Customer-facing terminology: Subject (top-level container, legacy: Curriculum), Document (content item made of Pages, legacy: Topic), Page (unit within a Document, legacy: Step), Category (grouping: Company / Policies / Processes, legacy: Sector). - A Page can contain richtext, links, embeds, videos, images, files, and tables. Version history and commenting are available on Pages. - Subjects are categorized as Company, Policies, or Processes. - This tool searches INSIDE content (page text, video transcripts, checklist items, file text). To find or list training subjects/documents by title, use fetch_curriculums instead. NOT for: team status reports, weekly updates, or check-ins — those live in the Updates feature (fetch_update_assignments); content search returns look-alike training documents from unrelated teams. NOT for Trainual product release notes / "what's new at Trainual" — no tool covers product announcements. NOT for per-user training progress, completion, or due dates — fetch_curriculum_assignments. NOT for looking up people or groups directly — fetch_users or fetch_groups respectively. NOT for credentials, certifications, or licenses uploaded to user profiles — fetch_profile_documents, including account-wide sweeps ("everyone's uploaded credentials"); the uploaded_file type here covers files uploaded into training content, not profile documents. NOT for a file the user attached to the current Assistant conversation — read_attached_file; a file the user just uploaded into the chat is never indexed here. Long bodies are trimmed: each result carries body_truncated and full_length. body_truncated: true means the document matched but its body was cut — the visible text may omit the answer even when the document is clearly relevant. Retry ONCE with a narrower, more specific query to rank the relevant portion higher; never conclude the information doesn't exist just because a truncated body doesn't show it. If a search returns nothing, retry with alternate phrasings, synonyms, and broader terms before concluding the content doesn't exist. Exception: when the question is about credentials, certifications, or licenses, do not spend retries here — that material lives on user profiles, so switch to fetch_profile_documents. Common use cases: - "What is our PTO policy?" / "How do we handle returns?" / "What's the onboarding process?" - "Show me checklists" / "Find training videos" / "List all flowcharts" - Fallback when other tools do not return the information needed Content types searched: - steps (training pages — the largest content type, where most answers live) - courses (Documents — the container for Pages; use to answer "do we have a Document about X?") - videos (with transcript text, type, and description) - checklists (with checklist item text) - flowcharts (with structure and content) - uploaded_files (with extracted plain text — files uploaded INTO training content only; a user's uploaded credentials, certifications, and licenses are profile documents and never appear here, so credential questions must go to fetch_profile_documents even when this type returns nothing) Use the content_types filter to narrow results to specific types (e.g., only videos, only checklists). Omit it to search across all content types. Each result includes: id, title, body text (page text, video transcript, checklist items, or extracted file text), body_truncated, full_length, citation (for response annotations), result_card (for navigation), owner, and curriculum/course context.
search_content
Retrieves feedback requests — first-class objects with a fulfillment status — from the requesting user's perspective. Read-only; responding to a request is not supported. Domain: - A request asks one or more responders for feedback ABOUT one user. Each responder gets an invitation whose status is 'pending' until they answer ('completed'). - Requests are personal-scope: users see requests they SENT and requests they were ASKED to answer. There is no account-wide request view, even for admins. An account-wide- sounding brief ("all feedback requests in the account") is still answerable — CALL this tool and report the requester's own sent/to-answer requests; a scope mismatch is never a reason to decline the call or to answer without calling it. Report those results as the requester's own requests, never as an account-wide or complete listing — an admin's results are exactly as personal-scope as anyone else's — and state plainly that no account-wide view exists. - A completed invitation links to the feedback record it produced (feedback_id) — fetch the response text via fetch_feedback with ids: [feedback_id]. Common use cases: - "Which of my feedback requests haven't been answered yet?" → role: 'sent', status: 'pending' - "Show me requests I've sent about my direct reports and their status" → role: 'sent', about_user_ids: [...] (resolve the reports via fetch_users include: children) - "Do I have feedback requests waiting on my response?" → role: 'to_answer', status: 'pending' FILTERS: - role (required): 'sent' = requests the user created; 'to_answer' = requests where the user is an asked responder (scoped to their own invitation). - status: 'pending' or 'completed'. For 'sent', filters on invitation fulfillment (a request with any pending invitation matches 'pending'; with any completed invitation matches 'completed'). For 'to_answer', filters the user's own invitation state. - about_user_ids: only requests about these users. Resolve names via fetch_users first. - created_after / created_before: ISO 8601 datetimes. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor until has_more is false before summarizing. A cursor is only valid for the SAME filters it was returned from — an invalid or mismatched cursor returns an error telling you to retry without it (omit cursor to restart from the first page). Returns {"feedback_requests": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}. Each record: {"id":"The feedback request's internal identifier","prompt":"The question the requester asked, as plain text","visibility":"Visibility the resulting feedback will carry: 'private', 'private_plus_manager', or 'manager_only' (requests are never public)","about_user":"The user the request is about. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","created_by":"The user who sent the request. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","invitations":"Who was asked to respond, each with fulfillment status. Structure: {\"id\":\"The invitation's internal identifier\",\"status\":\"'pending' (not yet answered) or 'completed' (the responder gave feedback)\",\"responded_at\":\"When the responder answered (ISO 8601), or null while pending\",\"recipient\":\"The user asked to give feedback. Structure: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}\",\"feedback_id\":\"The feedback record that fulfilled this invitation (fetch by id via fetch_feedback), or null while pending (or if the linked feedback record was since removed)\",\"result_card\":\"Not available for invitations (always null)\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the Feedback requests tab in the Trainual web app\",\"__typename\":\"The type of the object (always 'PerformanceFeedbackRequestInvitation')\"}","created_at":"When the request was sent (ISO 8601)","result_card":"Not available for feedback requests (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the Feedback requests tab in the Trainual web app","__typename":"The type of the object (always 'PerformanceFeedbackRequest')"}
fetch_feedback_requests
Read-only. Retrieves goals (OKRs/targets) the user has permission to see, by ID(s) or search queries, with optional related data like owner, watchers, recorded values, comments, and history. Owner, watcher (which may be a group), and linked-meeting fields are summary data only — call fetch_users, fetch_groups, or fetch_meetings with their IDs for full details. Use this tool when you need information about goals including progress, status, ownership, and targets. Domain: - Goals track progress toward a defined outcome with an end state — distinct from Scorecards (recurring measurable targets, no end state). - Goals and Scorecards are separate stores; neither tool returns the other's data. A metric/target/trend question that doesn't say "goal" or "scorecard" can be tracked in either product, so both this tool and fetch_scorecards must be queried to cover it. - Owner: exactly one per goal, responsible for driving progress. - Watchers: users or groups who can view progress. Includes the owner's direct managers by default. - Status: Not Started, On Track, Off Track, At Risk, or Done. - Metric: optional measurable target (e.g. "Close 50 deals") — a numeric value tracked against a target. - Observations: progress entries logged against a goal or its metric. - Due Date: optional target completion date. - Visibility: owners, watchers, owner's direct reports. Billing Admins see all. NOT for the full picture alone: "team status", "catch me up", "full picture", or "what should I focus on" questions usually also need fetch_update_assignments (what people reported) and fetch_meetings (meeting activity) — fetch_goals does not cover general meeting or update- submission activity beyond what's already linked to a specific goal. Common use cases: - "What goals am I working on?" - "What's the status of [goal name]?" - "Which goals are off track?" - "Who owns the revenue goal?" FILTERS: You can provide ids, queries, owner_ids, status, or combinations: - ids only: Fetch specific goals by ID - queries only: Search goals by title or description (multiple queries use OR logic - matches ANY term) - Both ids AND queries: First filters to the provided IDs, then searches within that filtered set (INTERSECTION: must match at least one query term AND be in the ids list) - owner_ids: Filter goals by owner user IDs. Use fetch_users first to resolve names to IDs. - watcher_ids: Filter goals watched by specific user IDs (direct or via group membership). Automatically excludes goals owned by the same user (use owner_ids for owned goals). - exclude_owner_ids: Exclude goals owned by these user IDs from results. - status: Filter goals by status (multiple values use OR logic) - due_before / due_after: Filter by the goal's target (due) date. Use for time-bounded questions like "goals due this quarter" or "what's due by end of month". Goals with no target date are excluded when either bound is set. For a pure date-range question, pass ONLY due_before/due_after — do NOT also pass queries. queries is ANDed with the date bounds, so adding words like "due date" or "deadline" wrongly drops goals whose title and description don't contain those literal words. - Neither: Returns all goals visible to the current user The queries parameter searches the following fields: goal title, description If a title search returns nothing, retry with partial words, singular/plural variants, and related terms from the request before concluding the goal doesn't exist (e.g. "the Q3 revenue growth goal" → queries: ["revenue", "Q3", "growth"]). Treat non-exact keyword matches as candidates, not a confirmed match. **Optional includes**: • owner - The user who owns this goal • watchers - Users and groups watching this goal • children - Sub-goals under this goal • parent - The parent goal if this is a sub-goal • observations - Recorded values (progress updates) with numeric values and status snapshots over time • comments - Comments on this goal • goal_histories - History of edits (state before each change) • meetings — Meetings linked to this goal Returns the following fields: {"id":"The goal's internal identifier","title":"The name of the goal","description":"A detailed description of what this goal aims to achieve","target_value":"The primary target value. For single-target goals, this is the goal. For range goals, this is the upper bound of the range.","secondary_value":"The lower bound of the range. Only present when the goal is a range goal; null otherwise.","target_date":"The target completion date for the goal (ISO 8601)","status":"Internal status identifier, computed from the latest recorded value. Never show the raw value to users. When narrating, render 'not_started' as \"Not Started\", 'on_track' as \"On Track\", 'off_track' as \"Off Track\", 'at_risk' as \"At Risk\", 'done' as \"Done\".","current_value":"The current progress value. Already aggregated — for Cumulative goals this is the sum of recorded values; for Trend goals it is the latest recorded value.","unit":"The unit of measurement and formatting hint. Format recorded values as: 'currency' → prefix with $ (e.g. '$5,000'), 'percentage' → suffix with % (e.g. '85%'), 'count' → plain number (e.g. '1,234').","measurement_type":"How progress is tracked, as a human-readable label: 'Trend' (latest recorded value is the current state) or 'Cumulative' (values sum over time).","parent_id":"The ID of the parent goal, if this is a sub-goal","created_at":"When the goal was created (ISO 8601)","updated_at":"When the goal was last updated (ISO 8601)","result_card":"Not available for goals (always null)","web_url":"Absolute URL to the goal page in the Trainual web app (nil when account context is unavailable)","citation":"A string used to identify the record in citations","__typename":"The type of the object (always 'OperationsGoal')"}
fetch_goals
Retrieves growth areas — persistent, named development focuses — the user is entitled to see, with title, description text, status, dates, owner, and creator. Read-only. Domain: - A growth area belongs to exactly ONE owner. It can be created by the owner or by their manager, so creator and owner may differ — both are returned and filterable. - Status lifecycle: 'draft' and 'active' mean not done / in progress; 'completed' is done; 'archived' is abandoned. When the user asks what is "not done", "unfinished", or "in progress", PASS status: ["draft","active"] — do not fetch all statuses and classify the results yourself; archived items are abandoned, NOT "not done". "Overdue" → target_before: now AND status: ["draft","active"] (completed/archived items are never overdue). An unqualified request ("show me X's growth areas") means ALL statuses — omit the key (or pass status: ['any']); do NOT narrow to draft/active unless the user asks what is open or not done. - Entitlement: users see their own growth areas and their org-chart reports' — the whole reporting subtree below them, not just direct reports. Account-wide visibility requires billing-admin or an admin with performance full access — a plain admin or group manager does NOT see group members' growth areas. Enforced per record; results may legitimately be empty — when they are, say the items may exist but aren't visible to the requester, don't assert none exist. - Topics/themes are NOT stored. Infer them from the returned title and description text. - NOT ad-hoc praise or private feedback given between people; that's fetch_feedback. Common use cases: - "Show me my growth areas" → status: ['any'] (or omit status entirely) - "Which of my growth areas aren't done?" → status: ["draft","active"] - "Growth areas my manager created for me" → owner_ids: [me], creator_ids: [manager id] - "Growth areas I created for Dani" → creator_ids: [me], owner_ids: [Dani] — ALWAYS pair creator_ids with owner_ids when the question names whose growth areas they are; creator_ids alone returns everything that person ever created, including their own. owner_ids is DANI (whose profile the areas live on) — NEVER yourself for a "for <someone else>" question; owner_ids: [me] + creator_ids: [me] returns your own self-created areas. - "What are my team's growth themes?" → resolve the team via fetch_users/fetch_groups, pass owner_ids FILTERS (all optional, AND semantics): - ids: direct record lookup (e.g. for follow-ups). Unentitled ids are silently excluded. - owner_ids: whose growth areas. Resolve names, groups, and "team" references to user IDs first via fetch_users/fetch_groups. For "my team": a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. - creator_ids: who created them — distinct from owner. - status: any of 'draft', 'active', 'completed', 'archived'. Omit for all statuses. - target_after / target_before: ISO 8601 — target-date window (due soon, overdue). - created_after / created_before: ISO 8601 — creation window (when the focus was SET). - completed_after / completed_before: ISO 8601 — completion window (when the focus FINISHED). Use for "completed in <period>" questions — created_after only tells you when it was set, not when it finished, and will miss items set earlier and completed later. - updated_after / updated_before: ISO 8601 — last-edit window. Any edit bumps updated_at (activity proxy, not proof of substantive progress). Use updated_before to find growth areas that have gone quiet. - There is NO text-search parameter — retrieve and infer topics from the returned title/description text. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor (same filters — changing filters invalidates the cursor) until has_more is false. Retrieve ALL pages before synthesizing themes or trends. total_count is the full entitled count for the current filters. Returns {"growth_areas": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}. Each record: {"id":"The growth area's internal identifier","title":"The named development focus","description":"Optional detail as plain text.","status":"'draft', 'active', 'completed', 'archived' ('draft'/'active' = open; see tool description for filter semantics)","target_date":"Target completion date (ISO 8601 date), or null","completed_date":"When it was marked completed (ISO 8601 date), or null","created_at":"When it was created (ISO 8601)","updated_at":"When it was last edited in any way (ISO 8601). Activity proxy only — any edit bumps it; not proof of substantive progress","owner":"The person this growth area belongs to — exactly one. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","creator":"Who created it — the owner themselves or their manager; may differ from owner. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","result_card":"Not available for growth areas (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the owner's profile page (where growth areas live)","__typename":"The type of the object (always 'PerformanceGrowthArea')"}
fetch_growth_areas
Read-only. Retrieves specific meeting items by id — agenda items, their talking points, action items, or their subtasks — when you already hold an item id from a previous fetch_meetings result and need to drill into that one item without re-fetching the whole meeting. Each result carries the item's full detail plus `parent` (the agenda item or action item it sits under, null for top-level items) and `meeting` (id and title). NOT for finding meetings, listing an agenda, or answering "what's on my agenda" — use fetch_meetings for those. Ids here are the string `id` values from fetch_meetings' item objects, never meeting ids. Ids that are not returned were not found or are not visible to this user; say so rather than substituting other items. Returns an array of: {"id":"The item's identifier (use with fetch_meeting_items)","text":"The item title (short text)","content_html":"The item description/notes, sanitized to Markdown from its rich-text body. Read this, not just text, to understand what the item is about","kind":"'agenda_item' (a topic to discuss; its children are talking points) or 'action_item' (a task; its children are subtasks)","recurring":"True when this item carries forward to the next occurrence even after being completed","position":"Display order within its parent or section","owner":"The user assigned to this item, or null. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","due_by":"Deadline (ISO 8601 date), null if none","completed_at":"When completed (ISO 8601). Present = completed, null = open.","deferred_at":"When deferred (ISO 8601), null if not deferred","deferred_until":"When a deferred item resurfaces (ISO 8601)","archived_at":"When archived (ISO 8601), null if not archived","comments":"Comments on this item, oldest first. Structure: {\"id\":\"The comment's internal identifier\",\"content_html\":\"The comment content in HTML format\",\"created_at\":\"When the comment was created (ISO 8601)\",\"created_by\":\"The user who wrote the comment. Structure: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}\",\"__typename\":\"The type of the object (always 'Comment')\"}","attachments":"Files attached to this item. Structure: {\"id\":\"The attachment's identifier\",\"filename\":\"The uploaded file name\",\"content_type\":\"MIME type of the file\",\"byte_size\":\"File size in bytes\",\"uploaded_by\":\"The user who attached the file. Structure: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}\",\"created_at\":\"When the file was attached (ISO 8601)\",\"__typename\":\"The type of the object (always 'OperationsItemAttachment')\"}","parent_id":"For a talking point or subtask, the id of its parent item; null for top-level items","meeting_id":"The meeting this item belongs to","children":"Nested talking points (under an agenda item) or subtasks (under an action item), same structure as this object. Always present; [] when there are none","__typename":"The type of the object (always 'OperationsMeetingItem')","parent":"For a talking point or subtask, { id, text } of the agenda item or action item it sits under; null for top-level items","meeting":"{ id, title } of the meeting this item belongs to"}
fetch_meeting_items
Read-only. Retrieves meetings the user has permission to see, by ID(s) or search queries, with optional related data: owner, attendees, agenda items (with their talking points), action items (with their subtasks), and linked goals. Owner, attendee (which may be a group), and linked-goal fields are summary data only — call fetch_users, fetch_groups, or fetch_goals with their IDs for full details. Domain: - Meetings provide structured recurring agendas for 1-on-1s, team syncs, and other regular check-ins. Each meeting has an agenda that carries forward between occurrences. - Owner: the user who created and manages the meeting. - Attendees: users or groups. Group attendee includes all members. - Agenda items: the topics a meeting covers — recurring ones reappear every occurrence, one-off ones belong to a single occurrence. Each has a short title (text), a rich-text description (content_html), an optional owner, comments, attachments, and nested talking points in `children` (sub-points to cover under that topic). - Action items: tasks with an owner and optional due date that persist until completed. Same fields as agenda items; their `children` are subtasks. - Every item, at every level, carries the same fields. Use `content_html` and comments — not just `text` — to explain what an item is actually about. - `children` is always present. When it is [] the item has NO talking points or subtasks: say so. An item's own `text`/`content_html` describes the item itself and is never a talking point or subtask — do not restate it as one. - "Discussion topics" is the former name for one-off agenda items — a user asking about them means agenda_items. - Meeting Notes: free-form notes captured during an occurrence. - Cadence: recurrence schedule (weekly, biweekly, monthly, etc.). NOT for the full picture alone: meeting prep, 1-on-1 prep, and "catch me up"/"team status" questions usually also need fetch_goals (goal progress) and fetch_update_assignments (what people reported) — fetch_meetings does not cover general goal or update-submission activity beyond what's already linked to a specific meeting. Common use cases: - "What meetings do I have this week?" - "What's the agenda for my next team sync?" - "Help me prepare for my 1-on-1 with [person]" - "What did we discuss under [agenda item]?" → its children (talking points) **Assembling "the agenda":** A customer's idea of "the agenda" — or "what's coming up", "what should I cover", or anything meeting-prep — is the WHOLE picture: agenda items with their talking points AND outstanding action items with their subtasks. For these questions, include: ["agenda_items", "action_items"] is REQUIRED, not optional — request both in one call (add "meeting_goals" when prep is implied). Never report an empty agenda without having requested both. When listing action items, always state owner, due_by, and completion state for each. To drill into a single item you already hold an id for (a talking point, subtask, agenda item, or action item), use fetch_meeting_items instead of re-fetching the meeting. **Meeting types** (team syncs, all-hands, project check-ins, and 1-on-1s are all meetings, distinguished by attendees and cadence): - General: any combination of user and group attendees. Most user queries ("my meetings", "meetings this week", "how many meetings") refer to ALL meetings. - Recurring: any meeting with a cadence. Identify by checking the cadence field in the response (non-empty = recurring). - 1-on-1: a specific subtype — recurring, with 1 owner (User) + 1 attendee (User), and no Group attendees. To identify from results: include meeting_attendees, then check that cadence is non-empty, there is exactly 1 attendee with __typename: 'User', and none with __typename: 'Group'. - One-off: a meeting with no cadence field. FILTERS: You can provide ids, queries, date range, person_ids, or combinations: - ids only: Fetch specific meetings by ID - queries only: Search meetings by title, agenda item text, and action item text (multiple queries use OR logic — matches ANY term) - Both ids AND queries: First filters to the provided IDs, then searches within that set - starts_after / starts_before: Filter by meeting start time range (ISO 8601) - person_ids: Filter meetings where specific users participate (as owner, direct attendee, or group member). Use fetch_users first to resolve names to IDs. Prefer person_ids over queries when the user names a person — a name in queries fuzzily matches other people's meetings too. - Neither: Returns all meetings visible to the current user If a title search returns nothing, retry with partial words, singular/plural variants, and related terms from the request before concluding the meeting doesn't exist (e.g. "the weekly product sync meeting" → queries: ["product", "sync", "weekly"]). Treat non-exact keyword matches as candidates, not a confirmed match. Meeting status (upcoming vs ended) and recurrence (cadence field) are included in the response data. **Result ordering**: - Searches with queries return most-relevant-first, weighted toward recent meetings, with one result per recurring series (its newest occurrence). For recency questions ("last", "most recent", "latest", "previous") on a search, the first result is usually the answer. - Results without queries (ids, person_ids, or date filters only) are ordered oldest-first (starts_at ascending). For recency questions there, set starts_before: <current datetime> and answer from the result with the latest starts_at — never assume the first result is the most recent. **Optional includes**: • meeting_owner — The current owner of this meeting • meeting_attendees — Users and groups attending this meeting • agenda_items — Agenda items with owner, description, comments, attachments, and nested talking points • action_items — Action items with owner, due date, completion state, comments, attachments, and nested subtasks • meeting_goals — Goals linked to this meeting When requesting agenda_items or action_items, always narrow the call with ids, person_ids, queries, or a starts_after/starts_before window — item includes make each meeting large, and an unfiltered call on a busy account returns far more than one question needs. Comments and attachments belong to a specific item, not the meeting. Use the item's `text` and `content_html` to identify what a comment was about, along with the commenter. Returns the following fields: {"id":"The meeting's internal identifier","title":"The name of the meeting","cadence":"Human-readable recurrence schedule (e.g. \"Weekly on Mondays\"). Null if one-off.","timezone":"The IANA timezone for this meeting","starts_at":"Scheduled start time (ISO 8601)","ends_at":"Scheduled end time (ISO 8601)","started_at":"When the meeting actually started (ISO 8601). Present = started, null = not yet started.","ended_at":"When the meeting actually ended (ISO 8601). Present = ended, null = not yet ended.","summary":"AI-generated meeting summary text, available after meeting ends","created_at":"When the meeting was created (ISO 8601)","updated_at":"When the meeting was last updated (ISO 8601)","result_card":"Pipe-delimited string: 'OperationsMeeting|{uuid}|{title}'","web_url":"Absolute URL to the meeting page in the Trainual web app (nil when account context is unavailable)","citation":"A string used to identify the record in citations","__typename":"The type of the object (always 'OperationsMeeting')"} Each entry in agenda_items and action_items (and each of its children) has this structure: {"id":"The item's identifier (use with fetch_meeting_items)","text":"The item title (short text)","content_html":"The item description/notes, sanitized to Markdown from its rich-text body. Read this, not just text, to understand what the item is about","kind":"'agenda_item' (a topic to discuss; its children are talking points) or 'action_item' (a task; its children are subtasks)","recurring":"True when this item carries forward to the next occurrence even after being completed","position":"Display order within its parent or section","owner":"The user assigned to this item, or null. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","due_by":"Deadline (ISO 8601 date), null if none","completed_at":"When completed (ISO 8601). Present = completed, null = open.","deferred_at":"When deferred (ISO 8601), null if not deferred","deferred_until":"When a deferred item resurfaces (ISO 8601)","archived_at":"When archived (ISO 8601), null if not archived","comments":"Comments on this item, oldest first. Structure: {\"id\":\"The comment's internal identifier\",\"content_html\":\"The comment content in HTML format\",\"created_at\":\"When the comment was created (ISO 8601)\",\"created_by\":\"The user who wrote the comment. Structure: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}\",\"__typename\":\"The type of the object (always 'Comment')\"}","attachments":"Files attached to this item. Structure: {\"id\":\"The attachment's identifier\",\"filename\":\"The uploaded file name\",\"content_type\":\"MIME type of the file\",\"byte_size\":\"File size in bytes\",\"uploaded_by\":\"The user who attached the file. Structure: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}\",\"created_at\":\"When the file was attached (ISO 8601)\",\"__typename\":\"The type of the object (always 'OperationsItemAttachment')\"}","parent_id":"For a talking point or subtask, the id of its parent item; null for top-level items","meeting_id":"The meeting this item belongs to","children":"Nested talking points (under an agenda item) or subtasks (under an action item), same structure as this object. Always present; [] when there are none","__typename":"The type of the object (always 'OperationsMeetingItem')"}
fetch_meetings
Read-only. Look up who someone is — identity, contact info, profile data, role history, skills, interests, working style, and reporting structure. Domain: - Permission levels are cumulative — General (view assigned items), Contributor (edit assigned items), Author (create and assign), Admin (reports, manage users), Billing Admin (manage billing and plans). - Users can configure their profile (name, title, phone, email, pronouns, time zone, birth month/day with optional hidden birthday, LinkedIn URL, "Working with me" notes, interests, skills, role history). Email notifications: daily update (new assignments, ownership changes, review tags) and weekly incomplete-work reminders. NOT for: training progress, completions, or due dates — fetch_curriculum_assignments is the only tool with per-user assignment data. NOT for group-level attributes (a team's responsibilities, software, membership) — fetch_groups with the matching include. Profile data is the source of truth: treat returned skills, interests, and bio as authoritative. Never guess or fabricate skills/interests, and never add names beyond those in the results. If a value appeared in a result earlier in the conversation, do not later claim it was not found. Resolving people by name: - If a name lookup returns nothing, retry with nickname and spelling variants as additional query terms before concluding the person isn't found (e.g. "Mike" → ["Mike", "Michael"], "Jess" → ["Jessica"]). - When there is no exact match, results may be approximate (closest by name) — treat them as candidates to confirm or disambiguate, never as a single asserted match. Common use cases: - "Who is [person]?" / job title, email, phone, LinkedIn — base fields, no include needed. - "What are [person]'s skills / interests?" (include: skills, hashtags) - "What are [person]'s responsibilities?" (include: responsibilities) - "What roles has [person] held?" (include: user_roles) - "Who does [person] report to?" (include: parent) / "Who reports to [person]?" (include: children) - "Who are [person]'s peers?" — fetch [person] with include: parent, then fetch the parent with include: children; the children minus [person] are the peers. - Comparison/commonality questions ("what do I have in common with X") — fetch BOTH people with include: [skills, hashtags]. - "List all users" / "Who are the engineers?" (permissions / group_ids filters) - Reverse lookups ("who knows [skill]?", "who is interested in [topic]?", "who else is a [job title]?", "who mentions [thing] in their bio?") — pass the term as a query. FILTERS: ids, queries, both, or neither: - ids only: specific users by ID - queries only: searches user name, job title, skills, interests, bio text, and "working with me" notes (OR logic across multiple terms) - Both: INTERSECTION — must match at least one query term AND be in the ids list - Neither: all accessible users - permissions: narrow to these levels ('general', 'contributor', 'author', 'admin', 'billing_admin') - group_ids: narrow to users in these groups (resolve names to IDs with fetch_groups first) **Optional includes**: parent (direct manager), children (direct reports), groups, software (owned/managed by the user — NOT software granted only through group membership; see fetch_softwares/fetch_groups for that), responsibilities (the user's complete set, direct plus group-inherited, each with name, description, assignment_source and via_groups — answers "what is [person] responsible for?" on its own; fetch_responsibilities cannot scope to a person), skills, hashtags (interests — hobbies, passions, out-of-work topics; pair skills with hashtags for two-person comparisons — a single-person lookup uses the minimal default includes), user_roles (job title history). Returns the following fields: {"id":"The user's internal identifier","name":"The user's full name","job_title":"The user's job title","avatar":"URL to the user's avatar image","result_card":"A string used for client-side navigation","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)","__typename":"The type of the object (always 'User')","bio":"The user's biography","completion_percentage":"The percentage of assigned content the user has completed","pronouns":"The user's preferred pronouns","email":"The user's email address. Use to answer how to reach someone in writing or to identify users by email. Returns nil if the account has disabled showing email addresses on profiles.","phone_number":"The user's phone number, if set. Use to answer how to reach someone by phone. Returns nil if the user has not set a phone number, or if the account has disabled showing phone numbers on profiles.","linkedin_url":"The URL of the user's LinkedIn profile, if set. Returns nil otherwise.","invitation_sent_at":"The date the user was invited to join Trainual, formatted as ISO 8601. Surfaced on the profile UI as \"Invite date\" — phrase responses using that label. Use to answer questions like \"When was [user] invited?\" or \"Who are the most recently added members?\". Returns nil if the user was not invited (e.g., the account owner).","working_with_me":"The user's working style, communication preferences, and collaboration cues — the \"Working with [User]\" section of their profile, written by the user themselves. Returned as plain text. Common use cases: helping someone understand how to collaborate effectively with this person, comparing two people's working styles to find compatibility or differences, summarizing what to know before a first interaction, or answering questions like \"how do Taylor and I best work together?\" or \"what's Taylor's preferred communication style?\". Choose whatever output format suits the question (prose, table, comparison list). Returns nil if the user has not filled in this field.","parent":"The user's direct manager or supervisor in the organizational hierarchy (immediate superior only). Use this field to answer questions such as: \"Who does [user] report to?\", \"Who is [user]'s manager?\", \"Who is [user]'s supervisor?\". Returns nil if the user has no manager (e.g., CEO or top-level user). The parent user includes the following fields: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","children":"The users who directly report to this user in the organizational hierarchy (immediate subordinates only). Use this field to answer questions such as: \"Who reports to [user]?\", \"Who are [user]'s direct reports?\", \"Who does [user] manage?\", \"How many people report to [user]?\". Returns an empty array if the user has no direct reports. Each child user has the same structure as 'parent' above. Tip: to find a user's peers (others with the same manager), fetch the user's parent and then fetch the parent's children — that list, minus the user themselves, is the peer set.","groups":"Useful to determine the groups that the user is a member of and answer questions such as: What groups am I in? What groups is that user a part of? What groups is [specific user] a member of? A list of groups the user belongs to, Returns the following fields: {\"id\":\"The group's internal identifier\",\"name\":\"The name of the group. This is primary way that the UI and users identify the group.\\nIMPORTANT: Groups with name 'Everyone' are special system groups that automatically contain all users in the account.\\nThese groups cannot be deleted and their membership cannot be manually modified (users are automatically added/removed).\",\"description\":\"A brief description of the group\",\"kind\":\"The type of group, such as role, team, department, location, other\",\"web_url\":\"Absolute URL to the group page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'Group')\"}","time_zone":"The user's time zone","time_zone_info":"Detailed information about the user's time zone","start_date":"The date the user started, formatted as MM/DD/YYYY","birth_day":"The day of the month the user was born, as an integer (1-31). When answering questions about birthdays, combine this with birth_month to form a complete date (e.g., birth_day: 15, birth_month: 3 should be presented as 'March 15th'). Returns nil if not set or hidden.","birth_month":"The month the user was born, as an integer (1-12 where 1=January, 2=February, etc.). When answering questions about birthdays, combine this with birth_day to form a complete date (e.g., birth_day: 15, birth_month: 3 should be presented as 'March 15th'). Returns nil if not set or hidden.","software":"A list of software, tools, equipment that the user is directly assigned as an OWNER of. This field shows DIRECT ownership only. Users may also have access to additional software through their group memberships (check user.groups → group.software for complete picture). Useful for queries like: \"What software does [user] own?\", \"What tools is [user] responsible for managing?\". To answer \"What software does [user] USE?\" combine this field with software from all their groups. Structure: {\"id\":\"The software's internal identifier\",\"name\":\"The name of the software, tool, equipment, or vendor (e.g., \\\"Slack\\\", \\\"Zoom\\\", \\\"MacBook Pro\\\"). This is how users refer to the software in conversations. Software can be assigned in two ways: (1) Direct assignment to USERS (owners): Specific users are designated as owners of the software. (2) Assignment to GROUPS: All members of the group have access to/use the software. To answer queries about software: \\\"What software does [user] use?\\\" check user.software (shows direct ownership) PLUS any software assigned to groups the user belongs to. \\\"What software is assigned to [group]?\\\" check group.software (all members have access). \\\"Who uses [software]?\\\" check both direct owners AND groups assigned to it. Note on \\\"use\\\" vs \\\"own\\\": A user \\\"owns\\\" software if directly assigned as an owner. A user \\\"uses\\\" or \\\"has access to\\\" software if assigned via group membership.\",\"description\":\"A brief description of what this software is, what it does, or how it's used in the organization. May include setup instructions, access details, or usage guidelines.\",\"logo\":\"URL to the software or vendor logo image (if available)\",\"url\":\"URL to the software website, documentation, login page, or vendor information\",\"category\":\"The category of the software (e.g., 'Productivity', 'Communication', 'Development', 'Design'). Helps organize and filter software by type.\",\"resource_contents\":\"Array of attached content for this software (links and connected items). Structure: {\\\"id\\\":\\\"The resource content's internal identifier\\\",\\\"title\\\":\\\"The title of the attached content (falls back to the contentable title when present)\\\",\\\"url\\\":\\\"The URL for the attached content\\\",\\\"contentable_type\\\":\\\"The type of the contentable record associated with this attachment (if any)\\\",\\\"contentable_id\\\":\\\"The id of the contentable record associated with this attachment (if any)\\\",\\\"curriculum_type\\\":\\\"The curriculum type for this attachment (if any)\\\",\\\"citation\\\":\\\"The string used to identify the record in citations\\\",\\\"result_card\\\":\\\"The string used for client-side navigation\\\",\\\"__typename\\\":\\\"The type of the object (always 'ResourceContent')\\\"}\",\"owners\":\"Array of users who are designated as owners/managers of this software\",\"groups\":\"Array of groups that have access to this software (all group members can use it)\",\"__typename\":\"The type of the object (always 'Software')\"}","responsibilities":"The COMPLETE set of responsibilities this user holds — both those assigned directly to the user and those inherited through their group memberships. Answers \"What are all of [user]'s responsibilities?\" / \"What is [user] responsible for?\" with no need to separately fetch group responsibilities. Each item carries an `assignment_source` ('direct' when assigned to the user individually, 'group' when inherited via a group) and `via_groups` (the groups the responsibility is inherited through, each with id and name; empty array when the responsibility is direct-only). A responsibility assigned both directly and via a group has source 'direct' and still lists that group in `via_groups`. Structure: each item has {\"id\":\"The responsibility's internal identifier\",\"name\":\"The name of the responsibility. This is the primary way users identify responsibilities.\\n\\nA responsibility is a task or role that users are expected to perform. Responsibilities are assigned to users or groups,\\nand inherit to all members of the group. Useful for queries like: \\\"What is [user] responsible for?\\\",\\n\\\"What responsibilities does the [group name] have?\\\",\\n\\\"Who is responsible for [responsibility name]?\\\" (check which groups have it).\\n\\nIMPORTANT - How Responsibilities Are Assigned:\\nResponsibilities can be assigned to both individual users AND groups.\\nWhen assigned to a GROUP: All members of that group inherit the responsibility.\\nWhen assigned to a USER: Only that specific user has the responsibility.\\n\\nTo answer queries about responsibilities: \\\"What is [user] responsible for?\\\" check user.responsibilities (direct assignments)\\nAND all responsibilities from their groups. \\\"What is everyone in [group] responsible for?\\\" check group.responsibilities\\n(applies to all members). \\\"Who is responsible for X?\\\" search users/groups with that responsibility.\",\"description\":\"A brief description of what this responsibility entails, including any relevant context about the work or expectations.\",\"__typename\":\"The type of the object (always 'Responsibility')\"} plus \"assignment_source\" ('direct' or 'group') and \"via_groups\" (array of { id, name }).","skills":"A list of skills the user has self-listed on their profile (e.g., 'Product Strategy', 'Data Analysis'). Use to answer questions like 'What are [user]'s skills?', 'Who on the team has experience with X?', or to aggregate skills across a group. Returns the following fields: {\"id\":\"The skill's internal identifier\",\"title\":\"The name of the skill (e.g., 'Product Strategy', 'Roadmapping', 'Data Analysis'). Skills are user-listed competencies on their profile, useful for answering questions like 'What are [user]'s skills?' or 'Who has experience with [skill]?'.\",\"__typename\":\"The type of the object (always 'Skill')\"}","hashtags":"The user's interests — hobbies, passions, or out-of-work topics they have self-tagged on their profile. Render inline as small chips beneath the bio in the UI. When phrasing responses, always refer to these as the user's \"interests\". Use to answer 'What are [user]'s interests?', 'Who else is into [topic]?', or to find shared interests between users. When answering broad interest questions, also consider the user's bio — interests may be described in prose there. Returns the following fields: {\"id\":\"Internal identifier for this interest record\",\"title\":\"The interest term, without any leading '#' (e.g., 'golf', 'travel', 'cycling'). These are hobbies, passions, or out-of-work topics the user has tagged themselves with. The profile UI renders them as small inline chips beneath the user's bio (no section label). When phrasing responses, refer to these as the user's \\\"interests\\\". Useful for questions like 'What are [user]'s interests?', 'Who else is into [topic]?', or finding shared interests between users. Bio text may also describe interests in prose — consider both this structured list and the bio when answering interest questions.\",\"__typename\":\"The type of the object (always 'Interest')\"}","user_roles":"The user's role history at the company — past and current job titles with their start and end dates. Surfaced on the profile UI as the \"Role history\" section; the current role is labeled \"Present\" rather than showing an end date. Phrase responses using \"role history\". Use to answer 'What roles has [user] held?', 'When did [user] become X?', or 'Who has been here since before \u003cyear\u003e?'. Returns the following fields: {\"id\":\"The role record's internal identifier\",\"title\":\"The job title held during this role (e.g., \\\"VP of Product\\\", \\\"Senior Engineer\\\")\",\"start_date\":\"The date the user started this role, formatted as YYYY-MM-DD\",\"end_date\":\"The date the user ended this role, formatted as YYYY-MM-DD. Returns nil for the user's current role (see is_current).\",\"is_current\":\"True for the role the user holds today; false for past roles in their history. The profile UI labels the current role as \\\"Present\\\" — mirror that phrasing in responses.\",\"__typename\":\"The type of the object (always 'UserRole')\"}","abilities":"The permissions/capabilities the current user has for this user. Includes 'update' (fields that can be updated) and 'delete' (whether the user can be deleted).","permission":"The user's permission level in Trainual. Internal identifier — never show the raw value to users. When narrating, render 'general' as \"General\", 'contributor' as \"Contributor\", 'author' as \"Author\", 'admin' as \"Admin\", 'billing_admin' as \"Billing Admin\". Capabilities are cumulative (General \u003c Contributor \u003c Author \u003c Admin \u003c Billing Admin). Use to answer \"What is [user]'s permission level?\", \"Is [user] an admin?\", or \"Who can create/assign content?\"."}
fetch_users
Retrieves praise and private feedback records the user is entitled to see, with the raw feedback text, participants, visibility, and timestamps. Read-only. Domain: - Public praise: positive recognition visible to the whole account. One or many recipients. - Private feedback: exactly one recipient, with a visibility tier: 'private' (author + recipient), 'private_plus_manager' (author + recipient + recipient's manager), or 'manager_only' (author + recipient's manager — the recipient cannot see it and it never appears in their own "received" results — EXCEPT for users with account-wide performance access (billing admins and admins with full performance access), who see all records including manager_only feedback about themselves). - Entitlement is enforced per record for the requesting user; results may legitimately be empty for records other users can see. - Sentiment and themes are NOT stored. Retrieve the records and infer them from the text. - People-feedback ONLY: praise and private feedback exchanged between people. NOT reports of problems with training content — content feedback is a training-content concept and is not retrievable through this tool; say so rather than reporting that none exists. Also NOT a manager's private observations about a person (visible only to the author who wrote them) — those are fetch_performance_notes. Common use cases: - "Show me feedback I've received" → relationship: 'received' - "Show me public praise I've given" → relationship: 'given', feedback_type: 'praise' - "Show me feedback Taylor has given Dani" → author_ids + recipient_ids (resolve names first) - "What are the feedback trends for my team this year?" → recipient_ids + created_after, then synthesize from the returned text FILTERS (all optional, combined with AND): - ids: Fetch specific feedback records by ID directly, e.g. a feedback_id returned from fetch_feedback_requests. Entitlement is still enforced — an ID you're not entitled to see is silently excluded. - feedback_type: 'praise' (public recognition) or 'private_feedback' (the private tiers). Deterministic — praise returns exactly the public records. OMIT feedback_type unless the user distinguishes praise from private/constructive feedback; plain "feedback" means both. - relationship: the requesting user's OWN relationship to the feedback — 'given' (they authored), 'received' (they are a recipient), 'involving' (either). Omit for no relationship constraint (e.g. company-wide questions). - author_ids / recipient_ids: filter by who gave / who received. Use fetch_users and fetch_groups FIRST to resolve names, groups, or "team" references to user IDs. For "my team": a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. For SOMEONE ELSE's received feedback ("what feedback has Dani received?"), pass recipient_ids ONLY and OMIT relationship — 'received' always means received BY THE REQUESTING USER, so combining relationship: 'received' with recipient_ids for another person demands records that are both; the tool returns an error if you do (symmetric for relationship: 'given' with author_ids). - visibility: explicit visibility tiers to include. - created_after / created_before: ISO 8601 datetimes. Any window works (last month, last 2 years). Do NOT pass either unless the user asks about a time period — an unqualified question ("praise I've given", "summarize my feedback") means ALL TIME; adding your own window silently hides older records the user asked for. - query: a single search term matched against the feedback text and participant names. PAGINATION: results are newest-first. If has_more is true, call again with cursor: next_cursor until has_more is false — retrieve ALL pages before running any analysis or synthesis, otherwise your answer is based on a partial dataset. total_count is the full entitled count for the current filters. A cursor is only valid for the SAME filters it was returned from — an invalid or mismatched cursor returns an error telling you to retry without it (omit cursor to restart from the first page). Returns {"feedback": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}. Each record: {"id":"The feedback record's internal identifier","feedback_type":"'praise' (public recognition, visible to the whole account) or 'private_feedback' (constructive or positive feedback with restricted visibility)","visibility":"Who can see this record: 'public' (everyone), 'private' (author + recipient), 'private_plus_manager' (author + recipient + recipient's manager), 'manager_only' (author + recipient's manager; hidden from the recipient unless they hold account-wide performance access)","text":"The feedback message as plain text. Sentiment/themes are NOT stored — infer them from this text.","author":"The user who gave the feedback. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","recipients":"The users this feedback is about. Praise may have many recipients; private feedback has exactly one. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","in_response_to_request_id":"The feedback request ID this record fulfills, or null if given unprompted. The request itself is only retrievable by its sender or invited responders (via fetch_feedback_requests).","created_at":"When the feedback was given (ISO 8601)","result_card":"Not available for feedback (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the Feedback page in the Trainual web app","__typename":"The type of the object (always 'PerformanceFeedback')"}
fetch_feedback
Read-only. Retrieves responsibility information — names, descriptions, and (optionally) assigned groups and users — by ID(s) or search terms. Domain: - Responsibilities can be assigned to individual users OR groups. When assigned to a GROUP, all members inherit it; when assigned to a USER, only that user has it. A user can hold responsibilities both directly and through group membership. NOT for "What are [person]'s responsibilities?" — this tool has no person filter (ids and queries only). Use fetch_users with include: responsibilities for a named person, or call this tool unfiltered with include: ['effective_users'] and find the person in the results. Common use cases: - "Who is responsible for [X]?" — search for the responsibility, then request include: ['effective_users'] to list the actual people responsible (it expands group members, not just the assigned groups; responsibility_assignees does not). - Get all responsibilities (no parameters), or by ID, or by search term. Parameter Usage: - No parameters: Returns ALL responsibilities in the account - ids only: Returns responsibilities matching the specified IDs - queries only: Returns responsibilities matching the search terms (name or description) - ids AND queries: Returns the INTERSECTION - only responsibilities that match BOTH the IDs AND the search terms - Multiple search terms can be provided so that multiple variations can be matched **Optional includes**: • responsibility_assignees - Users and groups directly assigned to this responsibility • effective_users - All individuals responsible (direct user assignees plus members of assigned groups). Use to answer "Who is responsible for [X]?" with actual people. Returns the following fields: {"id":"The responsibility's internal identifier","name":"The name of the responsibility. This is the primary way users identify responsibilities.\n\nA responsibility is a task or role that users are expected to perform. Responsibilities can be assigned to both\nindividual users AND groups. When assigned to a group, all members of that group inherit the responsibility.","description":"A brief description of what this responsibility entails, including any relevant context about the work or expectations.","responsibility_assignees":"Array of all assignees records showing how this responsibility is assigned to users and groups with the following fields: {\"id\":\"The assigned responsibility's internal identifier\",\"type\":\"The type of entity this responsibility is assigned to (either 'User' or 'Group')\",\"assigned_to\":\"The user or group to which this responsibility is assigned. User fields: {\\\"id\\\":\\\"The user's internal identifier\\\",\\\"name\\\":\\\"The user's full name\\\",\\\"job_title\\\":\\\"The user's job title\\\",\\\"avatar\\\":\\\"URL to the user's avatar image\\\",\\\"result_card\\\":\\\"A string used for client-side navigation\\\",\\\"citation\\\":\\\"A string used to identify the record in citations\\\",\\\"web_url\\\":\\\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'User')\\\"}, Group fields: {\\\"id\\\":\\\"The group's internal identifier\\\",\\\"name\\\":\\\"The name of the group. This is primary way that the UI and users identify the group.\\\\nIMPORTANT: Groups with name 'Everyone' are special system groups that automatically contain all users in the account.\\\\nThese groups cannot be deleted and their membership cannot be manually modified (users are automatically added/removed).\\\",\\\"description\\\":\\\"A brief description of the group\\\",\\\"kind\\\":\\\"The type of group, such as role, team, department, location, other\\\",\\\"web_url\\\":\\\"Absolute URL to the group page in the Trainual web app (nil when account context is unavailable)\\\",\\\"__typename\\\":\\\"The type of the object (always 'Group')\\\"}\",\"assigned_at\":\"The date/time this responsibility was assigned (i.e. when the user or group gained it), formatted as ISO 8601\"}","effective_users":"All individuals responsible for this — the direct user assignees plus the members of any assigned groups, deduplicated. Use to answer \"who is responsible for [X]?\" with the actual people (it expands group members), rather than listing the assigned groups. Returns the following fields: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}"}
fetch_responsibilities
Retrieves per-person participation rows for performance review cycles the user is entitled to see: WHO is being reviewed, WHO their effective reviewer is (with the reviewer's relationship to them), and each person's progress. Read-only; never returns review answers or results content — use fetch_review_responses for what people wrote, rated, or selected. Use fetch_review_cycles for the cycle object itself (questions, settings, rollups); chain via review_cycle_ids. Domain: - Each row is one person in one cycle. The reviewer defaults to the person's org-chart manager but can be a one-off designated reviewer for the cycle, or unassigned. - reviewer_relationship powers caveats — when answering who-reviews-whom, ALWAYS state the caveat: 'designated_non_manager' → the reviewer is NOT the participant's manager, say so explicitly; 'unassigned' + participant_has_manager false → the person has no manager set in Trainual. - Progress: self_review_status and downward_review_status are 'not_started' / 'in_progress' / 'submitted' (null when the cycle doesn't include that review type); workflow_stage is the overall stage ('to_write' → 'summary_pending' → 'delivered') and ignores the self-review; results_status says whether results were shared. These stage/status names may change — read them from each response rather than hardcoding them elsewhere. - Entitlement is enforced per record; results may legitimately be empty. - An EMPTY result for a filtered call means no one matches those filters — answer "none". NEVER answer from an earlier, differently-filtered call's results instead. Common use cases: - "Who am I reviewing this cycle?" → reviewer_ids: [current user] (+ cycle_status: ["active"]) - "Who is Dani's reviewer?" → participant_ids: [Dani's id]; read reviewer + relationship - "Which of my reports haven't done their self-review?" → reviewer_ids: [current user], self_review_status: ["not_started","in_progress"] - "Do any participants not have a reviewer set?" → review_cycle_ids: [cycle], then check reviewer_relationship == "unassigned" - "Everyone Taylor is reviewing" → reviewer_ids: [Taylor's id] a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. FILTERS (all optional, AND semantics): - ids: direct row lookup. Unentitled ids are silently excluded. - review_cycle_ids: rows for specific cycles (from fetch_review_cycles). - participant_ids: whose participation (the people being reviewed). - reviewer_ids: rows where these users are the assigned reviewer. - group_ids: participants belonging to these groups (resolve via fetch_groups). - cycle_status: any of 'draft', 'active', 'completed' — the cycle's status. - workflow_stage: any of 'to_write', 'summary_pending', 'delivered'. - self_review_status / downward_review_status: any of 'not_started', 'in_progress', 'submitted'. Rows where the cycle lacks that review type never match. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor (same filters) until has_more is false. Retrieve ALL pages before summarizing. Returns {"review_cycle_participants": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}, plus a "hint" key when a progress-status filter was used without any person scoping. Each record: {"id":"The participation row's internal identifier","review_cycle":"The cycle this row belongs to. Structure: {\"id\":\"The review cycle's internal identifier (use with fetch_review_cycles for full detail)\",\"title\":\"The cycle name\",\"status\":\"'draft', 'active', or 'completed'\",\"due_at\":\"Optional submission deadline (ISO 8601), or null\"}","participant":"The person being reviewed. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","reviewer":"The effective reviewer for this cycle (defaults to the participant's manager, overridable per cycle), or null when unassigned. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","reviewer_relationship":"'manager' (reviewer is the participant's org-chart manager), 'designated_non_manager' (a one-off reviewer for this cycle — caveat answers accordingly), or 'unassigned' (no reviewer resolved)","participant_has_manager":"Whether the participant has a manager set in the org chart. When false and unassigned, say so — e.g. \"they don't have a manager set in Trainual\".","self_review_status":"'not_started', 'in_progress', or 'submitted' — null when the cycle has no self-review","downward_review_status":"'not_started', 'in_progress', or 'submitted' — null when the cycle's downward mode is summary_only","results_status":"'not_shared', 'shared', or 'accepted' — whether review results were delivered to the participant","workflow_stage":"Overall stage: 'to_write' (downward review not submitted), 'summary_pending' (downward review submitted but results NOT yet shared — the reviewer still owes the summary and the share, so this needs action and is not complete), 'delivered' (results shared — the only finished stage). The self-review does not affect the stage: read self_review_status for that. Current product wording, may be refined.","result_card":"Not available for review participants (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the cycle's participants page","__typename":"The type of the object (always 'PerformanceReviewCycleParticipant')"}
fetch_review_cycle_participants
Retrieves performance review cycles the user is entitled to see — the cycle SETUP and PROGRESS objects (window, settings, question definitions, participant progress rollup). Read-only. Use fetch_review_cycle_participants for per-person rows (who reviews whom, individual progress). Review cycles are the formal manager/self review process — NOT ad-hoc praise or private feedback (fetch_feedback) and NOT growth areas (fetch_growth_areas). Domain: - A cycle is created and run by an owner (usually an admin/manager). Status: 'draft' (being set up, not launched), 'active' (launched), 'completed'. Cycles are persistent; a person can be in many cycles over time. - review_window is the retrospective lookback ('last_90_days'/'last_6_months'/'last_year' or 'custom' with period dates). - Cycles contain a downward review (reviewer evaluates the participant) and, when self_review is true, a self-review. downward_review_mode 'summary_only' means no downward questions. Question definitions are returned in FULL — kind, prompt, optional flag, rating_scale with its low/high endpoint labels and rating_scale_direction, rating_step_labels (numeric_rating only — one label per scale point), and for selection kinds the choice options; relay the complete config, not just the prompt text. Answers are NOT returned — use fetch_review_responses for review content. - participant_summary is a progress rollup over the cycle's participants: to_write (downward review not yet submitted), summary_pending (downward review in but results not yet shared), delivered (results shared). The self-review does not affect these buckets. This stage vocabulary may change — read it from each response rather than hardcoding these names elsewhere. - Entitlement is enforced per record; results may legitimately be empty. Common use cases: - "What review cycles have I created?" → owner_ids: [current user] - "Show me my active review cycles" → owner_ids: [current user], status: ["active"] - "What's the completion status of cycle X?" → ids/query, read participant_summary - "Show me all of Dani's review cycles" → participant_ids: [Dani's id] - "What questions are in the self-review?" → read questions where review_type = "self" a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. FILTERS (all optional, AND semantics): - ids: direct record lookup. Unentitled ids are silently excluded. - status: any of 'draft', 'active', 'completed'. Omit for all. - review_window: any of 'last_90_days', 'last_6_months', 'last_year', 'custom'. - owner_ids: who runs the cycle. Resolve names via fetch_users first. - participant_ids: cycles where these users are being reviewed. - reviewer_ids: cycles where these users are assigned as reviewers. - group_ids: cycles with participants from these groups (resolve via fetch_groups). - due_after / due_before: ISO 8601 — submission deadline window. - launched_after / launched_before: ISO 8601 — launch date window. - query: case-insensitive title match. Review cycle IDs for later calls (e.g. fetch_review_cycle_participants, fetch_review_responses) come ONLY from this tool's own results — never derived from a title or a year mentioned in one. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor (same filters — changing filters invalidates the cursor) until has_more is false. Retrieve ALL pages before summarizing. total_count is the full entitled count. Company-wide or historical listings ("every cycle", "across the company") are fully supported — there is no result cap; page through via cursor/has_more until every entitled record is retrieved. Volume is never a reason to decline or to ask the user to narrow the request. Returns {"review_cycles": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}, plus a "hint" key when a title query matched nothing. Each record: {"id":"The review cycle's internal identifier","title":"The cycle name","status":"'draft' (not yet launched), 'active' (launched, in progress), or 'completed'","review_window":"The retrospective lookback the cycle covers: 'last_90_days', 'last_6_months', 'last_year', or 'custom'. Relative windows have NO concrete calendar dates — report them as-is (e.g. \"the last 6 months\"); NEVER convert a relative window to specific dates.","period_starts_on":"Start date — ONLY set when review_window is 'custom', null otherwise. Null means no concrete start date exists; do not invent one.","period_ends_on":"End date — ONLY set when review_window is 'custom', null otherwise. Null means no concrete end date exists; do not invent one.","due_at":"Optional submission deadline (ISO 8601), or null","activated_at":"When the cycle was launched (ISO 8601), or null for drafts","completed_at":"When the cycle was ended (ISO 8601), or null","owner":"Who runs the cycle. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","creator":"Who originally created it; may differ from owner. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","self_review":"Whether the cycle includes a self-review. When false, participants have no self-review and self_review_status is null.","downward_review_mode":"'review_and_summary', 'review_only', or 'summary_only'. In 'summary_only' there are no downward questions and downward_review_status is null.","share_reviewer_responses":"Whether reviewees see their reviewer's full responses (true) or only a curated summary (false)","questions":"Question DEFINITIONS only — answers are never included. Each: {id, review_type (downward|self), kind (open_ended|single_selection|multiple_selection|numeric_rating|binary_rating), prompt, optional, rating_scale (2-10 or null), rating_low_label, rating_high_label, rating_step_labels (numeric_rating only — one label per scale point, in scale order, blank where unlabeled; [] for other kinds), rating_scale_direction (low_worst|low_best — which end reads as negative), options (choice texts)}","participant_summary":"Progress rollup for the participants the requesting user is entitled to know exist: {total, to_write (no downward review submitted yet), summary_pending (downward review submitted but results NOT yet shared with the reviewee — the reviewer still owes the summary and the share, so this needs action and is not complete), delivered (results shared — the only finished stage)}. The self-review does not affect these buckets.","result_card":"Not available for review cycles (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the cycle's page","__typename":"The type of the object (always 'PerformanceReviewCycle')"}
fetch_review_cycles
Retrieves the CONTENT of performance reviews the user is entitled to see: each person's self-review and their reviewer's downward review, with every answer returned alongside its question context (prompt, type, rating scale/labels, choice options). Read-only. Use fetch_review_cycle_participants for status-only queries (who has/hasn't finished — no content needed); fetch_review_cycles for cycle setup, question definitions, and progress rollups. Domain: - Each record is one response: 'self' (the participant reflecting on their own work) or 'downward' (the reviewer evaluating the participant). A participant has at most one of each per cycle. - answers list EVERY question on that side of the review. answered: false on a 'submitted' or 'in_progress' response means that (optional) question was left blank; a 'not_started' response has no answers at all. Report blanks as "left unanswered", not as missing data. - A rating answer's raw number means nothing on its own — always relay it together with rating_scale and rating_step_labels (the scale's ends are the first and last entries), and surface any attached written explanation (in the answer's text) alongside it; never report a bare number. State the qualitative label text itself, not just the number pair — e.g. "4 out of 5, toward 'Always delivers'", not just "4/5" or "4 out of 5". Blank step labels are normal — report the scale itself when none are set. - Drafts: only the response's own author ever sees draft content. Everyone else sees submitted responses only, per the product's sharing rules — a reviewee sees their downward review only after results are shared. An empty or smaller- than-expected result is the entitlement working; report what IS returned and note that some reviews may not be visible to the requesting user. - Cross-cycle by default: omit review_cycle_ids to get a person's reviews across cycles over time (historical and trend questions). - Person-named questions REQUIRE person scoping: resolve the names, then pass the ids in participant_user_ids (or reviewer_user_ids for reviews they wrote). A submitted_after/before window is NOT a substitute — a window alone pulls every entitled review in the account. - An EMPTY result for a filtered call means no entitled responses match — answer "none"/"not visible to you". NEVER answer from a differently-filtered call. Common use cases: - "What did I write in my self-review for the H1 cycle?" → participant_user_ids: [current user], review_type: ["self"], review_cycle_ids: [cycle] - "Have I finished my self-review? What's left?" → participant_user_ids: [current user], review_type: ["self"] — read status + answered flags - "Show me what I wrote about Dani" → reviewer_user_ids: [current user], participant_user_ids: [Dani's id], review_type: ["downward"] - "Which of my downward reviews are unwritten? Show me where I left off" → reviewer_user_ids: [current user], review_type: ["downward"], status: ["not_started","in_progress"] — content queries about unfinished reviews. For the COUNT or list of who owes what (no content needed), use fetch_review_cycle_participants instead. - "What did Dani say in her self-review last cycle?" → participant_user_ids: [Dani's id], review_type: ["self"] — pick the cycle from each record - "Show me Dani's completed reviews over the past two years" → participant_user_ids: [Dani's id], status: ["submitted"] — no cycle filter needed for history - Themes/sentiment/comparisons: retrieve the entitled records and synthesize yourself — the tool returns raw content only. a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. FILTERS (all optional, AND semantics): - ids: direct response lookup. Unentitled ids are silently excluded. - review_cycle_ids: responses in specific cycles (ids from fetch_review_cycles). - participant_user_ids: user ids of the people being reviewed. - reviewer_user_ids: user ids of assigned reviewers — combine with review_type: ["downward"] for "reviews X wrote". - group_ids: participants belonging to these groups (resolve via fetch_groups). - review_type: any of 'self', 'downward'. - status: any of 'not_started', 'in_progress', 'submitted'. - submitted_after / submitted_before: ISO 8601 bounds on the submission time. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor (same filters) until has_more is false. Retrieve ALL pages before summarizing. Returns {"review_responses": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}. Each record: {"id":"The review response's internal identifier","review_type":"'self' (the participant reflecting on their own work) or 'downward' (the reviewer evaluating the participant)","status":"'not_started', 'in_progress' (draft with at least one answer), or 'submitted'","submitted_at":"When the response was submitted (ISO 8601), or null while drafted — compare against the cycle due_at for deadline questions","review_cycle":"The cycle this response belongs to. Structure: {\"id\":\"The review cycle's internal identifier (use with fetch_review_cycles for full detail)\",\"title\":\"The cycle name\",\"status\":\"'draft', 'active', or 'completed'\",\"due_at\":\"Optional submission deadline (ISO 8601), or null\"}","participant":"The person being reviewed. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","reviewer":"Who wrote this downward response, or null on a self response and on legacy rows with no recorded author. Not re-pointed if the participant's reviewer changes later. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","answers":"One entry per question on this side of the review, in question order. Each: {question_id, prompt, kind, optional, answered, text, rating_value, rating_scale, rating_step_labels, rating_scale_direction, selected_options}. answered false with status 'submitted' or 'in_progress' means the (optional) question was left blank — distinct from a 'not_started' response where nothing was answered. text carries the open_ended answer, or the optional written explanation accompanying a rating. kind 'binary_rating': rating_value 1 = yes, 2 = no. kind 'numeric_rating': rating_value is on a 1..rating_scale scale; rating_step_labels label each point (blank entries are unlabeled); rating_scale_direction says whether low is worst or best. selected_options is the chosen option text for selection kinds.","result_card":"Not available for review responses (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the review cycle's page","__typename":"The type of the object (always 'PerformanceReviewResponse')"}
fetch_review_responses
Read-only. Retrieves scorecards the user has permission to see, by UUID(s) or search queries, with optional related data like owner, watchers, metric rows (with time-period values), and linked meetings. Owner, watcher (which may be a group), and linked-meeting fields are summary data only — call fetch_users, fetch_groups, or fetch_meetings with their IDs for full details. Use this tool when you need information about scorecards including metrics, targets, performance trends, thresholds, and scorecard ownership. Domain: - Scorecards track recurring measurable targets on a rolling cadence — distinct from Goals (one-time outcome, end state). - Goals and Scorecards are separate stores; neither tool returns the other's data. A metric/target/trend question that doesn't say "goal" or "scorecard" can be tracked in either product, so both this tool and fetch_goals must be queried to cover it. - Owner: one per scorecard. - Watchers: users or groups who can view the scorecard. - Scorecard Rows: individual metrics with name, target value, and unit. - Row Types: Manual Entry (user inputs), Link to Goal (auto-populated from a goal's metric), Follow Scorecard Row (synced from another scorecard's row). - Cadence: Daily, Weekly, or Monthly. - Period Values: recorded value per time period. Empty periods are unfilled. - Thresholds: optional color-coded ranges (red/yellow/green) indicating on-target, at-risk, or off-track. - Company Visibility: scorecards can optionally be made visible to the entire company. - Visibility: owners, watchers, attendees of linked meetings, direct reports. Billing Admins see all. Common use cases: - "What scorecards do I have access to?" - "What metrics am I being tracked on?" - "Which scorecard items are below target this week?" - "What's my trend over the past month on [scorecard name]?" - "Did I hit my target for [metric name] this week?" - "What meetings is [scorecard name] linked to?" - "Who owns [scorecard name]?" FILTERS: You can provide ids, queries, owner_ids, cadence, meeting_ids, or combinations: - ids only: Fetch specific scorecards by UUID - queries only: Search scorecards by title or by metric/row name (multiple queries use OR logic — matches ANY term) - Both ids AND queries: First filters to the provided UUIDs, then searches within that set - owner_ids: Filter scorecards by owner user IDs. Use fetch_users first to resolve names to IDs. - cadence: Filter by scorecard cadence (daily, weekly, monthly) - meeting_ids: Filter scorecards linked to specific meetings - Neither: Returns all scorecards visible to the current user The queries parameter searches the following fields: scorecard title AND metric/row name. A query that matches a metric/row name (e.g. "call attendance") resolves the scorecard that contains that row, and the matched row's metric data (target, direction, thresholds, period values) is returned automatically. If a title search returns nothing, retry with partial words, singular/plural variants, and related terms from the request before concluding the scorecard doesn't exist (e.g. "the sales call scorecard" → queries: ["sales", "call"]). Treat non-exact keyword or row-name matches as candidates, not a confirmed match. **Optional includes**: • owner — The user who owns this scorecard • watchers — Users and groups with visibility to this scorecard • scorecard_rows — Metric rows with targets, thresholds, row type, and pre-computed period values (last 12 periods based on cadence). Each period has a label, date range, and resolved value (snapshot: last value in range, delta: cumulative sum). • meetings — Meetings linked to this scorecard Returns the following fields: {"id":"The scorecard's UUID identifier","title":"The name of the scorecard","cadence":"How often the scorecard repeats: 'daily', 'weekly', or 'monthly'","week_ends_on":"The day the week ends on (0=Sunday through 6=Saturday). Only present for weekly scorecards.","company_visible":"Whether the scorecard is visible to the entire company","created_at":"When the scorecard was created (ISO 8601)","updated_at":"When the scorecard was last updated (ISO 8601)","result_card":"Pipe-delimited string: 'OperationsScorecard|{uuid}|{title}'","web_url":"Absolute URL to the scorecard page in the Trainual web app (nil when account context is unavailable)","citation":"A string used to identify the record in citations","__typename":"The type of the object (always 'OperationsScorecard')"}
fetch_scorecards
Read-only. Retrieves software, tool, and equipment details including linked training content, documentation, owners, categories, and which groups have access. Domain: - Covers software, tools, AND equipment — anything with a name, category, owner(s), and optionally linked training content or documentation (resource_contents). - Ownership and group access are separate: a software entry has owner(s) (individual users, via `owners`) and separately can be granted to groups (via `groups`) — a group's members don't become owners. This tool has no group_id filter — it can only show which groups a given software is granted to (include: groups), not list software by group. NOT for: searching INSIDE a linked document's or training content's text — use search_content. NOT for a person-first "what tools does [person] use?" lookup — fetch_users with include: software returns only software the person OWNS; a full "what can this person access" answer also needs their groups' software (fetch_users include: groups, then fetch_groups include: software for each, or read the `groups` field on the software entries here). Common use cases: - "How do I learn GitHub?" / "Where's the training for Slack?" - "Who owns Asana?" - "Which tools are missing content?" - "What's the URL for [tool]?" - "What tools are used by the Marketing team?" — this tool has no group filter; use fetch_groups(queries: ['Marketing'], include: ['software']) instead. - "What training exists for [tool]?" (returns linked content and docs) FILTERS: You can provide ids, queries, both, or neither: - ids only: Fetch specific software by ID - queries only: Search software by name, description, or category (multiple queries use OR logic - matches ANY term) - Both ids AND queries: First filters to the provided IDs, then searches within that filtered set (INTERSECTION: must match at least one query term AND be in the ids list) - Neither: Returns all accessible software The queries parameter searches the following fields: software name, description, category, and attached content (title/url) **Optional includes**: • owners - Users who own/manage this software • groups - Groups that have access to this software Returns the following fields: {"id":"The software's internal identifier","name":"The name of the software, tool, equipment, or vendor (e.g., \"Slack\", \"Zoom\", \"MacBook Pro\"). This is how users refer to the software in conversations. Software can be assigned in two ways: (1) Direct assignment to USERS (owners): Specific users are designated as owners of the software. (2) Assignment to GROUPS: All members of the group have access to/use the software. To answer queries about software: \"What software does [user] use?\" check user.software (shows direct ownership) PLUS any software assigned to groups the user belongs to. \"What software is assigned to [group]?\" check group.software (all members have access). \"Who uses [software]?\" check both direct owners AND groups assigned to it. Note on \"use\" vs \"own\": A user \"owns\" software if directly assigned as an owner. A user \"uses\" or \"has access to\" software if assigned via group membership.","description":"A brief description of what this software is, what it does, or how it's used in the organization. May include setup instructions, access details, or usage guidelines.","logo":"URL to the software or vendor logo image (if available)","url":"URL to the software website, documentation, login page, or vendor information","category":"The category of the software (e.g., 'Productivity', 'Communication', 'Development', 'Design'). Helps organize and filter software by type.","resource_contents":"Array of attached content for this software (links and connected items). Structure: {\"id\":\"The resource content's internal identifier\",\"title\":\"The title of the attached content (falls back to the contentable title when present)\",\"url\":\"The URL for the attached content\",\"contentable_type\":\"The type of the contentable record associated with this attachment (if any)\",\"contentable_id\":\"The id of the contentable record associated with this attachment (if any)\",\"curriculum_type\":\"The curriculum type for this attachment (if any)\",\"citation\":\"The string used to identify the record in citations\",\"result_card\":\"The string used for client-side navigation\",\"__typename\":\"The type of the object (always 'ResourceContent')\"}","owners":"Array of users who are designated as owners/managers of this software","groups":"Array of groups that have access to this software (all group members can use it)","__typename":"The type of the object (always 'Software')"}
fetch_softwares
Read-only. Retrieves update assignments (individual instances of updates assigned to users) the user has permission to see, by ID(s), search queries, or filters, with optional related data like user, responses, and comments. User and template fields are summary data only — call fetch_users or fetch_update_templates with their IDs for full details. IMPORTANT: If the user's query contains the word "update", use this tool or fetch_update_templates FIRST before searching content. Updates are a specific feature, not general content. Domain: - An Update Assignment is a specific instance sent to a user from an Update Template (see fetch_update_templates) with a due date based on the template's cadence. - Status: pending, submitted, or overdue. - Update Response: the user's submission of answers to the template's questions. Use this tool when you need information about update submissions, due dates, responses, or assignment status. Also use this tool for questions about what someone has been working on, team progress, performance reviews, or any question that benefits from knowing what people recently reported. NOT for the full picture alone: "catch me up", "team status", or "how is [person] performing" questions usually also need fetch_goals (goal progress) and fetch_meetings (meeting activity) — this tool alone only covers what people reported in their updates. Common use cases: - "What updates do I need to submit?" - "Who hasn't submitted their update?" - "Show me overdue update assignments" - "What has my team been working on lately?" - "Give me a full picture of how [person] is performing" FILTERS: You can provide ids, queries, update_request_ids, group_id, assigned_to_user_ids, status, due_before, due_after, or combinations: - ids only: Fetch specific assignments by ID - queries only: Search by template title and question text (multiple queries use OR logic) - update_request_ids: Filter assignments for specific templates - group_id: REQUIRED whenever the question is about a team/group/department's updates ("the Brand Marketing team's updates", "what did Engineering report"). Resolve the group with fetch_groups first, then pass its ID here — the server filters to exactly that group's active members and reports coverage, so you never need to copy member IDs yourself. The response echoes the resolved group (with archived_member_count when archived members were excluded from the roster), the assignments, and members_without_assignments: every group member with NO assignment matching the applied filters AND your visibility. Report those members as "no update found for the requested window" (not "did not submit" — an assignment outside your visibility looks the same) and account for each of them explicitly in your answer — never drop a member silently. Cannot be combined with assigned_to_user_ids. If fetch_groups finds no matching group, say you cannot confirm the group's membership — do NOT fall back to an unscoped fetch or a content search. Passing the Everyone group's ID is refused, since Everyone is every active user in the account, not a team — omit group_id for account-wide assignments, or resolve a specific team with fetch_groups instead. - assigned_to_user_ids: Filter assignments for specific NAMED INDIVIDUALS (use fetch_users to resolve names to IDs). For a team/group, use group_id instead — do not pass a hand-built member list, the template's other assignees, or members of related/similarly-named groups. Cannot be combined with group_id (the tool returns an error if both are set). The response echoes users_without_assignments (requested users with no matching assignment) and unresolved_user_ids — account for both in your answer. When the question names NO team or person ("who hasn't submitted the Weekly Standup?"), do not require a scope — filter by template and/or status alone. - status: Filter by assignment status (pending, submitted, overdue, late, on_time) - due_before / due_after: Filter by due date range (ISO 8601 date strings) - submitted_before / submitted_after: Filter by submission date range. Use these when asking about what people submitted during a time period (e.g., "this week"). Prefer over due_before/due_after for questions about responses/submissions rather than deadlines. - Neither: Returns all assignments visible to the current user **CRITICAL — When to use queries vs filters:** The queries parameter searches template title, question text, and response text. It is a SEARCH filter that RESTRICTS results to matching records. Only use queries when searching for a specific template by name (e.g., "Weekly Standup", "Project Review"). Do NOT pass queries for broad retrieval questions like "What did everyone say?", "Catch me up on updates", or "Summarize all updates this week." These questions want ALL data, not a text search. Use status and submitted_after/submitted_before (or due_before/due_after) filters instead, and omit queries entirely so all assignments in scope are returned. **Optional includes**: • user - The assigned user • requested_by - The user who requested this assignment • update_request - The parent update request template • responses - Submitted responses (excludes soft-deleted) • comments - Comments left on this assignment (e.g. follow-ups from managers). Each comment belongs to a specific assignee's submission, not the template, and carries its author in `created_by`. Include `user` and `update_request` alongside `comments` so the assignee and template appear as names rather than bare IDs. Returns the following fields: {"id":"The assignment's internal identifier","due_at":"When the assignment is due (ISO 8601)","submitted_at":"When the assignment was submitted (ISO 8601). Nil if not yet submitted.","submitted":"Whether the assignment has been submitted","overdue":"Whether the assignment is past due and not submitted","late":"Whether the assignment was submitted after the due date","on_time":"Whether the assignment was submitted on or before the due date","update_request_id":"The ID of the parent update request template","user_id":"The ID of the assigned user","created_at":"When the assignment was created (ISO 8601)","updated_at":"When the assignment was last updated (ISO 8601)","result_card":"Not available for update assignments (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the update assignment in the Trainual web app (nil when account context is unavailable)","__typename":"The type of the object (always 'OperationsUpdateRequestAssignment')"}
fetch_update_assignments
Read-only. Retrieves group information — teams, departments, roles, and other groupings of users. By default returns base fields only; use `include` for related resources. Domain: - Groups organize users. Kinds: Role, Team, Department, Location, Other, and the system-managed Everyone (all active users). Everyone can be assigned content and software, but NOT responsibilities. - Content, responsibilities, and software can be assigned directly to groups (as well as to individual users). NOT for content/responsibility/software search: `queries` matches group NAMES and DESCRIPTIONS only. A group will NEVER surface by its assigned responsibilities, software, or content. For "which group/team is responsible for [activity]?", search fetch_responsibilities with include: ['responsibility_assignees'] to see which groups (and users) it's assigned to; use include: ['effective_users'] instead when you need the actual people (it expands group membership into individuals) — do not keyword-search groups for it. Resolving a team/group by name: - A query can match several similarly-named but DISTINCT groups (e.g. "Brand" vs "Branding" vs "Brand Marketing"). For a specific team's membership, use the single exact-name match — never merge members across multiple groups. - "Everyone" is system-managed (every active user), not a real team. It is omitted from keyword matches unless searched by that exact name, and its member roster is returned as a count + note rather than the full list. **Optional includes**: • members - Users in the group (can be large, e.g., "Everyone" group) • managers - Users who manage the group (typically 1-3) • curriculums - Training content assigned to the group • responsibilities - Responsibilities assigned to the group • software - Software/tools assigned to the group • parent - Parent group in hierarchy (if any) • children - Child groups in hierarchy fetch_groups() with no filters returns base data only — fastest, recommended for listings. Non-managers don't see citation, created_at, or updated_at on a group record — a missing field means the user lacks manager/admin permission on that group, not that the data doesn't exist. A group's `software`, `curriculums`, and `responsibilities` keys are absent unless you asked for them in `include` — an absent key means the include was not requested, never that the group has none. For `curriculums` and `software` specifically, the key can also be stripped when requested if the requesting user lacks curriculum/software read permission on that group — either way, never conclude the group has none; when permission is the likelier cause, say the data isn't accessible to you rather than reporting it as absent. Returns the following fields: {"id":"The group's internal identifier","name":"The name of the group. This is primary way that the UI and users identify the group.\nIMPORTANT: Groups with name 'Everyone' are special system groups that automatically contain all users in the account.\nThese groups cannot be deleted and their membership cannot be manually modified (users are automatically added/removed).","description":"A brief description of the group","kind":"The type of group, such as role, team, department, location, other","web_url":"Absolute URL to the group page in the Trainual web app (nil when account context is unavailable)","__typename":"The type of the object (always 'Group')","result_card":"Pipe-delimited string: 'Group|{id}|{name}'","citation":"A string used to identify the record in citations","curriculums":"A list of training content (curriculums) assigned to this group. ALL members of the group are assigned this content and are expected to complete it. Reference this field to find what training content is assigned to a group. Structure: {\"id\":\"The curriculum's internal identifier\",\"title\":\"The title of the curriculum\",\"type\":\"The curriculum type. Can be curriculum (default), checklist, course, survey, flowchart, video, uploaded_file, premium_course\",\"published\":\"Whether the curriculum is published\",\"emoji\":\"The emoji associated with the curriculum\",\"result_card\":\"A string used for client-side navigation\",\"web_url\":\"Absolute URL to the curriculum page in the Trainual web app (nil when account context is unavailable)\",\"citation\":\"Not available for curriculums (always null)\",\"__typename\":\"The type of the object (always 'Curriculum')\"}","members":"A list of users who are members of this group. Reference this field to evaluate to who is \"in the group\", or who is a \"member of a group\", \"belongs to a group\", or \"part of a group\". Only minimal information is provided (id, name, title). Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"} For the system \"Everyone\" group this is not expanded — it returns a single { note, member_count } element, since it contains all active users and is not a real team. If the group has archived members, a trailing { note, member_count } element flags the exclusion — the note gives the archived count and member_count is the active-member count; the roster is complete for active members.","managers":"A list of users who manage this group. Reference this field to evaluate who is \"managing the group\" or who is a \"manager of a group\". Only minimal information is provided (id, name, title). Same structure as 'members'.","responsibilities":"A list of responsibilities assigned to this group. ALL members of the group inherit these responsibilities. Useful for queries like: \"What is everyone in [group] responsible for?\", \"What responsibilities does the [team name] have?\", \"Who is responsible for [responsibility name]?\" (check which groups have it). Structure: {\"id\":\"The responsibility's internal identifier\",\"name\":\"The name of the responsibility. This is the primary way users identify responsibilities.\\n\\nA responsibility is a task or role that users are expected to perform. Responsibilities are assigned to users or groups,\\nand inherit to all members of the group. Useful for queries like: \\\"What is [user] responsible for?\\\",\\n\\\"What responsibilities does the [group name] have?\\\",\\n\\\"Who is responsible for [responsibility name]?\\\" (check which groups have it).\\n\\nIMPORTANT - How Responsibilities Are Assigned:\\nResponsibilities can be assigned to both individual users AND groups.\\nWhen assigned to a GROUP: All members of that group inherit the responsibility.\\nWhen assigned to a USER: Only that specific user has the responsibility.\\n\\nTo answer queries about responsibilities: \\\"What is [user] responsible for?\\\" check user.responsibilities (direct assignments)\\nAND all responsibilities from their groups. \\\"What is everyone in [group] responsible for?\\\" check group.responsibilities\\n(applies to all members). \\\"Who is responsible for X?\\\" search users/groups with that responsibility.\",\"description\":\"A brief description of what this responsibility entails, including any relevant context about the work or expectations.\",\"__typename\":\"The type of the object (always 'Responsibility')\"}","software":"A list of software, tools, applications, equipment, and vendors assigned to this group. ALL members of the group have access to or use these items. Useful for when the users ask about \"tools\", \"software tools\", \"software \u0026 tools\", \"software and tools\", \"tooling\", \"applications\", \"apps\", or similar variations, pertaining to the Group. For example: \"What software does [group] use?\", \"What tools does [group] use?\", \"What software and tools does [group] have access to?\", \"What applications does the [team name] use?\", \"Who has access to [software/tool name]?\" (check which groups are assigned), \"What software tools do remote employees use?\", \"What tooling does [department] need?\" Structure: {\"id\":\"The software's internal identifier\",\"name\":\"The name of the software, tool, equipment, or vendor (e.g., \\\"Slack\\\", \\\"Zoom\\\", \\\"MacBook Pro\\\"). This is how users refer to the software in conversations. Software can be assigned in two ways: (1) Direct assignment to USERS (owners): Specific users are designated as owners of the software. (2) Assignment to GROUPS: All members of the group have access to/use the software. To answer queries about software: \\\"What software does [user] use?\\\" check user.software (shows direct ownership) PLUS any software assigned to groups the user belongs to. \\\"What software is assigned to [group]?\\\" check group.software (all members have access). \\\"Who uses [software]?\\\" check both direct owners AND groups assigned to it. Note on \\\"use\\\" vs \\\"own\\\": A user \\\"owns\\\" software if directly assigned as an owner. A user \\\"uses\\\" or \\\"has access to\\\" software if assigned via group membership.\",\"description\":\"A brief description of what this software is, what it does, or how it's used in the organization. May include setup instructions, access details, or usage guidelines.\",\"logo\":\"URL to the software or vendor logo image (if available)\",\"url\":\"URL to the software website, documentation, login page, or vendor information\",\"category\":\"The category of the software (e.g., 'Productivity', 'Communication', 'Development', 'Design'). Helps organize and filter software by type.\",\"resource_contents\":\"Array of attached content for this software (links and connected items). Structure: {\\\"id\\\":\\\"The resource content's internal identifier\\\",\\\"title\\\":\\\"The title of the attached content (falls back to the contentable title when present)\\\",\\\"url\\\":\\\"The URL for the attached content\\\",\\\"contentable_type\\\":\\\"The type of the contentable record associated with this attachment (if any)\\\",\\\"contentable_id\\\":\\\"The id of the contentable record associated with this attachment (if any)\\\",\\\"curriculum_type\\\":\\\"The curriculum type for this attachment (if any)\\\",\\\"citation\\\":\\\"The string used to identify the record in citations\\\",\\\"result_card\\\":\\\"The string used for client-side navigation\\\",\\\"__typename\\\":\\\"The type of the object (always 'ResourceContent')\\\"}\",\"owners\":\"Array of users who are designated as owners/managers of this software\",\"groups\":\"Array of groups that have access to this software (all group members can use it)\",\"__typename\":\"The type of the object (always 'Software')\"}","parent":"The parent group in the hierarchy (if any), with the following fields: {\"id\":\"The group's internal identifier\",\"name\":\"The name of the group. This is primary way that the UI and users identify the group.\\nIMPORTANT: Groups with name 'Everyone' are special system groups that automatically contain all users in the account.\\nThese groups cannot be deleted and their membership cannot be manually modified (users are automatically added/removed).\",\"description\":\"A brief description of the group\",\"kind\":\"The type of group, such as role, team, department, location, other\",\"web_url\":\"Absolute URL to the group page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'Group')\"}","children":"A list of child groups in the hierarchy (same structure as 'parent').","created_at":"When the group was created","updated_at":"When the group was last updated"}
fetch_groups
Read-only. Get individual assignment and completion status for users and training content. Shows who is assigned what, their progress (0-100%), completion status, and due dates. Use this tool whenever a question mentions a person and their training, assignments, progress, completion, or due dates — this is the only tool that returns per-user assignment details. Domain: - An assignment is a unique link to a user and a curriculum (content); it can be direct or via a group (user → group → content). - Access levels on an assignment: View (can view), Edit (can edit, mark as pending review), Full (can publish, manage access), Owner (one per item — can share publicly, transfer ownership, receives all content feedback). - Completion is tracked per content type and per Subject for each user. Aggregate (average %) is available at the Subject level. Status is derived: NotStarted (0%), Started (1-99%), Completed (100%). - An assignment can be required (must complete) or reference (optional). Both kinds are returned unless you filter: pass required: true for required-only, required: false for reference-only. Common use cases: - What training has [user] completed / in progress? (filters: user_id + status) - Who has completed / is assigned [curriculum]? (filters: curriculum_id + status) - Which users have overdue or upcoming-due assignments? (filters: due_date) - What reference (optional) assignments exist for [user]? (filters: user_id, required: false) Filter Usage: - filters: user_id, curriculum_id, status (NotStarted, Started, Completed), due_date (overdue, upcoming, no_due_date), required (true/false — omit to return both kinds) - Most questions about a person's training, progress, or overdue work mean REQUIRED assignments — pass required: true unless the user specifically asks about optional or reference content; otherwise reference assignments inflate counts the user didn't ask about. Returns the following fields: {"user":"The user assigned to the content (curriculum). Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","curriculum":"The curriculum in which the assignment is based off of. Structure: {\"id\":\"The curriculum's internal identifier\",\"title\":\"The title of the curriculum\",\"type\":\"The curriculum type. Can be curriculum (default), checklist, course, survey, flowchart, video, uploaded_file, premium_course\",\"published\":\"Whether the curriculum is published\",\"emoji\":\"The emoji associated with the curriculum\",\"result_card\":\"A string used for client-side navigation\",\"web_url\":\"Absolute URL to the curriculum page in the Trainual web app (nil when account context is unavailable)\",\"citation\":\"Not available for curriculums (always null)\",\"__typename\":\"The type of the object (always 'Curriculum')\"}","due_date":"The due date from the assignment (ISO 8601 format)","required":"Whether completion of this assignment is required (true) or reference only (false)","content_access":"The user's access level for this curriculum View: allows the user to see content once it's published. This does not include completion data or editing capabilities. Edit: allows the user to edit content and change the status of the content as pending review but not see completions of other users who might be assigned the same content Manage: allows the user to edit a curriculum, and manage access to the curriculum for other users Owner: is responsible for building and updating the content, can also see and manage completions of other users who are assigned the content","assignment_completion":{"overall":"Overall completion percentage (0-100)","elements":[{"title":"The title of the curriculum element","completion":"The completion percentage of the individual element (0-100)"}]},"status":"Derived status: NotStarted (completion = 0), Started (0 \u003c completion \u003c 100), Completed (completion = 100)","completion_date":"The date/time when the assignment was completed (ISO 8601 format)","assigned_date":"The date/time when the assignment was created (ISO 8601 format)","assigner":"The user who assigned this content. Use to answer \"Who assigned me this?\". Returns nil only when the assigner isn't recorded — e.g. system or automated assignments (such as group-based auto-assignment) or legacy data. Content a user assigned to themselves shows that user as the assigner, not nil. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}"}
fetch_curriculum_assignments
Read-only. Find and list training subjects (curriculums) by title, description, or ID. Subjects are top-level containers; fetching a specific Subject (by id or query) returns its full content inventory — every item inside it (Documents/Pages, Checklists, Flowcharts, Videos, Files, Tests). NOT for: searching INSIDE the text of those items (page contents, checklist tasks, video transcripts, flowchart nodes) — use search_content instead. This tool lists what's inside a Subject; search_content finds text within it. Domain: - Content types inside a Subject: Document (multimedia Pages, can require E-Signatures), Video (hosted or uploaded; uploaded videos have timestamped transcripts and can be required-watch), Test (scored knowledge check with pass/fail logic), Flowchart (visual process map with clickable nodes), Checklist (task run-list), File (uploaded file), Premium Course (third-party purchasable course). - Every Subject sits in one of three Categories: Company (story/values), Policies (rules/standards), Processes (step-by-step training). - Discoverability: Discoverable (visible to everyone), Private (assigned only), Requestable (visible, users must request access). - Publication is a status at the Subject or standalone level: Published (live) vs Unpublished. Within a published Subject, items can be Draft (hidden) or Finished (visible). - Templates are pre-built Subject packages (onboarding playbooks, policy packs, SOP bundles) that can be previewed and added to the account; they often include placeholders for customization. - Public Share generates a shareable link so anyone with the link can view a simplified experience of the Subject. - Training Paths curate content completion order with optional delays. - Content Feedback is tracked open → resolved and routed to owners/resolvers. Common use cases: - "Do we have training about [topic]?" (search by title/description) - "What content does [user] own?" / "What do I own / have I written / authored?" (owner_ids — pass the current user's ID for "my content") - "Is [curriculum] verified?" / "What's its completion percentage?" / "Show unverified or low-completion content" - "What content types does Subject X contain?" — fetch it by id or query for its full inventory Users with View permission on a set of curriculums will only see published curriculums. Users with higher permission levels (Manage, Owner) will see all curriculums published or not. If a curriculum is missing attributes, it means the user has lower permissions on that record — not that the data doesn't exist. Returns the following fields: {"id":"The curriculum's internal identifier","title":"The title of the curriculum","description":"The description of the curriculum","type":"The curriculum type. Can be curriculum (default), checklist, course, survey, flowchart, video, uploaded_file, premium_course","emoji":"The emoji associated with the curriculum","published":"Whether the curriculum is published, unpublished curriculums are considered drafts","created_at":"The date the curriculum was created","updated_at":"The date the curriculum was last updated","minutes_to_read":"The estimated time to complete the curriculum in minutes","category":"The category of the curriculum, Can be processes, company, policies.","owner":"The owner's name of the curriculum","completion_percentage":"The completion percentage of the curriculum, an average of all users completion percentage (Conditional based on the user's permissions)","requires_verification":"Whether the curriculum, when published, requires verification (boolean, Conditional based on the user's permissions)","verification_status":"The authoritative verification state: 'verified' (content is currently verified), 'unverified' (verification has lapsed or is pending — treat as NOT verified even if verified_at has a date), or 'not_available' (verification tracking is not enabled for this curriculum — say verification is not enabled rather than that you cannot confirm). (Conditional based on the user's permissions)","verified_at":"The date the curriculum was last verified (Conditional based on the user's permissions)","next_verification_due_at":"The date the current verification lapses and re-verification is due (Conditional based on the user's permissions)","locked_for_edit":"Whether the curriculum is locked for editing (boolean, Conditional based on the user's permissions)","completion_required":"Whether completion is required (boolean, Conditional based on the user's permissions)","expiring_completion":"Whether completion expires (boolean, Conditional based on the user's permissions)","completion_certificates":"Whether completion certificates are enabled (boolean, Conditional based on the user's permissions)","views_count":"The number of views of the curriculum (Conditional based on the user's permissions)","result_card":"A string used for client-side navigation","web_url":"Absolute URL to the curriculum page in the Trainual web app (nil when account context is unavailable)","contents":"The list of content items inside the Subject, each with an id, type, and title. A type of 'course' is a Document made up of Pages. Other types include checklist, flowchart, video, uploaded_file, survey, premium_course, and scorm_package. Use this to answer what content a Subject contains, e.g. \"what content types does this Subject have?\" or \"does it have a flowchart?\".","citation":"Not available for curriculums (always null)","__typename":"The type of the object (always 'Curriculum')"}
fetch_curriculums
Read-only. Retrieves update templates (recurring updates) the user has permission to see, by ID(s) or search queries, with optional related data like owner, watchers, questions, and assignments. Owner and watcher (which may be a group) fields are summary data only — call fetch_users or fetch_groups with their IDs for full details. IMPORTANT: If the user's query contains the word "update", use this tool or fetch_update_assignments FIRST before searching content. Updates are a specific feature, not general content. Domain: - Updates (also called check-ins) are cadence-based questionnaires for structured team status reports. - Update Template: defines questions, cadence (daily/weekly/monthly), and recipients. - Update Assignment: a specific instance sent to a user with a due date (see fetch_update_assignments). - Assignees: users or groups. Group assignment creates individual assignments per member. - Watchers: users or groups who can view submitted responses. Use this tool when you need information about update templates including cadence, questions, ownership, and assignees. Common use cases: - "What update templates exist?" - "What questions are in the weekly update?" - "Who owns the Friday standup update?" - "Show me all updates I own" FILTERS: You can provide ids, queries, owner_ids, watcher_ids, or combinations: - ids only: Fetch specific templates by ID - queries only: Search templates by title and question text (multiple queries use OR logic) - Both ids AND queries: First filters to the provided IDs, then searches within that filtered set - owner_ids: Filter templates by owner user IDs. Use fetch_users first to resolve names to IDs. - watcher_ids: Filter templates watched by specific user IDs. - Neither: Returns all templates visible to the current user **CRITICAL — When to use queries vs no filters:** The queries parameter searches template title, question text, and response text. It is a SEARCH filter that RESTRICTS results to matching records. Only use queries when searching for a specific template by name (e.g., "Weekly Standup", "Project Review"). Do NOT pass queries for broad listing questions like "What templates exist?", "Show me all updates", or "What update templates do I have?" These want ALL data. Omit queries entirely so all templates in scope are returned. **Optional includes**: • created_by - The user who created this template • owner - The template's owner. Always present in the response whether or not you pass this — passing `include: ["owner"]` is harmless and simply pre-loads it server-side. • watchers - Users and groups watching this template • assignees - Users and groups assigned to this template • questions - The questions in this template • assignments - Assignment instances for this template Returns the following fields: {"id":"The update request template's internal identifier","title":"The name of the update request template","cadence":"Human-readable recurrence schedule (e.g. \"Weekly on Mondays\"). Null for one-time updates.","activated_at":"When the template was activated (ISO 8601). Nil means draft.","recurring":"Whether this template has a recurring schedule","created_at":"When the template was created (ISO 8601)","updated_at":"When the template was last updated (ISO 8601)","result_card":"Not available for update requests (always null)","citation":"A string used to identify the record in citations","__typename":"The type of the object (always 'OperationsUpdateRequest')"}
fetch_update_templates
Retrieves the private notes the CURRENT USER has written about people — short (max 500 characters) manager-only observations kept on a person's profile. Read-only. Domain: - Notes are strictly author-private: a note is visible ONLY to the manager who wrote it. This tool NEVER returns notes written by anyone else — not to the person the note is about, not to their manager, not to admins. - Consequences you must respect when answering: - An empty result means the current user has written no matching notes. It says NOTHING about whether other people have notes on the subject — never claim "there are no notes about X", only "you have no notes about X". - Questions like "what notes are there about me?" can only surface notes the current user authored about themselves; other people's notes about them are invisible by design — say so rather than answering "none". - These are people-management notes, NOT feedback. Praise / private feedback someone gave or received is fetch_feedback; reports of problems with training content are neither. - Topics/sentiment are NOT stored. Infer them from the returned content text. Common use cases: - "My notes on Dani" / "what have I noted about Dani?" → user_ids: [Dani] - "Notes I've taken this quarter" → created_after: <quarter start> - "What did I flag about my reports last cycle?" → user_ids: [report ids], created_after/created_before bounding the cycle FILTERS (all optional, AND semantics): - ids: direct record lookup (e.g. for follow-ups). Unentitled ids are silently excluded. - user_ids: the people the notes are ABOUT. Resolve names to user IDs first via fetch_users. For "my team": a people-manager means their direct reports (fetch_users include: children); a group manager means members of the groups they manage. For a user who is BOTH: a brief that covers both scopes is fully specified — fetch both and label results by scope; a brief naming neither warrants one clarifying question — never pick one scope silently. When "team" cannot be resolved at all, ask rather than guess. - created_after / created_before: ISO 8601 — when the note was written. - There is NO text-search parameter — retrieve and infer topics from the returned content text. PAGINATION: newest-first; if has_more is true, call again with cursor: next_cursor (same filters — changing filters invalidates the cursor) until has_more is false. Retrieve ALL pages before synthesizing themes or trends. total_count is the full entitled count for the current filters. Returns {"notes": [...], "total_count": n, "has_more": bool, "next_cursor": str|null}. Each record: {"id":"The note's internal identifier","content":"The note body as plain text (max 500 characters)","subject_user":"The person the note is about. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","author":"The manager who wrote the note — the only person who can ever see it. Structure: {\"id\":\"The user's internal identifier\",\"name\":\"The user's full name\",\"job_title\":\"The user's job title\",\"avatar\":\"URL to the user's avatar image\",\"result_card\":\"A string used for client-side navigation\",\"citation\":\"A string used to identify the record in citations\",\"web_url\":\"Absolute URL to the user profile page in the Trainual web app (nil when account context is unavailable)\",\"__typename\":\"The type of the object (always 'User')\"}","created_at":"When the note was written (ISO 8601)","updated_at":"When the note was last edited (ISO 8601)","result_card":"Not available for notes (always null)","citation":"A string used to identify the record in citations","web_url":"Absolute URL to the subject's profile page (where notes live)","__typename":"The type of the object (always 'PerformanceNote')"}
fetch_performance_notes
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Trainual alternatives on ChatGPT?
As of 2026-09-22, Trainual competes with AgentGrid.io - Shared Drive, AirPrompter, Ambiguous Workspace, Atlas AI Agent, Concept Workspace, GetPaidX LastRevision.pro, Korva Connect, Lawve, Memco Shared Memory, Octopad, Operator Powers, Promptbanken, TEAM 30 — AI Company OS, Tech With Tam, Verde, Work Skill Creator, Workjournal, Xenition in ChatGPT Shared Team AI Workspaces & Skill Libraries, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.