action_items_complete
ChatGPTMark an action item as completed. Once completed, the action item's completion date is set to the current time. To reopen a completed action item, call action_items_update with isCompleted=false. Examples: - "Mark my follow-up call task as done" → provide the actionItemId - "Complete the proposal task" → provide the actionItemId Use action_items_search to find the action item ID first.
action_items_create
ChatGPTCreate a new action item (task, to-do, reminder, or follow-up) that can be assigned to users and associated with contacts. IMPORTANT: The assigneeId parameter and the response fields AssigneeId/CreatorId contain user IDs, not names. - To assign to yourself, omit assigneeId (defaults to current user) or call users_get_self first to get your user ID. - To assign to someone else, call users_search to find their user ID first. Examples: - "Create a task to call John next Friday" → provide description, contactId (from contacts_search), and dueDate - "Remind me to send a proposal by end of week" → provide description and dueDate - "Add an urgent follow-up task for the team lead" → provide description, assigneeId, and priority=High - "Log that I called Sarah yesterday" → provide description and a past dueDate, then call action_items_complete Due dates are normally in the future; a past date is accepted so completed work can be logged after the fact. Set hasDueTime=true only when the user named a specific time; otherwise the due date is treated as all-day. Priority is one of None, Low, Medium, High and defaults to None.
action_items_delete
ChatGPTPermanently delete an action item. Prefer action_items_complete when the work was done; delete only when the item was created by mistake or is no longer relevant. Keep-in-touch reminders cannot be deleted. Use action_items_search to find the action item ID first.
action_items_get
ChatGPTGet a single action item by ID, including its text, due date, priority, assignee, completion state, and referenced contacts. Use action_items_search to find the ID first when you only know what the task is about.
action_items_search
ChatGPTSearch and filter action items using one or more criteria. All specified criteria are combined with AND logic. IMPORTANT: The assignedTo parameter and the response fields AssigneeId/CreatorId contain user IDs, not names. - To search for "my action items", first call users_get_self to get your user ID, then pass it as assignedTo. - To display who an action item is assigned to or created by, call users_get with the AssigneeId or CreatorId. Examples: - "My incomplete action items" → call users_get_self first, then use assignedTo=<your userId>, isCompleted=false - "Action items due this week" → dueDateRange with Before/After bounds - "Completed items assigned to a specific user" → isCompleted=true, assignedTo=<userId> - "Tasks about a contact" → contactId=<contactId from contacts_search> - "High priority tasks mentioning renewal" → priority=High, query="renewal" Priority is one of None, Low, Medium, High. Omit any filter to return all accessible action items. Keep-in-touch reminders (auto-generated from a contact's keep-in-touch cadence) are excluded unless includeKeepInTouch=true. Pagination: returns up to 25 action items per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
action_items_update
ChatGPTUpdate an existing action item. Any combination of description, due date, assignee, priority, and completion state can change in one call; at least one field must be provided. Fields you omit are left unchanged. Examples: - "Move the follow-up task to next Friday" → provide actionItemId and dueDate - "Update the task description to include meeting notes" → provide actionItemId and description - "Hand this task to Sarah" → provide actionItemId and assigneeId (from users_search) - "Make the renewal task high priority" → provide actionItemId and priority=High - "Reopen the task I completed by mistake" → provide actionItemId and isCompleted=false - "Remove the due date" → provide actionItemId and clearDueDate=true Priority is one of None, Low, Medium, High. Past due dates are accepted. Use action_items_search to find the action item ID first.
blogs_cancel
ChatGPTCancel a blog post so it does not publish: an unscheduled draft, a scheduled post, or one held for compliance approval. A post that has already published cannot be taken down through this tool — do that in Levitate. Use blogs_search to find the blog ID.
blogs_create_draft
ChatGPTCreate a DRAFT blog post. The draft is never published by this tool: it stays unscheduled until blogs_schedule is called, and the account's compliance review still applies at that point. Read the levitate://blog-post-creation guide before using this tool. Content — pass the body as HTML (<h2>/<h3> subheadings, <p> paragraphs, <ul>/<ol> lists). Do NOT include the title as an <h1> in the body; the title is a separate field and the site renders it. ALWAYS show the user the title and the body and get their confirmation before creating the draft. Images — optionally attach one main/hero image: upload it with files_create_upload first, then pass its fileId as mainImage. Images inside the body must be added in Levitate.
blogs_get
ChatGPTGet a single blog post by ID, including its status, schedule, slug, compliance state, and full HTML body. Use blogs_search to find blog IDs.
blogs_schedule
ChatGPTSchedule a draft blog post to publish at the given future date, or reschedule one that has not published yet. ALWAYS confirm the exact date with the user before calling this tool — once the date arrives the post is published publicly on the account's blog. Leave confirm unset and the user is prompted to approve the post and date where the client supports it; re-issue the call unchanged with their answer. Pass confirm=true only when they have already agreed to this exact post and date. A response noting the user declined leaves any existing schedule untouched — do not retry it. Constraints: - The date must be at least ~15 minutes in the future, leaving a window to review and cancel. - Immediate publishing is not available through this tool. - On accounts with compliance review enabled, the post is routed through approval instead of being scheduled directly: it lands in Pending status and only publishes once the review is answered. Usually the approval goes to YOU (the caller), or to the account's compliance reviewer address where one is configured. A round raised on a broker-dealer account set up for officer filing is emailed to the firm's compliance officer instead, who submits it to the broker-dealer themselves, and a decline rejects the post; a post already pending with a Levitate approver before the account moved to officer filing stays with them. complianceReviewedByOfficer on the result says which holds this post. The recorded Levitate approver is a fallback for a filing that stalls or whose link expires, not the normal route — so a held post is not guaranteed to publish on its date. You cannot choose the reviewer from here; read the returned note for who holds it. - A Rejected, Cancelled, or Failed post cannot be revived here — handle those in Levitate. Use blogs_cancel to stop a scheduled or pending post before it publishes.
blogs_search
ChatGPTSearch the account's blog posts. Visibility follows the Levitate UI: regular users see their own posts; account admins and account-wide contexts see everyone's. Drafts have no scheduled date, so to list them pass status=Draft (the dateRange is ignored in that case). For every other status the search is by scheduled publish date — pass a dateRange to narrow the window. Bodies are truncated in these results; call blogs_get for a post's full HTML. Pagination: up to 25 posts per page. Pass the response's nextCursor back as cursor to advance; the cursor is opaque.
blogs_update
ChatGPTUpdate the title, body, or main image of a blog post that has not published yet. Only the fields you pass are changed; omitted fields are left as they are (this tool cannot clear the main image — do that in Levitate). Editable only while the post is an unscheduled draft or a scheduled post that has not been through compliance review. A post that a reviewer has already approved or rejected, or that is currently awaiting review, must be edited in Levitate so it can be re-reviewed — this tool refuses it rather than quietly publishing unreviewed changes. Read the post with blogs_get first so you change only what the user asked for.
calendar_provider_get_meeting
ChatGPTFetch full details for a single meeting by provider meeting ID. Returns description, attendees with RSVP status and resolved Levitate contact IDs (when matchable), conferencing URL, and deep links. Use this after calendar_provider_search when you need attendee details or description content beyond the lightweight search result. When the meeting is not found or cannot be fetched, the response has Found=false and Meeting=null.
calendar_provider_search
ChatGPTSearch the user's connected calendar provider (Google Calendar, Microsoft / Outlook, Exchange) for meetings on the authenticated user's calendar. Use keyword for free-text search over meeting summary, description, and location. On providers that don't support native keyword search, keyword is ignored and keywordFilterApplied is false in the response — post-filter results client-side. Filter by contactId (Levitate contact) or attendeeEmail to surface meetings involving a specific person. Without a date range, searches the 30 days before and after today. Examples: - "What's on my calendar this week?" -> dateRange with bounds - "When did I last meet with contact X?" -> contactId=<id>, dateRange.Before=today - "Upcoming meetings about the Q2 renewal" -> keyword="Q2 renewal", dateRange.After=today
companies_get_timeline
ChatGPTReturn a company's activity timeline — notes, meetings, sent emails, phone calls, text messages, deals, and follow-ups — most recent first (up to 100 events). Use after companies_search to understand the history of interactions with a company. This is the company-level counterpart to contacts_get_timeline: it aggregates activity across the company (including its associated contacts), whereas the contact timeline is scoped to a single person. Each event includes its type, timestamp, a human-readable summary, and type-specific details (e.g. email subject and recipients, an action item's due/completion dates).
companies_search
ChatGPTSearch and filter companies by name and tags, with AND/OR/NOT tag logic. All specified filters are combined with AND logic. Pagination: returns up to 25 companies per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages. Examples: - "Companies in the Q2 blitz that haven't been called yet" → allTags=["Q2 Blitz"], excludeTags=["Called"] - "Companies tagged Prospect or Lead" → anyTags=["Prospect", "Lead"] - "Acme companies tagged VIP" → name="Acme", allTags=["VIP"] Omit any filter to return all companies. Combine as many filters as needed.
contacts_add_email
ChatGPTAdd an email address to an existing contact. Get the contactId from contacts_search or contacts_get_profile first. The contact's existing email addresses are always kept — this only adds. Set makePrimary to true when the new address should become the contact's main email (for example, when correcting a wrong primary address; the old one is retained as a secondary). If the email already belongs to a different contact this returns an error rather than creating a conflict.
contacts_add_phone
ChatGPTAdd a phone number to an existing contact. Get the contactId from contacts_search or contacts_get_profile first. The contact's existing phone numbers are always kept — this only adds. Optionally pass a label such as "Cell", "Work", or "Home".
contacts_add_tags
ChatGPTAdd one or more tags to a list of contacts. Use after searching to apply tags to matching contacts. Tag names that don't already exist are created automatically — this is how new tags come into existence, so use this tool to satisfy requests to "create a tag" or "make a new tag group" (there is no separate create-tag tool). Call tags_search first when you intend to reuse an existing tag, to avoid near-duplicates. Examples: - After searching donations, tag all donors with "2025 Gala Donor" - After finding contacts in a specific company, tag them with "Key Account" Returns a summary of how many contacts were successfully tagged and any failures.
contacts_create
ChatGPTCreate a new contact. Supply either both a first and last name, or an email address (at minimum one of those). The company is inferred from the email domain and visibility defaults to your account's default — do not pass them. To tag the contact, pass tags (maximum 10). Ground tag names with tags_search first so you reuse the account's existing tags (e.g. "VIP") instead of creating near-duplicates. Unknown tags are created automatically. If a contact with the given email already exists, this returns an error instead of creating a duplicate — fall back to contacts_search to find the existing contact and contacts_add_tags to tag it.
contacts_get_profile
ChatGPTReturn the full profile for a known contact — identity, key dates, tags, custom properties, and communication metadata.
contacts_get_timeline
ChatGPTReturn a contact's activity timeline — meetings, sent emails, notes, phone calls, text messages, action items, survey responses, e-signature activity (a document sent for signature, signed, declined, voided or expired, with the document title and any reason), and more — most recent first (up to 100 events). Use after contacts_search or contacts_get_profile to understand the history of interactions with a contact. Each event includes its type, timestamp, a human-readable summary, and type-specific details (e.g. email subject and recipients, an action item's due/completion dates).
contacts_search
ChatGPTSearch and filter contacts using one or more criteria. All specified criteria are combined with AND logic. Pagination: returns up to 25 contacts per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages. Examples: - "Contacts in New York not communicated with in the last 6 months" → location="New York", lastCommunicatedBefore=<date 6 months ago> - "VC-tagged contacts at Venture Inc" → tags=["VC"], companyName="Venture Inc" - "All contacts tagged VIP in California" → tags=["VIP"], location="CA" Omit any filter to return all contacts. Combine as many filters as needed.
contacts_update_details
ChatGPTUpdate an existing contact's core details: first name, last name, and/or job title. Get the contactId from contacts_search or contacts_get_profile first. This is a targeted edit — only the fields you pass are changed; every field you omit (or leave blank) is left exactly as it was. This tool cannot clear a field; pass at least one non-blank value. Use it to correct a misspelled name or fill in a job title, not to change email or phone (use contacts_add_email / contacts_add_phone for those).
document_checklist_archive
ChatGPTArchive a checklist item that should not have been on the list. It disappears from lists and summaries (unless includeArchived is requested) and can no longer be matched. To mark a document as not expected this period, prefer document_checklist_update with status Waived.
document_checklist_list
ChatGPTList a contact's expected documents with their status: Open (still owed), Satisfied (a received file matched it, or a person confirmed it), Flagged (a received file probably matches; needs review — see matchedSharedFileId and shared_files_list), or Waived (no longer expected). Further files that match a resolved item outright (a second copy, the next invoice) are in additionalFiles. When the file is a bundle of several documents, matchedDocumentIndex (and additionalFiles[].documentIndex) names the document inside it: its index in that file's classification documents (see shared_files_list). Each file's revision (matchedRevision, additionalFiles[].revision) is Original, Corrected or Amended, or absent when unknown (a file recorded by hand, or one with no recorded revision — check shared_files_list before calling it an original); a corrected or amended copy arriving after the item was resolved puts it back to Flagged, because the figures changed — point the reviewer at that file. A voided form never matches an item. Optionally narrow to one period. Counts by status come back alongside the items, so this is also the per-contact progress check. Archived items are excluded unless includeArchived is true.
document_checklist_seed
ChatGPTRecord the documents a contact is expected to provide for a period (for example the tax year "2025"), typically seeded from what they provided last time. Each item names the document family (matched first), optionally the specific type and the issuer (matched second), and a label people will read. Items that duplicate a non-archived item (same family, type and issuer) are skipped and counted. Pass replaceOpen: true to archive the contact's still-open items for the period first, so the new list replaces the old one; satisfied, flagged and waived items are always kept. Once seeded, inbound files the contact uploads are classified (when the account has file classification on) and matched against these items automatically: a confident match marks the item Satisfied, a weaker or ambiguous one marks it Flagged for review. Use contacts_search to find the contact id.
document_checklist_summary
ChatGPTFor every contact carrying a tag (for example "Tax-Prep"), report where their checklist stands for a period: counts of Open, Satisfied, Flagged and Waived items plus the labels still open and the labels flagged for review. Contacts with hasChecklist: false have never been seeded. This is the daily progress view and the input for reminder outreach: open labels are what to ask for. Pagination: up to 100 contacts per page, sorted by name. Pass nextCursor back as cursor.
document_checklist_update
ChatGPTChange an expected document: fix its label, family, type, issuer or period; add notes; or set its status by hand — Satisfied (confirm a flagged match or record a document received outside Levitate), Waived (no longer expected), Open (reopen; clears any match), or Flagged. Pass matchedSharedFileId to record which shared file satisfied it. At least one field is required. Use document_checklist_list to find the item id.
donations_campaign_search
ChatGPTSearch for donation campaigns by name. Use this tool first when a user asks about donations for a specific campaign by name — call this to resolve the campaign name to an ID, then pass that ID to donations_search. Returns campaigns whose names match the query (partial, case-insensitive). Omit the query to list all campaigns. Pagination: returns up to 10 campaigns per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
donations_search
ChatGPTSearch and filter donations using one or more criteria. All specified criteria are combined with AND logic. Pagination: returns up to 100 donations per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages. Examples: - "Donations over $100 last month" → amountRange.Min="100", dateRange.After=<date 1 month ago> - "Donations for campaign X" → campaignId="<id>" - "All donations tagged VIP" → tags=["VIP"] - "What has contact Y donated?" → contactId="<id>" Omit any filter to return all donations. Combine as many filters as needed.
email_campaigns_cancel
ChatGPTCancel a queued or scheduled email campaign so it does not send (emails already sent are unaffected). Use email_campaigns_search to find the campaign ID.
email_campaigns_create
ChatGPTCreate an email campaign AND schedule it to start sending after startDate, in one step. There is no unscheduled "draft" state: a campaign created here is committed to send (subject to the lead time below, and to compliance approval when the account requires it). Use email_campaigns_cancel to stop it before it starts. ALWAYS confirm the subject, body, audience, AND the exact start date with the user before calling this tool — once the start date arrives it sends real email to real contacts. The required lead time guarantees the creator gets Levitate's day-before reminder and a window to cancel, but that is a safety net, not a substitute for confirming first. This is the DEFAULT way to email contacts through Levitate: sends are logged on each contact's timeline, tracked (opens, replies, clicks), and honor the account's compliance, approval, and unsubscribe rules. Do NOT use email_provider_send / email_provider_create_draft for contact outreach — those bypass Levitate entirely and are reserved for when the user explicitly asks to send directly from their own mailbox. Read the levitate://email-campaign-creation guide before using this tool. Start date (required, ISO 8601, e.g. '2026-06-10T14:00:00Z'): - Immediate sends are not available; the date must be in the future. - Self-sends require ~25 hours of lead time (so the creator receives the day-before reminder and can cancel). - On-behalf sends require the account's send-on-behalf wait time (default 2 days). - A too-early date is rejected with the earliest allowed value. To preview the projected send window for a large audience before committing, you can create it, then call email_campaigns_estimate / email_campaigns_get, and email_campaigns_cancel if the user changes their mind (the lead time leaves ample room). Audience — provide exactly one of: - recipients: an explicit list of contacts (max 500), each {contactId, optional subject, optional htmlBody}. Use contacts_search to find IDs. - filter parameters (tags / companyName / location / lastCommunicatedDateRange): resolved the same way as contacts_search. Use contacts_search with the same parameters first to preview who will be targeted. Content — provide htmlBody, or templateId to start from an existing template (htmlBody then overrides the template body if both are given). Signature — optional, and never added unless asked for. signatureTemplateId is exactly one of "default" (the sender's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Exceptions: an on-behalf campaign always carries the on-behalf sender's default (accepts only "default" or unset), and an HTML newsletter never carries one (accepts only "none" or unset). Never write a signature into htmlBody. Attachments — optionally attach files (PDFs, images, etc.). Upload each with files_create_upload first, then pass its fileId in attachments; the bytes never pass through this tool. Combined size must stay within the user's email provider per-message limit. To make an image appear inline in the body, embed it in the HTML instead — attachments are sent as downloadable files. Per-contact customization — the campaign-level subject/htmlBody are the default for everyone. To tailor a specific recipient (a bespoke sentence for a VIP, a different opening), set subject and/or htmlBody on that entry in recipients; it overrides the default for that contact only. This is for variation that ISN'T expressible as a merge placeholder — for "insert each person's first name", use a {{placeholder}} in the default body instead of customizing every recipient. Per-contact customization is only available with the explicit recipients audience, not the filter audience. Personalization — you may insert merge placeholders in the subject and body (campaign-level OR per-contact) using {{placeholder}} syntax, written as plain text (e.g. "Hi {{first name}},"); each is filled in per recipient at send time. Call email_placeholders_list for th…
email_campaigns_estimate
ChatGPTDry-run a campaign send to preview the audience size and the projected send window before scheduling. The projection accounts for the account's daily send limits (large campaigns are spread across days), business hours, and holidays. ALWAYS call this before email_campaigns_schedule: the response includes minimumAllowedStartDate, the earliest start date the schedule tool will accept for this campaign, so you can propose a valid date the first time. Nothing is sent or scheduled by this tool.
email_campaigns_get
ChatGPTGet a single email campaign by ID, including its status, schedule, audience size, engagement stats, the campaign-level HTML body, and which contacts have per-contact overrides. Use email_campaigns_search to find campaign IDs.
email_campaigns_schedule
ChatGPTReschedule an existing email campaign that has not started sending yet — move its start date earlier or later. New campaigns are created already-scheduled by email_campaigns_create; use this only to change the start date of a campaign that is already queued (or to (re)apply a date to a campaign created in the Levitate UI). ALWAYS confirm the exact start date with the user before calling this tool — once the start date arrives the campaign sends real emails to real contacts. Leave confirm unset and the user is prompted to approve the campaign and start date where the client supports it; re-issue the call unchanged with their answer. Pass confirm=true only when they have already agreed to this exact campaign and date. A response noting the user declined leaves the existing schedule untouched — do not retry it. Constraints (also returned by email_campaigns_estimate as minimumAllowedStartDate): - Immediate sends are not available through this tool. - Campaigns the current user sends themselves require at least ~25 hours of lead time, which guarantees the creator receives Levitate's day-before reminder notification and has a window to cancel. - On-behalf campaigns require the account's send-on-behalf wait time (default 2 days). - Campaigns pending compliance approval keep their hold; the schedule takes effect once approved. When complianceReviewedByOfficer is true on the result, that approval is the firm's compliance officer's and no Levitate user holds one; when false, a Levitate approver holds it — including a campaign raised before the account moved to officer filing. Relay the returned note. Use email_campaigns_cancel to stop a scheduled campaign before its start date.
email_campaigns_search
ChatGPTSearch email campaigns (bulk email sends) visible to the current user. All specified criteria are combined with AND logic. Results include status, schedule, and engagement stats (sent/opened/replied/bounced counts). Visibility follows the same rules as the Levitate UI: regular users see their own campaigns; admins also see shared/approval campaigns. Examples: - "My queued campaigns" → status="Queued" - "Campaigns sent in May" → dateRange with After="2026-05-01" and Before="2026-05-31" - "Everything including individual sends" → includeNonCampaignSends=true Pagination: returns up to 25 campaigns per page. Pass the response's nextCursor back as cursor to advance; the cursor is opaque.
email_placeholders_list
ChatGPTList the merge placeholders you can use in an email subject or body (including per-contact overrides). Each is replaced per recipient at send time. Write them as plain text (e.g. "Hi {{first name}},") — do not hand-author placeholder HTML. Any {{...}} not in this list, or malformed, is rejected when you create a campaign, so check here rather than guessing.
email_provider_create_draft
ChatGPTCreate a draft email in the user's connected email provider. The draft lands in their Drafts folder — it is NOT sent. The user must review and send it themselves from their email client. Returns the provider draft id and a web link (when available). Note — drafts created here live only in the user's mailbox and are not logged or tracked in Levitate. For outreach to contacts that should appear on their Levitate timeline (with open/reply tracking and compliance handling), use email_campaigns_create instead; reserve this tool for when the user explicitly wants a draft in their own email client. Supported on Gmail, Microsoft 365 (Outlook), and on-prem Exchange (EWS); IMAP and SMTP-only providers return an error. WebLink: Outlook links directly to the draft. Gmail links to the Drafts folder of the user's default Google account in their browser — Gmail's API has no per-draft URL, and the link can land on the wrong account if the user has multiple Google accounts signed in. Exchange returns no web link. Provide at least one of: a recipient (to/cc/bcc), a subject, or a body. Optional inline attachments (base64) may be supplied; combined size is capped at the maximum message size the user's email provider allows. They are passed through to the provider with this draft only and are NOT persisted to Levitate. Signature — optional, and never added unless asked for (the mailbox does not add one either). signatureTemplateId is exactly one of "default" (the user's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Never write a signature into the body. Citations — when the email is written from a Levitate template (email_templates_get), pass its id as templateId: a {{citations}} merge field in the body or signature is then filled with that template's vetted citations. Without templateId, or when the template has none, the field is removed. Never write citations yourself.
email_provider_draft_reply
ChatGPTSaves a threaded reply as a DRAFT in the user's mailbox without sending it, so they can read it over and send it themselves. Prefer this over email_provider_reply whenever the user has not clearly asked for the reply to go out immediately. Replies cannot add the user's Levitate signature. Do not write one into the body; tell the user instead. Pass a providerMessageId from email_provider_search or email_provider_get_message. Recipients are derived from that message exactly as with email_provider_reply: replying to a message the user SENT addresses the people it was sent to, as following up on it in a mail client would. Not every mailbox can do this: IMAP and SMTP connections have no drafts at all, and Microsoft 365 needs the user to have granted mailbox write access. Call email_provider_reply_capability first when unsure; a refusal here explains which of the two applies.
email_provider_get_message
ChatGPTFetch full email message details (including body content) from the user's connected email provider. Primary usage: Pass providerMessageIds from email_provider_search results for direct message retrieval. Fallback usage: Pass contactId with a date range to search for messages (slower, less precise). This retrieves content directly from the provider (Gmail, Outlook, Exchange), NOT from Levitate bulk emails or campaigns.
email_provider_list_categories
ChatGPTList the categories defined in the user's Outlook mailbox — the valid names to pass to email_provider_set_categories, and the ones their existing Outlook rules can match on. MICROSOFT 365 / OUTLOOK ONLY; other providers return an error. Reading the category list needs its own mailbox permission, granted by the same one-time reconnect email_provider_set_categories describes — if the user has not granted it, the error says so and names the link. Treat that as a permission problem to report, NOT as "this mailbox has no categories". Call this before setting categories rather than guessing a name. An empty list from a successful call means the user has genuinely defined no categories yet.
email_provider_list_folders
ChatGPTList every folder in the user's Outlook mailbox that email_provider_move_message can move mail into, nested folders included, each with its id and full path (e.g. "Inbox/Clients"). Deleted Items and Outbox are left out because they cannot be move targets. MICROSOFT 365 / OUTLOOK ONLY; other providers return an error. Needs no extra permission beyond the user's existing email connection. Call this before moving rather than guessing a folder name, and pass the path or id it returns.
email_provider_move_message
ChatGPTMove a message in the user's mailbox into another existing folder — how a triage classification gets mail that has already arrived filed. Outlook rules only run on delivery, so setting a category on mail already in the mailbox does not move it; this does. MICROSOFT 365 / OUTLOOK ONLY. Gmail, on-prem Exchange, and IMAP/SMTP mailboxes return an error. Requires the same one-time reconnect for mailbox write permission as email_provider_create_draft — if the user has not granted it, the error says so and names the link. Pass providerMessageId from email_provider_search or email_provider_get_message, and destinationFolder as a folder id or full path from email_provider_list_folders (e.g. "Inbox/Clients"). Prefer the id, especially when filing many messages: it resolves directly, while a path or name re-reads the whole folder list on every call. A bare folder name works only when no other folder shares it. The folder must already exist; this never creates one, and Deleted Items and Outbox cannot be targeted. The moved message gets a NEW providerMessageId, returned here — use it for any later call on that message. A NotFound error can mean the message was already moved, including by an earlier attempt of this same call.
email_provider_reply
ChatGPTReplies to a message in the user's connected mailbox, INSIDE the conversation it belongs to. Use this, not email_provider_send, whenever answering a message the user received. email_provider_send starts a brand new conversation, so a reply sent that way reaches the recipient detached from the thread they started. Replies cannot add the user's Levitate signature. Do not write one into the body; tell the user instead. Pass a providerMessageId from email_provider_search or email_provider_get_message. Recipients are derived from that message rather than supplied: replyAll=false (the default) answers the sender alone, and replyAll=true also copies everyone on the original's To and Cc, minus the user themselves. Following up on a message the user SENT addresses the people it was sent to rather than the user, so the default is the right setting there too. Mailbox differences, which email_provider_reply_capability reports up front: - Microsoft 365 / Outlook quotes the original itself and cannot attach files to a reply. - Gmail, Exchange and IMAP send the body as composed and can attach files. The user is asked to confirm before anything is sent, and the prompt names the resolved recipients, because on a reply they come from the message rather than from this call.
email_provider_reply_capability
ChatGPTReports whether the user's connected mailbox can reply inside an existing conversation, and what a reply can carry there. Call this before promising a reply with an attachment or exact formatting. Supported=false means email_provider_reply will refuse for this mailbox; say so rather than falling back to email_provider_send, which would reach the recipient as a detached new message.
email_provider_search
ChatGPTSearch the user's connected email provider (Gmail, Outlook, Exchange) communication history. Returns email metadata (subject, sender, recipients, timestamps, ProviderMessageId) without body content. Use email_provider_get_message with ProviderMessageId to retrieve the full message body. All searches hit the user's mailbox directly via the email provider. When a query is provided, the search uses the provider's keyword matching (subject + body). Without a query, results are filtered by contact, email address, direction, and/or date range. Without an explicit date range, the last 30 days are searched. Date handling: a date-only bound (e.g. '2026-08-25') is read in the user's own Levitate time zone, so "one day" means their calendar day, not a UTC day. Supply a full ISO 8601 timestamp with an offset or 'Z' to specify an exact instant instead. SearchedAfter and SearchedBefore on the response report the UTC window that was actually applied. Pagination: this is a newest-first feed, not a cursored list — there is no cursor parameter, and maxResults plus dateRange are the only controls. To walk backwards through a large range, re-issue the search with dateRange.Before set to the oldest Timestamp you received. Coverage: WindowComplete=true means the entire requested window was examined, so a message's absence is proof it is not there. WindowComplete=false means the provider stopped short and TotalCount is a floor rather than a total — narrow the range and search again. TotalCount counts matches found in the window, not all mail in the mailbox. IMPORTANT: SenderEmail, ToEmails, CcEmails, BccEmails contain email addresses. ContactIds holds the Levitate contact IDs of every participant on the message that matches a contact record, and SenderId the sender's contact ID; both are empty/null when no contact record matches the address. Examples: - "Find emails about the renewal proposal" -> query="renewal proposal" - "Emails with john@example.com" -> emailAddress="john@example.com" - "Emails I sent last week" -> direction=Sent, dateRange with After/Before bounds - "All emails for contact X" -> contactId=<contactId> - "Search for emails about insurance from last month" -> query="insurance", dateRange with bounds
email_provider_send
ChatGPTSend an email immediately from the user's connected email provider (Gmail, Microsoft 365 / Outlook, Exchange, IMAP/SMTP). The message is sent on the user's behalf from their own mailbox and CANNOT be unsent. IMPORTANT — this BYPASSES Levitate: the send is not logged to any contact timeline, gets no open/reply tracking, and skips Levitate's compliance, approval, and unsubscribe handling. Default to the email_campaigns_* tools for any outreach to contacts; use this tool ONLY when the user EXPLICITLY asks to send directly through their email provider (e.g. "send it straight from my Outlook", "don't log this in Levitate"). When in doubt, ask the user which they want. Prefer email_provider_create_draft when the user should review the message before it goes out; only send directly when the user has clearly asked for the email to be sent. Confirmation: leave confirm unset and the user is prompted to approve this exact send where the client supports it — re-issue the call unchanged with their answer. Pass confirm=true only when the user has already agreed to these exact recipients and subject. A response with sent=false means they declined; do not retry it. Requires at least one recipient (to, cc, or bcc) and a subject or body. A single send is limited to 10 recipients across to, cc, and bcc — this tool is for individual messages, not bulk mail. For multiple contacts or any campaign-style outreach, use email_campaigns_create instead. Optional inline attachments (base64) may be supplied; combined size is capped at the maximum message size the user's email provider allows. They are passed through to the provider with this send only and are NOT persisted to Levitate. Signature — optional, and never added unless asked for (the mailbox does not add one either). signatureTemplateId is exactly one of "default" (the user's default Levitate signature), an id from email_signatures_list, or "none". Unset means no signature. A value that doesn't resolve to one of the user's signatures is rejected, never swapped for another. Never write a signature into the body. Citations — when the email is written from a Levitate template (email_templates_get), pass its id as templateId: a {{citations}} merge field in the body or signature is then filled with that template's vetted citations. Without templateId, or when the template has none, the field is removed. Never write citations yourself. Returns the RFC message id and provider message id when the provider reports them. The sent message lands in the user's Sent folder, so it appears in email_provider_search results like any other sent mail.
email_provider_set_categories
ChatGPTAdd, remove, or replace Outlook categories on a message already in the user's mailbox. Categories are the hook the user's own Outlook rules match on ("assigned to category"). This tool never moves or deletes anything, and the routing map stays in Outlook where the user can edit it. Outlook rules only run when mail arrives, so a category set on mail already in the mailbox will not trigger a rule; to file that mail, use email_provider_move_message. MICROSOFT 365 / OUTLOOK ONLY. Gmail, on-prem Exchange, and IMAP/SMTP mailboxes return an error; there is no Gmail-label equivalent. Requires a one-time reconnect to grant mailbox write permission — if the user has not granted it, the error says so and they reconnect at the link given, then the call can be retried. Pass providerMessageId from email_provider_search or email_provider_get_message. Prefer names from email_provider_list_categories. A name that is not in that list still applies to the message, but Outlook shows it unstyled and no existing rule will match it, so a typo silently does nothing useful. Returns the message's FULL category set after the update, which for add/remove includes categories that were already there.
email_signatures_list
ChatGPTList the email signatures the current user has set up in Levitate, with their HTML and which one is the default. Signatures are optional: email_campaigns_create, email_provider_create_draft and email_provider_send add one only when signatureTemplateId is an id from this list or "default" (the entry marked IsDefault); "none" or unset adds none. An empty list means the user has no signature, so "default" would be rejected — leave signatureTemplateId unset.
email_templates_get
ChatGPTGet a single email template by ID, including its full HTML content. Use email_templates_search to find template IDs.
email_templates_search
ChatGPTSearch the email templates available to the current user: their own templates plus templates shared account-wide. (The broader industry/system template library is not included in these results.) Templates are pre-written (often pre-approved) content — prefer starting a campaign from a template via email_campaigns_create's templateId parameter instead of writing content from scratch. Results are sorted by most recently modified. Use email_templates_get to read a template's full content. Pagination: returns up to 25 templates per page. Pass the response's nextCursor back as cursor to advance; the cursor is opaque.
files_analyze
ChatGPTRead an uploaded file and answer a question about it — classify it, describe it, extract what it is about — without the file's contents ever passing through this conversation. Upload the file with files_create_upload first, POST its bytes, then pass the fileId here. How it works: the file's text is extracted server-side (PDF text layer, with OCR for scanned pages; OCR for images; Word .docx; Excel .xlsx/.xls; plain text, CSV, TSV, Markdown and JSON), sensitive values are redacted before any model sees it, a model answers the prompt, and the upload is deleted. maxPages limits how many pages of a PDF or sheets of a workbook are read: with a prompt the default is 3 and the most is 10, and the text is capped at the first 20,000 characters; without one (classification) the default and the most are 100, and every page is read. pagesRead and totalPages report the coverage, truncated is true whenever part of the document went unread, and unreadablePages lists PDF pages OCR could not read at all. totalPages is null for Word files, which have no fixed pages until rendered. The answer is all that comes back — never the document text. Redaction always runs and removes Social Security and tax id numbers, account, card and routing numbers, credentials, email addresses, and every other number except tax years, tax-form names (W-2, 1099-INT, K-1) and one- or two-digit box/line numbers; names and postal addresses are not redacted. Markers [REDACTED] and [NUMBER] show where. So this tool can say what a document is and who issued it, but it cannot report amounts or account numbers. Omit prompt for the built-in classification. A file often holds several documents (a client's whole year of tax forms scanned into one PDF), so the answer is a JSON object {"documents": [...]} with one entry per document in page order, each with startPage and endPage (null for files without pages), documentType, documentFamily, issuer, period, description, suggestedFileName (YYYY-MM-DD <description>), confidence, and revision (Original, Corrected, Amended or Void — read from the form's CORRECTED/VOID box, a W-2c, or an Amended K-1; Original when there is no mark or it can't be read). An entry whose documentType is null covers pages too garbled to identify. Otherwise prompt is free-form (up to 4,000 characters) and responseFormat chooses text (default) or json. deleteAfter (default true) removes the upload once analyzed, so reuse the fileId only when you passed false. Files over 25 MB, and types other than those listed, are rejected. Requires the account's AI features to be enabled.
files_create_upload
ChatGPTBegin uploading a file. Returns an uploadUrl and a single-use uploadToken. Upload the raw file bytes with a single HTTP POST to uploadUrl, sending header Authorization: Bearer <uploadToken> (and optionally X-Content-Sha256: <hex sha256> for an integrity check). The body must be the file's raw bytes: set Content-Type to the file's MIME type, application/octet-stream, or omit it. Never send multipart/form-data; it is rejected. The bytes travel over ordinary HTTP — never paste file contents into this tool. On success the file is identified by the returned fileId, which you pass to file-aware tools — an email attachment (email_provider_* / email_campaigns_create_draft), an image on a social post (social_posts_create_draft), or a blog post's main/hero image (blogs_create_draft / blogs_update). Uploads are transient and expire automatically, so create the upload shortly before referencing it. The token is good for one upload and then expires.
files_get
ChatGPTReturn metadata for an uploaded file by id, including a short-lived signed download URL for ready files. Does not return the file bytes.
notes_create
ChatGPTCreate a new text note associated with a specific contact. Use this tool to: - Add notes, observations, or comments about a contact - Record meeting notes, phone call summaries, or conversation details - Log follow-up reminders or next steps - Document interactions, touchpoints, or relationship history The note is automatically linked to the specified contact and appears in their timeline.
notes_search
ChatGPTSearch and filter notes using one or more criteria. All specified criteria are combined with AND logic. Each returned note is enriched with its activity type and the contacts it references — name, company, email, job title, tags, phone numbers, address, key facts, and custom properties — so you don't need to look contacts up separately. REP / OWNER FILTERING: - To filter by the reps (note creators) who logged the notes, pass their names in ownedByNames (e.g. ["Jane Smith", "Bob Lee"]) — they are resolved to users on the account automatically. - If a name can't be resolved to exactly one user it is returned in unresolvedReps (reason "no_match", "ambiguous" with candidate users, or "lookup_failed" for a transient error). Resolve it with users_search, then re-call passing the user IDs in ownedByUserIds. - ownedByUserIds accepts explicit creator user IDs; ownedBy is the legacy single-ID equivalent. All three are combined. Omit them all to include every rep (e.g. an account-wide activity report). The response field CreatorId is a user ID, not a name — call users_get to display who created a note. Examples: - "Activity for Jane and Bob last week" -> ownedByNames=["Jane Smith","Bob Lee"] + creationDateRange - "All notes logged this month" -> creationDateRange only (no owner filter) - "My recent notes" -> call users_get_self first, then ownedByUserIds=[<your userId>] - "Notes about a contact" -> contactId=<contactId> - "Notes containing 'meeting'" -> searchText="meeting" NOTES: - contactId takes priority; other filters are not applied when it is set. - Rep-name resolution and includeEmailsAndTexts apply to the activity path (no searchText). When searchText (or lastModifiedDateRange) is supplied, only the single legacy ownedBy is honored; any ownedByNames/ownedByUserIds/includeEmailsAndTexts you also passed are listed in the response's ignoredFilters so you know they did not take effect. - Date ranges are inclusive whole days: a date-only before covers through the end of that day. - By default, auto-generated bulk-send notes (email blasts, newsletters, text campaigns) are EXCLUDED so the results reflect manual outreach; meeting notes are always kept. Set includeEmailsAndTexts=true to include bulk-send notes. Pagination: returns up to 25 notes per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
notes_update
ChatGPTUpdate the text content of an existing note while preserving all associated contacts and metadata. Use this tool to: - Update note content with new information or corrections - Modify existing observations or meeting notes - Edit follow-up details or action items within notes - Add additional context to existing notes Only the text content is modified - creation date, referenced contacts, and relationships remain unchanged.
opportunities_boards_list
ChatGPTList all opportunity boards and their stages. Call this first to discover board IDs and stage names before searching opportunities. Returns all boards with their stages, including deal size rollup data (total and average) per stage.
opportunities_search
ChatGPTSearch and filter opportunities on a board. boardId is required — call opportunities_boards_list first to get board IDs. Filter by name, company, contact, owner, close date range, deal size range, or tags. Only one of name/companyId/primaryContactId/ownerId may be specified per request. ownerId expects a user ID — call users_get_self for "my opportunities". companyId and primaryContactId expect entity IDs. Examples: - "All opportunities on board X" → boardId="<id>" - "Opportunities closing this quarter" → boardId="<id>", closeDateRange.After=<quarter start>, closeDateRange.Before=<quarter end> - "My deals over $50k" → boardId="<id>", ownerId="<userId>", dealSizeRange.Min="50000" - "Opportunities tagged Enterprise" → boardId="<id>", tags=["Enterprise"] Pagination: returns up to 25 opportunities per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
policies_carriers_search
ChatGPTSearch for insurance carriers by name. Use this tool first when a user asks about policies for a specific carrier by name — call this to resolve the carrier name to an ID, then pass that ID to policies_search. Returns carriers whose names match the query (partial, case-insensitive). Omit the query to list all carriers. Pagination: returns up to 10 carriers per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
policies_lines_of_business_search
ChatGPTSearch for insurance lines of business by name. Use this tool first when a user asks about policies for a specific line of business by name — call this to resolve the line of business name to an ID, then pass that ID to policies_search. Returns lines of business whose names match the query (partial, case-insensitive). Omit the query to list all lines of business. Pagination: returns up to 10 lines of business per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
policies_search
ChatGPTSearch and filter insurance policies using one or more criteria. All specified criteria are combined with AND logic. Pagination: returns up to 50 policies per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages. Examples: - "Policies renewing next month" → renewalDateRange.After=<start of next month>, renewalDateRange.Before=<end of next month> - "Policies with premium over $1000" → premiumRange.Min="1000" - "Policies for contact X" → contactId="<id>" - "Policies from carrier Y" → carrierId="<id>" (use policies_carriers_search to resolve names to IDs) Omit any filter to return all policies. Combine as many filters as needed. Use policies_carriers_search and policies_lines_of_business_search to resolve ids in the response to human-readable names.
shared_files_list
ChatGPTList the files exchanged with a contact through Levitate: documents the contact uploaded via a file request, survey or text (direction Received) and files sent to them (Sent). An executed e-signature document is filed as Received with origin SigningRequest: it is the sealed copy of a document the contact signed, not something they uploaded. Origin Upload means a staff member added the file to the contact directly; it has direction None, so filtering by either direction leaves it out. Origin ClientPortal means the contact uploaded the file through their client portal on their own, not in answer to a file request; it is Received. Each entry carries the file name and size, how it arrived (origin), and — when the account has automatic file classification enabled — a classification for inbound files: status (Classified, Skipped, Failed), documentType, documentFamily, issuer, period, a one-line description, a suggested file name, a confidence, and a revision: Original, Corrected (a 1099 with its CORRECTED box checked, or a W-2c), Amended (a K-1 marked Amended) or Void (a 1099 the issuer voided; it never satisfies a checklist item); absent when unknown (not classified, or classified before revisions were recorded). A file that holds several documents (a scanned bundle of tax forms) also carries documents: one entry per document with its index, startPage/endPage and the same fields, plus Skipped entries (with a reason) for pages that could not be read or lay past the 100-page limit; pagesRead/totalPages give the coverage, and the top-level fields then describe the first document. Classification is always produced from redacted text, so it carries no identifiers or figures from the document (names can appear). Use direction to see only what the contact sent. Pagination: up to 50 files per page, newest first. Pass the response's nextCursor back as cursor to get the next page; the cursor is opaque, not an offset. Use contacts_search to find the contact id.
social_connections_list
ChatGPTList the current user's connected social media accounts/pages (Facebook, Instagram, LinkedIn). Call this BEFORE social_posts_create_draft: each entry's pageId is what you pass as a target's pageId. Only accounts with state Connected can publish. An account that is Disconnected, NoTarget, or whose token has expired must be reconnected by the user in Levitate first — surface that to the user rather than trying to post to it. A Facebook/Instagram account with an authFailureReason is being rejected by Meta even if it still shows Connected: tell the user what to fix (for CheckpointRequired/AccountUnconfirmed, log in at facebook.com first; otherwise reconnect in Levitate) before drafting a post to it.
social_posts_cancel
ChatGPTCancel a scheduled or pending social post so it does not publish. An unscheduled draft is deleted; a scheduled or pending post is marked Cancelled. Posts that have already started or finished publishing cannot be cancelled. Use social_posts_search to find the post ID.
social_posts_create_draft
ChatGPTCreate a DRAFT social media post. The draft is never published by this tool: it stays unscheduled until social_posts_schedule is called, and account rules (compliance review) still apply at that point. Read the levitate://social-post-creation guide before using this tool. Targets — provide one or more pages from social_connections_list, each {provider, pageId}. Every target must be a Connected account the current user owns; an unknown or disconnected page is rejected. Content — plain text. The limit depends on the platforms targeted: Instagram 2,200, LinkedIn 3,000, Facebook 63,206; a post going to several is bound by the strictest of them. Do NOT include the user's social signature or any required disclosure; those are appended automatically at publish time. ALWAYS show the user the content and the target pages and get their confirmation before creating the draft. A Facebook Page mention is written inline as {{@Page Name|PAGE_ID}}; only Facebook tags the Page, Instagram and LinkedIn publish the name. Images — optionally attach images, up to 10 for Facebook and Instagram and 20 for LinkedIn, a post going to several being bound by the strictest (no video; add video in Levitate). Upload each image with files_create_upload first, then pass its fileId here. Instagram REQUIRES at least one image: an Instagram target with no image is created as a draft but is rejected at schedule time, so attach an image here (or in Levitate) before scheduling it.
social_posts_get
ChatGPTGet a single social media post by ID, including its status, schedule, target pages with per-platform publish state, the post body, and engagement stats. Use social_posts_search to find post IDs.
social_posts_schedule
ChatGPTSchedule a draft social post to publish at the given future date, or reschedule one that has not published yet. ALWAYS confirm the exact date and the target pages with the user before calling this tool — once the date arrives the post is published publicly to the connected accounts. Constraints: - The start date must be at least ~15 minutes in the future, leaving a window to review and cancel. - Immediate publishing is not available through this tool. - On accounts with compliance review enabled, the post is routed through approval instead of being scheduled directly: it lands in Pending status and only publishes once the review is answered. - Who reviews it depends on the post's review round. Usually a Levitate user approves it in the app. A round raised on a broker-dealer account configured for officer filing is emailed to the firm's compliance officer instead — they submit it to the broker-dealer themselves, no Levitate user holds an approval, and if they decline the post is cancelled rather than published. A post already pending with a Levitate approver before the account moved to officer filing stays with that approver. complianceReviewedByOfficer on the returned post says which holds it; relay it rather than assuming an in-app approval. Use social_posts_cancel to stop a scheduled or pending post before it publishes.
social_posts_search
ChatGPTSearch the current user's social media posts. Results include status, schedule, targets, and (after publishing) engagement stats. Visibility follows the Levitate UI: regular users see their own posts; admins and account-wide contexts see everyone's. Drafts have no scheduled date, so to list them pass status=Draft (the dateRange is ignored in that case). For every other status the search is by scheduled/publish date — pass a dateRange to narrow the window. Pagination: up to 25 posts per page. Pass the response's nextCursor back as cursor to advance; the cursor is opaque.
surveys_custom_create
ChatGPTCreate a new custom survey shell with branding, an optional date window, and per-field contact-info requirements. This creates the survey but does not add any questions — use surveys_question_add for that, in the order they should appear. Read the custom_survey_creation resource (levitate://custom-survey-creation) before calling — it explains the two-phase create-then-add-questions flow, the three-state contact-info model, and how to wire question-visibility branching using IDs returned from prior calls. Returns the newly created survey's ID. Hold on to it — every surveys_question_add call needs it. The new survey emails its creator on every response. That is on by default and no parameter here changes it — say so once when you confirm the survey is created, and point anyone who wants it off at the survey's settings in the Levitate web app. Requires the account's Surveys feature. If it is off, this fails with "Surveys aren't enabled on this account" — relay that to the user rather than retrying or working around it, and do not start the question-design conversation until it is on.
surveys_event_registration_responses_search
ChatGPTSearch and filter responses for an event registration survey. You must provide an eventSurveyId — use surveys_event_registrations_search first to find it. Examples: - "Show all registrations for event X" → eventSurveyId="<id>" - "Who's attending?" → eventSurveyId="<id>", attendanceStatus="Attending" - "Check-ins for today's event" → eventSurveyId="<id>", attendanceStatus="CheckedIn" Filter by attendance status: 'Attending', 'NotAttending', 'NoResponse', or 'CheckedIn'. Each response includes an IsAnonymous field indicating whether it is linked to a contact. Omit optional filters to return all responses (newest first). Pagination: returns up to 50 responses per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
surveys_event_registrations_search
ChatGPTSearch and list event registration surveys. Use this tool to find event IDs before searching for event responses with surveys_event_registration_responses_search. Returns event surveys with full event details including location, start/end times, timezone, capacity, and registration deadline. When EventIsAllDay is true the event has no set times: EventStartTime and EventEndTime are its first and last dates in the event's timezone. Examples: - "List all my events" → no filters - "Find my gala event" → query="gala" - "Show upcoming events" → includeExpired=false (default) Results are sorted by name. Omit filters to list active, non-expired events. Pagination: returns up to 25 events per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
surveys_question_add
ChatGPTAdd a single question to a custom survey. Call once per question, in the order the questions should appear — there is no reordering tool. Read the custom_survey_creation resource (levitate://custom-survey-creation) before calling. Key rules: - DropDown and CheckBoxes questions REQUIRE the options parameter (the choices, in display order). - All other types (ShortAnswer, LongAnswer, YesNo, FileUpload, LinearScale, Nps) MUST NOT pass options. - LongAnswer is a multi-line free-text answer (use it instead of ShortAnswer when a paragraph is expected). - YesNo renders a single yes/no choice; it takes no options. - LinearScale is a numeric scale question (Google-Forms style, e.g. 1–5); Nps is the standard 0–10 Net Promoter Score question. Both render as a numeric scale with no options — the scale bounds/end-labels use standard defaults and are not configurable from this tool. - visibleWhen makes the question conditional on an earlier DropDown or CheckBoxes question's answer. Source the controllingQuestionId and optionIds from the response of an earlier surveys_question_add call — never guess them. Returns the new questionId and, for DropDown/CheckBoxes, the persisted option labels and their optionIds. Hold on to those — later surveys_question_add calls reference them when wiring visibleWhen branching.
surveys_responses_search
ChatGPTSearch and filter responses for a specific survey (excluding events — use surveys_event_registration_responses_search for events). You must provide a surveyId and surveyType — use surveys_search first to find them. Examples: - "Show all responses for survey X" → surveyId="<id>", surveyType="Satisfaction" - "Responses from contact Y" → surveyId="<id>", surveyType="Custom", contactId="<id>" - "5-star reviews this month" → surveyId="<id>", surveyType="Satisfaction", ratings=[5], dateRange.After=<start of month> Type-specific filters: - Satisfaction surveys: use 'ratings' (1-5) to filter by star rating - Custom surveys: use 'searchName' to filter responses by contact name (either first or last) Each response includes an IsAnonymous field indicating whether it is linked to a contact. Omit optional filters to return all responses (newest first). Pagination: returns up to 50 responses per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
surveys_search
ChatGPTSearch and list surveys of a specific type. Use this tool to find survey IDs before searching for survey responses with surveys_responses_search. For events, use surveys_event_registrations_search instead. You must specify a surveyType. If the user does not specify a type, call this tool once for each type ('Satisfaction' and 'Custom') and combine the results. Examples: - "Find my NPS survey" → surveyType="Satisfaction", query="NPS" - "Show all custom surveys" → surveyType="Custom" - "List all my surveys" → call once with surveyType="Satisfaction", once with surveyType="Custom" Results are sorted by name. Surveys the product created for its own plumbing are excluded, so "all my surveys" means all the ones the customer built — a volunteer signup form created by the volunteering setup will not appear. Those are still reachable by id, so if the user names a survey this tool cannot find, ask them for its id instead of reporting that it does not exist. Pagination: returns up to 25 surveys per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages.
tags_search
ChatGPTSearch the account's existing tags by name prefix. Use this to ground tagging in the tags the account already uses: call it before contacts_add_tags so you reuse a canonical existing tag (e.g. "VIP") instead of creating a near-duplicate ("vip", "VIP Client", "Important Customer"). Pagination: returns up to 25 tags per page. To retrieve subsequent pages, pass the response's nextCursor back as the cursor parameter on the next call. The cursor is opaque — do not construct, parse, or substitute a numeric offset. When hasMore is false there are no further pages. Omit query to list all of the account's tags. Hidden tags are never returned.
users_get
ChatGPTReturn a user's profile by their ID. Use this to resolve user IDs (e.g. AssigneeId, CreatorId from action items) into display names.
users_get_self
ChatGPTReturn the current authenticated user's profile (ID, name, email, role). Call this FIRST when the user refers to themselves with "my", "me", "I", "mine". Use the returned ID as assignedTo in action_items_search.
users_search
ChatGPTSearch users on the account by name (or partial name) and return matching users with their IDs. Use this to resolve a rep/user name into a user ID — for example to disambiguate a name that notes_search reported in unresolvedReps, then re-call notes_search with the chosen ID in ownedByUserIds. Returns all matches; if more than one user matches, ask which one is intended.
zoom_summarize_meeting
ChatGPTGenerate an AI summary of a recorded Zoom meeting the user held with a specific contact, and return a link to the source Zoom recording. It finds the meeting with the contact on the user's calendar and pulls that meeting's Zoom transcript: directly when the calendar event used a unique (per-booking) Zoom link, or — for a generic/personal link — from the recording closest in time to the calendar event. Requires the user to have connected Zoom AND granted the optional recording/transcript permissions; otherwise the call fails with a message explaining how to enable it.
action_items_complete
Claudeaction_items_create
Claudeaction_items_delete
Claudeaction_items_get
Claudeaction_items_search
Claudeaction_items_update
Claudeblogs_cancel
Claudeblogs_create_draft
Claudeblogs_get
Claudeblogs_schedule
Claudeblogs_search
Claudeblogs_update
Claudecalendar_provider_get_meeting
Claudecalendar_provider_search
Claudecompanies_get_timeline
Claudecompanies_search
Claudecontacts_add_email
Claudecontacts_add_phone
Claudecontacts_add_tags
Claudecontacts_create
Claudecontacts_get_profile
Claudecontacts_get_timeline
Claudecontacts_search
Claudecontacts_update_details
Claudedocument_checklist_archive
Claudedocument_checklist_list
Claudedocument_checklist_seed
Claudedocument_checklist_summary
Claudedocument_checklist_update
Claudedonations_campaign_search
Claudedonations_search
Claudeemail_campaigns_cancel
Claudeemail_campaigns_create
Claudeemail_campaigns_estimate
Claudeemail_campaigns_get
Claudeemail_campaigns_schedule
Claudeemail_campaigns_search
Claudeemail_placeholders_list
Claudeemail_provider_create_draft
Claudeemail_provider_draft_reply
Claudeemail_provider_get_message
Claudeemail_provider_list_categories
Claudeemail_provider_list_folders
Claudeemail_provider_move_message
Claudeemail_provider_reply
Claudeemail_provider_reply_capability
Claudeemail_provider_search
Claudeemail_provider_send
Claudeemail_provider_set_categories
Claudeemail_signatures_list
Claudeemail_templates_get
Claudeemail_templates_search
Claudefiles_analyze
Claudefiles_create_upload
Claudefiles_get
Claudenotes_create
Claudenotes_search
Claudenotes_update
Claudeopportunities_boards_list
Claudeopportunities_search
Claudepolicies_carriers_search
Claudepolicies_lines_of_business_search
Claudepolicies_search
Claudeshared_files_list
Claudesocial_connections_list
Claudesocial_posts_cancel
Claudesocial_posts_create_draft
Claudesocial_posts_get
Claudesocial_posts_schedule
Claudesocial_posts_search
Claudesurveys_custom_create
Claudesurveys_event_registration_responses_search
Claudesurveys_event_registrations_search
Claudesurveys_question_add
Claudesurveys_responses_search
Claudesurveys_search
Claudetags_search
Claudeusers_get
Claudeusers_get_self
Claudeusers_search
Claudezoom_summarize_meeting
Claude