Reference

The Chirply Handbook

Everything Chirply does, what it costs, and where the honest limits are — in one page. All 144 capability areas below are live in production today, and the prices and plan limits are the same ones the checkout charges.

This document is generated from the product itself — the feature catalog, the plan matrix, and the live registry of every operation the platform exposes — so it cannot quietly go stale. It is written to be read by a person and eaten by a machine: the same text is served as plain markdown at https://chirply.io/handbook.txt for indexers and AI knowledge bases.

What Chirply is, in one paragraph

If you read nothing else, read this.

Chirply is an all-in-one business platform that combines a CRM, a full phone system, AI phone agents, a unified SMS/email/live-chat inbox, marketing campaigns, Google/YouTube and Meta advertising, calendars and appointment booking, automations, AI-built websites and funnels, storefronts, courses and communities, lead generation, internal team chat, reporting, and payments into a single login. It is aimed at small businesses, sales teams, and marketing agencies who are currently paying for five or six separate tools that do not talk to each other. Its two defining decisions are these: you can connect your OWN accounts with the underlying providers — Twilio for calls and texts, Mailgun for email, your own AI model key, and Stripe for payments — so you pay providers directly and keep ownership of the underlying accounts; and product operations are exposed to AI agents through a public API, a built-in MCP server, and the assistant inside the app. It is sold as a monthly subscription starting at $7/month.

Chirply is operated by Vaughn Labs. The public site is https://chirply.io, the application lives at https://app.chirply.io, and support is reachable at support@chirply.io. There are 144 distinct capability areas live in production today, spread across 16 product categories.

Chirply buyer questions: prices, trial, AI and agency setup

Direct answers with links to the relevant product details and terms.

What is Chirply, and who makes it?
Chirply is the CRM, calling and automation platform at chirply.io, operated by Vaughn Labs. It brings contacts, phone calls, AI receptionists, SMS and email, booking, workflows, websites, funnels and invoicing into one product for small businesses, sales teams and agencies. The signed-in application is at app.chirply.io.

Read more: Product features · Company and official images · The team and story

What does Chirply cost?
There are five retail plans: Spark $7/month ($70/year), Build $27/month ($270/year), Launch $47/month ($470/year), Grow $77/month ($770/year), Scale $97/month ($970/year). Paying yearly costs ten months rather than twelve, so two months are free. Contacts are unlimited on every plan, and nothing is metered: once a plan includes a channel, that channel is unlimited on it, because the provider accounts are yours (your Twilio, your Mailgun, your model key) and they bill you directly. Spark and Build are entry plans that do not include calls, texts or marketing email — those start on Launch. The plans differ by capability and capacity rather than by usage.

Read more: Current plans and comparison

Can I sign up and try Chirply?
Everyone starts with the full platform free for 14 days on Scale. Scale is the only plan with a free trial. A card is required, and you pay nothing today. After your trial, stay on Scale at $97/month or downgrade to any other retail plan. Choose a lower plan in Billing before the trial ends to start there when billing begins, or cancel before then and pay nothing. Start through the public pricing page. This is the Chirply subscription trial; connected-provider usage is billed separately. Entry plans and partner subscriptions have their own purchase terms.

Read more: Start a trial and read renewal terms

Are phone calls, SMS, email and AI usage free?
No. For connected Twilio, Mailgun and AI model accounts, you pay those providers for usage separately from the Chirply subscription. A plan must include a channel before you can use it; unlimited included-channel volume is not free provider usage. Other optional services can have their own charges. Review the pricing page and the relevant provider's current rates before choosing a plan.

Read more: Subscription and provider costs · Twilio setup and costs

Can an agency sell Chirply under its own brand?
White-Label Partner is the superset. It grants everything Reseller Partner does — client client accounts, wholesale pricing, selling your own plans — and adds your own brand, colours and logo, your own domains, and a branded installable app. Nobody needs both: White-Label already contains the Reseller side of it, and Chirply will not sell you the cheaper tier once you hold the higher one. Included. The White-Label Partner subscription is the whole of what you pay Chirply — it carries a full Scale-level account with it, so there is no separate Scale charge and nothing to buy twice. One subscription, not two. (The one exception is the one-time lifetime white-label sold on some campaign signups: that one is a single payment added to a discounted Scale subscription you keep paying separately. Your Billing screen shows which of the two you hold.)

Read more: White-label CRM for agencies · Partner plans and costs

Which Chirply plans include an AI receptionist?
AI phone agents are included on Grow and Scale. Streaming voice, website knowledge crawling and outbound AI calls are separate capabilities: streaming is included on Scale, website crawling on Scale, and outbound calling on Scale. Booking and transfers require configuration and permissions. A paid appointment uses a booking link instead of being completed by the booking tool during a call. Provider usage is separate.

Read more: AI receptionist overview · Setup, booking limits and testing

Can AI agents and integrations use Chirply?
Chirply exposes a public REST API, a built-in MCP server and an in-app assistant through a shared capability catalog. Available operations depend on workspace permissions and plan access. The API documentation describes authentication and operations; connecting an agent does not itself grant unrestricted access or make calls, messages and paid actions free.

Read more: Public API documentation · Product handbook and action catalog

How should I compare Chirply with another CRM?
Compare the workflows you need, plan limits, provider setup, total subscription and usage costs, client branding and migration requirements. Use the product comparisons and test your actual workflow during the trial. A similar feature name does not establish identical behavior, and existing data or workflows may need a separate migration plan.

Read more: CRM comparisons · Chirply and GoHighLevel · Current product release history

Can I move contacts from another CRM to Chirply?
Chirply supports contact CSV imports through Contacts → Import. Start with a small file, review the column mapping and check the imported records before moving the full list. Existing email or phone matches are not overwritten by the import. A contact CSV does not transfer another CRM's workflow logic, snapshots or historical conversations: inventory those separately and test the replacement workflows before switching. Preserve the source system's consent and reporting records where needed.

Read more: Migration evaluation checklist · Contact and workflow capabilities

Can I use my existing business phone number with Chirply?
You can import a number already held in the Twilio account connected to your Chirply workspace. A number held at another carrier needs the applicable Twilio porting process before it appears in that account's inventory. Check the number's voice and SMS capabilities, your Chirply plan's number allowance and the provider's requirements before planning a switch. Number rental and provider usage are separate from the Chirply subscription; connecting a number does not itself approve SMS sending.

Read more: Twilio connection, number import and porting · Plan allowances and costs

Where can I find official Chirply logos and product screenshots?
Chirply's brand and media page at chirply.io/brand provides official logo downloads, captioned product screenshots and company information for the CRM from Vaughn Labs. The screenshots use sample records in Chirply's product components; they are illustrations of the interface, not customer results. Read the image usage and permission sections before reuse. Downloading an asset does not grant an open license or imply endorsement.

Read more: Official logos and product images · Image usage and credit · Request permission

Can Chirply handle recurring retainers and payment plans?
Yes. Standard and Product invoices support recurring line items for ongoing subscriptions. A Payment Plan invoice splits a finite total into scheduled installments and requires access to advanced invoicing. Payments use the workspace's connected Stripe account. Creating a draft does not charge or email anyone; publishing makes its payment page available, and sending an invoice emails its link. Confirm the plan, seller, billing interval and collection terms before using it with clients. Invoice actions do not establish automatic two-way sync with every accounting package.

Read more: Agency invoicing workflow and billing models · Plan access and costs · Invoice action catalog

Can Chirply collect client testimonials and review requests?
Chirply's Reputation area creates trackable review links and sends requests to CRM contacts by SMS or email through connected providers. Creating a link sends nothing; delivering it sends a real message with separate provider usage costs. The feedback journey collects a rating and written feedback, then shows configured public review options regardless of rating. A completed private request is not proof of a public review, and a testimonial-candidate flag is not publication permission. Video recording and editing require a separately evaluated recording workflow.

Read more: Testimonial and review collection workflow · Review request API and MCP actions · Plans and provider costs

Can Chirply create and assign follow-up tasks automatically?
Chirply provides a Create task action for supported workflows and call outcomes. It sets title, description, priority and a due interval, and links the available contact context. The current action does not select an assignee or deal. Review those fields in Tasks or use the task API, which supports assignment and contact or deal associations. Due-in days are 24-hour intervals from execution, not a business-day calendar. Creating a task does not complete the work or itself send a client message.

Read more: Task automation setup and ownership handoff · Agency project management scorecard · Task API and MCP documentation

Who Chirply is for — and who it isn't

Qualify against this before pitching anything else.

Strong fits

  • Businesses whose revenue depends on the phone — home services (roofing, HVAC, plumbing, solar, remodeling), insurance, real estate, mortgage, legal intake, medical and dental practices, auto dealers, staffing.
  • Anyone running outbound: a team dialing lists, following up on leads, or chasing quotes. The power dialer, call outcomes, and ringless voicemail are built for exactly this.
  • Anyone drowning in inbound they can't answer. AI phone agents pick up at 3am, on weekends, and while the crew is on a roof.
  • Marketing agencies and consultants who want to resell a platform under their own brand instead of pushing clients to somebody else's login.
  • Businesses already paying for a CRM, a dialer, an email tool, a page builder, and a scheduling tool separately — the consolidation case is the easiest sale Chirply has.
  • Technically-inclined operators who want their own AI agents to drive the CRM. Chirply is unusual in exposing every operation to machines, not just a token API — and it goes further than most: a workspace can connect its own Supabase account and manage real project backends from inside the product, and anyone can build and publish an app that runs inside Chirply.
  • Restaurants, and martial-arts schools and similar studios. These are strong fits rather than awkward ones, because there are first-party vertical apps for both — see the section on apps bought per workspace. Do not tell a restaurant or a dojo that Chirply has nothing for them.

Weak fits — do not force these

  • Enterprises needing SOC 2 attestation, procurement review, or a signed BAA today. Chirply is a young platform built in public; it is not the safe answer for a compliance-gated buyer.
  • Businesses with no phone motion and no outbound at all — a pure e-commerce store with no sales calls gets less than half the value.
  • Buyers who refuse to open their own Twilio and Mailgun accounts. Bring-your-own is the whole pricing model; there is no fully-bundled option.
  • Anyone who needs deep native integrations with a specific vertical system of record today. Chirply has a full REST API and webhooks, but a prebuilt connector to a niche industry tool probably does not exist yet.
  • Buyers who need a card-free trial. Chirply offers a public 14-day Scale trial at https://chirply.io/pricing with a card required; usage through connected providers is separate.

The pricing model, and why it matters

The single most misunderstood thing about Chirply. Get this right on a call.

Most platforms in this category buy telephony and email wholesale and resell it to you with a margin on top — you pay them per text, per minute, per email, and per contact. Chirply does not do that. You connect your own Twilio account, your own Mailgun account, your own AI model key, and your own Stripe account. Chirply orchestrates them. The money for calls, texts, emails, and AI tokens goes from you to those providers directly, at their published rates, on their bill.

There are five retail plans: Spark $7/month ($70/year), Build $27/month ($270/year), Launch $47/month ($470/year), Grow $77/month ($770/year), Scale $97/month ($970/year). Paying yearly costs ten months rather than twelve, so two months are free. Contacts are unlimited on every plan, and nothing is metered: once a plan includes a channel, that channel is unlimited on it, because the provider accounts are yours (your Twilio, your Mailgun, your model key) and they bill you directly. Spark and Build are entry plans that do not include calls, texts or marketing email — those start on Launch. The plans differ by capability and capacity rather than by usage.

The Chirply subscription therefore buys capability and capacity, not volume. Plans are separated by how many phone numbers, AI agents, sales bridges, IVR menus, funnels, workflows and seats you get, and which of the heavier features are switched on — never by how much you use them.

The honest trade-off, which an agent should raise before the buyer does

  • The customer has to open a Twilio account and a Mailgun account. Connecting them is mostly automatic now — Chirply creates what it needs inside those accounts when the credentials are saved, and there are no Twilio webhooks to copy anywhere — but opening and verifying the accounts is still a setup step a fully-bundled competitor does not have, and US text messaging additionally needs carrier registration, which is a waiting game nobody can shortcut.
  • The customer receives two or three bills instead of one: Chirply's subscription, plus their carrier and email usage.
  • In exchange, usage is at wholesale rates with no markup, and at any real volume that is dramatically cheaper. A business sending tens of thousands of texts a month is the clearest case.

What Chirply replaces

The consolidation pitch, category by category.

Chirply is not a point solution. On a discovery call, the fastest way to establish value is to find out what the prospect is already paying for and count how many of these boxes are already in their stack.

  • CRM and contact database — contacts, companies, custom fields, tags, lists, lifecycle stages, activity timeline.
  • Sales pipeline / deal tracking — drag-and-drop boards with stages you define.
  • Phone system — business numbers, a browser softphone, warm transfer, three-way calling, voicemail, call recording and transcription.
  • Power dialer / outbound calling tool — named call queues anyone or any automation can fill, worked without touching the dial pad.
  • Ringless voicemail service — drop a recording into a mailbox without the phone ringing.
  • Voice broadcast / call blast — one message to a whole list, with answering-machine detection.
  • IVR / phone-tree provider — press-1 menus, inbound and outbound, built visually.
  • AI receptionist / answering service — an agent that answers, holds a real conversation, captures details, and transfers to a human.
  • SMS marketing tool — two-way texting, autoresponders, bulk sends, STOP handling.
  • Email marketing tool — broadcasts, templates, merge fields, opens, clicks, bounces, unsubscribes.
  • Cold-outreach sending infrastructure — sending pools that rotate a big send across several of your own verified sender addresses, per-address warmup ramps, and SPF/DKIM/DMARC/MX health checks on your sending domains.
  • Email list verification — addresses checked before you send to them, on your own verification key or on the Mailgun account you already have.
  • Live-chat and website messaging tool — branded widgets, visitor context, AI replies, human handoff, and the same unified conversation history.
  • Marketing automation / workflow builder — triggers, waits, branches, and a full action catalog.
  • Calendar and appointment scheduler — event types, availability, public booking pages, reminders, payments, and appointment-triggered automations.
  • Website, landing-page, and funnel builder — multi-step sites, forms that create contacts, editable niche templates, and member-only pages with access products.
  • Lead generation / scraping tool — a B2B business database and Google Maps search, enriched and deduped into the CRM.
  • Link shortener with tracking — branded short links, per-recipient tracking, click attribution.
  • Website visitor analytics — visitor tracking that resolves to a contact record.
  • Heat maps and session replay — click and scroll-depth maps kept separate for phone, tablet and desktop, and recordings of individual sessions you can play back.
  • Web push / desktop notification service — browser notifications to your own team, per person and per topic.
  • Customer and revenue intelligence — Stripe payments, subscriptions, refunds, disputes, customer status, and lifetime value on the CRM record.
  • Conversation and revenue intelligence — call transcripts read back as a summary, an outcome, sentiment, topics and the objections raised, plus deal risk scoring and a pipeline forecast.
  • Design tool — a multi-page editor with text, shapes, images and gradients, size presets for social, print and web, and a media library that everything else in the platform files its uploads into.
  • Affiliate program software — recruiting, tracking, commission ladders, contests and payouts for YOUR products. It has its own section further down, but it belongs on this list when you are counting subscriptions.
  • Invoicing tool — six invoice types on one pricing engine, with payments landing on the contact timeline.
  • White-label agency platform — resell the whole thing under your own brand and domain.

And one answer that is not a category at all: Chirply has an app platform, so "it doesn't do the specific thing I need" is not necessarily the end of the conversation. Apps run inside the product — their own pages, dashboard widgets, cards on the contact record — they can be run by an automation and can start one, and they get scoped access to the same action catalog everything else uses. Someone technical can point their own AI coding agent at Chirply's MCP server and have it build and publish one. Be accurate about the state of it, though: the platform, the SDK and the review pipeline are built and live, and the catalog of published apps is first-party today. Do not describe a bustling third-party marketplace.

The claim to make is consolidation and a shared system of record: a call, a text, an email, an AI conversation, a payment, and an automation run all land on the same contact record, so there is one place to look before picking up the phone. The claim NOT to make is that Chirply is the deepest tool in every one of those categories. It is not, and saying so gets caught in the demo.

The current platform, beyond the core catalog

Major shipped systems that matter in a product evaluation and are easy to miss in a feature checklist.

Advertising, creative, and conversion delivery

Google Search and YouTube campaign tools now sit alongside Meta advertising. Start in Ads, select a connected advertiser account, build and validate a campaign, and review its budget before launch. Google Launch creates enabled advertising and can incur spend; a saved draft does not. Matching AI-generated landing pages stay drafts and generated follow-up workflows stay paused until separately reviewed. Ad delivery still depends on the provider’s review and account eligibility. Conversion delivery settings cover Meta, Google Ads, and optional GA4; delivery receipts and synthetic validation are diagnostic evidence, not a promise of attribution or results.

AI Writer, brand voice, and durable site builds

AI Writer creates, grades, and rewrites emails and coordinated sequences using a selected framework, workspace brand voice, and AI Brain context. A sequence can become a paused manual-trigger automation; generation itself sends nothing. The website builder goes beyond a single prompt: review a sitemap, resolve missing business facts, connect products and bookings, monitor saved build progress, adjust AI allowances, pause or resume, and retry unfinished work. Generated pages still need review and publication. AI generation is billed separately through the connected provider.

Staff collaboration and connected commerce

Team Chat provides internal channels, private rooms, direct messages, mentions, reactions, search, and notification preferences, separate from the customer inbox. Integration keys participate as integrations in open channels, without access to private rooms or DMs. Shopify brings customers, products, orders, refunds, and abandoned checkouts into the workspace; ongoing sync can trigger configured recovery workflows, so importing is not automatically a read-only action. Klaviyo supports resumable imports, mirrored records, webhook events, and scoped API operations. These connections do not mean every provider operation has its own native Chirply screen.

Where the rest of the product fits

The feature catalog below also covers courses and certificates, customer communities, storefronts and retail operations, proposals and signatures, blogs and CMS, managed WordPress, directories, custom objects and reports, enrichment, tenant help desks, client reports, and industry apps. Those are existing product areas, not roadmap promises. Check the plan matrix, app purchase requirements, and each connection’s availability before recommending a setup. Zapier setup and invite guidance are available under Settings → Integrations → Zapier; an available integration or recipe is not an already-installed automation.

Conversations, live chat, and visitor context

The conversations inbox now treats SMS, email, and website live chat as one customer history. Branded chat widgets can collect visitor details, use AI for first response, hand a conversation to a human, and carry page and session context into the thread. Conversations can be deleted by an authorized user when they no longer belong in the record.

Calendars, websites, funnels, and members

Chirply includes Calendly-style event types, timezone-aware availability, public booking pages, pay-to-book, reminders, and appointment automation triggers. The site and funnel builder includes editable multi-page templates across common business niches, responsive desktop/tablet/mobile previews, password or passwordless member login, members-only page gates, and access products that can be granted or revoked per person.

Website identity and conversions

Website tracking groups visits by person across anonymous sessions and devices without merging one known contact into another on a guess. A visitor can be identified by a form or integration, prior activity folds into the contact timeline, and sites can record first-class lead and sale conversion events. Live Visitors separates who is active now from the persistent recent-visitor feed.

The same tracker also produces heat maps and session replays, and the two have deliberately different defaults. Heat maps are ON by default: clicks, rage clicks, and a scroll-depth histogram, aggregated per page — by path, so a campaign's query string does not shatter one page into fifty — and kept apart for phone, tablet and desktop, because a single map averaged across all three is a picture of a layout nobody ever saw. They are aggregated as they are written rather than replayed from raw events, so the thousandth visitor to a page costs no more storage than the second, and the viewer says outright when a page has too few views to mean anything yet.

Session replay is the opposite: it is OFF by default and switched on per site, because it is the most invasive thing the product does. A site that has not turned it on downloads no recorder and sends no bytes. Where it is on, the workspace picks the retention window (thirty days unless they change it, anywhere from one day to a year), one recording covers one page load rather than a whole visit, and recordings are stored compressed rather than in the database. The privacy behaviour is worth stating on a call because it is stronger than buyers expect: everything a visitor TYPES is masked to asterisks in the browser before anything is uploaded — passwords, emails, phone numbers, free text, every input type — and that is not a setting a site can turn off. Canvas contents are never recorded, and anything already marked sensitive for the app's screen-share privacy mode is dropped from the recording too. A site can block further regions with a CSS class or attribute, and deleting a single replay is a first-class operation for handling an erasure request.

Email deliverability: pools, rotation, warmup, and domain health

This is the strongest answer Chirply has to "will my email actually land?", and it is worth raising unprompted with anyone doing volume. A sending pool is a named set of the workspace's own verified sender addresses that a bulk send rotates across, so one mailbox is not carrying a campaign on its own. Rotation is least-used-today-first rather than a round robin — the address that has sent fewest today goes next, ties broken by the order the addresses sit in the pool — and any address that has already hit its allowance for the day is skipped rather than pushed. If every member is capped, the campaign parks until tomorrow instead of failing the remaining recipients.

Each address can be put on a warmup ramp: start at a small number of emails on day one, add a fixed number each day, and level off at a ceiling. Warmup is off until the customer turns it on, and the starting point, the daily step and the ceiling are all theirs to set. A pool can also carry one Reply-To that overrides every member's own, so replies to a rotated send land in one place; leave it blank and a reply goes back to whichever address actually sent that message.

Separately there is a domain health check for each connected sending domain: whether the provider itself considers the domain verified, and whether SPF, DKIM, DMARC and MX are actually right, each with a plain-language description of what to fix. Be precise about what this is — five discrete checks, run when someone asks for them, advisory. It is not a reputation score, it does not track bounce or complaint rates, and it does not pull a failing domain out of rotation by itself. It all runs on the customer's own Mailgun or Resend account, which is the point: the reputation being warmed belongs to them.

Conversation and revenue intelligence

Calls that are recorded and transcribed can also be read. This is opt-in per phone number and off by default, and it needs transcription switched on for that number, because it works from the transcript. Each analyzed call comes back with a summary, an outcome, a sentiment, the topics it covered, the objections that were raised, suggested action items and a lead score. The thing that makes it useful rather than decorative is that the outcomes, topics and objections come from a fixed, closed vocabulary instead of free text — otherwise the same objection gets written three different ways in three days and a quarter's worth of calls will not add up into anything you can count or trend.

On the money side, an opt-in deal scorer — off by default, separately from call analysis — rates open deals for risk, gathers the evidence first from the workspace's own call, message and stage history, flags deals that have gone quiet past a threshold the customer sets, and produces a forecast that is deliberately shown next to the ordinary stage-probability forecast so the two can be compared. The forecast arithmetic itself is not a model guess.

Two things not to overclaim. There is no "loss reason" field — what exists is objection tagging, ranked over a period, which answers the same question but is not the same words. And a talk-ratio figure is only honest on calls handled by an AI phone agent, because those transcripts know who spoke; ordinary carrier transcription returns one undifferentiated stream, so the ratio is left blank rather than guessed. Finally, the cost: analysis is a model call per call, billed to the customer's own AI key, which is why the operations that trigger it are classified high-risk and the assistant will not re-analyze a year of history because somebody asked it to refresh the numbers.

Desktop notifications

Chirply can push a notification to a team member's browser — a new message or lead, a missed call, an AI employee stopped and waiting for a human to approve something, a payment, or an upcoming appointment — with those five as separate switches each person controls for themselves. Two honest boundaries: this reaches STAFF only and is not a way to message a contact or a customer, and on iPhones the browser only offers notifications once the app has been added to the home screen. Notifications resolve against the host the person subscribed on, so a white-label agency's client gets the agency's icon and is taken back to the agency's own domain.

The media library and the Design Studio

Every workspace has a media library, and it is more than an upload folder: files that other parts of the platform generate or store — AI Studio output, funnel images, social uploads, message attachments — register themselves into it, so there is one place to find everything the business has made. It takes images, video, audio and PDFs, organized into folders, with each file checked against its actual contents rather than trusting what the browser called it.

Alongside it is a real design editor, not a template picker. A multi-page canvas with text, images and shapes; solid or gradient fills, strokes, rotation, opacity and locking; a layers panel, undo and redo, alignment and duplication; a curated font set; ready-made starting templates; and size presets for the formats people actually need — social posts and stories, video thumbnails, banners, flyers and posters, presentations, business cards, logos, email headers, website heroes and link-preview images. It pulls images straight from the media library. Export is PNG, at native or double resolution — do not promise a print-ready PDF, because that is not what it produces.

Capture videos and optional guides

Assets → Videos & guides opens Capture. Record a screen or camera in the browser, pause and resume, recover saved local segments, or import an existing video. A video does not require a guide. When written instructions help, add ordered guide steps and screenshots, maintain a transcript and timed captions, or request generation with the workspace's configured providers. AI processing is an explicit billed-provider operation, not a free background promise.

Share the video, guide, or both using a workspace-branded unlisted link; guide-only sharing does not expose the video. Links can be revoked, shared pages can be embedded, and the original recording can be downloaded. Capture uses private recording storage, unlike the media library's permanent public asset URLs. The downloadable Chrome extension supports selected-tab walkthrough capture, but a new ZIP does not update an existing Chrome Web Store installation. Do not promise native desktop capture, advanced multi-track editing, or complete Loom feature parity.

Bring your own backend: Supabase

For the technical end of the customer base, a workspace can connect its OWN Supabase account — by pasted access token or by authorizing Chirply into one of their Supabase organizations — and then list, provision, inspect, query and tear down real Supabase projects from inside Chirply, and record which project backs which site, funnel or installed app. Projects live in the customer's own Supabase organization and Supabase bills them for it directly; Chirply holds no credits and adds no margin, which is the same arrangement as Twilio and Mailgun. Creating a project starts real compute, so that operation and the destructive ones are classified high-risk.

State the boundary clearly, because it is easy to oversell into something it is not: this is a management console for the customer's Supabase account. It is not data residency, and it does not move Chirply's own records. A prospect who asks "so my contacts and call history live in my own database?" should be told no — that data stays in Chirply — and that what this gives them is their own Supabase projects, managed from one place and drivable by the same API and MCP server as everything else.

Vertical apps, bought per workspace

Some first-party products are sold as apps rather than folded into a plan, and are installed per workspace from the in-app store. They are not included in Launch, Grow, or Scale. This matters on a call in both directions: a restaurant or a martial-arts school is a strong fit and should never be told there is nothing for them, and a prospect on any plan should never be told these are already included.

  • Restaurant — menus with categories, dishes and modifier groups, and an 86 switch that reaches the diner's screen straight away; a point of sale with split checks; per-table tablet ordering; a kitchen display; inventory with recipes and stock movements; and public online ordering and reservation pages under the restaurant's own brand. Card payments run through the restaurant's own Stripe account.
  • Martial Arts Gym — programs with their own belt and stripe ladders, member enrollments (a member is a CRM contact, not a separate person record), append-only promotion history so nobody edits the past to fix a typo, a weekly class schedule, attendance, retention reporting, and a lobby check-in kiosk on a signed link that can be revoked if the tablet walks off.
  • Signage — screens driven from the workspace, on any device that can open a browser. This one is genuinely different from the other two: it is sold as its own small monthly subscription with a free trial through its own sign-up rather than the in-app store, and buying only Signage creates a restricted account rather than a full Chirply workspace.

Never quote a price for one of these from this document. The store listing inside the app is what the customer is actually charged and it is the only source of truth — send them there. Every operation these apps add is in the action catalog at the end of this document, so an agent can run a restaurant's menu or award a gym belt through the API or the MCP server just as a person would through the screen.

Stripe-connected CRM

A connected Stripe account syncs payments, failures, refunds, disputes, subscriptions, and cancellations into Chirply. Events are matched to contacts, customer status and lifetime value are visible in the CRM, and real-time webhook sync can keep the record current automatically. The activity log also includes unmatched account-level payment activity so the business view is not limited to records that happened to match a contact.

Agency and reseller operations

Agencies can create, provision, suspend, reactivate, close, restore, and re-plan client workspaces. They can apply their own branding and domain, automate Cloudflare DNS setup, pass pooled provider credentials into client accounts where supported, define usage prices and prepaid credit balances, and route eligible client payments through their connected Stripe account. Availability depends on the partner entitlement and on any rollout gate shown in the product.

Operational visibility

The dashboard is customizable: widgets can be shown, hidden, reordered, and resized across multiple widths and heights. Activity views combine calls, texts, emails, automation runs, deal movement, website behavior, contacts, and payments, with daily and calendar summaries available through the same capability layer used by API and agent clients.

Capture: Record an explanation. Build a guide when you need one.

Videos, screenshots, optional walkthroughs and a shared place for feedback are included from Spark. Workspace storage limits apply; optional AI uses your connected provider and is billed separately.

Screen and camera recording

Explain the work while you show it. Record a screen, window or tab, your camera, or both, with microphone audio. Keep the result as a video when a written guide would add unnecessary work.

  • Device selection, microphone level preview and countdown
  • Pause, resume, restart and discard with confirmation
  • Saved local recording segments and retryable upload
  • Browser audio depends on the source and operating system

Screenshots and visual annotations

Make your point with one image or a timed callout. Take a standalone screenshot, crop and annotate it, then share it with comments and replies. Video annotations and caption layouts can move and change over time.

  • Screenshot crop, drawing, arrows, highlights and text
  • Timed video annotations and draggable caption layouts
  • Shared conversations on screenshots and videos
  • Original media and published image revisions remain intact

Optional walkthroughs and guides

Give someone steps they can follow at their own pace. Choose a walkthrough to collect supported browser steps, or create and edit a guide after recording. Ordinary video mode does not collect page interactions.

  • Edit and reorder steps, screenshots and instructions
  • Crop, highlight and redact guide screenshots
  • Share a video, guide or combined view
  • Manual guides work without an AI connection

Recording comments and watch activity

Keep questions and follow-up next to the explanation. Use timestamped comments and replies, reactions, watch notifications and recent dashboard activity. Choose notification preferences for the workspace recording.

  • Timestamp links take viewers to the relevant moment
  • Comment moderation and author editing
  • Watch and comment notification preferences
  • Recent recording activity available from the dashboard

Recording library and publishing

Organize your explanations and choose what viewers see. Keep personal or workspace recordings in a searchable library, organize playlists, and publish a reviewed version before sharing. Saving a draft does not silently replace the published guide.

  • Collections, ordered playlists and watch later
  • Published snapshots and explicit draft restore
  • Revocable share links with expiry
  • Original video download and video export tools

Telephony: A whole phone system, not a click-to-dial button.

Chirply runs on your own Twilio account, so you keep carrier-rate pricing and own every number, recording, and log. Everything below is built in — no bolt-on dialer, no second login.

Browser dialer (softphone)

Take and make calls from the same tab your CRM is in. A real softphone docked in the top bar of every page. Inbound calls ring your browser wherever you are in the app, and outbound goes out on your business caller ID.

  • Mute, keypad (for punching through other companies' IVRs), add a third party, warm transfer with the caller held while you consult
  • Simulring your online team — first to answer takes it
  • Missed calls fall through to voicemail and land on the contact's timeline
  • Drag the panel anywhere; it survives navigating the app

Power dialer & call queues

Work a list of 200 leads without touching the dial pad once. Keep as many named call queues as you need — “Callbacks today”, “Trial expiring”, “New leads” — and fill them from anywhere: tick contacts in the CRM, add someone by hand, or have an automation drop them in. Open a queue, hit Start calling, and Chirply walks it for you: dial, talk, log the outcome, next.

  • Many queues, worked whenever you want — the list lives on the server, not in one browser tab
  • Anything can fill a queue: bulk select, a workflow step, a call outcome, or the API
  • Outcomes are written back to the queue, so two reps can work the same list without doubling up
  • Auto-advance after you log a disposition and a note; pause and resume any time
  • Automations can fire the moment someone is called off a queue, branching on the outcome

Predictive dialer

Keep every seated rep talking instead of listening to ringback. A second way to work a call queue: the server dials several numbers per free agent, screens answering machines, and only bridges the people who say hello. Pacing, abandon-rate targets, and wrap-up live on the session — billed on the workspace's own Twilio account.

  • Opens on any existing call queue; a session with no seated rep dials nobody
  • Answering-machine detection with a separate path for machines versus live answers
  • Lines-per-agent, max lines, and an abandon-rate target you can change mid-shift
  • Outcomes write back to the same queue and fire the same follow-up actions as power dial

Call outcomes that do the follow-up

Stop remembering to send the follow-up. Picking the outcome sends it. Define your own call dispositions (name + color) in Settings, then attach actions to them. Choosing an outcome fires those actions in the background while you're already dialing the next number — and the calls nobody logged are collected into a queue instead of quietly disappearing.

  • "Left voicemail" → text them, tag them, and enroll them in a follow-up sequence — automatically
  • Any action in the platform is attachable: SMS, email, RVM, tag, list, pipeline stage, task, AI call
  • An "awaiting outcome" review queue catches every call no browser saw end — desk phones, the mobile app, sales-bridge legs — with a workspace-wide count and one click to work through them
  • Set an outcome on any past call, including calls made before you had outcomes at all; the same actions and automations fire either way
  • Ask for a suggestion and it reads the call's own transcript on your AI account, then tells you which outcome it picked and why — it suggests, you decide
  • A call outcome is its own automation trigger, filterable by which outcome and by call direction, and it re-fires when you correct a wrong one

Ringless voicemail

Land in 500 voicemail boxes without a single phone ringing. A two-leg carrier drop that deposits your recording straight into their mailbox. Their handset never rings, so you're not interrupting anyone — they just see a voicemail waiting.

  • Record it in the browser or generate it with text-to-speech
  • Merge fields are spoken correctly — no robot reading "open brace"
  • DNC list, suppressions, and quiet-hours enforced before every drop
  • Fire it one-off from a contact, from a call outcome, from an automation, or in bulk

Sales bridge — instant warm transfer

Connect a hot lead to a live human in about 15 seconds. The moment a lead is ready, Chirply rings your entire rep pool at once, whispers the lead's context to whoever answers, and bridges the first one to press 1 straight through to the lead.

  • Simulring cell phones and browser softphones together
  • Whisper the lead's name, city, and source before they're connected — recorded or spoken
  • Atomic first-to-claim: exactly one rep wins, every other leg is dropped cleanly
  • Optional SMS heads-up to each rep, dual-channel recording on the bridged call

IVR builder — inbound and outbound

Route every caller correctly without hiring a receptionist. Build press-1 phone trees once and use them on the way in and the way out. Each digit can dial a number, take a voicemail, speak a message, send a text, or open a sub-menu.

  • Recorded intro (record in-browser or upload) or text-to-speech greeting
  • Merge fields in the greeting — callers hear their own name
  • Nested sub-menus, graceful no-input fallback
  • The same menu drives outbound campaigns: they answer, they hear the menu, they press a key

Voice broadcast & call blast

Get one message to a whole list in minutes. Dial an entire audience with a pre-recorded message, text-to-speech, an interactive IVR, or an AI agent — with answering-machine detection branching to a separate voicemail script.

  • Answering machine detection: humans hear one script, mailboxes hear another
  • Quiet hours, DNC, and wallet balance checked before every single dial
  • Concurrency cap so you don't blow up your own switchboard
  • Optional SMS follow-up fired off the same campaign

Recording & transcription

Coach from real calls instead of relying on memory. Opt-in recording per number. Audio is pulled off Twilio into your own storage and the provider's copy is deleted, so there's one place your recordings live.

  • Per-number opt-in, with a recording announcement for consent where you need it
  • Automatic transcription attached to the call log
  • Delete the audio and keep the log and transcript

Per-number control

Every line behaves exactly the way that line should. Each phone number gets its own settings page — no hunting through a shared console.

  • Internal label (the call log names the line, not just the digits)
  • Inbound voice routing: ring the team, an IVR, an AI agent, or forward out
  • Transparent forwarding that shows the original caller's number
  • Outbound caller ID, availability hours, recording and transcription toggles

Line-type intelligence

Know it's a mobile before you spend money texting it. Every contact and lead number is classified mobile, landline, or VoIP and shown with an icon across contacts, contact detail, and lead results.

  • Automatic lookup on new numbers, plus a one-time scan of your existing database
  • Platform-wide shared cache — a number is only ever paid for once
  • Runs on your own Twilio at roughly a fraction of a cent per number

Call tracking & dynamic number insertion

Know which ad, keyword, and publisher produced the phone call. Build call-tracking campaigns that route inbound calls, attribute the source, apply conversion rules, and calculate revenue, payout, and margin from the same call record.

  • Static tracking numbers or website number pools with a one-line DNI snippet
  • Priority, round-robin, and weighted routing with geo and business-hours filters
  • Duration, webhook, or manually confirmed conversions
  • Sticky callers, repeat-call dedupe, recording, and campaign-level reporting

SIP desk phones

Put a physical phone on the same system as the browser dialer. Provision standard VoIP desk phones against the workspace's own Twilio SIP domain, assign them to team seats, and control exactly which business numbers ring each handset.

  • Automatic SIP-domain setup on the first device
  • One-time credential display with secure password rotation
  • Per-device enable, seat assignment, and number routing controls
  • Inbound ringing and outbound calling billed through the workspace's Twilio account

Call scripts & live objection assist

Give a new rep the words, and a quiet nudge when the call turns. Ordered talk-track steps plus a handler for each objection, written once and open beside the dialer. Switch assist on for a script and Chirply reads the live transcript and puts one short line on the rep's screen — it never speaks to the customer.

  • Ordered steps for the talk track, and objection handlers keyed to the same 13 objections call intelligence counts, so coaching and reporting share one vocabulary
  • Assist stays off until you enable it on that script, and stays quiet until the line's transcription has produced something to read
  • One coaching line of 200 characters or less, on the rep's screen only — the assist never joins the call and never speaks
  • Runs on your own AI account, and only re-reads once the transcript has actually grown
  • Scripts travel in snapshots and arrive switched off, so a cloned workspace never starts assisting before anyone has read them

AI: AI that answers the phone — not a chatbot in the corner.

Chirply's AI agents hold real phone conversations, take real actions in the CRM, and hand off to humans when it matters. Bring your own model key and pick the model per agent.

AI phone agents (receptionist)

Never miss another inbound call, at 3am or on a Sunday. Point any number at an AI agent and it answers, holds a natural conversation, and actually does things — captures the caller's details, takes a message, or warm-transfers to a human.

  • Creates and updates the contact record from what the caller says
  • Takes a message and files it as a task for the right person
  • Warm-transfers to a number or to whoever on your team is online — with take-a-message fallback if nobody picks up
  • Leaves your voicemail script after the beep when it hits an answering machine

Real-time voice, not walkie-talkie

It sounds like a person, because it doesn't leave dead air. Calls stream in real time over a dedicated edge worker instead of waiting for a full reply before speaking. The agent starts talking on its first few words, and you can interrupt it mid-sentence.

  • Roughly one second of gap after you stop talking
  • Barge-in: talk over it and it stops and listens
  • Automatically falls back to the standard flow if anything on the streaming path hiccups — a caller is never dropped

AI Brain knowledge base

Teach it your business once, and every agent knows it. Organize everything your agents should know into topics and items — hours, pricing, services, policies, objection handling — then drop it into any agent's greeting, persona, or goals.

  • Upload what you already have: PDF, Word, spreadsheets, HTML, CSV, Markdown, or plain text
  • Or point it at your website and let it read the pages — one page, a section, or the whole domain
  • Merge the whole brain, one topic, or one item into any prompt
  • Word counts and copy chips so you can see what you're spending on context
  • Change the knowledge once; every agent using it updates

Pick the voice it speaks in

Audition voices in the browser instead of calling yourself to hear one. Every agent gets its own voice and language. Choose from the built-in phone voices, or from your own cloned and premium voices if you've connected ElevenLabs.

  • Your ElevenLabs account's own voices — including ones you cloned — listed in the picker
  • Press play and hear a sample right there, no test call needed
  • Set per agent, so your receptionist and your outbound campaigns can sound different

Outbound AI calls & AI campaigns

Qualify a list of 1,000 without a rep on the phone. The same agents make outbound calls — one at a time from a call outcome or an automation, or as a bulk campaign with a per-campaign goal.

  • "AI call" is a first-class action anywhere actions live
  • Bulk AI campaigns ride the same dispatcher: quiet hours, DNC, wallet, metering
  • Every call logged with a full transcript, an AI summary, and an outcome on the contact timeline

AI throughout the app

The blank page problem, gone. AI is woven through the CRM, messaging, and the funnel builder — draft a reply, summarize a contact, or generate a whole landing page.

  • AI page and funnel generation
  • Message drafting and contact summarization
  • A searchable model picker with live input/output pricing and context windows, so you compare cost before committing

AI Writer & brand voice

Turn a campaign brief into copy and a reviewable follow-up sequence. Write, grade, and rewrite emails using a copywriting framework, the workspace's brand voice, and selected AI Brain knowledge. Generate a coordinated series and compile it into an automation.

  • Framework selection with strategy and email-by-email sequence briefs
  • Workspace voice settings shared across generated copy
  • Email and sequence generation uses the workspace's billed AI account
  • Compiled sequences start paused with a manual trigger; generating copy sends nobody a message

AI Studio for images, video & audio

Create the campaign assets without opening six more subscriptions. Generate and transform images, video, avatars, voice, music, and audio from one studio while using your own connected AI accounts.

  • Image generation plus video generation, animation, upscaling, background removal, and lip sync
  • Talking-head avatars, voiceovers, voice cloning and conversion, transcription, cleanup, and dubbing
  • Music, songs, and sound effects from the same generation library
  • Model catalog exposes the real provider, price, and capabilities before you run anything

In-app Copilot

Ask for the outcome instead of hunting through menus. A workspace-aware assistant can search Chirply, answer questions from live CRM context, and propose the same actions available throughout the app.

  • Searchable conversation history and workspace-specific context
  • Reads and actions come from the platform's documented capability catalog
  • Approval required before it sends, spends, publishes, or destroys
  • Past chats can be reopened or removed from one place

Custom tools for voice agents

Let a caller check an order, book service, or update another system live. Connect authenticated external APIs, describe safe reusable operations, test them, publish immutable versions, and assign each tool only to the AI agents that need it.

  • Bearer, basic, API-key, and unauthenticated HTTPS connections
  • Typed inputs, request templates, response instructions, and hard timeouts
  • Encrypted credentials that are never returned to the browser or model
  • Draft, test, publish, assign, and redacted execution history

AI Employees

Hire a coworker with a name, a job, and permissions you set. A five-step hiring wizard — face and name, personality, duties, permissions, then the offer letter — produces a named AI coworker with standing duties, a budget and an approvals inbox, instead of a chat box holding the keys to everything.

  • Access granted per domain at four levels: nothing, view, do the work, or propose — where propose lets it ask to send, spend or delete and a person approves each one
  • Standing duties on a schedule down to every five minutes, each borrowing a named person's authority, with a run log for every execution
  • A duty that fails five times running pauses itself instead of failing forever
  • A daily token budget per employee, checked before each run, so nothing quietly loops up a bill overnight
  • An approvals inbox with a pending count — approving in chat and approving in the inbox settle the same record

Revenue Operator (shadow mode)

See the stalled deals worth recovering, without an AI sending anything on its own. A read-only recovery board over at-risk pipeline: prioritized next moves, coverage, and a flagged-to-won-or-lost ledger that does not pretend correlation is causation. It proposes. It does not text, book, or collect until a later approval phase ships.

  • Ranks open risks from stored deal intelligence — no extra model call and no spend
  • Proposed next moves sit beside the deal, with coverage KPIs for the book
  • Currencies stay separate; partial populations are marked instead of rounded away
  • Sends nothing, starts nothing, and changes nothing — Copilot can open the board, not act from it

AI-first app platform: If Chirply cannot do it yet, your AI can add it.

Chirply is an extensible business operating system, not a sealed feature list. Give your AI coding agent the outcome you need and it can build an app against Chirply's documented capability catalog, install it inside the workspace, and make it part of the same data, automation, and customer journey — often in 30 minutes to a few hours.

AI-built custom apps

Turn “Chirply does not do that” into a working first version today. Use Codex, Claude, or another coding agent to build a focused Chirply app from a plain-language requirement instead of waiting through a traditional product roadmap.

  • The developer guide, manifest contract, and capability catalog are readable by coding agents
  • A narrow internal tool can take about 30 minutes; a richer app can take a few hours
  • Build privately for one workspace, distribute to clients, or submit it to the public marketplace
  • The result installs inside Chirply instead of becoming another disconnected login

Pages, widgets & contact cards

An installed app lives where the work already happens. Apps can add full pages to workspace navigation, widgets to the customizable dashboard, and context-aware cards directly on contact records.

  • Up to 20 declared pages, 20 dashboard widgets, and 20 contact cards per app version
  • Contact cards receive the current contact context automatically
  • App surfaces inherit the workspace install and permission boundary
  • External and hosted interfaces render in isolated, sandboxed frames

App actions & event triggers

The app becomes part of Chirply's workflows, not a tab beside them. An app can contribute its own typed actions to automations, call outcomes, bulk selections, and contact menus, then react to the same business events Chirply already emits.

  • Chirply renders the app action's fields and sends the validated inputs to the app
  • Subscribe to events such as contact created, message received, deal won, and invoice paid
  • Signed event delivery with retries and delivery history
  • The same app action can appear across automation, disposition, bulk, and contact surfaces

Scoped access to the whole platform

Build on Chirply's CRM, communications, billing, and operations instead of recreating them. Installed apps call the same permanent capability registry used by Chirply's REST API, MCP server, and Copilot, through a short-lived in-app bridge or a rotatable server token.

  • Read or act across contacts, pipelines, tasks, messaging, bookings, commerce, sites, and more
  • Fine-grained domain read/write scopes are approved at install time
  • Money-spending and outward-facing operations require an explicit confirm grant
  • Revoking an install immediately closes its data and action access

App-owned data inside Chirply

Keep extension data tenant-scoped and attached to the installation. Every install gets a simple namespaced data store for settings and records, so lightweight apps do not need a separate database just to remember their state.

  • Set, get, list, and delete JSON values through documented capabilities
  • Data is isolated by workspace, app, and installation
  • Multiple installs of the same app can keep separate configurations
  • Hosted apps can stay entirely inside Chirply's runtime for compact use cases

Public marketplace & private distribution

Install the missing capability or turn your solution into a product. Browse a moderated app store, install public listings with a clear permission screen, or keep an app private and deploy it only to the workspaces that need it.

  • Native integrations, external apps, and Chirply-hosted apps
  • Listing pages with screenshots, feature copy, pricing choices, and publisher details
  • Moderation and reporting before unsafe or misleading listings spread
  • Any workspace can install; eligible agencies can build and publish

Versions, release notes & controlled updates

Improve an app without silently changing every customer's workspace. Publish immutable app versions, show installed workspaces what changed, and let an admin review and apply an available update deliberately.

  • Draft, publish, review, list, install, update, uninstall, and revoke lifecycle
  • Version-specific manifest and permission requests
  • Release notes and update availability inside the installed-app screen
  • Rotatable install tokens and platform-admin revocation controls

Sell apps and collect recurring revenue

The extension you needed can become a software business of its own. Publishers can price an app as a one-time purchase, monthly subscription, yearly subscription, or several buyer-selectable options, then receive payouts through Stripe Connect.

  • Optional setup fees plus monthly, annual, lifetime, or free price choices
  • Marketplace checkout installs only after Stripe verifies the payment
  • Developer payout onboarding and status inside Chirply
  • Subscription status controls whether a paid installation stays active

Native & connected apps

Core extensions can change how Chirply works, not just render in a box. First-party native apps use the same install model while opening built-in product surfaces. Connected apps can bring an outside system's data and operations into Chirply.

  • Native apps for directories, desk phones, business cards, and other modular features
  • GoHighLevel provisioning and migration inside the workspace
  • Shopify customers, products, collections, orders, abandoned checkouts, refunds, and privacy requests
  • Klaviyo profiles, consent, events, audiences, campaigns, flows, catalogs, webhooks, and reporting

Industry apps: Whole industries, running inside the same CRM.

Complete industry applications that live inside the platform rather than beside it. The Restaurant and gym apps run on the workspace's own contacts, messaging, payments, and automations — so an order, a check-in, or a booking is CRM activity the moment it happens, with no sync to configure and no second customer list to keep straight.

Restaurant

Run the floor, the kitchen, and online orders from the system that already holds your customers. Thirteen screens covering a working restaurant — menus, point of sale, kitchen display, table tablets, inventory, and a public ordering and reservation site on your own address — with every guest landing in the same contact record your marketing already uses.

  • Menus with categories, dishes, modifier groups, and one-tap 86'ing when something runs out
  • Point of sale that splits a check evenly or by item, records cash, takes cards on your own Stripe account, and emails or texts the receipt
  • Kitchen display with per-station tickets — bump a single item or the whole ticket
  • A per-table tablet screen staff launch and hand to the guest, plus a live floor view of which tables have an open check and what is booked next
  • Inventory with recipes that deplete stock as dishes are fired, a full movement history, and a reorder list of everything at or below its par level
  • Public ordering and reservations at /eat/your-restaurant — or on your own custom domain — fully under your brand, with no mention of the platform
  • A ready-made restaurant website template whose menu section reads the live menu, so 86'ing a dish updates the website and the kitchen at once
  • Guests get their own links to track an order and pay from their phone, or to view and cancel a reservation without calling

Martial arts gym

Belts, attendance and the front-desk tablet, tied to the contact record. Programs with your own rank ladders, students who are simply CRM contacts with an enrollment, and a class schedule they check into — plus a kiosk link that turns any tablet at the front desk into a check-in station.

  • Custom belt ladders per program, with stripes and the full promotion history for every student
  • A member is a CRM contact plus an enrollment — there is no second list of people to keep in sync
  • Promotion eligibility computed from classes attended since the last promotion and months at the current rank — advisory, because the instructor decides
  • Weekly class schedule with check-in, an attendance log, and reporting that surfaces the students who have gone quiet
  • A signed kiosk link that turns any tablet into a check-in station with no login, and one button that disconnects every tablet at once if it leaks
  • A ready-made gym website template whose timetable section renders the live class schedule, so the site is current the moment you move a class

Chirply Signage

Add digital signage to the platform for $9.99 a month, free for the first 30 days. Chirply sells and provisions Chirply Signage end to end — the public offer page, the Stripe subscription and its trial, and the provisioning that creates the workspace, the owner login, and the live app install in one atomic step. The screens themselves are driven from the Signage app that install points at.

  • $9.99 a month through Stripe with a 30-day free trial, and nothing charged at signup — the card is held for the day-30 renewal
  • Signing up provisions the workspace, the owner account, the app install, and the welcome email in one pass, and unwinds the whole thing cleanly if any step fails
  • A time-limited upgrade at signup swaps the app subscription for the full Scale plan at $47 a month with Signage included free
  • Owner-only capabilities report the plan, renewal date, and offer status and accept or decline the upgrade, so an AI agent can answer "what am I paying for" without a human

CRM: The system of record everything else writes to.

Calls, texts, emails, payments, AI conversations, and automation runs all land on the same contact record — so there's one place to look before you pick up the phone.

Contacts & companies

One record per human, with everything they've ever done on it. Inline-editable contact records with companies, business name, website, and address — plus your own custom fields for whatever your business actually tracks.

  • Custom fields of every type, usable as merge fields everywhere
  • Phone matching that ignores formatting — (409) 893-0064 finds 4098930064
  • Duplicate phone numbers are refused on the way in, and anything already doubled up is surfaced for you to sort out
  • Tags, lifecycle stage, and per-row quick actions

Sales pipelines

See the whole board and drag a deal to where it really is. Drag-and-drop deal pipelines with stages you define — and stage changes that can trigger automations.

  • Multiple pipelines, custom stages
  • "Deal stage changed" is an automation trigger
  • "Move pipeline stage" is an action any automation, outcome, or bulk selection can fire

Tasks & activity timeline

Nothing falls through, and you can prove what happened. A tabbed activity feed on every contact with multi-select filters by channel and direction, plus tasks with priorities and due dates.

  • Calls, SMS, email, AI sessions, payments, and automation runs on one timeline
  • Filter to just inbound calls, or just email, in a click
  • Tasks created by hand, by an automation, or by an AI agent taking a message

Lists & bulk actions

Do one thing to two thousand people at once. First-class contact lists, plus a multi-select bulk actions bar on contacts and lists that offers every action the platform has. Lists are the ones you curate by hand; smart segments below are the ones that keep themselves current.

  • Select all across pages, not just the visible ones
  • Point any bulk action at a saved smart segment instead of ticking rows
  • Tag, list, lifecycle, pipeline stage, task, delete
  • Bulk SMS and email, personalized with merge fields and threaded into each contact's own conversation
  • Bulk ringless voicemail, outbound IVR, sales bridge, AI call, campaign enroll

Merge fields everywhere

Personalization that works in every field, not just email. One renderer powers the whole platform — every built-in contact field plus all of your custom fields, with a searchable picker beside every composer.

  • 26 built-in tokens including nested address parts
  • Checkboxes render Yes/No, multi-selects comma-spaced
  • Works in SMS, email, voice TTS, IVR greetings, AI personas and goals, and campaign copy

Custom dashboard & business activity

Open Chirply and see what moved before you open a report. A drag-and-resize dashboard combines pipeline, revenue, calls, contacts, tasks, live visitors, chat, and recent activity in the layout each workspace wants.

  • Date and pipeline filters shared across the dashboard
  • Live operational widgets alongside revenue and conversion widgets
  • Activity calendar and feed with channel-level filters
  • Saved per-workspace layout with a one-click reset

Digital business cards & card scanner

Turn a handshake into a clean CRM record before the card gets lost. Create public, shareable team business cards and use AI vision to read physical cards into the CRM, including front and optional back images.

  • Public profile and downloadable vCard for every published team card
  • Names, roles, phones, emails, website, socials, bio, and theme controls
  • AI card scan creates a contact or updates the phone/email match
  • Save another Chirply card into contacts without creating duplicates

Workspace-wide search

Jump to the record you meant without remembering where it lives. Search contacts, companies, deals, and pipelines together from one command surface and open the matching record directly.

  • One query across the core CRM object types
  • Direct links to the exact contact, company, deal board, or pipeline
  • Available to people, the REST API, MCP clients, and Copilot

Smart segments

Define an audience once as rules and let it keep itself current. Rule-based audiences over the contact record and everything attached to it, so “booked but never showed, and nobody has called them in two weeks” becomes a saved segment you send to — not a spreadsheet someone exports again every Monday.

  • 49 built-in fields grouped as Contact, Address, Consent & safety, Membership, Broadcast email engagement, Website engagement and CRM activity — plus every custom field you have added
  • Related-record rules across Bookings, Stripe, Sales, Work, Conversations, Calls and Forms, with 45 more filters underneath them
  • Text, number, date, boolean and relation operators — including “is in the last N days” and count rules like “has more than two open tasks”
  • Every filter on a related record has to match the same record, so two unrelated appointments can't fake a match
  • Preview the exact match count and sample contacts before saving, with up to 20 conditions per segment

Custom report builder

Answer your own questions about the business without exporting to a spreadsheet. Build reports at /reports from six datasets — contacts, deals, calls, messages, appointments and revenue — choosing the dimensions, metrics, filters and time bucket yourself. Save the ones you'll run again and share them with the workspace.

  • Six datasets with their own dimensions, metrics and filters — daily, weekly, monthly or total time buckets
  • Reports run only through a declared catalog, so a report can never reach data its dataset doesn't expose
  • Save reports privately or share them with the whole workspace
  • Export any result to CSV

Custom objects

Model the records your industry actually runs on, not just contacts and deals. Define your own record types — properties, vehicles, policies, pets — with typed fields, then create, list, and link records under /objects like any built-in part of the CRM.

  • Text, number, date, boolean, select and more field kinds, with a chosen display label per type
  • The record form validates with the same rules the server enforces, in plain language
  • Records are workspace-scoped with row-level security like every other table
  • Full API, MCP and Copilot access through the same capability registry as the rest of the product

Scheduling: From available slot to paid appointment.

Publish branded booking pages, coordinate one person or a whole team, collect the right intake details, and keep every appointment attached to the contact who booked it.

Public booking pages

Let leads book the right meeting without the email ping-pong. Every event type gets a shareable booking page with your availability, timezone handling, intake questions, confirmation copy, and location instructions.

  • One-on-one, group, collective, and round-robin events
  • Phone, in-person, video, Google Meet, Zoom, Teams, or custom locations
  • Minimum notice, date range, buffers, capacity, and slot interval controls
  • Custom confirmation message and post-booking redirect

Team availability & round robin

Offer the team, not one person's calendar. Create reusable schedules, date-specific overrides, and host pools that distribute appointments or require multiple people to attend together.

  • Workspace-local hours with invitee timezone display
  • Per-host schedules, priority, and required-host rules
  • Round-robin assignment and collective availability
  • Closed dates and custom hours without rebuilding the week

Appointment operations

See every booking and keep the customer informed. Staff can manage appointments while customers receive secure links to confirm, reschedule, or cancel their own booking.

  • Confirmed, completed, canceled, and no-show states
  • Contact matching and appointment history
  • Email and SMS reminders at configurable offsets
  • Cancellation reason and reschedule lineage retained

Paid appointments

Take the deposit before the time is reserved. Require payment on an event type and collect it on the workspace's own Stripe account, so the deposit lands in the business's bank and not in a platform balance.

  • Per-event price and currency
  • Payment status carried on the appointment
  • Money is collected on the workspace's own Stripe account, never pooled through the platform
  • Booking notifications wait for the payment outcome

Google & Microsoft calendar sync

Your outside calendar and your booking pages stop double-booking each other. Connect a host's Google Calendar or Microsoft 365 / Outlook account. Busy times flow in before slots are offered, and confirmed bookings are written out as real calendar events.

  • Google Calendar and Microsoft 365 / Outlook, linked per host from Scheduling → Connections
  • Inbound busy-time sync merged into availability before a slot is ever shown
  • Outbound event creation, update and deletion mirrored onto every calendar marked for write-back
  • A broken or expired connection records its error and falls back to internal availability — it can never take the booking page down
  • Staff can also reschedule any appointment from their side with a slot picker, keeping the lineage

Messaging & email: Every conversation in one thread.

Two-way SMS, email, WhatsApp, Messenger, and Instagram against the same contact, with the compliance plumbing — unsubscribes, STOP handling, suppressions, quiet hours — already wired.

Internal team chat

Keep staff conversations alongside the work they are discussing. Create open or private channels and direct messages for workspace members, with message search, mentions, reactions, unread state, and notification preferences.

  • Channel membership and private conversations respect the acting person's access
  • Edit and delete messages with the same permissions in the UI and capability handlers
  • API integrations can participate in open channels under an integration identity; keys cannot read private channels or direct messages
  • Staff chat is separate from the customer conversations inbox

Unified conversations inbox

Stop switching apps to find out what you already told them. Inbound and outbound SMS, email, WhatsApp, Messenger, and Instagram threaded together per contact, with color-coded bubbles for direction.

  • Reply from the inbox or straight from the contact record
  • Inbound email routed in via your own sending domain
  • WhatsApp, Messenger, and Instagram sit in the same thread as SMS and email
  • Every message on the shared activity timeline

WhatsApp Business

Text the number they already have open, inside the 24-hour window or with an approved template. Connect a WhatsApp Business number through Meta, match inbound chats to CRM contacts, reply free-form inside the customer-care window, and send live-revalidated approved templates outside it.

  • Account and number discovery against the connected Meta business
  • 24-hour free-form replies, with the window shown before a send can fail
  • Approved templates revalidated before send, including variables and media
  • Independent WhatsApp consent ledger, quiet hours in the recipient's timezone, and delivery receipts reconciled to a local message id

RCS business messaging

Send branded rich cards when the handset supports them, and fall back to SMS when it doesn't. Onboard an RCS sender in the workspace's own Twilio account, then send rich cards with a plain-text fallback. Twilio decides at delivery time whether the message went out as RCS or SMS, and Chirply meters whichever actually landed.

  • Sender status, templates, and a Google-verified onboarding path that typically takes weeks — Chirply does not invent a shortcut
  • Rich cards with a required SMS fallback for handsets that cannot do RCS
  • Delivered-channel recorded after send, so reporting and wallet charges follow what Twilio actually used
  • Hidden until RCS is enabled for the workspace; every other message still goes out as ordinary SMS

Messenger & Instagram DMs

Answer social leads without losing the CRM context. Connect Facebook Pages and linked Instagram professional accounts so inbound DMs become real Chirply conversations attached to the right contact.

  • Facebook Messenger and Instagram direct messages in the shared inbox
  • Meta's reply-window rules shown before a send can fail
  • Comments, mentions, reactions, and message events retained
  • Human replies and AI assistance use the same conversation history

Autoresponders

A reply goes out in seconds, at 2am, without you. Rule-based automatic replies on inbound messages, fully merge-field aware.

  • Trigger on inbound message content
  • Personalized with the contact's real details
  • Handed off to automations for anything more involved

Broadcast campaigns

Reach a whole segment on any channel, from one screen. One-off blasts by email, SMS, ringless voicemail, outbound IVR or AI call — one composer, one audience builder, real analytics. Multi-step follow-ups are automations.

  • Any channel from one composer — email, SMS, voicemail drop, IVR or AI call
  • Send windows, days of week, timezone, and throttle-per-minute
  • Email goes out through your sender pool, so warmup caps are respected and a send bigger than today's capacity parks the remainder for tomorrow instead of failing it
  • Every send appears in the background jobs monitor, where you can pause, stop, reschedule or slow it down while it is still running
  • Signed one-click unsubscribe, SMS STOP handling, and provider bounce/complaint suppression
  • Opens, clicks, bounces, unsubscribes, and per-recipient status

Templates

Write the good version once and reuse it forever. Reusable SMS, email, and ringless-voicemail templates — including recorded audio or text-to-speech for voicemail — available from every composer.

  • "Start from a template" in the bulk text and email composer
  • Voicemail templates store the recording or the TTS script
  • Templates are selectable from automations and call outcomes too

Compliance built in

The boring parts that keep you out of trouble. A shared compliance layer every outbound channel runs through — no per-feature reimplementation, no gaps.

  • Do-not-call list and per-org suppressions
  • Quiet hours by local timezone on every voice and campaign channel
  • TCPA consent text on the click-to-call widget, recording announcements on calls

Communications command center

See what needs a human across every channel. A cross-channel communications view rolls unread conversations, calls, email, SMS, social messages, and live chat into one operational queue.

  • Unread counts shared with the navigation
  • Archive and restore without deleting history
  • Newest customer touch surfaced first
  • Direct path back to the contact and full thread

Email senders, pools & warmup

Send from several mailboxes so no single domain carries the whole list. Connect as many Mailgun and Resend accounts as you want, give every address its own identity, and group them into a pool your campaigns send through. Warmup ramps a new address up instead of throwing a cold domain at fifty thousand people on day one.

  • Multiple Mailgun and Resend connections, each address with its own display name, reply-to and status
  • Pool rotation always picks the mailbox that has sent the least so far today, skipping any already at its cap
  • Warmup starts at 10 a day, steps up by 10 a day and settles at 200 — every one of those numbers adjustable per address
  • A one-click domain health check covering provider verification, SPF, DKIM, DMARC and MX, reported in plain language
  • A campaign larger than the pool's remaining capacity parks the rest until tomorrow — nobody is marked failed for running out of room

AI inbound email responses

Every inbound email gets a considered reply, even the ones that arrive at 2am. Point an AI agent at an inbound email address and it answers on your behalf — or, in draft mode, writes the reply and waits in the thread for a human to approve it before anything sends.

  • Per-address modes: off, draft-for-approval, or send automatically
  • Draft mode queues the reply in the conversation itself — approve, edit or discard from the thread
  • RFC 3834 loop guards so two robots can never trap each other in an infinite reply loop
  • Runs on your own AI account with your Brain knowledge, like every other AI surface

Automations: One action catalog. Available everywhere.

Chirply has a single registry of things it can do. Every surface that fires actions — workflows, call outcomes, bulk selections — draws from the same list, so a capability can never exist in one place and be missing in another.

Visual workflow builder

Build the follow-up once and let it run forever. Multi-step workflows with waits and branching, triggered by what actually happens in your business.

  • Triggers: contact created, tag added, deal stage changed, form submitted, message received, call completed, on a schedule, or manually / by webhook
  • Steps: send SMS or email, add or remove tags, add to a list, move a pipeline stage, create a task, wait, call a webhook, notify your team
  • Branches read your own custom fields as well as the built-in ones, and steps can fill a custom field from what the event carried
  • Voice steps: ringless voicemail, outbound IVR, sales bridge, AI call, enroll in a campaign
  • Full run history so you can see what fired and why

Route each plan down its own path

One automation can serve every plan you sell. Stripe entry points carry the price and product the customer actually bought, so a workflow can narrow to one plan or send each plan somewhere different — assign the right access, tag them, create the account, and tell your team.

  • Narrow a Stripe entry point to the Price IDs or Product IDs you choose, straight from your Stripe catalogue — list the monthly and the yearly price together and one workflow serves both
  • Or keep one workflow and split it: an If / otherwise or a Switch routes on the price the event carried
  • Every Stripe event publishes its price, product, plan name, amount, interval and quantity as data you can insert into any step
  • Works on new subscriptions, cancellations, and the payments and renewals behind them

The shared action engine

Add a capability once and it shows up in every menu. Actions are defined in one registry with their fields and the surfaces they're allowed on. Workflows, call dispositions, and bulk actions all render from it.

  • Same action, same options, whether you're in a workflow or a bulk selection
  • Pickers for numbers, IVR menus, campaigns, sales bridges, AI agents, lists, and stages
  • Registry-driven, so the menus can't drift out of sync

Webhooks & external API actions

Connect the odd system nobody has a native integration for. Trigger a workflow from a signed public URL or call an outside API from inside a flow with configurable method, authentication, headers, query parameters, and body.

  • Incoming webhook trigger per workflow
  • Bearer, basic, and API-key authentication
  • JSON, form, raw, or automatic Chirply payloads
  • Merge fields work in URLs, headers, queries, and bodies

Branching, waits & run history

Build a real journey and see exactly where every person went. Visual flows branch on contact and event data, park safely through timed waits, and retain the node-by-node execution history for every enrolled contact.

  • Condition branches and explicit success paths
  • Durable waits that resume on a later dispatcher tick
  • Manual, bulk, event, schedule, and API enrollment
  • Run detail shows what fired, what changed, and what failed

Click-to-call widget

Turn website visitors into live phone calls. An embeddable call-me button for any site. A visitor enters their number, your team rings, and the two are bridged — usually inside 20 seconds.

  • Simulring or sequential dialing of your rep pool, with a whisper before connect
  • Business-hours scheduling and a desktop / mobile visibility switch
  • Your logo, colors, copy, and "powered by" line — or none at all
  • Origin allow-list, daily call cap, TCPA consent text, and missed-lead notifications

Background jobs & send pacing

Change your mind halfway through a send to twelve thousand people. Every bulk action runs as a job you can watch and steer. Pause it, stop it, move its start time, or slow it down while it is running — the change lands on what has not gone out yet, and never on what already has.

  • Pause, resume, cancel, reschedule or re-pace a running job in a single action
  • A cursor tracks exactly what has been sent, so re-pacing or stopping only touches the remainder
  • Scheduled jobs wait here until their start time, honouring send windows and per-minute, per-hour and per-day throttles
  • Covers outbound work — bulk email, SMS, automation enrollment, action runs — and bulk record updates like tags, lifecycle, lists and deletes

Sites, funnels & commerce: Build the journey, take the order, and deliver the access.

Websites, funnels, checkout, invoices, gated content, and domains share the same CRM and automation layer. A submission is never stranded in a separate page-builder account.

Funnel & website builder

Ship the customer-facing experience without another platform. Build standalone sites and multi-step conversion funnels from reusable sections and responsive components, then publish them from the same workspace.

  • Pages, navigation, forms, countdowns, pricing, testimonials, checkout, and custom HTML
  • Desktop, tablet, and mobile previews
  • Form submissions create or update contacts and can trigger workflows
  • Draft, publish, unpublish, version, restore, and performance reporting

Forms, surveys, quizzes & lead capture

Collect structured answers and put them straight to work. Build reusable forms, surveys, quizzes, and applications outside the page editor, publish them for embedding or sharing, and map every submission into the CRM and automation layer.

  • Drag-and-configure fields with required states, CRM mappings, and multi-step pages
  • Conditional branching, answer piping, scoring, outcomes, and qualification logic
  • Published embed and share destinations
  • Submission history tied to the matching contact
  • Form-submitted triggers for immediate follow-up

AI creative partner

Start with a complete first draft instead of an empty canvas. Generate a site or funnel from a prompt, rewrite copy in place, create supporting images, and ask AI to make structured edits without flattening the page into uneditable markup.

  • Whole-funnel and single-page generation
  • Structured AI edits that preserve editable components
  • Copy rewriting and image generation
  • Version snapshots and restore before risky changes
  • Durable build progress with pause, resume, cancellation, and page-level retry controls
  • Review and revise the sitemap, resolve missing business facts, and connect booking or product resources
  • Generation uses bounded AI allowances and leaves pages as drafts for separate publication

Templates & marketplace

Reuse the good setup instead of rebuilding it for every client. Start from built-in funnel patterns, save a page or section as a reusable template, or publish approved templates for other workspaces to install.

  • Built-in templates for lead gen, webinars, offers, events, SaaS, and local business
  • Page, section, funnel, and workspace-level templates
  • Private reuse plus moderated public marketplace listings
  • Preview before install or publish

Checkout, order bumps & upsells

Raise the order value without sending buyers through another tool. Sell through embedded order forms with optional bumps and one-click post-purchase upsells, all charged through the workspace's connected Stripe account.

  • One-time and recurring products
  • Order bump on the checkout step
  • One-click upsell and downsell flows
  • Orders, payment state, refunds, and customer identity retained

Storefronts, carts & retail operations

Run the entire store without splitting customer and order data across platforms. Launch a branded storefront from the same catalog funnels use, then manage variants, inventory, collections, carts, discounts, checkout, orders and fulfillment beside the CRM.

  • Hosted storefront, product pages, search, collections, persistent carts, and Stripe checkout
  • Physical, digital, service, subscription, variant, SKU, stock, and backorder support
  • Server-validated discounts, abandoned carts, delivery details, order status, and tracking
  • Purchases become CRM customers, inventory movements, and automation triggers automatically

Member sites & access products

Sell protected content and control who can open each page. Turn a site into a member experience with passwordless login, named access products, page-level gates, invitations, and manual or automated entitlement changes.

  • Secure email login links
  • Page access by one or more products
  • Invite, grant, revoke, suspend, and sign out members
  • Member history tied back to the CRM contact

Courses, quizzes & certificates

Deliver a real learning product and see who finishes it. Build courses from ordered modules and rich lessons, enroll contacts, track progress, test comprehension, and issue publicly verifiable completion certificates.

  • Video, rich content, downloads, duration, drafts, and ordered modules
  • Drip schedules and community-level gates
  • AI-generated multiple-choice quiz drafts with passing requirements
  • Enrollment, lesson progress, completion automations, and certificate lookup

Customer communities

Keep the conversation, learning, and customer identity together. Turn a member site into a moderated community with spaces, posts, comments, access gates, points, levels, and leaderboards.

  • Open, level-gated, product-gated, and staff-only spaces
  • Pinned posts plus reversible post and comment moderation
  • Points, configurable levels, and 7-day, 30-day, or all-time leaderboards
  • Level-ups can unlock content and trigger automations

Proposals, estimates & e-signatures

Move from scoped work to a signed agreement without another document tool. Create proposals, estimates, and contracts, link them to invoices, email a private review link, and keep a typed-name signature plus a certificate row on the document. This is not DocuSign-class multi-party signing.

  • Draft and edit commercial documents before anything is sent
  • Real recipient delivery through the workspace's Mailgun account
  • The buyer types their name to accept; Chirply stores certificate data and document history
  • Signed records become immutable and stay linked to payment
  • A separate paid Proposals app adds a price book, financing options, and convert-to-invoice

Custom domains

Your brand on the address bar, not ours. Point a domain at Chirply and it's provisioned automatically — DNS record and SSL certificate handled through the Cloudflare API.

  • Search, purchase, connect, and verify domains inside Chirply
  • Custom domains for funnels, links, invoices, and the white-labeled app
  • Automatic certificate issuance
  • Host and path routing to the right tenant experience

Pixels & site scripts

Install measurement once and use it across every published page. Create reusable advertising pixels and scripts, attach them to the right domains and funnels, and keep the installation visible in one place.

  • Facebook and custom pixel definitions
  • Reusable script library
  • Per-domain and per-page attachment controls
  • Safe hosted delivery instead of copy-paste drift

CMS, blogs & SEO operations

Publish an actual content system, not a pile of disconnected landing pages. Create structured content collections and blogs, draft and schedule entries, import WordPress content, and audit the on-page SEO before publishing.

  • Reusable collections and custom entries for structured site content
  • Draft, schedule, publish, unpublish, and update lifecycle
  • WordPress import for existing posts and content
  • SEO audit plus page-level titles, descriptions, redirects, and social metadata

Managed WordPress hosting

Launch and operate client WordPress sites from the same agency workspace. Provision hardened WordPress servers in your own DigitalOcean account, connect domains, issue HTTPS, and manage the site lifecycle without leaving Chirply.

  • Plan catalog and domain availability checks before launch
  • Automated server, WordPress, DNS, and certificate provisioning
  • Site status, retry controls, credentials, backups, and operational details
  • Confirmed destruction for sites you intentionally retire

Business directories & local marketplaces

Turn a niche or geography into an owned lead-generation asset. Build branded directories with categories, custom listing fields, editorial posts, claim flows, lead forms, custom domains, and automated listing acquisition.

  • Custom categories, fields, listings, posts, themes, and public publishing
  • Business claim review and lead-routing operations
  • Geography-based acquisition planning, budgets, campaigns, and retryable imports
  • Each directory installs as a native Chirply app and feeds the wider CRM

Funnel A/B testing

Let the traffic decide which page version sells, not the loudest opinion. Run two versions of a funnel page against live traffic. Visitors are assigned server-side — no flicker, no client-side swap — and stay on their version for the whole test.

  • Deterministic assignment via a first-party cookie, so a returning visitor always sees the same version
  • Adjustable traffic split between the two arms
  • Bots and cookie-less clients get version A and are never counted, so crawlers can't skew a result
  • Results are reported with honest significance — the page tells you when there isn't enough traffic to call a winner yet

Assets & design: Make the artwork where the campaign already lives.

Every file the workspace uploads or generates lands in one library, and the editor that makes the next one sits beside it — so a graphic goes from idea to a funnel, an email, or a Facebook post without a round trip through another tool or another subscription.

Capture videos & guides

Show someone how it works, then share the video or turn it into a guide. Record your screen or camera from Assets → Videos & guides. A quick screencast stands on its own; add an editable walkthrough when the task needs written instructions.

  • Browser recording with pause, resume, local recovery, and resumable private uploads
  • Import existing videos, edit guide steps, maintain transcripts and timed captions, and trim a separate video copy
  • Share a video, a guide, or both through a branded unlisted page; revoke the link when access should end
  • Embed shared recordings and download the original source file
  • Use recording management through the REST API, MCP server, and in-app assistant
  • The downloadable Chrome extension adds selected-tab walkthrough capture; its ZIP release and Chrome Web Store rollout are separate

Media library

One address for every image, video, audio file, and PDF the business owns. Upload it once, file it into folders, and reuse it anywhere. Every file gets a permanent public URL, so a link you pasted into a campaign last quarter still resolves after the file has been renamed and moved.

  • Images, video, audio, and PDFs — up to 25 MB a file, 10 files and 60 MB in a single upload, with the type checked against the bytes and not the extension
  • Folders, rename, move, and delete; renaming a file never changes its URL
  • Generate an image on your own AI account and it lands in the library ready to use
  • Machines can pull a file straight in from a URL through the API, with private and internal addresses refused
  • Uploaded SVGs are served under a no-script sandbox, so a logo someone sent you can't carry code into your pages
  • AI Studio output, funnel AI images, and social uploads file themselves here automatically — nothing to remember and nothing to re-upload

Design Studio

Design the post, the flyer, and the email header without a separate subscription. A drag-and-drop canvas editor built into the workspace. Start from a named size or type your own, layer text, shapes, and images, and export a PNG that is already in your media library.

  • 16 named presets — Instagram post, Story/Reel, Facebook post and cover, YouTube thumbnail, LinkedIn banner, flyer, poster, email header, 16:9 presentation, business card, logo, invoice header, website hero, blog cover, and link preview — plus any custom size
  • Layered text, shapes, and images with a properties panel for position, rotation, opacity, fill, gradient, and stroke
  • Twelve curated fonts, documents up to 20 pages, and a lock control on any element you are done moving
  • Ten built-in starter designs, and PNG export at 1x or 2x — download it or push it straight into the library
  • Pull artwork from the media library or generate it on your own AI account without leaving the canvas
  • Save any design as a reusable template the whole workspace starts from

Lead generation & intent: Find new prospects and see who is already raising a hand.

Chirply combines outbound lead sourcing with first-party visitor identity, tracked links, embedded chat, and conversion widgets so both cold and warm demand land in the same CRM.

Multi-source lead search

Build a targeted prospect list without leaving the CRM. Search a large B2B business database, Google Maps, Yelp, or domain registrant data, inspect the results, and import only the prospects you want.

  • Business, category, geography, keyword, rating, review, and contact filters
  • Paginated results with select-all across pages
  • Email, contact, and company-detail enrichment where available
  • Live cost estimate before a paid search or enrichment runs

Domain-owner prospecting

Find the people behind relevant domains, not just another company list. Search a historical database of roughly 26 million non-private domain registrations by keyword, domain ending, country, or registrant, then bring selected owners into the CRM.

  • No subscription and no per-search fee once the app is in the workspace
  • Registrant name, company, phone, email, address, registrar, and dates where available
  • Look up one domain or discover other domains owned by the same registrant
  • Privacy-protected registrations are excluded instead of sold as empty leads
  • Bulk import up to 500 matched registrants into contacts

Lead dedupe & import control

Pay for new prospects, not the same phone number twice. Every source normalizes phones and business data before import, flags matches against prior searches and the CRM, and reports exactly what was new or skipped.

  • Phone-unique dedupe across searches and contacts
  • Duplicate counts visible before import
  • Source and search history retained on the contact
  • Bulk import into the CRM with selected rows only

Website visitor intelligence

See buying intent before the form arrives. Install a lightweight first-party tracker and watch live visitors, sessions, pages, traffic sources, campaigns, and returning people across every connected site. The same tracker feeds the heat maps and session replay below — one script, three views of the same behaviour.

  • Live visitor board with page and session context
  • Anonymous visitor history that merges into a known person later
  • UTM, referrer, click-id, device, and geography context
  • Per-person and per-site activity timelines
  • Heat maps and session replay run off this same tracker, so turning one on adds no second snippet to your site

Link Wizard

Turn every shared URL into a measurable, controllable asset. Create branded links with schedules, expiry, click caps, destination rules, pixels, recipient tracking, and custom social-preview cards.

  • Custom link domains and branded slugs
  • Device, country, date, and maximum-click routing
  • Per-link analytics and known-recipient history
  • Optional tracking script and advertising pixels

Live chat & AI handoff

Capture the question while the buyer is still on the page. Embed a branded chat widget, answer from the Chirply inbox, let AI handle routine turns, and take over with the full visitor and conversation context intact.

  • Multiple widgets with their own branding and status
  • Shared human inbox with close and takeover controls
  • AI-to-human and human-to-AI handoff
  • Visitor identity and click-path context beside the conversation

Heat maps

See where people actually click, and where they give up. Click and scroll maps for any tracked page, aggregated as visits happen rather than reconstructed one session at a time — so a thousand visits fit in a single picture and you can still tell which button people are hammering.

  • Click density plus a ranked list of the elements taking the most hits, each with its share of the total
  • Rage clicks flagged when someone jabs the same 30-pixel area three times, each click within 700ms of the last — usually something that looks clickable and isn't
  • A scroll-depth curve with a fold line marking where half your visitors stop reading
  • Separate maps for mobile, tablet and desktop, because the layout they saw was not the same one
  • A plain warning below about 30 views, so nobody redesigns a page off the back of four visitors
  • Reset a page's map after a redesign so the old layout's clicks don't muddy the new one

Session replay

Watch the session that went wrong, without recording anything private. Turn it on for a site and Chirply records visits as a replayable document. Every input is masked in the browser before a single byte is uploaded, so what comes back is behaviour — never keystrokes.

  • Off by default and enabled per site; a site not using it never even downloads the recorder
  • Retention you choose from 1 to 365 days — 30 by default — with expired recordings purged automatically
  • Player at 1x, 2x, 4x and 8x with inactivity skipped, so a nine-minute session watches in about one
  • Every keystroke masked in the browser before upload; add data-redact or the block class to exclude whole regions
  • Recordings are attributed to the identified person, so a replay sits alongside everything else you know about them

Contact enrichment waterfall

Fill in what you don't know about a contact without ever overwriting what you do. An ordered waterfall of lookups — website visitor identity, cross-field inference, the Domain Leads database, phone line-type intel, and an optional paid Outscraper business lookup — that runs cheapest first and stops as soon as nothing is missing.

  • Fill-blanks-only by contract: a non-empty field can never be overwritten, whatever a provider claims
  • Every value carries provenance — which step supplied it, and what a paid lookup cost
  • Paid steps are opt-in per run with a budget cap, and are skipped with a logged reason otherwise
  • Paid lookups bill the workspace's own provider accounts (Outscraper key, Domain Leads access) — never a platform meter

Revenue & billing: From deal value to money collected.

Quotes, invoices, payment schedules, Stripe activity, attribution, affiliates, and workspace usage live beside the contacts and deals that produced them.

Invoices & quotes

Send the commercial terms from the same record your team sold from. Create branded invoices and quotes with reusable line items, public links, status history, reminders, and a customer-facing payment experience.

  • Draft, publish, send, duplicate, close, archive, and mark paid
  • One-time, recurring, payment-plan, and scheduled charge structures
  • Public document, order, and payment timeline
  • Charge a saved card or collect through checkout

Flexible payment collection

Match the payment schedule to the way the customer agreed to buy. Collect a one-time payment, start a subscription, split a finite payment plan, schedule a future charge, or combine immediate and recurring line items.

  • Card collection and saved payment methods through Stripe
  • Finite installment plans distinct from subscriptions
  • Deferred and scheduled payments
  • Failed, paid, canceled, and refunded states retained

Stripe customer & revenue sync

See what a contact paid without opening Stripe. Connect one or more Stripe accounts and sync customers, payments, refunds, subscriptions, and failed charges into Chirply's customer and revenue views.

  • Real-time webhook sync plus manual backfill
  • Payer matching by contact identity
  • Provider retries deduped before they reach the timeline
  • Revenue separated from unrelated activity on a shared platform account

Revenue & conversion dashboards

Connect activity to the money it produced. Monitor collected revenue, subscription run rate, pipeline value, source performance, funnel conversion, campaigns, links, and orders from their operational dashboards.

  • Gross, cost, refund, and collected-revenue treatment
  • MRR and ARR kept separate from cash collected
  • Pipeline, source, funnel, link, and campaign reporting
  • Workspace-local date boundaries

Affiliate programs

Let partners bring the customers and see what they earned. Run first-party affiliate campaigns with tracked links, referrals, commissions, multi-level downlines, leaderboards, payout methods, and Stripe Connect onboarding.

  • Campaign-specific links and default attribution
  • Referral, commission, and payout ledgers
  • Affiliate portal and leaderboard
  • Admin payout queue with Stripe Connect or manual payout state

Usage wallets & cost controls

Know the spend before a campaign quietly runs the account dry. Meter calls, messages, email, AI, leads, lookups, and voicemail against workspace balances and agency rate cards, with enforcement at the expensive operation itself.

  • Per-event usage ledger and balance
  • Stripe-backed wallet top-up and auto-recharge off a saved card, credited only after the payment succeeds
  • Agency wholesale cost, markup, and client rate cards
  • Campaigns pause cleanly when funds are unavailable
  • Workspace and superadmin usage reporting

Conversation & revenue intelligence

Turn what was actually said on your calls into a number you can act on. Call transcripts analysed against a fixed taxonomy — a closed list of objections, topics, outcomes and risks — so the answers are countable instead of a wall of prose that reads differently every week.

  • Ranked objections and topics over a 30-day window, with talk ratio reported only for the calls where the speakers could be told apart
  • Per call: a short summary, the outcome, sentiment, the next step if anyone agreed to one, and one coaching note — or none, because it will not manufacture criticism
  • Deals scored on health, risk and days since contact, with the evidence behind each verdict stored beside it
  • Two forecasts side by side — one from stage win rates, one from what was said on the calls — and the gap between them
  • Feeds your automations: workflows can start when a call's analysis lands (filtered by mood, topic, or objection) or the moment a deal turns at-risk
  • Runs on your own AI account, switched on per phone number, and needs that number's transcription on to see anything

Recurring subscriptions you sell

Sell your own memberships and let access manage itself. Sell recurring products through your funnels on your own Stripe account. A paid subscription grants the buyer's access automatically, a lapsed one revokes it, and subscribers manage their own card and cancellation through a Stripe billing portal.

  • Charged on the workspace's own Stripe account — including Connect sales — never pooled through the platform
  • Membership access is granted on payment and revoked when the subscription ends, with no manual list-keeping
  • Buyers update their card or cancel through Stripe's billing portal, so card details never touch Chirply
  • A sensible default portal configuration is created for Stripe accounts that never set one up

Reputation: Ask for the review at the only moment it works.

The minute a job is done is the minute goodwill peaks. Chirply asks then, routes the happy ones to whichever public site you care about, and quietly catches the unhappy ones before they post.

Review requests & tracking links

Every finished job asks for the review by itself. Generate a trackable review link per customer and send it from a workflow the moment work is marked complete. You see who opened it, who clicked, and who left one.

  • One link per customer, so you know exactly who reviewed
  • Fires from any workflow trigger — task completed, invoice paid, deal won
  • Opened / clicked / completed status on every request
  • Send over SMS or email on the channel they already reply to — through your own number and sending address, logged in their conversation

Review destinations

Send people to the site that actually matters for your business. Attach Google, Facebook, Yelp, Trustpilot, BBB, Tripadvisor or any custom URL to each location. The customer picks from the ones you chose, in the order you set.

  • Per-location destinations — a multi-site business isn't one review page
  • Any custom review URL, not just the platforms we pre-list
  • Order them so your priority site is first
  • Pause a location without deleting its history

Private feedback & service recovery

Hear about the bad experience before the internet does. Customers give you their honest experience first. That feedback stays private to your team, with an assignee and a recovery status, so an unhappy customer becomes a phone call instead of a one-star review.

  • First-party feedback that is never published anywhere
  • Needs follow-up / in progress / resolved, with an owner
  • Internal notes on every response
  • Public review destinations still offered to everyone, whatever they rated you

Google review ingestion, AI replies & review widget

See every Google review in one place, draft the response in seconds, and show the best ones on your site. Link each location to its Google Maps listing and Chirply pulls its reviews in through your own Outscraper account — deduplicated on re-sync, never doubled. An AI draft gets a reply started, and an embeddable widget puts your reviews on any site you run.

  • Google review sync per location, keyed on the provider review id so re-syncing never duplicates
  • AI reply drafts written on your own AI account — you edit and post them; publishing directly back to Google is still to come
  • Embeddable review widget with a minimum-star threshold you control
  • Runs on the workspace's own Outscraper key, the same connection the lead finder uses

Social & advertising: Connect advertising and social activity to the CRM.

Connect your own advertising accounts, build Google and YouTube campaigns, manage Meta advertising, publish social content, and bring leads and conversion evidence back into the workspace. Provider permissions and account eligibility still apply.

Google Search & YouTube campaigns

Build the ad, landing page, and follow-up in one workspace. Connect an advertiser account, generate Search copy and keyword suggestions or a YouTube script, review the campaign, and validate it before creating or launching it.

  • Account reporting, published landing-page selection, and campaign status controls
  • Brand voice and AI Brain context, with voice intake and screenshot references
  • Matching AI-built landing pages stay drafts; generated follow-up workflows start paused
  • Launch creates enabled advertising and can spend the reviewed daily budget on your Google account, subject to Google's review and eligibility
  • A YouTube script is not a rendered video; AI generation and advertising have separate provider costs

Advertising conversion delivery

Send consented conversion signals and see delivery receipts. Configure Meta, Google Ads, and optional GA4 tracking for the workspace's sites, with server delivery settings, connection checks, and recent event receipts.

  • Meta Pixel and server events, Google Ads server authorization, and optional GA4 settings
  • Recent event delivery states and safe error details
  • Synthetic connection and validation tools without recording real purchases
  • Transport acceptance is not proof of attribution, and validation does not guarantee campaign results

Social content calendar

Plan and publish without losing the campaign context. Draft, schedule, publish, retry, and cancel Facebook Page and Instagram posts from one visual content calendar, with optional manual handoff for Groups.

  • One post, many destinations across Facebook Pages and Instagram
  • Text, link, and uploaded-image posts
  • Per-network rules checked before you schedule, not at publishing time
  • Draft, scheduled, published, failed, and canceled states
  • Group posting checklist when Meta requires a human handoff

Meta ads management

Build and control campaigns beside the leads they generate. Browse connected ad accounts, build campaigns and creatives, inspect campaign and individual-ad performance, and pause or resume delivery from the workspace.

  • Campaign, ad-set, creative, and ad inventory
  • New campaigns created safely in a paused state
  • Budget, objective, targeting, and destination controls
  • Activation is an explicit, confirmed action
  • Delivery states and parent campaign/ad-set state are shown when resuming an individual ad
  • Advertising is billed by Meta; access depends on the connected account's permissions

Facebook Lead Ads

Lead-form submissions in the CRM in seconds, mapped the way you want. Discover the lead forms on each connected Page, decide question by question where every answer lands, and let new leads arrive as contacts your automations can act on straight away.

  • Forms are discovered per Page and start switched off — a new form never quietly begins importing
  • Map each question to a CRM field, keep it as a custom answer, or ignore it outright
  • Leads arrive as contacts and fire a lead-received trigger any workflow can start from
  • Runs on the workspace's own connected Facebook account, with the last sync time and any error kept per form

Agency & platform: Built to be resold, from the schema up.

Chirply is multi-tenant at the database level, not by convention — four tiers, row-level security on every table, and a white-label layer that was in the design from day one.

White-label & reseller

Sell it as your own product, at your own price. Run the whole platform under your brand and your domain, issue sub-accounts to your clients, and bill them yourself.

  • Your logo, colors, and domain across the app and auth emails
  • Client workspaces under your agency, each fully isolated
  • Agency rebilling and markup on usage

Teams, roles & sub-accounts

Give people exactly the access they should have. A four-tier hierarchy — platform, agency, sub-account, user — with owner, admin, and member roles and email invites.

  • Agency admins reach into their own sub-accounts; clients never see each other
  • Invite by email with a role attached
  • Superadmin console with audited "view as org" impersonation

Reseller plans, pooling & client billing

Package Chirply as your own recurring software offer. Create your own client plans and limits, pool selected provider credentials, connect Stripe, set rate-card markups, and start or stop billing per sub-account.

  • Custom plan names, entitlements, usage limits, and client assignment
  • Stripe Connect onboarding and account status for agencies; client charges are collected on the client's own Stripe account
  • Optional pooled Twilio, Mailgun, AI, and lead-provider credentials
  • Client credit adjustments, suspension, restoration, and billing sync

Bring your own providers

Carrier-rate pricing and no vendor holding your data hostage. Twenty providers you connect with your own accounts and pay directly — telephony, email, AI, media, leads, commerce, payments and hosting. Chirply never marks up the wire.

  • Connect services including Twilio, Mailgun, Resend, OpenRouter, ElevenLabs, fal.ai, Replicate, Outscraper, Firecrawl, Facebook & Instagram, Google Ads, Stripe, PayPal, Shopify, Klaviyo, BookFunnel, GoHighLevel, Supabase and Cloudflare; availability and setup differ by provider
  • Plus DigitalOcean behind managed WordPress hosting, and NeverBounce behind email validation
  • Credentials stored encrypted, per workspace, never shared across tenants
  • Every provider card shows the exact webhook URLs to paste and the events to enable
  • Providers that need no setup say so outright instead of leaving you guessing

Snapshots & reusable account setups

Package a working workspace and deploy it again safely. Bundle funnels, workflows, templates, fields, pipelines, widgets, settings, and related assets into versioned snapshots for clients or the marketplace.

  • Preview every create, update, replace, and skipped item before install
  • Resolve workspace-specific numbers, domains, and credentials through install slots
  • Publish versions and push approved updates to sub-accounts
  • Undo an install when the generated changes need to be removed

API & built-in MCP server

Your AI agents can drive Chirply directly. The public REST action API, built-in MCP server, and in-app Copilot all read the same capability registry, so software can operate the same product people do.

  • Hundreds of documented reads and actions across every product domain
  • Catalog, search, describe, and run from the same permanent action names
  • Bearer-authenticated with scoped, revocable API keys
  • Confirm-classified actions stop Copilot before it sends, spends, or destroys

Developer apps & integration marketplace

Let partners extend the platform without sharing a master key. Create installable apps with versioned permissions and tokens, test their connections, publish a version, and submit it for platform review and directory listing.

  • Draft, version, publish, review, install, and uninstall lifecycle
  • Declared capability scopes per app version
  • Rotatable installation tokens
  • Moderated app and snapshot marketplace

GoHighLevel connection & migration

Run both systems together, or move into Chirply without treating the old account like a black box. Provision or connect a HighLevel sub-account, scan what is there, monitor signed webhooks, import contacts safely, and use the official LeadConnector API for migration or ongoing interoperability.

  • Create a complimentary HighLevel sub-account from inside Chirply and link it to the workspace automatically
  • Inventory contacts, pipelines, calendars, workflows, forms, surveys, and custom fields
  • Non-destructive contact, pipeline, opportunity, and appointment import matched by normalized phone or email
  • Conversation history and workflow conversion are not imported yet — those stay on the HighLevel side until that seam closes
  • Snapshot metadata, share links, webhook health, and per-resource scope diagnostics

Carrier trust & messaging registration

Handle the registration work that keeps calls and texts deliverable. Guide each workspace through Twilio business identity, caller-name, call-signing, messaging-profile, and A2P brand and campaign registration.

  • Business profile validation and submission
  • CNAM, SHAKEN/STIR, Voice Integrity, branded-calling guidance, and messaging-profile paths
  • A2P brand, use case, campaign, and number assignment
  • Provider status refresh and plain-language review state

Security, privacy mode & audit trail

Keep tenants separate and demos safe. Row-level security protects tenant data, provider secrets stay server-only and encrypted, sensitive screens can be privacy-masked, and privileged impersonation is visibly audited.

  • RLS enabled on every table, policies delegating to security-definer helpers
  • Impersonation recorded to an audit log and surfaced with a persistent banner
  • Server-only secrets never reachable from the browser bundle
  • Configurable blur and reveal controls for screen-sharing real accounts

Platform administration & crash operations

Operate the whole SaaS without reaching into the database. A guarded superadmin console covers tenants, users, plans, payments, usage, affiliates, marketplace review, support, and a deploy-aware production crash queue.

  • Tenant inspection, entitlements, suspension, and audited impersonation
  • User suspension, deletion preview, and account compensation
  • Revenue, payment, plan, and usage controls
  • Grouped crash reports that reopen automatically when a deployed regression returns

Desktop notifications

Know a customer replied without keeping a tab open all day. Browser push to each device you approve, so a message, a missed call or an approval waiting on you reaches the machine you are actually sitting at.

  • Approved per device — turn it on for your laptop and not for the shared machine at reception
  • Choose what is allowed to interrupt you: messages, calls, approvals, payments or reminders
  • Send yourself a test notification, so you know it works before you start relying on it
  • On a white-label agency's own domain the notification carries the agency's name and icon

Your own installable app

Your agency's clients install your app, not ours. On a white-label agency's own domain Chirply serves a complete web app manifest under the agency's name, icon and colors — so a client installs it to a phone home screen or a desktop dock as the agency's product, with nothing in it naming the platform.

  • Requires the white-label entitlement; on by default from there, with one switch to turn it off
  • Agency name, short name, theme and background color, plus long-press shortcuts into Conversations and Contacts
  • No icon uploaded yet? One is generated from the brand's initial on the brand's own color, in both standard and maskable form
  • The offline screen names the agency rather than Chirply
  • A shared Chirply iOS/Android companion covers inbox, dialer, contacts, and pipeline; agency-branded store listings are the remaining seam
  • the BRANDING is the white-label part: an agency's app carries their name, icon and colors on their own domain. Chirply's own host installs as Chirply.

Bring your own Supabase

Own the database your funnels and apps write into. Connect your own Supabase account and point workspaces, funnels or installed apps at your own projects. Chirply never bills you for the database, because Supabase bills you directly.

  • Connect by OAuth or a pasted access token, both encrypted server-side, with the token refreshing itself and falling back if OAuth is revoked
  • Create a real project in your own Supabase organization, in any of 17 regions, on your own card with nothing added on top
  • Link a backend per workspace, per funnel or per installed app, falling back to the workspace default
  • Only the anon key ever reaches the browser — the service-role key and database password stay encrypted on the server

Support center & feature board

Report a bug with the recording attached, and watch what gets built. Support lives inside the app: threaded bug reports with real attachments, and a feature board where requests are voted on in the open and carry a status you can see.

  • Bug reports with a threaded conversation and attachments — screenshots, screen recordings, PDFs and logs, up to 25 MB each
  • One feature board shared across the whole platform, with upvotes, comments and six statuses: open, under review, planned, building, shipped and declined
  • Members see their own reports and owners and admins see the workspace's — enforced by row-level security, not by hiding buttons
  • Runs under the agency's brand in a white-label workspace

What's new

Tell whether the fix you were waiting for has actually reached you. Every production deploy that goes green writes an entry, summarised from the commits it carried, with the version you are currently running shown at the top of the page.

  • One entry per deploy that actually shipped — nothing lists a build that never made it out
  • The running version is displayed and its entry pinned, so “is this live for me yet” takes one glance
  • Notes are generated from the commits in that release rather than written up afterwards
  • Brand-scrubbed for white-label, so an agency's clients never read the platform's name in a changelog

Tenant help desk

Run your own support operation — tickets, SLAs and satisfaction scores — under your own brand. Every workspace gets a help desk at /helpdesk: a branded public portal where customers submit tickets, agent queues with priorities and SLA timers, and a CSAT score collected when the ticket closes.

  • Branded submission portal and a secure per-ticket status link — no login needed to follow a ticket
  • Queues, priorities, assignees, and SLA due times tracked per ticket
  • CSAT score and comment collected from the requester on resolution
  • Replies land on the ticket's status link and notify your team by push — email delivery of replies isn't built yet, so requesters follow the link

Scheduled client reports

Every client gets their numbers on schedule without anyone assembling them. An agency sets a standing order per sub-account — weekly or monthly — and Chirply emails that client their report for the completed period, plus a cross-client rollup so the agency sees every account's numbers side by side.

  • Weekly or monthly cadence per sub-account, with chosen recipients
  • Reports cover the previous completed period and can never send twice for the same one
  • White-labeled under the agency's brand, not the platform's
  • A cross-client rollup view for the agency across all sub-accounts

Outbound webhooks API

Your systems hear about events the moment they happen, instead of polling for them. Register webhook endpoints against your API key and Chirply delivers platform events to them — signed, retried with backoff, and logged per delivery.

  • Subscribe any HTTPS endpoint to the events you care about, via /api/v1/webhooks or the capability surfaces
  • Every delivery is HMAC-signed; the signing secret is shown exactly once at creation and stored encrypted
  • Failed deliveries retry with backoff, with per-delivery status and error visible
  • Up to 200 active event-endpoint subscriptions per workspace

Two-factor authentication (TOTP)

A stolen password stops being enough to get into the account. Enroll an authenticator app in Settings → Security and sign-in asks for the six-digit code. Enforcement runs at the database level, so a session that skipped the second factor is limited everywhere — not just where the UI remembered to check.

  • Standard TOTP — works with any authenticator app, no SMS codes to intercept
  • Enroll, verify and remove factors from Settings → Security
  • Database-level step-up: a password-only session on a 2FA account is restricted by policy, not by the front end
  • Available to every workspace on every plan

Setup checklists

Find out what is missing before the campaign fails, not after. Plain-language prerequisite cards for the parts of the platform that depend on an outside account, each step checked against your own connected accounts wherever a machine can check it.

  • Eleven checklists: AI phone agents, business texting, custom domains, email sending and receiving, Facebook & Instagram, AI Studio, affiliate payouts, Restaurant, Google review ingestion, contact enrichment and recurring subscriptions
  • Live checks against your own connections — Twilio, Mailgun, OpenRouter, ElevenLabs, fal.ai, Replicate, Meta, Stripe, PayPal, Cloudflare, Outscraper, and whether you have an active number
  • Steps no machine can see — carrier registration, DNS verification, an addendum you signed — are yours to confirm, and say so plainly
  • Advisory and never blocking: once every step is met the card disappears instead of nagging

Pricing — the plans

Three publicly purchasable plans. Prices are per workspace, in US dollars, billed monthly or yearly.

Annual billing is ten times the monthly price, which is two months free. Everything in a lower plan is included in every higher plan. Volume — contacts, calls, texts, emails, voicemail drops — is unlimited on all of them, including Launch, because the customer pays their own providers for it.

Spark — $7/month, or $70/year (two months free).

For: Getting paid. Send the link, send the invoice, get paid.

  • Unlimited contacts & companies
  • Capture in full — screen recordings, screenshots, guides, comments & viewer alerts
  • Link Wizard in full — branded short links & per-person tracking
  • Invoicing in full — one-off, recurring, payment plans & deposits
  • Checkout on your own Stripe, with receipts
  • Pipeline, tasks, lists & full activity timeline

Build — $27/month, or $270/year (two months free).

For: Getting found. Put your offer on the internet, under your own domain.

  • Everything in Spark, plus:
  • 3 funnels & landing pages · 3 forms, surveys & quizzes
  • 1 course with quizzes, certificates & member login
  • 1 custom domain
  • Booking pages with calendar sync

Launch — $47/month, or $470/year (two months free).

For: Solo operator. Run your whole book of business out of one login.

  • Everything in Build, plus:
  • Unlimited calls, texts & emails on your own Twilio and Mailgun
  • Browser dialer with recording · 1 number, 1 sales bridge, 1 IVR
  • Unified conversations inbox & broadcasts
  • 5 funnels · 3 courses · 2 custom domains · 3 automations

Grow — $77/month, or $770/year (two months free).

For: Small team. Add an AI receptionist, ringless voicemail, and your team.

  • Everything in Launch, plus:
  • 1 AI phone agent with its own knowledge base
  • Ringless voicemail + voice broadcast
  • Power dialer & call transcription
  • 10 seats · 5 numbers · 25 automations
  • Lead generation, REST API & custom domain

Scale — $97/month, or $970/year (two months free).

For: Agency & power user. Unlimited everything, and your AI agents can drive it. This is the plan most buyers should land on, and the one marked most popular on the pricing page.

  • Everything in Grow, plus:
  • Unlimited AI phone agents
  • Real-time streaming voice (no dead air)
  • Outbound AI calls & bulk AI campaigns
  • Built-in MCP server + unlimited API keys
  • Unlimited seats, numbers, bridges, IVRs & funnels

Pricing — the full plan comparison

Every limit on every plan, exactly as published on the pricing page. Use this to answer 'is X included on Y?' precisely.

SparkBuildLaunchGrowScale
Price per month$7$27$47$77$97
Price per year$70$270$470$770$970

Capture — videos, screenshots & guides

CapabilitySparkBuildLaunchGrowScale
All Capture features (Included from Spark: recordings, screenshots, guides, annotations, editing, sharing, comments, viewer alerts and dashboard. Workspace storage and processing safety limits apply; connected AI providers bill separately.)IncludedIncludedIncludedIncludedIncluded
Custom domains for Capture (Dedicated domains for shared videos, screenshots and guides. Choose a workspace default or override it per capture. Domain registration is separate.)10101010Unlimited

Volume

Contacts are unlimited from the first rung up. Reaching those contacts — calls, texts and conversation email — starts on Launch, and runs on your own Twilio and Mailgun, so you pay carrier rates directly and we never mark up the wire. Nothing is metered on any plan.

CapabilitySparkBuildLaunchGrowScale
Contacts & companiesUnlimitedUnlimitedUnlimitedUnlimitedUnlimited
Calls — inbound & outbound (Talking to customers starts on Launch)Not on this planNot on this planUnlimitedUnlimitedUnlimited
SMS & MMSNot on this planNot on this planUnlimitedUnlimitedUnlimited
Marketing & conversation emails (Invoices, receipts, booking confirmations and form notifications send on every plan — this is the inbox and the campaigns)Not on this planNot on this planUnlimitedUnlimitedUnlimited
Ringless voicemail drops (Included with ringless voicemail)Not on this planNot on this planNot on this planUnlimitedUnlimited

CRM

CapabilitySparkBuildLaunchGrowScale
Team seats12210Unlimited
Sales pipelines1115Unlimited
Custom fields (Usable as merge fields everywhere)10101050Unlimited
Lists, tags, tasks & activity timelineIncludedIncludedIncludedIncludedIncluded
Bulk actionsTag, list, stage, taskTag, list, stage, taskTag, list, stage, task+ bulk SMS & emailEvery action
Custom dashboard & business activity feed (Drag the widgets you care about into place)IncludedIncludedIncludedIncludedIncluded
Workspace-wide searchIncludedIncludedIncludedIncludedIncluded
Smart segments (Saved filters that keep themselves up to date)Not on this planNot on this planNot on this planIncludedIncluded
Digital business cards & AI card scannerNot on this planNot on this planNot on this planIncludedIncluded
Custom objects (Model anything — properties, policies, pets — with its own fields and records)Not on this planNot on this planNot on this planNot on this planIncluded

Telephony & voice

CapabilitySparkBuildLaunchGrowScale
Phone numbersNot on this planNot on this plan15Unlimited
Browser dialer (softphone)Not on this planNot on this planIncludedIncludedIncluded
Warm transfer & 3-way calling (Included with the browser dialer)Not on this planNot on this planIncludedIncludedIncluded
Call recording (Included with the browser dialer)Not on this planNot on this planIncludedIncludedIncluded
Call transcriptionNot on this planNot on this planNot on this planIncludedIncluded
Power dialer & call queues (Named server-side lists the dialer works straight through)Not on this planNot on this planNot on this planIncludedIncluded
Predictive dialer (Server-paced multi-line dialing with answering-machine screening)Not on this planNot on this planNot on this planNot on this planIncluded
Call outcomes with attached actions (Prompted after every call — Launch includes 1 attached action per outcome)Not on this planNot on this plan1UnlimitedUnlimited
Call scripts & live objection assist (Talk tracks beside the dialer, with a quiet on-screen nudge)Not on this planNot on this planNot on this planIncludedIncluded
Sales bridges (Hot lead to a live rep in ~15 seconds)Not on this planNot on this plan13Unlimited
IVR flows (Inbound and outbound, same builder)Not on this planNot on this plan15Unlimited
Ringless voicemailNot on this planNot on this planNot on this planIncludedIncluded
Voice broadcast & call blastNot on this planNot on this planNot on this planIncludedIncluded
Per-number settings & routing (Included with phone numbers)Not on this planNot on this planIncludedIncludedIncluded
Call tracking & dynamic number insertion (Pay-per-call routing and source attribution)Not on this planNot on this planNot on this planNot on this planIncluded
SIP desk phonesNot on this planNot on this planNot on this planNot on this planIncluded
Line-type intelligence (Included with phone numbers)Not on this planNot on this planIncludedIncludedIncluded

AI

CapabilitySparkBuildLaunchGrowScale
AI phone agents (Answer inbound, capture details, transfer to a human)Not on this planNot on this planNot on this plan1Unlimited
Real-time streaming voice (~1s response, barge-in — not walkie-talkie)Not on this planNot on this planNot on this planNot on this planIncluded
AI Brain knowledge base (Grow includes 1 brain with document upload; Scale is unlimited brains)Not on this planNot on this planNot on this planIncludedIncluded
Website crawling into the AI Brain (Point a brain at a site and keep its knowledge fresh)Not on this planNot on this planNot on this planNot on this planIncluded
Outbound AI callsNot on this planNot on this planNot on this planNot on this planIncluded
Bulk AI call campaignsNot on this planNot on this planNot on this planNot on this planIncluded
AI drafting & contact summariesNot on this planNot on this planNot on this planIncludedIncluded
Choose the voice your agent speaks inNot on this planNot on this planNot on this planIncludedIncluded
In-app Copilot (Drive the whole platform in plain English)Not on this planNot on this planNot on this planIncludedIncluded
Custom tools for voice agents (Let an agent look things up or act mid-call)Not on this planNot on this planNot on this planNot on this planIncluded
AI Studio — images, video, voice & music (Generate, upscale, remove backgrounds, clone a voice, dub, lip-sync)Not on this planNot on this planNot on this planIncludedIncluded
AI Employees (Named coworkers with standing duties, a budget and an approvals inbox)Not on this planNot on this planNot on this planNot on this planIncluded
Revenue Operator (shadow mode) (Read-only recovery board — it proposes, it does not send)Not on this planNot on this planNot on this planIncludedIncluded
Bring your own model keyIncludedIncludedIncludedIncludedIncluded

Messaging & campaigns

CapabilitySparkBuildLaunchGrowScale
Unified conversations inboxNot on this planNot on this planIncludedIncludedIncluded
AutorespondersNot on this planNot on this plan110Unlimited
Broadcasts — email, SMS, voicemail, IVR & AI callsNot on this planNot on this planUnlimitedUnlimitedUnlimited
SMS, email & voicemail templatesNot on this planNot on this plan10UnlimitedUnlimited
Facebook Messenger & Instagram DMs in the same inboxNot on this planNot on this planNot on this planIncludedIncluded
WhatsApp Business (24-hour window plus approved templates, on your Meta number)Not on this planNot on this planNot on this planIncludedIncluded
RCS business messaging (Rich cards through your Twilio sender, with SMS fallback)Not on this planNot on this planNot on this planNot on this planIncluded
Communications command center (Everything unread, across every channel, in one queue)Not on this planNot on this planNot on this planIncludedIncluded
Email senders, pools & warmup (Rotate several From addresses and ramp a new domain safely)Not on this planNot on this planNot on this planNot on this planIncluded
Compliance — DNC, quiet hours, STOP, unsubscribeIncludedIncludedIncludedIncludedIncluded

Automations

CapabilitySparkBuildLaunchGrowScale
Workflows (active)Not on this planNot on this plan325Unlimited
Full trigger set & run historyIncludedIncludedIncludedIncludedIncluded
Voice steps — RVM, IVR, sales bridge, AI callNot on this planNot on this planNot on this planIncludedIncluded
Click-to-call widgetsNot on this planNot on this planNot on this plan1Unlimited
Background jobs & send pacing (Pause, stop, reschedule or slow a send while it is still running)IncludedIncludedIncludedIncludedIncluded

Sites, funnels & content

Everything you publish — the page that takes the order, and the content that brings people to it.

CapabilitySparkBuildLaunchGrowScale
Funnels & landing pagesNot on this plan3510Unlimited
Standalone forms, surveys & quizzesNot on this plan3510Unlimited
AI page & funnel generationNot on this planNot on this planNot on this planIncludedIncluded
Funnel, page & section template library (Built-in patterns, your own saved templates, and the public marketplace)IncludedIncludedIncludedIncludedIncluded
Website custom domains (Chirply subdomain included)Not on this plan125Unlimited
Funnel A/B testing (Split traffic between page variants and let the numbers pick the winner)Not on this planNot on this planNot on this planIncludedIncluded
Pixels & site scriptsIncludedIncludedIncludedIncludedIncluded
CMS, blogs & SEO operations (Content collections, scheduled posts, WordPress import, on-page audit)Not on this planNot on this planNot on this planIncludedIncluded
Managed WordPress hosting (Provisioned into your own DigitalOcean account)Not on this planNot on this planNot on this planNot on this planIncluded
Business directories & local marketplacesNot on this planNot on this planNot on this planNot on this planIncluded

Lead generation & intent

Finding new prospects, and spotting which of the ones you already have are raising a hand.

CapabilitySparkBuildLaunchGrowScale
Built-in lead generation (B2B database + Google Maps, deduped into the CRM)Not on this planNot on this planNot on this planIncludedIncluded
Lead dedupe & import control (One phone number is one contact — duplicates merge themselves)IncludedIncludedIncludedIncludedIncluded
Link Wizard — branded short links & per-person trackingIncludedIncludedIncludedIncludedIncluded
Website visitor intelligence (See which company and person is on your site)Not on this planNot on this planNot on this planIncludedIncluded
Live chat widget & AI handoffNot on this planNot on this planNot on this planIncludedIncluded
Heat maps (Where people actually click, tap and stop scrolling)Not on this planNot on this planNot on this planIncludedIncluded
Session replay (Watch a real visit back, with typed input masked)Not on this planNot on this planNot on this planNot on this planIncluded
Contact enrichment waterfall (Fill in a contact's title, company and socials from your connected data providers)Not on this planNot on this planNot on this planIncludedIncluded

Scheduling & appointments

Booking pages that write to the same calendar your team already works.

CapabilitySparkBuildLaunchGrowScale
Public booking pagesNot on this planIncludedIncludedIncludedIncluded
Appointment reminders & rescheduling (Included with booking pages — email confirmations on Build, SMS reminders from Launch)Not on this planIncludedIncludedIncludedIncluded
Calendar sync (Google and Microsoft 365) (Included with booking pages)Not on this planIncludedIncludedIncludedIncluded
Team availability & round robinNot on this planNot on this planNot on this planIncludedIncluded
Paid appointments — deposits & prepayNot on this planNot on this planNot on this planIncludedIncluded

Commerce, courses & communities

The things you sell, and the places customers consume them.

CapabilitySparkBuildLaunchGrowScale
Checkout, order bumps & upsellsIncludedIncludedIncludedIncludedIncluded
Countdown offers on funnel pagesIncludedIncludedIncludedIncludedIncluded
Courses, quizzes & certificatesNot on this plan1310Unlimited
Member sites & access products (How a buyer logs in to the course or product they bought)Not on this planIncludedIncludedIncludedIncluded
Recurring subscription products (Sell a subscription through checkout, billed on your own Stripe)Not on this planNot on this planNot on this planIncludedIncluded
Storefronts, carts & discount codesNot on this planNot on this planNot on this planNot on this planIncluded
Customer communities (Member feeds, points and leaderboards under your brand)Not on this planNot on this planNot on this planNot on this planIncluded

Money & reporting

From the value of the deal to the money actually collected.

CapabilitySparkBuildLaunchGrowScale
Invoicing — one-off & recurringIncludedIncludedIncludedIncludedIncluded
Advanced invoice structures — group invoices, payment plans, trial laddersIncludedIncludedIncludedIncludedIncluded
Payment plans, deposits & scheduled chargesIncludedIncludedIncludedIncludedIncluded
Payments on the contact timelineIncludedIncludedIncludedIncludedIncluded
Stripe customer & revenue sync (What a contact has paid, without opening Stripe)Not on this planNot on this planNot on this planIncludedIncluded
Revenue, pipeline & conversion dashboardsIncludedIncludedIncludedIncludedIncluded
Custom report builder (Compose your own tables and charts from the workspace's data)Not on this planNot on this planNot on this planIncludedIncluded
Scheduled white-label client reports (Recurring branded PDF reports emailed to your clients)Not on this planNot on this planNot on this planNot on this planIncluded
Usage metering, rate cards & spend controls (Meter calls, messages, email and AI against a workspace balance, with Stripe top-up and auto-recharge)Not on this planNot on this planNot on this planNot on this planIncluded
Conversation & revenue intelligence (Objections, deal risk and a forecast from what was said on the calls)Not on this planNot on this planNot on this planNot on this planIncluded

Assets & design

Make the artwork where the campaign already lives, instead of paying for a separate design tool.

CapabilitySparkBuildLaunchGrowScale
Media library (Every image, video, audio file and PDF the workspace owns, in one place)IncludedIncludedIncludedIncludedIncluded
Design Studio (Drag-and-drop canvas — 16 preset sizes, layers, fonts, PNG export)IncludedIncludedIncludedIncludedIncluded
Saved design templatesNot on this planNot on this planNot on this planIncludedIncluded
Generate artwork on your own AI account, straight into the libraryNot on this planNot on this planNot on this planIncludedIncluded

Reputation & referrals

Turning finished work into the next customer.

CapabilitySparkBuildLaunchGrowScale
Review requests & trackable review linksNot on this planNot on this planNot on this planIncludedIncluded
Review destinations — Google, Facebook, Yelp & more (Included with review requests)Not on this planNot on this planNot on this planIncludedIncluded
Private feedback & service recovery (Catch an unhappy customer before they post · Included with review requests)Not on this planNot on this planNot on this planIncludedIncluded
Google review ingestion, AI drafts & review widget (Pulls via your Outscraper key; posting the reply back to Google is still open)Not on this planNot on this planNot on this planIncludedIncluded
Two-tier affiliate programNot on this planNot on this planNot on this planNot on this planIncluded

Social & ads

Paid and organic acquisition, filed against the same contacts.

CapabilitySparkBuildLaunchGrowScale
Social publishing calendarNot on this planNot on this planNot on this planIncludedIncluded
Facebook Lead Ads into the CRMNot on this planNot on this planNot on this planIncludedIncluded
Facebook ads manager (More ad networks are on the way)Not on this planNot on this planNot on this planNot on this planIncluded

Apps & marketplace

When Chirply does not do it yet, an app does — installed from the marketplace, or built by your own coding agent.

CapabilitySparkBuildLaunchGrowScale
Install apps from the marketplace (Industry apps install into this workspace and run inside it)IncludedIncludedIncludedIncludedIncluded
Integrations directory with a free connection testIncludedIncludedIncludedIncludedIncluded
Build your own apps with a coding agentNot on this planNot on this planNot on this planNot on this planIncluded
App pages, widgets & contact-card panels (Included with app developer tools)Not on this planNot on this planNot on this planNot on this planIncluded
App-owned data & event triggers inside Chirply (Included with app developer tools)Not on this planNot on this planNot on this planNot on this planIncluded
Publish and sell apps to other workspaces (Buyers pay through your own connected Stripe · Included with app developer tools)Not on this planNot on this planNot on this planNot on this planIncluded

Platform & agent-native

CapabilitySparkBuildLaunchGrowScale
REST APINot on this planNot on this planNot on this planIncludedIncluded
API keysNot on this planNot on this planNot on this plan2Unlimited
Built-in MCP server (Let Claude and other agents operate your CRM as a tool)Not on this planNot on this planNot on this planNot on this planIncluded
Webhooks — triggers & stepsNot on this planNot on this planNot on this planIncludedIncluded
Bring your own providersIncludedIncludedIncludedIncludedIncluded
Bring your own Supabase (Point workspaces, funnels and apps at your own database)Not on this planNot on this planNot on this planNot on this planIncluded
Tenant help desk — tickets, SLA & CSAT (Run your own customers' support inside the workspace)Not on this planNot on this planNot on this planIncludedIncluded
Two-factor authenticationIncludedIncludedIncludedIncludedIncluded
GoHighLevel connection & migration (Contacts, pipelines, deals and appointments import; conversation and workflow conversion still open)IncludedIncludedIncludedIncludedIncluded
Carrier trust & A2P registration (Guided business profile, CNAM, brand and campaign on your own Twilio · Included with phone numbers)Not on this planNot on this planIncludedIncludedIncluded
Teams, roles & permissionsIncludedIncludedIncludedIncludedIncluded
Security, privacy mode & audit trailIncludedIncludedIncludedIncludedIncluded
Desktop notifications (Browser push, approved per device)IncludedIncludedIncludedIncludedIncluded
Support center & feature boardIncludedIncludedIncludedIncludedIncluded
Release notes & setup checklistsIncludedIncludedIncludedIncludedIncluded
SupportAI support, 24/7AI support, 24/7AI support, 24/7AI support, 24/7AI support + human escalation
Account snapshots (Freeze a workspace's setup and reinstall it anywhere)Not on this plan1325Unlimited
Sell snapshots & list on the marketplace (Buyers pay through your own connected Stripe — we take no cut)Not on this planNot on this planNot on this planNot on this planIncluded

Pricing — reseller and white-label partner subscriptions

These REPLACE a retail plan rather than sitting on top of one. Each includes Scale in full, so a partner tier is the whole of what an agency pays us.

Two capabilities are deliberately not on any retail plan: issuing client sub-accounts, and white-labeling the platform. Both are partner add-ons, aimed at agencies and consultants who want to sell Chirply as their own product.

Reseller Partner

Sell Chirply to your clients and keep the margin. Includes Scale, in full.

  • Issue client sub-accounts on any plan level
  • Set your own price — you keep the spread
  • Spin up and manage client workspaces in a click
  • Wholesale rates on every account you open

White-Label Partner

Ship the whole platform as your own product. Includes Scale + Reseller, in full.

  • Your logo, name and colors across the entire app
  • Your own domain — clients never see Chirply
  • Branded auth emails and client dashboards
  • Agency rebilling and markup controls

What the partner tiers cost

Reseller Partner
$297/month, and that is the agency's ENTIRE Chirply subscription — it includes Scale, so there is no plan charge underneath it. Resellable client workspaces at wholesale pricing. A lower founding rate exists only inside the timed window offered shortly after signup.
White-Label Partner
$497/month, likewise the agency's entire subscription with Scale included. Rebrands the whole platform — logo, name, colors, custom domain, branded auth emails, client-facing dashboards, and agency rebilling. A lower founding rate exists only inside the timed post-signup window.

The branded app — the white-label point most agencies do not expect

Worth naming explicitly on an agency call, because it sounds like it should be impossible: on the White-Label tier, an agency's clients can install the AGENCY'S app. On the agency's own app domain, Chirply serves a web app manifest carrying the agency's name, icon, colors and shortcuts, and the client adds it to their phone's home screen or their desktop, where it opens standalone with no browser chrome around it. No developer accounts, no store listings, no review cycles, no per-agency build — the agency uploads a square PNG, or lets Chirply generate a lettermark from their brand color, and it is done.

Two honest details. app.chirply.io deliberately does NOT offer this, so it is genuinely something the partner has and Chirply's own front door does not — the install only exists on an agency's own active domain, and it stops the moment the white-label entitlement lapses. And on iPhones there is no install button available to any website: the client has to use Share, then Add to Home Screen, and the product shows them those steps rather than a button that does nothing. Android and desktop Chrome offer a real prompt.

No — the partner tiers are bought outright rather than trialled. The trial runs on the retail ladder; a partner tier is paid from day one, and accepting one ends the trial and replaces it. The partner entitlement is withdrawn when the subscription ends: the branding, the custom domains and access to client accounts stop. Nothing is deleted for you. If you have live client accounts, raise it in Support before cancelling so the wind-down is planned rather than abrupt.

An important disclosure for any conversation involving partners: a Chirply account sold by a reseller or white-label partner is created, priced, billed, and supported by that independent partner, not by Chirply. Partners are not our agents and do not speak for us.

Chirply Affiliates (earn by referring)

Chirply's own referral program: every account holder can earn commission by promoting Chirply itself, automatically — no application.

Chirply pays two-tier recurring commission on referred subscriptions. The default published terms are 25% on people you refer directly and 5% on the people they in turn refer, paid recurring for as long as the referred subscription stays active. Partner-audience terms are richer than standard terms.

Commission rates are set per campaign by platform admins and can change, so treat the numbers above as the standing default rather than a contractual promise. A prospect who wants exact current terms should read them on their own affiliate page inside the app, which always renders the live campaign they are actually on.

  • Everyone with an account is enrolled automatically — there is nothing to apply for.
  • Referral tracking works from any page on the marketing site, via a ref link.
  • Payouts run through Stripe Connect or PayPal.
  • Two tiers: direct referrals and their referrals.

Your affiliate program (run one for your business)

Separate from Chirply's own program above: every workspace can run a full affiliate program for ITS products, inside Chirply.

The Affiliates module is a built-in replacement for a standalone affiliate tool: define the offer — a percent or flat amount per sale, one-time or recurring, as a single rate or a multi-level ladder — and Chirply handles recruiting, tracking, the money math, and payouts. Commission terms are snapshot onto each referral when it's captured, so changing your rates later never rewrites what an existing referral earns.

  • Create a campaign and share its public signup link anywhere — affiliates apply (or are approved automatically) without needing a Chirply login.
  • Commission ladders go up to 10 levels deep — level 1 pays the referrer, level 2 the affiliate who recruited them, and so on — and any affiliate can be given a personal special deal (their own ladder or recurring window) that applies to their future referrals only.
  • Every affiliate gets their own portal with a real sign-in (emailed code, magic link, or password) — live clicks, referrals, earnings, and payout history — plus tracked referral links with a configurable attribution cookie window.
  • Contests and leaderboards keep affiliates competing: time-boxed contests with prizes by rank and frozen final results, plus an always-on leaderboard where peers appear privacy-masked and anyone can opt out of being shown.
  • Sales from your connected Stripe account and funnels attribute to the referring affiliate automatically; sales that happen elsewhere can be recorded by hand.
  • Commissions sit through a refund-safe hold window, then you approve them (or let the campaign auto-approve) and pay out automatically by PayPal or Stripe Connect from your own accounts — or by hand — with the ledger reconciled row for row.
  • Refunds claw commission back automatically.

Like everything else in the product, the whole module is operable by machine: every action from creating a program to paying an affiliate is exposed through the API, MCP, and the in-app assistant under the affiliate_program domain.

What a customer pays OUTSIDE the Chirply subscription

Never let a prospect discover this after they've signed. Raise it during discovery.

In the standard bring-your-own setup, the customer holds accounts with the providers below and pays them directly at published rates. Chirply does not add a markup to those provider bills. Which accounts a customer needs depends entirely on what they turn on — a business that only uses the CRM and pipelines needs none of them. A reseller may instead provide pooled credentials and charge its client through Chirply's prepaid credit ledger at rates the reseller controls; that is a separate partner arrangement, not Chirply marking up the customer's own provider account.

Twilio (required for anything phone or SMS)
Phone numbers, inbound and outbound minutes, SMS and MMS, ringless voicemail delivery, call recording, transcription, and line-type lookups. Billed by Twilio at their carrier rates.
Mailgun, or Resend (required for email)
Sending and receiving email on the customer's own domain, including bounce and complaint handling. Either provider works, and sending pools, warmup and domain health run on both. Billed by whichever one they use.
An AI model provider — OpenRouter (required for AI features)
Tokens consumed by AI phone agents, AI drafting, contact summaries, and AI page generation. The model picker in-app shows live input and output pricing per model so the customer can compare cost before committing.
ElevenLabs (optional)
Premium and cloned voices for AI agents and pre-rendered voicemail or IVR audio. Only needed if the built-in phone voices aren't enough.
Outscraper (optional)
Powers built-in lead generation — the B2B business database and Google Maps search. Only needed if the customer uses lead gen.
Firecrawl (optional)
Website crawling that reads a customer's site into an AI agent's knowledge base.
Stripe (optional)
Only needed if the customer wants to take payments or send invoices. Their own Stripe account, their own money, standard Stripe fees.
Domain registration (optional)
A custom domain for funnels or a white-labeled app. Customers can bring one they already own, or buy one inside Chirply.
DigitalOcean (required for managed WordPress hosting)
WordPress sites run on servers in the CUSTOMER'S OWN DigitalOcean account, connected by a scoped authorization they can revoke from either side. DigitalOcean bills them for the server, and roughly a fifth more on top if they switch on backups. Chirply shows the estimated monthly infrastructure cost before anything launches, and nothing is charged until they confirm — but from that moment the meter is running in their DigitalOcean account, not in their Chirply bill.
Supabase (optional)
Only if the workspace connects its own Supabase account to back a site, a funnel, or an installed app. Projects are created in the customer's own Supabase organization and Supabase bills them directly — their free tier is a real starting point, and Chirply adds no margin.
An email-verification provider — NeverBounce (optional)
Checking that an address is real before sending to it, on the customer's own key, charged per address checked. Optional twice over: list verification is switched off until they turn it on, and a customer who already has Mailgun connected can use Mailgun's own address validation instead of opening a second account.
AI image and video providers — fal.ai, Replicate (optional)
Only if the customer uses AI Studio to generate images or video. Their own key, billed per render by whichever provider they connect.

A direct bring-your-own workspace is billed by its providers. A client using a reseller's pooled providers can be balance-gated: pooled sends pause cleanly when the reseller-managed prepaid credit balance runs out. Ask which connection model the workspace uses before describing billing behavior.

How someone actually gets started

The buying and onboarding path, end to end.

Everyone starts with the full platform free for 14 days on Scale. Scale is the only plan with a free trial. A card is required, and you pay nothing today. After your trial, stay on Scale at $97/month or downgrade to any other retail plan. Choose a lower plan in Billing before the trial ends to start there when billing begins, or cancel before then and pay nothing. Start at https://chirply.io/pricing. Entry plans and partner tiers are paid purchases; invitations and platform-issued accounts are separate ways to join.

  • Start at https://chirply.io/pricing. Card details are entered inline. The Scale trial charges $0 today; an entry-plan purchase charges the selected billing period today.
  • Set up the workspace: name it, brand it, and invite teammates by email with a role attached.
  • Connect providers. Most of them now configure themselves. Saving a Twilio Account SID and auth token makes Chirply create the API key and the voice application inside that Twilio account, and every number bought or brought in through Chirply is pointed back at the workspace automatically — for Twilio there is no webhook URL to copy anywhere. Mailgun is provisioned the same way on save (inbound route, delivery-event webhooks, open tracking), as are Meta, Shopify, and Klaviyo. Stripe also attempts webhook provisioning when keys are saved; permissions and live versus test mode affect whether it succeeds. Where a provider still needs manual configuration, use the connection card’s current instructions and health state rather than assuming saved credentials prove delivery works.
  • Buy or port a phone number, then configure it. Every number gets its own settings page — label, inbound routing, caller ID, availability hours, recording and transcription.
  • Import contacts, or generate fresh ones with built-in lead generation.
  • Turn on what the business actually needs: dialer, AI agent, campaigns, automations, funnels.

Practical onboarding note worth mentioning to nervous buyers: a whole workspace configuration can be captured as a snapshot and reinstalled into another workspace. Agencies use this to set a client up in one click instead of rebuilding from scratch, and there is a marketplace where snapshots can be shared or sold.

Agent-native: the API, the MCP server, and the in-app assistant

The differentiator most competitors cannot match, and the reason this handbook exists.

Chirply is built so that anything a human can do by clicking, a machine can also do. That is not a marketing line about having an API — it is an architectural rule enforced in the codebase. Every action is defined exactly once, and three surfaces are thin adapters over that one definition, which means they cannot drift apart.

Public REST API
Every action is a POST to a predictable endpoint. A discovery endpoint publishes the full catalog with a JSON Schema for each action's arguments, so an integrator or an agent reads it once and knows the whole API without a hand-written client. Authenticated with scoped, revocable API keys. Available from the Grow plan up.
Built-in MCP server
Claude and any other MCP-speaking agent can operate the CRM as a tool — same keys, same permissions, same validation as the API. Available on the Scale plan.
In-app assistant
A unified assistant inside the app that both answers questions and takes actions on the user's behalf. Anything irreversible, outward-facing, or that spends money is classified as high-risk and the assistant refuses to run it without a human clicking Approve.

The complete live operation list, with its current count and a plain description of each action, is generated at the end of this document directly from the capability registry.

Why this matters commercially: a business that wants its own AI agents to book appointments, update deals, send follow-ups, or run reports can point them straight at Chirply. Most CRMs in this price bracket expose a handful of endpoints and call it an API.

Security, tenancy, and data ownership

  • Multi-tenant at the database level, not by convention. Row-level security is the authorization boundary and it is enforced by the database, not by application code remembering to filter.
  • A four-tier hierarchy: platform, agency, sub-account, and user, with owner / admin / member roles inside each organization. Agency admins can reach into their own sub-accounts; clients never see each other.
  • Provider credentials are stored encrypted, per workspace, and are never shared across tenants.
  • Server-only secrets are never reachable from the browser bundle.
  • Support impersonation ('view as org') is recorded to an audit log and surfaced to the user with a persistent banner.
  • A screen-share privacy mode redacts sensitive data on screen, for demos and support calls.
  • Customers retain their provider accounts, numbers, email domains, and provider billing history. CRM history and stored recordings also live in Chirply: recording audio is copied into Chirply-managed storage and the provider copy is deleted. Plan data and media exports before leaving; provider ownership is not a backup of the entire workspace.

What NOT to claim: Chirply does not currently hold SOC 2, ISO 27001, or HIPAA attestation, and does not sign BAAs. If a prospect's buying process requires any of those, say so plainly and escalate to a human rather than improvising.

Compliance — the parts that keep customers out of trouble

A shared layer every outbound channel runs through, so there is no per-feature gap.

  • A do-not-call list and per-workspace suppression lists, checked before every outbound send on every channel.
  • Quiet hours evaluated in the contact's local timezone across voice and campaign channels. Quiet hours are opt-in and off by default, and an explicit send-now always sends.
  • SMS STOP handling and signed one-click unsubscribe links on email.
  • A per-channel unsubscribe center that records who opted out of what, and how.
  • Provider bounce and complaint suppression fed back automatically.
  • TCPA consent text on the click-to-call widget, and recording announcements on calls where consent needs to be captured.
  • Carrier registration support — A2P 10DLC and voice trust — driven against the customer's own Twilio account.

Framing for a sales conversation: Chirply gives a business the tooling to comply. It does not make them compliant, and it is not legal advice. Whether a given campaign is lawful depends on their consent records and their jurisdiction. Do not tell a prospect that using Chirply makes cold outreach legal.

Support, roadmap, and how the company operates

  • AI support is available 24/7 on every plan, and answering questions works with nothing connected — that runs on Chirply's own model key against the product documentation, and it deliberately never sees a summary of the workspace's customers. Having the assistant DO the work rather than explain it runs on the workspace's own OpenRouter key: with no key connected, a request to take an action comes back as instructions for doing it yourself plus a one-line nudge to connect one. Say that plainly rather than promising an assistant that acts out of the box.
  • Scale adds human escalation, and it is the same thread — a platform admin takes over the conversation the customer is already having, rather than moving them to a second inbox.
  • Chirply is built in public. A daily shipping log at /progression publishes what went live each day, and /roadmap shows what is coming.
  • There is a public feature board where customers can file bug reports and vote on requests.
  • There is an official Chirply community on Facebook, at facebook.com/groups/1024890953769526, where customers and the team share tips and help each other.
  • Support email: support@chirply.io.

Building in public is a real asset on a sales call with a skeptical buyer: the ship log is a verifiable, dated record of the product moving, which is exactly the objection ('is this thing going to still exist next year?') that a young platform normally cannot answer.

Frequently asked questions

Short, accurate answers an agent can say out loud.

What does Chirply cost?
5 plans: Spark at $7/month, Build at $27/month, Launch at $47/month, Grow at $77/month, and Scale at $97/month, each with two months free if paid annually.
Is there a free trial?
Everyone starts with the full platform free for 14 days on Scale. Scale is the only plan with a free trial. A card is required, and you pay nothing today. After your trial, stay on Scale at $97/month or downgrade to any other retail plan. Choose a lower plan in Billing before the trial ends to start there when billing begins, or cancel before then and pay nothing.
Do I pay per contact, per text, or per minute?
There are five retail plans: Spark $7/month ($70/year), Build $27/month ($270/year), Launch $47/month ($470/year), Grow $77/month ($770/year), Scale $97/month ($970/year). Paying yearly costs ten months rather than twelve, so two months are free. Contacts are unlimited on every plan, and nothing is metered: once a plan includes a channel, that channel is unlimited on it, because the provider accounts are yours (your Twilio, your Mailgun, your model key) and they bill you directly. Spark and Build are entry plans that do not include calls, texts or marketing email — those start on Launch. The plans differ by capability and capacity rather than by usage.
So I need my own Twilio account?
Yes, for phone calls and SMS. Email supports connected providers including Mailgun and Resend; use the setup instructions for the provider you choose. Chirply shows you exactly what to paste and where. It is an extra setup step, and in exchange your usage is at wholesale rates.
Can it answer my phone when nobody's available?
Yes. Point any number at an AI phone agent and it answers, holds a real conversation, captures the caller's details into the CRM, takes a message as a task, or warm-transfers to whoever on your team is online. On Scale it streams in real time, so there is about a second of gap and you can interrupt it mid-sentence.
Can I call from my computer?
Yes. There is a browser softphone docked in the top bar on every page. Inbound calls ring your browser wherever you are in the app; outbound goes out on your business caller ID. Mute, keypad, add a third party, and warm transfer with the caller on hold are all there.
What is a sales bridge?
When a lead is hot, Chirply rings your whole rep pool at once — cell phones and browser softphones together — whispers the lead's context to whoever answers, and bridges the first rep who presses 1 straight through to the lead. Typically about 15 seconds from trigger to live conversation.
What is ringless voicemail?
A carrier drop that deposits your recording straight into someone's voicemail box without their handset ever ringing. You record it in the browser or generate it with text-to-speech, and merge fields are spoken correctly.
Can I text and email my whole list?
Yes — broadcasts go out by email, SMS, ringless voicemail, outbound IVR, or AI call from one composer, with send windows, day-of-week rules, timezone handling, and a per-minute throttle. You get opens, clicks, bounces, unsubscribes, and per-recipient status. For email specifically you can spread a big send across a pool of your own sender addresses rather than hammering one: rotation sends from whichever address has sent least today, each address can be on a warmup ramp that starts small and climbs daily to a ceiling you set, and any address that has hit its allowance is skipped — if they all have, the campaign parks until tomorrow instead of dropping the rest of your list. There's also a check on each sending domain that tells you whether SPF, DKIM, DMARC and MX are actually right, before you find out the hard way.
Does it have automations?
Yes. A visual workflow builder with triggers (contact created, tag added, deal stage changed, form submitted, message received, call completed, on a schedule, or by webhook), waits and branching, and a full action catalog including the voice actions. Every run is logged so you can see what fired and why.
Can I build landing pages?
Yes — a multi-step funnel and page builder with blocks, forms that create contacts and can trigger a workflow, AI generation for a first draft, and publishing behind your own custom domain with DNS and SSL handled automatically.
Where do leads come from?
Chirply has lead generation built in: search a B2B business database or Google Maps from inside the app, enrich the results, and import them to the CRM deduped by phone number. You see a live cost estimate at published rates before you spend anything.
Can I white-label it?
Yes, as a partner add-on. The White-Label Partner tier puts your logo, name, colors, and domain across the entire app including auth emails, so your clients never see Chirply. Reseller Partner lets you issue and bill client sub-accounts at your own price.
Can my own AI agents use it?
Yes. There is a public REST API and a built-in MCP server backed by the same live capability registry, permissions, and validation used by the app. The exhaustive current catalog and count appear at the end of this handbook, so an agent does not have to rely on a stale endpoint list.
Will it import my existing contacts?
Yes. Contacts import into the CRM, and duplicate phone numbers are refused on the way in — one phone number is one contact, with anything already doubled up surfaced for you to resolve.
Does it record calls?
Yes, opt-in per phone number, with an optional recording announcement for consent. Audio is pulled off the provider into storage so there is one place your recordings live, and transcription is attached to the call log. You can delete the audio and keep the log and transcript. If you also switch on analysis for that number — separate toggle, off until you turn it on, and it needs transcription running — the transcript gets read back to you as a summary, an outcome, sentiment, the topics covered, the objections raised and a lead score, all drawn from a fixed vocabulary so you can actually count and trend them across a quarter rather than re-reading prose. That part runs on your own AI key, one model call per call.
Can I keep my existing phone number?
Yes — numbers are held in your own Twilio account, so porting an existing business number is a standard Twilio port and the number stays yours.
How many people can use it?
Two seats on Launch, ten on Grow, unlimited on Scale. Invites go out by email with a role attached — owner, admin, or member.
Can I change plans later?
Yes, self-serve. Upgrades charge and switch immediately; downgrades take effect at the end of the current billing period. You can also update your card and cancel yourself, without emailing anyone.
What happens if I cancel?
Your Twilio account and numbers, email domain, and Stripe history remain in your own provider accounts. Chirply also stores CRM data and recording audio; do not assume those are all still at the provider. Arrange the exports you need before leaving and check the current workspace retention and deletion terms.
Is my data separated from other customers'?
Yes. Chirply is multi-tenant at the database level with row-level security enforced by the database itself, not by application code remembering to filter. Provider credentials are encrypted per workspace and never shared.
Are you HIPAA or SOC 2 compliant?
No. Chirply does not currently hold SOC 2, ISO 27001, or HIPAA attestation and does not sign BAAs. If your buying process requires that, Chirply is not the right fit today.
How long does setup take?
A workspace with contacts, a phone number, and a dialer is a same-day job. Connecting providers is the slow part, and it is mostly waiting on Twilio and Mailgun verification rather than on Chirply. Agencies can capture a finished setup as a snapshot and reinstall it into a new client workspace in one click.
I run a restaurant / a martial arts school. Is there anything for me?
Yes, and it's a real product rather than a repurposed template. There's a Restaurant app — menus with modifier groups and an 86 switch, a point of sale with split checks, tableside tablet ordering, a kitchen display, inventory, and public online ordering and reservations under your own brand — and a Martial Arts Gym app — programs with belt and stripe ladders, enrollments, promotion history, the weekly class schedule, attendance, and a check-in kiosk for the lobby. Both are bought per workspace from the in-app store rather than being included in a plan, so check the current price on the listing itself.
Can I see what people actually do on my website?
Yes, at three levels. Visitor tracking resolves anonymous sessions into a person and then into a contact record. Heat maps show where people click and how far they scroll, kept separate for phone, tablet and desktop so you're not looking at an average of three different layouts. And session replay lets you watch an individual page visit back — that one is off by default and you switch it on per site, everything a visitor types is masked before it ever leaves their browser, and you set how long recordings are kept.
What if Chirply doesn't do the one thing I need?
It may not have to be on our roadmap for you to get it. Chirply has an app platform: apps run inside the product with their own pages, dashboard widgets and cards on the contact record, they can be run by an automation and can start one, and they get scoped access to the same action catalog everything else uses. If you have someone technical, they can point an AI coding agent at our MCP server and have it build and publish one. Being straight with you: the platform and the review process are live, and the published apps today are ours rather than a large third-party catalog.
Can I use my own database?
Partly, and it's worth being precise. You can connect your own Supabase account and create, manage, query and tear down real Supabase projects from inside Chirply, and attach one to a site, a funnel or an installed app — Supabase bills you directly and we take no margin. What that does not mean is that your Chirply data moves: your contacts, calls and messages stay in Chirply. If you're asking about data residency, the answer is no today.
Who's behind it?
Chirply is built and operated by Vaughn Labs. It is developed in public — there is a dated daily shipping log of everything that goes live, and a public roadmap.

Objection handling

The objections that actually come up, with the honest answer rather than the clever one.

"I already have a CRM."
Good — then the question isn't the CRM, it's what's bolted onto it. How many separate tools are you paying for around it: a dialer, a texting app, an email tool, a page builder, a scheduler? Chirply's case is that those stop being separate systems, and every call, text, email, and payment lands on the same contact record.
"This is cheaper than what I'm paying — what's the catch?"
There's a real one and I'd rather say it now: you bring your own Twilio and Mailgun accounts and pay them directly. That's an extra setup step and a second bill. What you get for it is unlimited contacts, calls, texts and emails on the subscription, because we're not reselling you minutes at a markup.
"I don't want to set up Twilio."
Fair — though it's less work than it used to be. You open the account and paste your Account SID and auth token in once. Chirply then creates the API key and the voice app inside your Twilio for you, and points each number you buy or bring in back at your workspace. There are no webhook URLs to copy. What's genuinely left is opening and verifying the account, and carrier registration if you want to text US numbers, which is a waiting game on the carriers' side rather than on ours. Support will walk you through it. If you'd rather never touch a provider account at all, a fully-bundled competitor is honestly the better fit for you.
"You're a new company. What if you disappear?"
Two honest answers. One: recordings are copied into Chirply-managed storage and the Twilio copy is deleted, so arrange exports rather than assuming all CRM data or recordings remain at the provider. Your provider accounts, phone numbers, email domain and provider payment history remain yours, so you're not holding a bag if we vanish. Two: we build in public — there's a dated log of exactly what shipped every single day. You can go read it right now instead of taking my word for it.
"Does it do everything GoHighLevel does?"
Not everything, and I'm not going to pretend otherwise. Where Chirply is genuinely strong is telephony depth and being agent-native: the live capability catalog at the end of this handbook is exposed to AI agents through the API and MCP server. Where a mature competitor may still be ahead is breadth of prebuilt integrations — though that gap is narrower than it looks, because there's an app platform: apps run inside Chirply with scoped access to the same action catalog, and if you have someone technical they can point an AI coding agent at our MCP server and have the missing piece built rather than wait on somebody's roadmap. There are also whole vertical products a general platform doesn't have — a restaurant POS, a gym management system — bought per workspace. Tell me the three things you actually use every day and I'll tell you straight whether we do them.
Can I try it free first?
Everyone starts with the full platform free for 14 days on Scale. Scale is the only plan with a free trial. A card is required, and you pay nothing today. After your trial, stay on Scale at $97/month or downgrade to any other retail plan. Choose a lower plan in Billing before the trial ends to start there when billing begins, or cancel before then and pay nothing.
"It's too expensive."
Compared to what, specifically? Add up what you're paying now for CRM, dialer, texting, email, and page builder. And check whether you're being charged per contact or per message anywhere, because that's the line that grows on you — here it doesn't.
"I need to talk to my partner / team."
Of course. Take the time you need — nothing here expires. If it helps the conversation, tell me the one thing they'll push back on and I'll give you a straight answer to bring them.
"We're too small for this."
Spark is $7 a month and holds unlimited contacts, branded links, and the whole invoicing and checkout product — enough to run a one-person business's money end to end. It does not include calling or texting; that starts at $47 on Launch, which adds a number, a browser dialer with recording, the conversations inbox and automations. If you are on the phone at all, Launch pays for itself on one recovered lead.
"We're too big / too complex."
Then the API and the MCP server are the part to look at, plus unlimited seats, numbers, and workflows on Scale. If you have someone technical, they can drive the whole platform programmatically rather than through the UI.
"AI answering my phone will annoy my customers."
It can, if it's bad. The specific thing to judge is dead air — most AI phone systems make you wait for a full reply before they speak. On Scale, Chirply streams in real time: about a second of gap, and you can talk over it and it stops. And it hands off to a human whenever it should. Let me set one up and call it yourself.
"Is this compliant? Can I cold-call/text with it?"
Chirply gives you the tooling — do-not-call lists, suppression lists, quiet hours by the contact's timezone, STOP handling, one-click unsubscribe, consent text, recording announcements. What it can't do is make outreach lawful on its own; that depends on your consent records and your jurisdiction, and it's a question for your attorney, not for me.

Discovery questions worth asking on a call

What to find out before recommending a plan. Each answer maps to a specific feature.

  • How do most of your customers reach you — do they call, or fill out a form? (Calls means telephony and AI receptionist. Forms means funnels and automations.)
  • What happens right now when someone calls and nobody picks up? (The single best opening for AI phone agents.)
  • How many calls a day are you missing, roughly? (Turns the problem into a number.)
  • Is anyone on your team calling out to leads or lists? (Power dialer, call outcomes, ringless voicemail.)
  • How fast do you get back to a new lead — minutes, hours, or the next day? (Sales bridge: fifteen seconds.)
  • What are you using today to keep track of customers and deals? (Establishes the incumbent and the switching cost.)
  • What else are you paying for around it — texting, email, page builder, scheduler? (Builds the consolidation math.)
  • Do you have a Twilio account already, or would that be new? (Surfaces the setup objection before it ambushes you.)
  • Do you text your customers today? Is anyone handling STOP requests? (Compliance risk they may not know they have.)
  • How many people would need a login? (Check the current plan matrix below; seat allowances differ by plan.)
  • Are you doing this for your own business, or do you have clients you'd want to set up too? (Qualifies for the reseller or white-label add-on — a much bigger deal.)
  • Do you have anyone technical, or use AI tools already? (Qualifies the agent-native pitch, which is wasted on most buyers and decisive for a few.)

Guardrails — what an AI agent must NOT say

Read this before writing an outbound script. Every line here exists because getting it wrong costs a customer or creates a legal problem.

  • Do not invent features. Before answering 'no' to "can it do X?", check the complete action catalog at the end of this document — it is generated from the live registry and it is more current than any prose above it, including these guardrails. If it isn't in the catalog and isn't described here, say 'I don't think we do that today, let me get you a straight answer' rather than guessing. Denying something Chirply actually ships costs a customer exactly as surely as promising something it doesn't.
  • Do not promise SOC 2, HIPAA, ISO 27001, a BAA, or any compliance attestation. Chirply has none of these today.
  • Do not tell anyone Chirply makes their outreach legal, or advise on TCPA, consent, or DNC obligations. Describe the tooling; refer the legal question to their attorney.
  • Describe the Scale trial accurately: 14 days, card required, $0 subscription charge today, then renewal unless changed or cancelled. A few standalone offers reached by their own link run a different length and keep it — the Chirply and GoHighLevel side-by-side is 30 days — so if someone quotes a number that is not 14, they are probably on one of those rather than mistaken; point them at their Billing page, which shows the exact end date. Do not promise a card-free trial, free provider usage, free partner access or a permanent free plan.
  • Do not imply that calls, texts, and emails are free. They are unlimited on the Chirply subscription and billed by the customer's own providers.
  • Do not disparage competitors or state competitor pricing, feature sets, or outage history as fact.
  • Do not claim a specific ROI, revenue increase, close-rate lift, or income figure. There are no published customer results to stand behind.
  • Do not promise a delivery date for anything on the roadmap.
  • Do not describe Chirply as an autodialer for cold, non-consented lists, or pitch it as a way to get around carrier filtering or do-not-call rules.
  • Do not offer a discount, a custom price, an extension, or a contract term. Pricing is what is published.
  • Do not speak for a reseller or white-label partner's account, pricing, or support. Those are independent businesses.
  • Identify yourself as an AI when asked, and honor a request to stop calling immediately and permanently.

Glossary of Chirply terms

Vocabulary a caller may use, or may need explained back to them.

Workspace / organization
One business's account. Contacts, numbers, campaigns and settings all belong to a workspace and are invisible to every other workspace.
Sub-account
A client workspace issued underneath an agency by a Reseller Partner. The agency can reach into it; the client cannot see other clients.
Softphone
The browser dialer docked in the top bar — makes and receives calls without a desk phone or an app.
Power dialer
Works through a call queue automatically: dial, talk, log the outcome, advance to the next one. Queues are named lists anyone — or any automation — can add people to.
Call queue vs. call script
Two different things people mix up. A call queue is WHO to ring — a named, server-side list the power dialer works through. A call script is WHAT to say — the panel that rides along beside a live call with the talk track and the objection handlers. One is the list; the other is the words.
Disposition / call outcome
The result you log after a call. Outcomes are yours to define, and each can carry actions that fire automatically when you pick it.
Sales bridge
Rings your whole rep pool at once and connects the first one to answer straight to a hot lead, with a whisper of context first.
RVM / ringless voicemail
Deposits a recording into a voicemail box without the phone ringing.
IVR
A press-1 phone menu. Chirply's builder drives both inbound menus and outbound campaigns.
Whisper
A short message played only to the rep — the lead's name, city, and source — before the two are connected.
AMD / answering machine detection
Detects whether a human or a machine picked up, so humans hear one script and mailboxes hear another.
Simulring
Rings several devices or people at once; whoever answers first takes the call.
AI Brain
The knowledge base an AI agent draws on — hours, pricing, services, policies, objection handling — built from uploads or by reading a website.
Merge field
A placeholder like the contact's first name that gets replaced with their real details. Works in SMS, email, spoken voice, IVR greetings, and AI prompts.
Broadcast
A one-off send to a whole audience on any channel. Multi-step follow-ups are automations, not broadcasts.
Automation / workflow
A trigger plus a sequence of steps with waits and branching that runs by itself.
Snapshot
A frozen copy of a workspace's configuration that can be reinstalled into another workspace, shared, or sold.
Capability / action
One thing the platform can do, defined once and available to the UI, the REST API, the MCP server, and the in-app assistant identically.
MCP server
A standard way for AI agents like Claude to use Chirply as a tool.
White-label
Running the entire platform under your own brand and domain so your clients never see the name Chirply.
Tracked website vs. Chirply pages
A tracked website is somebody's existing site, anywhere, carrying Chirply's tracking snippet. Chirply pages are the funnels, sites and checkouts built inside Chirply, which carry the same tracking without anyone installing anything. Visitor data, heat maps and replays work on both — the difference is only who hosts the page.
Heat map
An aggregate picture of one page: where people clicked, where they clicked repeatedly in frustration, and how far down they scrolled. Built up as visits happen rather than replayed from raw logs, and kept separate for phone, tablet and desktop. On by default.
Session replay
A playback of one visitor's page visit, reconstructed from what the page did rather than from video. Off by default and switched on per site. Everything the visitor types is masked before it leaves their browser.
Email pool
A named set of the workspace's own verified sender addresses that a bulk send rotates across, so one mailbox is not carrying a whole campaign. The pool can force a single Reply-To across all of them.
Warmup
Easing a new sending address into volume so mailbox providers learn to trust it: start small on day one, add a fixed number each day, level off at a ceiling. Set per address, and off until switched on.
Domain health
A check on a sending domain — is the provider happy with it, and are SPF, DKIM, DMARC and MX correct — with plain-language remedies. Advisory: it reports, it does not pause anything for you.
AI employee
A named AI coworker with a specific job and a specific set of granted capabilities, rather than a general assistant. When one reaches something it is not allowed to do alone, it stops and waits in an approvals inbox for a human.
App / extension
A unit of functionality that runs inside Chirply — its own pages, dashboard widgets, cards on the contact record — with scoped access to the action catalog. Some are first-party products bought per workspace, like the Restaurant and Gym apps; the platform also lets a developer build and publish one, with a review step before it goes public.
Design Studio
The built-in design editor: a multi-page canvas with text, images and shapes, size presets for social, print and web, and PNG export.
Capture
The workspace's video recording and optional walkthrough-guide library, reached through Assets → Videos & guides. Recording, editing, and sharing are separate choices; recording a video does not force a guide.
Media library
The workspace's one place for uploaded and generated files — images, video, audio and PDFs, in folders. Other parts of the platform file their own uploads into it automatically, so it is not just what someone dragged in by hand.

Complete action catalog

All 2226 operations Chirply exposes, across 136 domains. Every one is available to the app's UI, the REST API, the MCP server, and the in-app assistant identically.

This is the exhaustive answer to "can Chirply do X?". Each entry is one thing the platform can do, with the name a machine calls it by, the wording used on the button a person would click, and a description of the effect. Entries marked HIGH RISK are irreversible, outward-facing, or spend money — the in-app assistant will not run those without a human clicking Approve.

Read-only operations are marked READ. Everything else changes data. Some operations additionally require an admin or owner role in the workspace, and that is noted where it applies.

Actions — activity

3 operations.

Activity summary (activity.summary)
[READ] The Activity Calendar's headline totals for a period: emails sent, opened, clicked and bounced; unsubscribes and new subscribers; inbound and outbound phone calls; inbound and outbound one-to-one emails; automation runs; and successful payments, refunds, disputes, customers and subscriptions across every Stripe account connected to the account. Money is returned in integer cents plus a formatted string, with the currency. Read-only; changes nothing.
Activity calendar (activity.calendar)
[READ] The full per-day breakdown behind the Activity Calendar for a period: for each day, emails sent/opened/clicked/bounced, new subscribers, unsubscribes, inbound/outbound phone calls, inbound/outbound one-to-one emails, automation runs, and successful payments, refunds, disputes, new customers and new subscriptions across every Stripe account connected to the account, plus the campaigns that went out that day with their send count and open rate. Also returns the period totals and two daily trend series (subscriber growth, and email + revenue). Money is integer cents. Read-only; changes nothing.
Activity Log (activity.feed)
[READ] The dashboard's live activity feed, newest first — every new contact, call and text landing, auto-reply and broadcast going out, website visit, automation, and Stripe money movement (payments received, failed and refunded; subscriptions started and canceled) across every connected Stripe account, in one stream, each event naming the contact, deal and teammate it involves where known. Website visits and their individual pages include trafficClassification (status, label, confidence, agent, reason). Estimates distinguish identified_bot (self-reported crawler), suspected_bot, likely_human and unknown; provider identity and human identity are unverified. Grouped visits retain the strongest automation evidence across included pages, and legacy events without event-time evidence remain unknown. Website visits are grouped per visitor per sitting rather than one event per page view: each carries its recorded traffic attribution badges (including multiple sources and UTM/campaign details), the pages read (newest first), how many there were, and the visitor's IP address where the tracker recorded one — personal data under GDPR, so treat it accordingly. Every event naming a contact who has paid also carries that person's money — lifetime value net of refunds and monthly run rate in integer cents, how many payments and live subscriptions they have, and across how many connected Stripe accounts — so a website visit by a paying customer is distinguishable from one by a stranger; the field is absent for anyone who has never paid. This is the org-wide view (use contacts.list_activity for one person's timeline). Optionally narrow to certain event types — 'contacts' is newly added people and 'payments' is the Stripe bucket. Contacts a teammate has muted from the feed (contacts.set_feed_visibility) are left out here too. Reads nothing outside this org and changes nothing.

Actions — ad_tracking

8 operations.

Open ad tracking (ad_tracking.get_settings)
[READ · ADMIN ONLY] Read this account's advertising tracking settings and whether server credentials are saved. Returns public IDs and connection flags only; never returns tokens, secrets or visitor identity.
Save tracking settings (ad_tracking.save_settings)
[HIGH RISK · ADMIN ONLY] Save this account's Meta Pixel, Conversions API, Google Ads and optional GA4 settings. Enabling tracking sends consented visitors' page views and conversions to the account's advertising accounts. Credentials are encrypted; this does not buy ads or send customer messages.
Connect Google Ads (ad_tracking.google_connection)
[READ · ADMIN ONLY] Get this account's Google Ads connection link and platform availability. An account owner or admin must open the link in their signed-in browser and approve Google access. This returns no credentials, connects nothing by itself and spends no money.
Disconnect Google Ads server (ad_tracking.disconnect_google)
[HIGH RISK · ADMIN ONLY] Remove this account's encrypted Google Ads server authorization and cancel pending authorization attempts. Disables direct server imports and restores any configured browser conversion actions. Does not delete past conversions, revoke unrelated Google connections, change ads or spend money.
Validate Google Ads server setup (ad_tracking.test_google_ads_connection)
[HIGH RISK · ADMIN ONLY] Validate this account's saved Google Ads server conversion destinations using Google's Data Manager validate-only mode. Sends a synthetic payload without real customer data, records no conversion, changes no campaign and spends no money. Validation does not prove campaign attribution.
Recent ad events (ad_tracking.list_events)
[READ · ADMIN ONLY] List recent server advertising event delivery receipts for this account. Shows destination, event type, delivery state and safe errors without visitor data or credentials. GA4 delivered means transport was accepted, not confirmed attribution.
Send Meta test event (ad_tracking.test_meta_connection)
[HIGH RISK · ADMIN ONLY] Send one synthetic connection event to Meta's Test Events tool using this account's saved Pixel ID and encrypted token. Requires an explicit Test Event Code; it sends no customer identity, records no real lead or purchase and spends no advertising money.
Validate GA4 setup (ad_tracking.test_ga4_connection)
[HIGH RISK · ADMIN ONLY] Send a synthetic purchase payload to Google's Measurement Protocol validation endpoint for this account's saved GA4 setup. Records no real purchase and spends no money. Google validates payload format only; this does not verify the API secret, event ingestion or Google Ads attribution.

Actions — affiliate_program

36 operations.

Affiliate program overview (affiliate_program.overview)
[READ] Headline numbers for this account's own affiliate program (the program it runs for its products, not Chirply's): affiliate counts by status, clicks, referrals, referred customers, commission totals by status, and the top-earning affiliates. Optionally narrowed to one program or a start date.
List programs (affiliate_program.list_programs)
[READ] List this account's affiliate programs — the offers it runs (reward terms, cookie window, approval and payout settings) — each with its public signup URL.
Open a program (affiliate_program.get_program)
[READ] Fetch one affiliate program with all of its settings — reward terms, tier-2 terms, cookie window, approval switches, hold days, minimum payout — plus its public signup URL.
Get signup link (affiliate_program.get_signup_link)
[READ] The public 'become an affiliate' URL for a program — the link to share anywhere you recruit affiliates. Anyone who opens it can apply to join the program (auto-approved if the program is set that way), so treat it as public.
List affiliates (affiliate_program.list_affiliates)
[READ] List the affiliates recruited into this account's program(s) — name, email, referral code, status, and custom rate — filterable by program and status, searchable by name, email, or code. Portal tokens are never included in lists; open one affiliate to get their portal link.
Open an affiliate (affiliate_program.get_affiliate)
[READ] Fetch one affiliate with everything a manager sees: profile and status, their shareable referral link(s), their private portal URL (a bearer link — anyone holding it sees their dashboard, so share it only with the affiliate themself), and their commission balance.
List referrals (affiliate_program.list_referrals)
[READ] List the people affiliates have referred — leads and customers — with the reward terms snapshot each referral locked in at capture time. Filterable by program, affiliate, and status.
List commissions (affiliate_program.list_commissions)
[READ] List the commission ledger — one row per tier per referred payment, with amount, status, and when it clears its hold. Pending + approved rows are real money the account owes its affiliates. Filterable by program, affiliate, and status.
List payouts (affiliate_program.list_payouts)
[READ] List payouts to affiliates — amount, method, destination, and status. A pending payout has claimed its commissions but the money hasn't been sent yet. Filterable by affiliate, program, and status.
Create program (affiliate_program.create_program)
[HIGH RISK · ADMIN ONLY] Create an affiliate program (a campaign) for this account's own products: the offer (percent or flat per sale, one-time or recurring, optionally a multi-level ladder up to 10 levels deep), cookie window, approval and payout settings. THIS COMMITS REAL MONEY: the account owes the stated commission on every referred sale from the moment it exists, its signup URL is publicly live immediately, and commission rates are never backdated — so an over-generous rate cannot be corrected on referrals already captured under it.
Edit program (affiliate_program.update_program)
[HIGH RISK · ADMIN ONLY] Update a program's settings — name, terms, reward (including the multi-level ladder), cookie window, approval switches, hold days, minimum payout, destination URL, or pause/resume it. Omitted fields are left alone. THIS CHANGES WHAT THE WORKSPACE OWES on every sale from now on, and the public signup and terms pages change with it. Rate changes apply to NEW referrals only — every existing referral keeps the terms it was captured under, so a rate raised by mistake cannot be walked back on referrals captured in the meantime.
Archive program (affiliate_program.archive_program)
[HIGH RISK · ADMIN ONLY] Archive a program: its signup page and referral links stop working and no new clicks, referrals, or commissions are tracked. Existing referrals keep their snapshots and commission already earned STAYS OWED — archiving stops future tracking, it does not void money. There is no unarchive in the UI, so treat this as final.
Add an affiliate (affiliate_program.add_affiliate)
[ADMIN ONLY] Recruit an affiliate by hand (they normally join through the program's public signup link). Mints their referral code, portal link, and default tracked link. The result includes their portal URL — a private bearer link to send to that person, and only that person.
Approve affiliate (affiliate_program.approve_affiliate)
[ADMIN ONLY] Approve a pending affiliate (or reactivate a paused one): their referral links start earning attribution and their portal shows them as active.
Pause affiliate (affiliate_program.pause_affiliate)
[ADMIN ONLY] Pause an affiliate: new clicks on their links stop earning attribution until they're approved again. Their existing referrals and earned commission are untouched.
Ban affiliate (affiliate_program.ban_affiliate)
[HIGH RISK · ADMIN ONLY] Ban an affiliate — an outward-facing action against a real person: their portal login stops working immediately, their links stop earning, and they can't be paid out while banned. Use for fraud or terms violations; use 'Pause affiliate' for anything temporary.
Set custom rate (affiliate_program.set_affiliate_rate)
[HIGH RISK · ADMIN ONLY] Give one affiliate a personal commission percent that replaces the program's percent, or clear it back to the program rate. THIS CHANGES WHAT A REAL PERSON IS PAID. It applies to referrals they capture FROM NOW ON — existing referrals keep the terms they locked in, because rates are never backdated, so neither a raise nor a cut can be undone for anything captured while it stood.
Add a referral (affiliate_program.add_referral)
[ADMIN ONLY] Manually credit a person to an affiliate — for deals that arrived outside the tracked links (a phone call, a conference). Snapshots the program's current reward terms onto the referral; when this person later pays, those terms decide the commission. First touch wins: if the person is already a referral, the existing attribution is returned unchanged.
Record a sale (affiliate_program.record_sale)
[HIGH RISK · ADMIN ONLY] Record a referred payment by hand and write the commission it earns — REAL MONEY the account then owes its affiliate(s), one ledger row per tier, at the terms snapshot on the referral. Use for sales that happened outside connected Stripe. Supply external_ref to make retries safe: the same reference is never recorded twice.
Approve commission (affiliate_program.approve_commission)
[ADMIN ONLY] Approve one pending commission, clearing it for payout — this confirms the account owes the money and lets 'Pay an affiliate' claim it.
Reject commission (affiliate_program.reject_commission)
[HIGH RISK · ADMIN ONLY] Refuse a pending or approved commission (fraud, dispute, self-referral) — the affiliate permanently loses this money from their balance. Already-paid commissions can't be rejected.
Pay an affiliate (affiliate_program.create_payout)
[HIGH RISK · ADMIN ONLY] Create a payout for an affiliate's approved commission — a COMMITMENT TO PAY REAL MONEY to a real person. Claims their approved commissions (oldest first, whole rows only, up to the optional cap) and marks them paid. The money itself moves outside Chirply (PayPal, bank transfer); mark the payout paid once it's sent, or cancel it to release the balance.
Mark payout paid (affiliate_program.mark_payout_paid)
[HIGH RISK · ADMIN ONLY] Confirm the money actually left — the PayPal send or bank transfer happened. Stamps who processed it and when, and settles the affiliate's balance so those commissions are never queued for payment again. It does not move money itself, which is exactly the risk: marking a payout paid that was never sent quietly writes off what the account still owes a real person, and there is no un-mark.
Cancel payout (affiliate_program.cancel_payout)
[ADMIN ONLY] Call off a payout that hasn't been sent yet: the commissions it claimed return to 'approved' and the affiliate's payable balance is restored. A payout already marked paid can't be canceled.
Special deal (affiliate_program.set_affiliate_deal)
[HIGH RISK · ADMIN ONLY] Give one affiliate a personal deal that replaces the campaign's standard terms — their own multi-level commission ladder, and/or their own recurring window. THIS CHANGES WHAT A REAL PERSON EARNS on referrals they capture FROM NOW ON, and never touches the past: every referral already captured keeps the terms it locked in, so a deal set by mistake cannot be reversed for anything captured while it stood. Pass null for a field to clear it back to the campaign's terms (an affiliate with no overrides simply follows the campaign, so raising the campaign later raises them too).
List contests (affiliate_program.list_contests)
[READ] List this account's affiliate contests — time-boxed competitions ('most new customers this month wins $500') with live standings on every affiliate's portal. Each row includes its status (draft = not visible yet, active = live and counting, ended = winners frozen, canceled = never happened), metric, window, and prizes.
Open a contest (affiliate_program.get_contest)
[READ] Fetch one contest with its full setup (metric, window, prizes) and its standings: LIVE standings computed over the contest window while it's a draft or active, or the FROZEN winners once it has ended. Names here are the affiliates' real names — this is a manager surface; the affiliates' own portals show peers masked.
New contest (affiliate_program.create_contest)
[ADMIN ONLY] Create an affiliate contest as a DRAFT — a time-boxed competition with a metric, a window, and prizes by rank. Drafts are invisible to affiliates and cost nothing until you start them (affiliate_program.start_contest); the prizes are your own commitment to deliver, outside Chirply. Ties share a rank and every affiliate tied at a prized rank wins that prize.
Edit contest (affiliate_program.update_contest)
[ADMIN ONLY] Update a draft or active contest's setup — name, description, metric, window, or prizes. Omitted fields are left alone. An ended or canceled contest can't be edited: a result that has been announced is history.
Start contest (affiliate_program.start_contest)
[HIGH RISK · ADMIN ONLY] Take a draft contest live: it appears on every affiliate's portal leaderboard page and the standings start counting over its window. This is OUTWARD-FACING and it PROMISES A PRIZE — every ACTIVE affiliate is entered automatically, including ones who hide themselves from the always-on leaderboard, and they will see the contest and its stated reward. Starting one by accident commits the account to it in front of everybody.
End contest & announce winners (affiliate_program.end_contest)
[HIGH RISK · ADMIN ONLY] End an active contest NOW and FREEZE the final standings as its winners, with prizes attached by rank — affiliates see the result on their portals immediately. This is permanent: an announced result never changes, even if more sales land later, and the prizes you promised are now owed to real people. Ending before the scheduled close counts only what happened up to this moment.
Cancel contest (affiliate_program.cancel_contest)
[HIGH RISK · ADMIN ONLY] Call off a draft or active contest as if it never happened: no winners are computed, no prizes are owed, and it disappears from every affiliate's portal. Affiliates who were competing lose the contest they were told about — an outward-facing disappointment — and there is no undo.
Leaderboard (affiliate_program.get_leaderboard)
[READ] The always-on affiliate leaderboard for a program — top active affiliates ranked by a metric over the last 30 days or all time, ties sharing a rank. Names here are real (this is a manager surface); on the affiliates' own portals every peer appears masked as first name + last initial. Affiliates who chose 'Hide me from the leaderboard' are left off this board too — it's a display surface, unlike contest standings which always count everyone.
Send payout (affiliate_program.send_payout)
[HIGH RISK · ADMIN ONLY] Send a pending payout down its rail RIGHT NOW — this moves real money from your own PayPal or Stripe account to the affiliate immediately. The rail is the affiliate's saved payout method unless you override it: 'paypal' sends a PayPal payout from your connected PayPal (settles within minutes), 'stripe' transfers out of your own Stripe balance into the affiliate's Stripe account instantly, and 'manual' just records that you already sent the money yourself. If the provider refuses, the payout is marked failed and the claimed commissions are released back to the affiliate's balance so nothing is silently swallowed.
Set payout method (affiliate_program.set_payout_method)
[HIGH RISK · ADMIN ONLY] Save how an affiliate gets paid from now on: 'paypal' (automatic PayPal payout to their saved email), 'stripe' (automatic transfer to the Stripe account they set up from their portal), or 'manual' (a human sends the money and marks it paid). THIS DECIDES WHERE REAL MONEY GOES — affiliate_program.send_payout follows whatever is stored here — and it overwrites the previous setting with no record of it. Changes future sends only; payouts already on their way are untouched.
Payout rails (affiliate_program.get_payout_rails)
[READ] Check whether this account can pay affiliates automatically, and (optionally) where one affiliate stands: is PayPal connected, is Stripe connected, and for a given affiliate their saved payout method, PayPal email, and Stripe Connect onboarding status (none / onboarding / active / restricted — payouts only flow once it's active). The readiness card on the payouts page walks through the same prerequisites, including the one thing this can't verify from here: Stripe Connect must also be enabled on your own Stripe dashboard.

Actions — affiliates

16 operations.

Your affiliate link (affiliates.get_program)
[READ] Get the caller's own affiliate link, referral code, and exactly what they earn at BOTH tiers — tier 1 on customers they refer directly, tier 2 on customers referred by affiliates they recruited. Also returns which campaign and rate table (everyone vs partner) they're on. Read-only; costs nothing. Every account holder is an affiliate automatically, so this always returns something.
Save automatic delivery (affiliates.set_contact_delivery)
[HIGH RISK] Turn automatic affiliate lead delivery on or off for the caller's current account. Enabling saves the destination immediately, starts creating or matching contacts for every existing attributed opt-in and customer in the background, then keeps delivering future opt-ins and sales with source and offer tags. Newly created contacts can trigger the account's contact-created automations, which may send real email or SMS, place calls, or incur provider charges. Disabling stops future delivery and never deletes contacts already delivered.
Link to a specific page (affiliates.build_link)
[READ] Build the caller's affiliate link pointing at a specific page of the marketing site — the pricing page, a blog post, anything. Any page works; the referral is captured site-wide. Optionally tag it with a campaign to run on that campaign's terms. Read-only.
Offers & links (affiliates.list_offers)
[READ] List every public offer the caller can promote, including their ready-to-share tracked link, the audience and promise for each funnel, every upsell/downsell in buyer order, what the customer pays at each step, and the caller's exact tier-1 payout on that payment. Read-only; creates no links in a third-party system and spends nothing.
Your affiliate earnings (affiliates.stats)
[READ] The caller's affiliate numbers: how much is due to be paid out, how much is still in the clearing period, how much has been paid out all time, the split between tier-1 earnings (their own referrals) and tier-2 earnings (their team's), and how many people clicked, signed up, and became paying customers. Read-only.
How each offer is doing (affiliates.offer_stats)
[READ] Break the caller's affiliate numbers down by which of the published offers produced them — for every offer separately: visitors, total clicks, opt-ins, paying customers, opt-in rate, conversion rate, earnings per visitor, and the commission that offer has earned split into ready-to-withdraw, still clearing, already paid, reversed, and the tier-1/tier-2 split. Also names the offer that has earned the most so far. Two rows are not offers and are never named as the best: 'other' is referred traffic that landed on pages outside any funnel, such as the blog or pricing, and 'untracked' is earnings recorded before per-offer tracking existed, which cannot be traced to a funnel. Read-only; spends nothing and changes nothing.
Your team (affiliates.downline)
[READ] List the affiliates the caller recruited — the people whose sales earn them tier-2 commission — with how many paying customers each has brought in and how much each has earned the caller. Read-only.
Leaderboard (affiliates.leaderboard)
[READ] The live affiliate leaderboard — who has the most paying customers, the most signups, or the most clicks, across everyone promoting the platform. Returns counts only, never anyone's earnings, and excludes affiliates who opted out. Also returns the caller's own position even when they're outside the top of the board. Use it to find who to reward. Read-only.
People you referred (affiliates.list_referrals)
[READ] List the people the caller referred and where each one got to — signed up, paying, cancelled, or voided — along with the commission terms locked in for each. A voided referral carries the reason it earns nothing (self_referral, fraud, duplicate, dispute, other). Read-only.
Your commissions (affiliates.list_commissions)
[READ] List the caller's individual commission entries — one per payment a referred customer made, including renewals, at both tiers. Shows what the customer paid, what the affiliate earned, which tier it came from, whether it has cleared the hold period / been paid out / been reversed by a refund, and WHO each one is for: on tier-1 rows `person_email`/`person_name` is the customer who paid; on tier-2 rows it's the team member (the affiliate the caller recruited) whose sale generated the override. Read-only.
Your payouts (affiliates.list_payouts)
[READ] List the caller's payout requests and their state — requested, sending, paid, failed or cancelled. Read-only.
Save payout details (affiliates.set_payout_method)
[HIGH RISK] Set where the caller's affiliate commission should be sent — a PayPal email address, or free-text bank details for a manual transfer. THIS IS A PAYMENT DESTINATION: it overwrites whatever was there before, with no record of the old value, and affiliates.send_payout later pays real money to exactly what is stored here. A wrong PayPal address bounces the payment at best and pays a stranger at worst, so the address must be confirmed with the person it belongs to before this is saved. Only the affiliate themselves can call it — an API key, OAuth token or installed app is refused, because an account credential is not the person whose money this is.
Set up with Stripe (affiliates.connect_stripe)
Start (or resume) Stripe Express onboarding so the caller can be paid straight to their bank. Returns a one-time Stripe URL the person must open in a browser and complete themselves — the platform never sees their bank details, and this capability cannot finish onboarding on their behalf. Safe to call repeatedly: the Stripe account is created once and reused, and the link is short-lived so a fresh one is minted each time.
Stripe payout status (affiliates.stripe_status)
[READ] Check whether the caller's Stripe Express account is ready to receive payouts. Re-reads the account from Stripe rather than trusting the stored copy, so it reflects onboarding they finished seconds ago. Read-only.
Chirply affiliate campaigns (affiliates.list_campaigns)
[READ] List campaigns in Chirply's own affiliate program (users earning commission for referring new Chirply customers — not a tenant's own affiliate programs), with their full rate tables: for each campaign, whether it is one tier or two, and what each audience (everyone vs partners) earns at each tier. Read-only. Available to any signed-in caller, since an affiliate is entitled to see the terms on offer.
Chirply affiliate dashboard (affiliates.overview)
[READ] Everything on the caller's Chirply Affiliates page in one call — their own account in Chirply's affiliate program (earning by referring new Chirply customers, not a tenant's own affiliate programs): their link and both tiers of terms, balances, click and referral counts, their team, and their most recent referrals, commissions and payouts. Use this instead of several separate reads when summarising someone's Chirply affiliate activity. Read-only.

Actions — agent_api_tools

8 operations.

List Agent API Tools (agent_api_tools.list)
[READ · ADMIN ONLY] List reusable API connections, draft/published agent tools, agent assignments, published versions, and recent redacted execution status for this account. Never returns stored credentials or full external responses.
Add connection (agent_api_tools.create_connection)
[ADMIN ONLY] Create a reusable account API connection. Authentication secrets are AES-256-GCM encrypted and can never be read back. This does not call the external API.
Edit connection (agent_api_tools.update_connection)
[ADMIN ONLY] Update a reusable API connection. Omit secret to keep the encrypted credential already stored; supplying one replaces it for every tool using this connection.
Add tool draft (agent_api_tools.create)
[ADMIN ONLY] Create a reusable Agent API Tool draft. It cannot run on calls until it is tested, published, and assigned to agents.
Publish (agent_api_tools.publish)
[HIGH RISK · ADMIN ONLY] Publish the current draft as a new immutable version. Every assigned live voice agent immediately receives this version; write tools may change a real external system without another human approval during a call.
Edit tool draft (agent_api_tools.update)
[ADMIN ONLY] Update the editable draft of a reusable Agent API Tool. Calls keep using the immutable active version until Publish is run, so incomplete edits cannot break assigned agents.
Save assignments (agent_api_tools.assign)
[ADMIN ONLY] Replace the complete set of agents allowed to use a reusable API tool. Assigned agents receive only its active published version.
Run test (agent_api_tools.test)
[HIGH RISK · ADMIN ONLY] Immediately call an external authenticated API using this tool's current draft configuration and supplied test input. A write-classified tool can change the external system for real; the response is bounded and credentials are never returned.

Actions — ai-agents

34 operations.

End test (ai_agents.finish_web_test)
Close the AI-agent rehearsal session behind a browser 'Start web call' test that never finished — the row the studio leaves open when the tab is closed, the laptop sleeps, or the network drops mid-test. A stranded session stays 'active' forever otherwise, which keeps it out of the agent's call history and out of its cost totals. Closing one stamps it completed and runs the same wrap-up (summary, outcome, pricing) a normally-ended test gets. Costs nothing and starts no call. Already-finished sessions are left exactly as they are.
List AI agents (ai_agents.list)
[READ] List the account's AI phone agents (AI receptionists) with their voice, model, language and whether each is active.
Open an AI agent (ai_agents.get)
[READ] Fetch one AI agent with every setting — persona, greeting, goals, voice and TTS provider, model, transfer rules, guardrails — plus the brain topics it's scoped to.
Create an AI agent (ai_agents.create)
Create an AI phone agent. Only a name is required; it gets the default Polly voice and no knowledge scope, ready to configure with ai_agents.update. IT IS CREATED ACTIVE, NOT PAUSED — `is_active` defaults to true, exactly as it does when a person creates one in the app. It cannot take a call until something points at it, but the moment a number is routed to it (ai_agents.attach_to_number) or a call campaign names it, this unconfigured agent WILL answer or place real calls with no further switch to flip. Pause it with ai_agents.set_active if you are creating it to configure later.
Edit an AI agent (ai_agents.update)
[HIGH RISK] Update any part of an AI agent — identity, persona and goals, greeting, voice and TTS provider, model, knowledge scope, what it's allowed to do on a call, transfer target, voicemail script and turn limit. Omitted fields are left alone. Everything is validated before anything is written. THIS SPENDS THE WORKSPACE'S MONEY AND CAN REACH REAL PEOPLE UNATTENDED, which is why it needs confirming: `use_relay=true` ADDS $0.07 PER MINUTE to every call this agent ever takes; granting `abilities` such as 'send_text', 'send_email' or 'add_to_campaign' is standing authorization for the AI to message real customers mid-call, on the account's own number and domain, with nobody reading the wording first; and `is_active=true` puts it back on the phone immediately.
Activate or pause an AI agent (ai_agents.set_active)
[HIGH RISK] Turn an AI agent on or off. Activating it PUTS IT ON THE PHONE IMMEDIATELY: from that moment it answers every inbound call on the numbers routed to it and places the outbound calls its campaigns queue, talking to real people and billing the account's own Twilio and OpenRouter accounts for every minute (plus $0.07/min if it runs on ConversationRelay), with no further approval. Pausing stops both; everything it's configured with is kept either way.
Delete an AI agent (ai_agents.delete)
[HIGH RISK] Permanently delete an AI agent. Refused while any call campaign is still using it — deleting mid-flight would leave every remaining recipient dialed, hearing silence, and metered. Numbers pointed at the agent fall back to the team automatically. This cannot be undone.
List agent voices (ai_agents.list_voices)
[READ] List every voice an AI agent can speak with: the curated Amazon Polly and Google catalogs (included with the platform, no extra account) and — when the account has connected ElevenLabs — the voices in its own ElevenLabs account. Use the returned ids with ai_agents.update. Each ElevenLabs voice carries live_call_safe: it is false for a voice the account CREATED itself (an instant or professional clone, a designed voice), because on a live call Twilio does the ElevenLabs synthesis from its own account and can only reach the shared ElevenLabs library — assigning one to an agent is refused. Those voices are still usable for voicemail drops and phone-menu prompts, where the audio is rendered up front with the account's own key.
Preview a voice (ai_agents.preview_voice)
[HIGH RISK] Audition an ElevenLabs voice without placing a call: synthesizes a short fixed sample line in its OWN ElevenLabs account, which SPENDS ITS CREDITS the first time a given voice is previewed (every preview after that is served from cache, free). Amazon Polly and Google voices cannot be previewed — Twilio only exposes them at call time, and the platform holds no AWS or Google credentials — so a preview is never faked with a substitute voice. Returns a link to play the audio; the bytes themselves aren't inlined.
List agent models (ai_agents.list_models)
[READ] List the OpenRouter models an AI agent can run on, with per-1M-token pricing, context window, and whether each supports tool calling (the voice agent requires it). Flags models measured too slow for live voice — a 'smart' model with a 16-second first token is unusable on a phone call.
List what an agent can be allowed to do (ai_agents.list_abilities)
[READ] List every ability an AI phone agent can be granted for use mid-call — messaging, CRM updates, campaigns, automations, and appointment scheduling. Use it to build `abilities` and the optional per-ability `ability_guardrails` map for ai_agents.update. Each entry says whether it reaches a real person immediately.
Point a number at an AI agent (ai_agents.attach_to_number)
[HIGH RISK · ADMIN ONLY] Route a phone number's incoming calls to an AI agent. THIS CHANGES WHO ANSWERS A LIVE BUSINESS PHONE LINE: the number's inbound destination becomes 'ai_agent', so from the next call onward real callers reach the AI instead of the team's phones, and every one of those calls bills the account's own Twilio and OpenRouter accounts. Whatever the number rang before (the team, another agent) stops receiving those calls until it is pointed back with ai_agents.detach_from_number. Manager-only, matching the number settings page.
Stop an AI agent answering a number (ai_agents.detach_from_number)
[ADMIN ONLY] Hand a phone number's incoming calls back to the team (simulring online browser agents, then voicemail). The agent itself is untouched. Manager-only, matching the number settings page.
Place a test call (ai_agents.test_call)
[HIGH RISK] Have an AI agent call a phone number right now so you can hear it — the agent page's 'Test call' button. THIS DIALS A REAL PHONE: it bills the account's own Twilio for the voice minutes and its OpenRouter account for the tokens the conversation uses (plus $0.07/min if the agent runs on ConversationRelay). The agent must be active and OpenRouter must be connected.
Have an AI agent call a contact (ai_agents.call_contact)
[HIGH RISK] Queue an AI agent to call one of your contacts on their stored phone number, dispatched immediately by the outbound call engine (do-not-contact and the wallet guard still apply; quiet hours are deliberately skipped because this is an explicit 'call them now'). THIS DIALS A REAL PERSON and bills Twilio voice minutes plus OpenRouter tokens. The agent must be active and OpenRouter must be connected.
List AI calls (ai_agents.list_calls)
[READ] List calls AI agents have handled — which agent took it, which of your phone numbers it ran on, direction, who was on the other end, status, outcome, turn count and what each call cost. Use ai_agents.get_call for the full transcript.
Open an AI call (ai_agents.get_call)
[READ] Fetch one AI call in full: which agent handled it and on which of your phone numbers, the turn-by-turn transcript, every tool the agent used, the summary and outcome, any message it took or contact fields it updated, and a link to the recording when one was kept.
List knowledge topics (brain.list_topics)
[READ] List the AI Brain's topics — the folders of knowledge agents answer from, and the unit an agent's knowledge scope is set in.
Create a knowledge topic (brain.create_topic)
Create a topic in the AI Brain. Topic names are unique per account and become merge-field slugs ({{brain.pricing_faq}}), so pick something an agent can be pointed at.
Rename a knowledge topic (brain.update_topic)
Change a knowledge topic's name or description. Its knowledge items are untouched.
Delete a knowledge topic (brain.delete_topic)
[HIGH RISK] Permanently delete a knowledge topic AND every knowledge item inside it. Agents scoped to this topic lose that knowledge on their next call. This cannot be undone.
List knowledge items (brain.list_knowledge)
[READ] List the AI Brain's knowledge items with their provenance — typed in by hand, extracted from an uploaded document, or crawled off a website — and how many words each holds. Body text is omitted unless you ask for it.
Preview what the AI would read (brain.compose)
[READ] Compose the exact knowledge block an AI writer is handed for one scope — the whole Brain, chosen topics, chosen entries, or nothing — and report how many topics, entries and words it resolves to and whether it had to be cut to fit the prompt budget. Use it to check a scope before paying for a generation; it is read-only, generates nothing, and contacts no provider.
Open a knowledge item (brain.get_knowledge)
[READ] Fetch one knowledge item with its full body text — exactly what an agent reads to a caller — plus where it came from and when it was last extracted.
Add a knowledge item (brain.add_knowledge)
[HIGH RISK] Add a knowledge item to a topic by typing the text in. This is the same column an uploaded document or a crawled page lands in, so the agent reads it by the identical path. Content may be left empty as a stub.
Edit a knowledge item (brain.update_knowledge)
[HIGH RISK] Update a knowledge item's title, description or body text. Provenance is deliberately kept: a crawled page someone tidied up by hand is still that page, which is what lets a re-crawl update this item instead of duplicating it.
Delete a knowledge item (brain.delete_knowledge)
[HIGH RISK] Permanently delete a knowledge item and any source documents stored behind it. Agents stop answering from it on their next call. This cannot be undone.
List source documents (brain.list_documents)
[READ] List the original documents stored behind knowledge items — filename, size, which extractor read it and how much text came out. Each row links to a download of the original.
Ingest a document from a URL (brain.add_document_from_url)
[HIGH RISK] Fetch a document from a URL, extract its text, and store it as knowledge — the machine-surface equivalent of the Brain's upload button (binary uploads can't ride a tool call). TXT/MD/CSV/TSV/JSON are decoded in-process for free; PDF/DOCX/DOC/ODT/RTF/XLSX/XLS/HTML are read by Firecrawl, which SPENDS THE WORKSPACE'S FIRECRAWL CREDITS and needs Firecrawl connected. Pass item_id to REPLACE an existing item's content (its old source documents are removed). Files over 20 MB, and scans with no text layer, are refused with the reason.
Crawl a website into the Brain (brain.crawl_website)
[HIGH RISK] Crawl a website (or a single page) with Firecrawl and import each page as a knowledge item in a topic. THIS SPENDS THE WORKSPACE'S FIRECRAWL CREDITS — roughly one per page crawled — so keep page_limit tight. Firecrawl must be connected. The crawl runs in the background for minutes; poll brain.get_crawl for progress. Re-crawling the same URL UPDATES the items it produced before rather than duplicating them, which is also how you re-ingest a site that has changed.
List website crawls (brain.list_crawls)
[READ] List website crawl jobs with their ingestion status — queued, crawling, done, failed or canceled — plus pages found, imported and skipped, and the Firecrawl credits each one used.
Check a crawl's progress (brain.get_crawl)
[READ] Fetch one website crawl job — where it is, how many pages have been crawled, imported and skipped, credits used, and the reason if it failed. Poll this after brain.crawl_website; a crawl runs for minutes.
Stop a website crawl (brain.cancel_crawl)
[HIGH RISK] Stop a crawl that is still queued or running, so it stops spending Firecrawl credits. Pages already imported stay in the Brain, and a canceled crawl can't be resumed — start a new one instead.
Delete a crawl from the history (brain.delete_crawl)
[HIGH RISK] Remove a crawl job from the history panel. The knowledge items it imported are left in place — delete those separately if you want them gone.

Actions — ai_employees

36 operations.

Choose Brain topics (ai_employees.list_brain_topics)
[READ · ADMIN ONLY] List this account's Brain topic names and descriptions for employee knowledge selection. Reads metadata only; does not expose item bodies or spend credits.
AI employees (ai_employees.list)
[READ] List the account's AI employees — its named, persistent AI coworkers — with each one's status (active or paused) and a plain-language summary of which feature areas it may touch and at what level.
Open an AI employee (ai_employees.get)
[READ] Fetch one AI employee: its persona, standing instructions, its own reference knowledge, permission grants, status, its most recent runs (what it has actually done), and how many of its proposed actions are still waiting for approval.
Grantable areas (ai_employees.list_grantable_areas)
[READ] List the feature areas an AI employee can be granted access to, with a plain-language label, how many actions each area holds, and whether it contains risky (approval-gated) actions. Use these domain names to build a valid `grants` object for ai_employees.hire or ai_employees.update.
Hire an AI employee (ai_employees.hire)
[HIGH RISK · ADMIN ONLY] Create a new AI employee: a persistent, named AI coworker that acts inside this account with the permissions you grant it. Once hired and given work, it operates real records — and in areas granted at the 'propose' level it can queue actions that, when approved, send real messages to real people, spend the organization's money, or delete data. Its work runs on the organization's own OpenRouter key and is billed to it; set `daily_token_budget` to cap what it may spend in a day.
Edit an AI employee (ai_employees.update)
[ADMIN ONLY] Update an AI employee's name, title, face emoji, persona, standing instructions, its own reference knowledge, permission grants, model, knowledge-base access, daily token budget, or status. Omitted fields are left alone; a supplied `grants` object REPLACES the previous grants entirely. Setting status to 'paused' stops it taking new work without losing its configuration or history; 'active' puts it back to work. Raising or removing `daily_token_budget` raises what the account can spend on this employee's OpenRouter usage in a day.
Delete an AI employee (ai_employees.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete an AI employee. Its conversations, run history, and pending approvals go with it, and this cannot be undone. Anything it already did to the account stays done. To stop one temporarily, pause it with ai_employees.update instead.
Employee activity (ai_employees.list_runs)
[READ] The AI employees' activity feed: every run — a task handed to an employee and what came of it — newest first, with its status (running, waiting on an approval, completed, failed), a one-line summary, and how many actions it took. Optionally filter to one employee.
Approvals inbox (ai_employees.list_approvals)
[READ] List the actions AI employees have proposed and stopped on — the risky ones (sending real messages, spending money, deleting data) that never run without a deliberate authorization. Each entry names the employee, the capability it wants to run, and the exact arguments. Pending ones are resolved with ai_employees.approve, which IS manager-only.
Approve a proposed action (ai_employees.approve)
[HIGH RISK · ADMIN ONLY] Authorize (or refuse) an action an AI employee proposed and stopped on, then let it carry on. Approving RUNS the action for real — it is one the employee flagged as irreversible, outward-facing, or costly, so it may send messages to real people, spend the organization's money, or destroy data. Refusing tells the employee no and it continues without it. Either way the employee resumes and its follow-up reply is returned.
Give an employee work (ai_employees.ask)
Hand a task or message to an AI employee and get its reply. The employee acts for real within its granted areas — reading and writing actual account records — and its turn consumes the organization's own OpenRouter credits immediately. Anything risky it wants to do (sending real messages, spending money, deleting) is NEVER run off its own decision: those come back in `pending` and appear in ai_employees.list_approvals for a second, deliberate ai_employees.approve call. Continues an existing conversation when you pass thread_id, otherwise starts one. A paused employee refuses new work.
Standing duties (ai_employees.list_duties)
[READ] Lists the standing duties an AI employee runs on a schedule — what each one is briefed to do, how often it runs, when it next runs, and whether it has been failing. A duty runs unattended and spends the organization's own OpenRouter credits every time it fires, so this is the list of what the account is paying for on a timer.
Add a standing duty (ai_employees.create_duty)
[HIGH RISK · ADMIN ONLY] Puts an AI employee on a schedule: from now on it runs the brief you give here, on its own, with nobody watching. EVERY run consumes the organization's own OpenRouter credits, and a duty set to run every 15 minutes runs ~96 times a day — the cost is recurring, not one-off. The employee acts for real within the areas it was hired with; anything risky (sending messages, spending money, deleting) still stops as a proposal in the approvals inbox rather than happening unattended. The configured report destination is standing permission for that report delivery, including billable email/SMS when selected. Other risky actions still need approval. The run acts under the authority of the employee's supervisor, and stops working entirely if that person leaves the account.
Edit a standing duty (ai_employees.update_duty)
[HIGH RISK · ADMIN ONLY] Changes a standing duty's brief, schedule or report destination. Saving an email/SMS recipient authorizes future report sends with normal provider charges and consent checks. Tightening the schedule increases how often the account's own OpenRouter credits are spent — every run costs, so 'every hour' to 'every 5 minutes' is a twelvefold increase in spend, not a preference. To simply stop or restart a duty, use ai_employees.set_duty_status instead.
Report deliveries (ai_employees.list_duty_deliveries)
[READ · ADMIN ONLY] Lists saved report delivery states, scheduled send times and errors for this account's standing duties. No messages are sent and no AI credits are spent. 'needs_review' means a provider submission may have happened; do not resend blindly.
Cancel report delivery (ai_employees.cancel_duty_delivery)
[ADMIN ONLY] Cancels a report delivery waiting for its run, queued for sending, or failed before provider submission. Keeps its saved report and history; does not stop the AI run. Cannot recall a sent message or stop a provider submission already in progress. Cancelling spends no credits.
Retry report delivery (ai_employees.retry_duty_delivery)
[HIGH RISK · ADMIN ONLY] Queues a failed report for another delivery attempt only when it is known no provider submission occurred. Sending an email or SMS uses the account's provider and may incur its normal charges; recipient consent and current permissions are checked again. Does not rerun the AI. A sent, in-progress or uncertain delivery cannot be retried here, preventing duplicate messages and charges.
Pause or resume a duty (ai_employees.set_duty_status)
[ADMIN ONLY] Switches a standing duty off ('paused') or back on ('active'). Pausing is the stop button: it takes effect before the next run, costs nothing, and keeps the duty and its history intact. Resuming re-arms the schedule from now — it does not replay runs missed while it was off. Resuming also clears the failure counter, so a duty that auto-paused itself after repeated failures starts fresh.
Delete a standing duty (ai_employees.delete_duty)
[HIGH RISK · ADMIN ONLY] Permanently removes a standing duty. The employee stops running it. Past runs stay in the activity log, but the duty itself and its schedule are gone and cannot be recovered — pause it instead if you might want it back.
Run a duty now (ai_employees.run_duty)
[HIGH RISK · ADMIN ONLY] Runs a standing duty immediately instead of waiting for its next scheduled time, and returns what the employee did. This is a real run: it acts on real account records and spends the organization's own OpenRouter credits now. It does not change the schedule — the next scheduled run still happens as planned. Anything risky the employee wants to do comes back as a proposal in ai_employees.list_approvals rather than being carried out. A paused duty can be run this way; a paused employee refuses.
Today's AI spend (ai_employees.budget)
[READ] Reports how many tokens an AI employee has used since midnight UTC against its daily token budget, and whether that budget is currently stopping it from taking work. An employee with no budget set has no ceiling. This is the number that decides whether the next scheduled run happens, so it is worth checking when a duty has gone quiet.
Hosting connections (ai_runners.connect_options)
[READ · ADMIN ONLY] Read this account’s Cloudflare and DigitalOcean hosting connections and available Cloudflare accounts. Provider credentials stay private. Does not create paid resources.
Connect hosting provider (ai_runners.authorize)
[ADMIN ONLY] Open account-bound provider authorization and return to this employee’s Infrastructure tab. When Cloudflare OAuth is unavailable, returns the scoped API token instructions. Connecting does not create paid resources.
Save hosting connection (ai_runners.connect_token)
[HIGH RISK · ADMIN ONLY] Verify and securely save a scoped provider API token for this account’s dedicated employee hosting connection. Replaces that hosting credential while preserving other provider integrations. Does not create paid resources. Use the secure Infrastructure form or a private API/MCP client, never a chat message.
Deploy employee hosting (ai_runners.deploy)
[HIGH RISK · ADMIN ONLY] Create two paid employee runners on your connected Cloudflare or DigitalOcean account. Provider hosting charges start as resources are created; model usage is billed separately. Saves deployment progress and automatically routes new jobs to this host after a healthy heartbeat. Repeated calls reuse the current deployment. No local installer is required.
Retry deployment (ai_runners.retry)
[HIGH RISK · ADMIN ONLY] Resume the employee’s failed deployment or resource removal after checking the saved provider resources. Deployment can create paid resources; an existing installation is reused. Removal continues stopping its provider charges.
Remove employee hosting (ai_runners.remove_hosting)
[HIGH RISK · ADMIN ONLY] Return new work to managed hosting, wait for existing runner jobs, then permanently delete the provider resources created by this employee’s saved deployment. Provider charges continue until deletion completes. Unrelated resources and legacy manual installations are not deleted.
Infrastructure status (ai_runners.status)
[READ · ADMIN ONLY] Read an employee's managed or customer-owned hosting, provider and last verified heartbeat. Does not provision resources or spend money.
Download setup (ai_runners.create_setup)
[HIGH RISK · ADMIN ONLY] Create a one-use, one-hour installer for this employee on Cloudflare Containers or DigitalOcean App Platform. The returned installer contains a pairing secret; keep it private. Downloading is free. Running it creates two paid containers in the customer's provider account. Model usage is billed separately by the account's OpenRouter connection. Hosting switches only after a healthy runner is explicitly enabled.
Use this infrastructure (ai_runners.set_hosting)
[HIGH RISK · ADMIN ONLY] Route new employee jobs to a connected customer runner, or return new jobs to Chirply-managed hosting. Existing leased work finishes on its current host. This does not delete paid provider resources; stop those in the provider account to stop their hosting charges.
Disconnect runner (ai_runners.revoke)
[HIGH RISK · ADMIN ONLY] Revoke the customer runner's employee-scoped credential and return new jobs to managed hosting. In-flight unconfirmed actions require review. Does not delete Cloudflare or DigitalOcean resources or stop their charges; remove those in the provider account.
Employee inboxes (ai_employees.list_inboxes)
[READ] Read an existing AI employee's Gmail assignments, shared account connection status, and exact actions permitted by both employee grants and caller access. Does not read message bodies, connect accounts or activate inbox work.
Save inbox assignments (ai_employees.save_inboxes)
[HIGH RISK · ADMIN ONLY] Configure selected connected Gmail accounts for an existing employee. Active assignments process future eligible mail using the account's OpenRouter credits, within existing employee grants; all writes and replies require manager approval. Paused saves configuration, and older messages are never enrolled. Does not activate a paused employee or send email itself.
Pause account (ai_employees.pause_inbox)
[ADMIN ONLY] Pause one employee Gmail assignment to stop new jobs and block further tools or approvals for its existing jobs. Retains configuration, mail and activity. An action already accepted by an external provider cannot be recalled by pausing.
Review inbox run (ai_employees.get_inbox_run)
[READ] Read one employee inbox job's recorded run and all approval proposals in its conversation, including older jobs outside the recent activity page. Returns an explicit error if the job is missing or belongs elsewhere. Does not approve actions or send email.
Inbox activity (ai_employees.inbox_activity)
[READ] Read durable Gmail jobs for one employee, including originating account and sender, subject, reasoning summary, errors, run links and whether manager approval is pending. Reads existing activity only; does not retry jobs or send email.

Actions — ai_studio

22 operations.

AI Studio library (ai_studio.list_generations)
[READ] List everything the AI Studio has generated for this account — images, video, voiceovers, music, avatars, songs and transcripts — newest first. Read-only; generates nothing and costs nothing.
Check a generation (ai_studio.get_generation)
[READ] Fetch one generation's current state and, once finished, the URL of the file it produced. THIS IS THE POLLING CALL for video, avatar, song and dubbing jobs: keep calling it until status is "succeeded" or "failed". It also advances any of this account's in-flight jobs, so polling here is what moves them along. Read-only; generates nothing and costs nothing.
Delete a generation (ai_studio.delete_generation)
[HIGH RISK] Permanently delete a generation and the file it produced from the account's storage. This cannot be undone, and any page, email or campaign already pointing at that file will break.
Video models (ai_studio.list_video_models)
[READ] List the video models the AI Studio can use, with what each one supports — clip lengths, aspect ratios, resolutions, and whether it generates its own audio. Read-only; costs nothing. Use it to pick a model id before calling ai_studio.generate_video.
Voices (ai_studio.list_voices)
[READ] List the voices in its own ElevenLabs account, including any cloned ones. Read-only; costs nothing. Use it to pick a voice id for ai_studio.generate_voiceover or ai_studio.convert_voice.
Generate an image (ai_studio.generate_image)
Generate an original image from a description, store it in the account's permanent storage, and return a public URL that can be dropped straight into a funnel page, email or campaign. Runs on the account's own OpenRouter key and is billed to that account at OpenRouter's own rate for the configured image model, which Chirply does not set or mark up. Nothing is published or sent.
Generate a video (ai_studio.generate_video)
[HIGH RISK] Generate a video clip from a written description. SPENDS REAL MONEY on its own fal.ai account — a few seconds of video typically costs several US dollars, far more than an image, and a failed or unwanted result is not refundable. Returns immediately with a generation id; rendering takes minutes, so poll ai_studio.get_generation until it succeeds.
Animate an image (ai_studio.animate_image)
[HIGH RISK] Turn a still image into a moving video clip. SPENDS REAL MONEY on its own fal.ai account — typically several US dollars per clip. The image must be at a public https URL the provider can download, such as one from ai_studio.generate_image. Returns immediately; poll ai_studio.get_generation until it succeeds.
Upscale a video (ai_studio.upscale_video)
[HIGH RISK] Increase a video's resolution and sharpness with Topaz, optionally raising its frame rate. SPENDS REAL MONEY on its own fal.ai account, priced by the length and resolution of the input. Returns immediately; poll ai_studio.get_generation until it succeeds.
Remove a video's background (ai_studio.remove_video_background)
[HIGH RISK] Cut the background out of a video, leaving the subject on transparency — for overlaying a presenter on a slide or page. SPENDS REAL MONEY on its own fal.ai account. Defaults to WebM output because it is the only format that carries real transparency; MP4 renders the removed background as solid black. Returns immediately; poll ai_studio.get_generation.
Lip-sync a video to new audio (ai_studio.lipsync_video)
[HIGH RISK] Re-time a person's mouth in a video to match a different audio track — for dubbing a recording or swapping the voiceover. SPENDS REAL MONEY on its own fal.ai account. Both files must be at public https URLs. Returns immediately; poll ai_studio.get_generation.
Generate an avatar portrait (ai_studio.generate_avatar_portrait)
Generate a photorealistic portrait to use as a presenter, or edit an existing one while keeping the same face. Supply referenceImageUrl to keep a character consistent across shots rather than getting a new stranger each time. Runs on the account's own OpenRouter key and is billed to that account at OpenRouter's own rate for the configured image model, which Chirply does not set or mark up. This is the first half of making a talking-head video — feed the result to ai_studio.generate_avatar_video.
Generate a talking-head video (ai_studio.generate_avatar_video)
[HIGH RISK] Turn a portrait plus a voiceover into a video of that person speaking the words, lips matched. SPENDS REAL MONEY on its own Replicate account, priced by the length of the audio. Make the voiceover FIRST with ai_studio.generate_voiceover — the video's length and cost follow the audio, so generating in the other order wastes money. Returns immediately; poll ai_studio.get_generation.
Generate a voiceover (ai_studio.generate_voiceover)
Read text aloud in a chosen voice and save the audio to the library with a public URL. Runs on its own ElevenLabs account and consumes their character quota. Nothing is played to anyone or attached to a call — it just produces a file you can use in a video, an IVR prompt, or a campaign.
Generate a music track (ai_studio.generate_music)
[HIGH RISK] Compose an original music track from a description of the style and mood. SPENDS REAL MONEY on its own ElevenLabs account — a full-length track consumes substantially more credit than a voiceover, and music generation is unavailable on the ElevenLabs free tier.
Generate a sound effect (ai_studio.generate_sound_effect)
Generate a short sound effect from a description — a whoosh, a notification chime, ambient room tone. Runs on its own ElevenLabs account and consumes a small amount of their quota.
Change the voice in a recording (ai_studio.convert_voice)
Re-perform an existing recording in a different voice, keeping the original delivery, timing and emotion. Useful for putting a consistent brand voice over a rough recording. Runs on its own ElevenLabs account and consumes their quota.
Clean up a recording (ai_studio.clean_up_audio)
Strip background noise, music and room echo from a recording, leaving clean speech. Runs on its own ElevenLabs account and consumes their quota. The original is left untouched — this produces a new file.
Transcribe a recording (ai_studio.transcribe_audio)
Turn a recording into text, optionally labelling who spoke each line. Returns the transcript directly and saves it to the library. Runs on its own ElevenLabs account and consumes their quota.
Dub into another language (ai_studio.dub_audio)
[HIGH RISK] Translate a recording or video into another language, re-voiced in the original speakers' own voices. SPENDS REAL MONEY on its own ElevenLabs account, priced by the length of the media. Returns immediately; dubbing takes minutes, so poll ai_studio.get_generation until it succeeds.
Clone a voice (ai_studio.clone_voice)
[HIGH RISK] Create a new voice in its own ElevenLabs account from recordings of someone speaking. The voice is created THERE, occupies one of that account's voice slots, and remains after disconnecting from this account. Instant cloning is restricted on some ElevenLabs plans. Only clone a voice you have the speaker's permission to use.
Generate a song (ai_studio.generate_song)
[HIGH RISK] Write and perform a complete song — music and sung vocals — from a style description and optional lyrics. SPENDS REAL MONEY on its own Replicate account. Returns immediately; generation takes minutes, so poll ai_studio.get_generation until it succeeds.

Actions — appdata

4 operations.

Store app data (appdata.set)
Store (create or overwrite) one value in your app's own data, keyed by collection + key, scoped to this install. Only your app can read it back.
Read app data (appdata.get)
[READ] Fetch one value from your app's own data by collection + key. Returns null if absent.
List app data (appdata.list)
[READ] List your app's stored records in a collection, optionally filtered by a key prefix.
Delete app data (appdata.delete)
[HIGH RISK] Delete one value from your app's own data by collection + key.

Actions — apps

23 operations.

How to build an app (apps.dev_guide)
[READ] Read this FIRST. Returns the complete guide to building and publishing a marketplace app with your own AI agent: the hosted vs external model, the create → publish_version → submit_for_review → (admin review) → install flow, the manifest (pages/widgets/cards), the App SDK (chirply.call / chirply.data / chirply.context), the scope grammar, and a minimal worked hosted app. After reading it, use apps.create, apps.publish_version, and apps.submit_for_review.
Create an app (apps.create)
[ADMIN ONLY] Create a new app in this agency's developer account, as a private draft. Doesn't publish or list it — that happens later via apps.submit_for_review and platform review. Requires an agency (white-label or reseller) plan. Both hosting modes are live: 'external' loads your own HTTPS URL in a sandboxed iframe, 'hosted' serves a self-contained HTML document you publish through apps.publish_version. Paid apps are live too — apps.start_purchase and apps.complete_purchase take real money from buyers — so set pricing_kind, price_cents and currency to what you actually intend to charge.
List my apps (apps.list)
[READ · ADMIN ONLY] List the apps this agency owns (drafts and published), newest first.
Open an app (apps.get)
[READ · ADMIN ONLY] Fetch one of this agency's apps by id, with all of its fields.
Edit an app (apps.update)
[ADMIN ONLY] Update an app's details, pricing, requested scopes, or visibility (private/unlisted). Doesn't change review status. Omitted fields are left alone. This edits a LISTED app too, not only a draft: the name, copy and price change on the public marketplace card immediately, with no re-review, and price_cents is what the next buyer is really charged. Repointing external_base_url moves every installed copy's UI to a different server.
Publish an app version (apps.publish_version)
[HIGH RISK · ADMIN ONLY] Publish an immutable version of an app: its manifest (the pages/widgets/cards/actions it adds) and, for a PLATFORM-HOSTED app, its `document` — a single self-contained HTML page (inline CSS/JS + the App SDK) served in a sandboxed iframe. This is how an AI agent ships an app it wrote onto the marketplace. It is OUTWARD-FACING AND PERMANENT: a published version cannot be edited or unpublished, a listed app's new installs pin it straight away, and the code in `document` runs inside other people's accounts. Version labels are unique per app, so a mistake can only be superseded, never withdrawn.
Submit an app for review (apps.submit_for_review)
[HIGH RISK · ADMIN ONLY] Move a draft app into the platform review queue so it can be approved and listed on the marketplace. This hands the app, its published code and its listing copy to platform reviewers outside this agency, and approval puts it in front of every account on the platform. The app must have a published version first.
Browse the app marketplace (apps.list_directory)
[READ] Browse apps that can be installed into this account — everything listed publicly, plus this agency's own apps (so you can install one before it's listed). Each app includes its cumulative download count across accounts, and an `is_owner` flag that is true for apps this account publishes (those can be managed in the developer portal).
Install an app (apps.install)
[HIGH RISK · ADMIN ONLY] Install an app into THIS account and issue it an access token with the scopes you grant. This gives third-party code ongoing API access to the account's data within those scopes — the token is shown once and can't be retrieved again. IT ALSO STARTS SENDING DATA OUT: if the app's manifest subscribes to events and you grant 'events:read', the install provisions those event subscriptions and returns a `webhook_secret`, after which this account POSTs the subscribed events (new contacts, inbound messages, won deals, paid invoices…) to the app developer's own server as they happen, until someone uninstalls. Grant the least it needs, and know where the data is going. Re-installing rotates the existing install.
List installed apps (apps.list_installs)
[READ · ADMIN ONLY] List the apps installed in this account, with their granted scopes and status.
View app updates (apps.list_updates)
[READ] List version updates for apps installed in this account. Each result identifies the installed version, newest published version, app-specific release notes, and whether an update is available. Marketplace app changes live here instead of the product-wide What's new feed.
View an app's what's new (apps.list_release_notes)
[READ] List the published version history and app-owned release notes for one app installed in this account. This is the app's own What's new feed, separate from the product-wide release feed.
Update app (apps.apply_update)
[HIGH RISK · ADMIN ONLY] Move one installed Marketplace app to its newest published version. For hosted or external apps this immediately changes the app UI and declared event subscriptions running in the account; native apps acknowledge the version of their already-deployed feature. Existing permissions and access token remain unchanged.
Installed account apps (apps.list_mobile_pages)
[READ] List the custom pages contributed by active apps installed in this account — first-party native apps (each gated by its own feature flag) plus external/hosted Marketplace apps when the app platform is on. This is the member-safe mobile navigation view: it returns only page labels and in-app routes, never install tokens, secrets, granted scopes, or configuration. Read-only.
Check app ownership (apps.entitlement)
[READ · ADMIN ONLY] Check what this account has PAID for on one app, which is a different question from whether it is currently installed. Returns how it was bought (paid once, monthly, or yearly), whether the account may install it again without paying, when a subscription's paid-up period ends, and whether that subscription is already cancelling. Reads only — spends no money and changes no install. Use it before apps.install on a paid app: an account that already owns one reinstalls for free, so a purchase is not always needed.
Uninstall an app (apps.uninstall)
[HIGH RISK · ADMIN ONLY] Revoke an app's install in this account. Its access token stops working immediately and the app can no longer reach any of this account's data. If the app is on a paid subscription this ALSO cancels that subscription at the end of the current period — billing stops, access continues until the period ends, and it can be reinstalled free until then, after which it switches off. Uninstalling never refunds and never destroys a one-time purchase: an app bought outright can always be reinstalled at no charge.
Rotate an install's token (apps.rotate_token)
[HIGH RISK · ADMIN ONLY] Issue a fresh access token for an installed app and invalidate the old one immediately. Use if a token may have leaked. The new token is shown once.
View a marketplace listing (apps.get_listing)
[READ] Fetch one marketplace app's public listing detail by slug or id: its full description, screenshots, icon, pricing, category, requested scopes, developer name, and how many accounts have it installed. Returns publicly-listed apps, plus your own agency's apps before they're listed. This is the read behind the app's detail page.
App install stats (apps.stats)
[READ · ADMIN ONLY] For an app your agency OWNS, how many accounts have installed it — total, active, revoked, and suspended. This is your developer analytics: it counts installs across all accounts (aggregate only, it never reveals which accounts).
Connect Stripe for payouts (apps.developer_connect)
[ADMIN ONLY] Start (or resume) Stripe Connect onboarding so your agency gets PAID for paid app installs. Returns a Stripe-hosted onboarding URL — open it, finish the steps, come back. Money from paid installs settles to this connected account (you're the merchant of record), minus the marketplace fee. Required before you can actually charge for an app.
Payout account status (apps.developer_connect_status)
[READ · ADMIN ONLY] Check your agency's Stripe Connect payout account for paid app installs — whether it's connected, can accept charges, and can receive payouts.
Continue to payment (apps.start_purchase)
[ADMIN ONLY] Prepare the payment form for a PAID app in THIS account. Creates an internal pending order and may create a short-lived Stripe CustomerSession to show an existing saved card; it does not create a Stripe PaymentIntent, charge money, or install the app. Submit payment details with apps.complete_purchase. Free apps use apps.install instead.
Pay now (apps.complete_purchase)
[HIGH RISK · ADMIN ONLY] Submit payment for a paid app prepared with apps.start_purchase. On the first call, confirmation_token must come from the buyer's completed Stripe Payment Element; only then does this create and confirm a REAL-MONEY one-time charge or monthly subscription on the developer's Stripe account. If customer authentication is required, call again without the token after Stripe.js completes it. Installs the app only after Stripe verifies payment.

Actions — assets

13 operations.

List files (assets.list)
[READ] List the organization's media library (uploaded images, videos, audio and documents), newest first, each with its permanent public URL. Filter by kind or folder and search names.
Open a file (assets.get)
[READ] Fetch one library file by id, including its permanent public URL.
Library totals (assets.stats)
[READ] The four headline counts on the Media Library screen: how many files are in the library, how many of those are images, how many Design Studio projects exist, and how many folders. Whole-account lifetime counts with no date window and no filters — assets.list answers 'which files' and pages, this answers 'how many'. Read-only.
Upload files (assets.upload)
Upload a file into the organization's media library by sending its bytes base64-encoded, and get back its permanent public Chirply URL — the same URL the Upload button produces, usable in emails, funnel pages, posts, designs and as an outbound message attachment. Accepts PNG, JPG, GIF, WebP, SVG, ICO, MP4, MOV, WebM, MP3, WAV, M4A, OGG and PDF files, up to 25 MB per file. THE EXTENSION ON `name` DECIDES THE TYPE: the file's real header bytes must match what that extension claims or the upload is rejected, and the stored content type comes from the extension alone — never from anything the caller asserts. Costs nothing and sends nothing; it stores the bytes and adds one row to the library, where anyone in the workspace can see and delete it. If the file is already on the public web, assets.import_from_url is cheaper than base64.
Import a file from a URL (assets.import_from_url)
[HIGH RISK] Download a file from a public https URL into the organization's media library and return its permanent Chirply URL. Accepts images, video, audio and PDF up to 25 MB. Use this instead of hotlinking: imported files can't break when the source disappears. THIS MAKES AN OUTBOUND REQUEST FROM CHIRPLY'S SERVERS to whatever address is given, so everything in the URL — path, query string, fragment — is disclosed to whoever operates it. That is why it asks for confirmation.
Generate an AI image (assets.generate_image)
[HIGH RISK] Generate an image from a description and save it straight into the media library, returning its permanent URL. THIS SPENDS REAL MONEY: the request runs on the organization's OWN OpenRouter API key, so the image-generation charge lands on the tenant's OpenRouter bill directly — there is no credit pool and no free allowance to absorb it. Each call is a separate billed generation whether or not the result is any good.
Rename a file (assets.rename)
Change a library file's display name. The URL never changes.
Move files to a folder (assets.move)
File one or more library files into a folder, or out of any folder.
Delete files (assets.delete)
[HIGH RISK] Permanently delete library files and their stored bytes. Anything embedding the file's URL (emails already sent, funnel pages, designs) will show a broken image. This cannot be undone.
List folders (assets.list_folders)
[READ] List the library's folders, alphabetically.
New folder (assets.create_folder)
Create a library folder to organize files into.
Rename folder (assets.rename_folder)
Change a library folder's display name. Nothing else moves: the files inside stay in it, and every file URL is unaffected because a folder is only a label on the library screen.
Delete a folder (assets.delete_folder)
[HIGH RISK] Permanently delete a library folder. The files inside are NOT deleted and their URLs keep working — they just become unfiled and reappear under 'All files'. The folder itself cannot be restored; recreating it does not re-gather what was in it, so the tidying has to be redone by hand.

Actions — assistant

6 operations.

Suggested questions (assistant.suggestions)
[READ] Read suggested assistant questions based on this account’s current setup, incoming conversations, open deals, and the caller’s assigned tasks. Uses existing records; does not call an AI model, send messages, or change data.
Ask the assistant (assistant.ask)
Send a message to the in-app AI assistant and get its reply. In 'chat' mode it only explains how the product works and changes nothing. In 'do' or 'smart' mode it can operate the account on your behalf — creating and editing records, running the same actions this API exposes — so treat its replies as having had real effects. Anything irreversible, outward-facing or costly (sending messages, spending money, deleting) is NEVER run off its own decision: those come back in `pending` for you to authorize with assistant.approve. Continues an existing conversation when you pass thread_id, otherwise starts one. Runs on the organization's own OpenRouter key and is billed to it; with no key connected, only 'chat' works.
Approve a proposed action (assistant.approve)
[HIGH RISK] Authorize (or refuse) the action the assistant stopped to ask about, then let it carry on. Approving RUNS the action for real — it is the one the assistant flagged as irreversible, outward-facing or costly, so it may send messages to real people, spend the organization's money or destroy data. Refusing tells the assistant no and it continues without it.
Past chats (assistant.threads)
[READ] List your conversations with the assistant, most recently used first. Titles are taken from the first thing said in each. This is a retention WINDOW, not a permanent archive: a conversation nobody has touched for `retention_days` (returned alongside the list) is deleted automatically, messages and all. Anything worth keeping should be copied out before then.
Read a conversation (assistant.thread)
[READ] Read one conversation back: what was asked, what the assistant answered, and every action it took along the way.
Delete a conversation (assistant.delete_thread)
[HIGH RISK] Permanently delete one conversation and every message in it. This cannot be undone. Anything the assistant already did to the account stays done — only the record of the conversation goes.

Actions — attribution

5 operations.

Acquisition sources (attribution.acquisition_outcomes)
[READ] Read first-touch acquisition channels, sources and campaigns from contacts' saved attribution, with new leads, noncanceled appointments and confirmed live-mode invoice, funnel and connected Stripe collections in an explicit UTC window. Group by channel, source or campaign; absent evidence stays unknown and unlinked payments stay unattributed. Mirrored payment intents are deduplicated and currencies stay separate. Counts are period activity, not one acquisition cohort or proof an ad caused a payment. No manual source costs are assigned to campaigns. Read-only; makes no ad-provider calls, changes no contacts and charges nobody.
Source outcomes and costs (attribution.source_outcomes)
[READ] Read leads created, noncanceled appointments booked and collected revenue by the contact's currently recorded source in an explicit UTC window. Only live-mode payments are included. Revenue stays separated by currency and deduplicates mirrored Stripe charges. Costs are manually entered evidence, not synchronized ad-platform spend; absent costs are unknown. Returns the latest 100 cost entries. Counts describe activity during the same period, not a single acquisition cohort; revenue/cost ratios are observational and exclude service costs. Read-only; makes no ad-provider calls and charges nobody.
Record source cost (attribution.record_spend)
[ADMIN ONLY] Record one manually verified source cost, currency, UTC date and evidence reference for reporting. Does not create ads, charge an account or transmit anything to an ad platform. Duplicate source/date/currency/reference combinations are rejected. Entries remain in the audit history; correct an error by voiding the entry and recording a replacement with a new reference. Owner/admin only.
Void source cost (attribution.void_spend)
[ADMIN ONLY] Exclude an erroneous manually recorded cost from future source-outcome totals while preserving its original values and who voided it. Changes reporting only; it does not refund money or change an ad account. A replacement uses a new evidence reference. Owner/admin only.
Revenue by Source (attribution.revenue_by_source)
[READ] Which lead source made the account money: collected revenue (invoices, funnels, and connected Stripe, deduped so the same charge is never counted twice) grouped by each PAYING CONTACT's recorded source, for an optional date range. Attribution is single-touch: every payment counts toward the one source stamped on the contact when it was created — no fractional multi-touch. Each source also carries its paying-contact count, refunds, and a first-touch UTM campaign breakdown from the contact's earliest tracked website visit. Three totals are reported separately and should not be conflated: knownSourceCents is money from a real acquisition channel; importedCents is money from contacts an importer created (Stripe customer sync, file import, API), which records how the record arrived and says nothing about what acquired the customer; unattributedCents is money on payments with no linked contact. A workspace that imported its customers can legitimately show zero known-source revenue. Read-only; changes nothing and charges nobody.

Actions — automations

39 operations.

List workflows (automations.list)
[READ] List the organization's automation workflows, newest first, with each one's trigger, whether it is active, and how many steps and runs it has. Other products may call these drips, nurture sequences, follow-up campaigns, or autoresponders.
Open a workflow (automations.get)
[READ] Fetch one workflow with its ordered steps and the webhook endpoint that can trigger it, matching the workflow editor page.
Copy AI instructions (automations.get_webhook_brief)
[READ] Produce a complete, paste-ready integration brief for one workflow's inbound webhook — the URL, the secret header when it has one, every contact field the endpoint accepts including this organization's own custom fields, the contact-matching rules, runnable curl and fetch examples, and what each response code means. Written for a person or an AI assistant wiring up another system; it is the same document the workflow builder's "Copy AI instructions" button copies. Reads only: nothing is sent, started or charged. The brief embeds the webhook secret, so treat the result as a credential.
Create automation (automations.create)
[HIGH RISK] Create a complete automation/workflow/drip/nurture/follow-up sequence in one call. This is the right action for 'when a new lead is added, send a welcome message', even if the user calls it an autoresponder or campaign. Supply steps and this builds the real editable flow, generates a useful name when omitted, and turns it on by default. Active message/call steps later reach real people and incur the org's provider charges. Omit steps to create a paused visual-canvas draft.
Edit workflow details (automations.update)
[HIGH RISK] Update a workflow's name, description, first visual start trigger, webhook secret, or its whole visual flow graph. Omitted fields are left alone. Supplying `flow` REPLACES the entire canvas — branches, actions and all — so read the workflow first and send the complete graph, not a patch. Changing the trigger or the flow of an ACTIVE workflow changes which real events fire it and can cause its real messages, calls or paid actions to run for a different audience.
Activate a workflow (automations.activate)
[HIGH RISK] ARMS A LIVE AUTOMATION. Once active, every matching event fires this workflow's steps for real — sending SMS/email, placing calls, dropping voicemails, enrolling contacts in campaigns, spending the tenant's money — with no further human approval. Check the steps before turning it on.
Pause a workflow (automations.pause)
Turn a workflow off. Its trigger stops firing it; the steps and run history are kept and it can be activated again. Manual runs still work while paused.
Delete a workflow (automations.delete)
[HIGH RISK] Permanently delete a workflow along with its steps and its entire run history. This cannot be undone.
List available step actions (automations.list_action_types)
[READ] The shared action registry — every action a workflow step (or a call disposition, or a bulk action) can run, with its editable fields. Read this before writing steps so action_config uses the right keys.
Send test request (automations.test_api_call)
[HIGH RISK] Send one real HTTPS request using the same Call an API configuration that a workflow step uses, then return the external service's HTTP status, timing, headers, and bounded response body. This does not save or run a workflow, but POST, PUT, PATCH, or DELETE may create data, trigger downstream work, spend money, or otherwise change the external system.
List workflow templates (automations.list_templates)
[READ] List this account's private normal-automation templates. Bot-flow starters and saved bot templates are deliberately excluded; the list omits full graphs and changes nothing.
Build this flow (automations.create_from_template)
Create a PAUSED normal automation from a private automation template. Bot-flow templates are rejected, nothing is sent, and the new automation cannot react to live events until separately activated.
View workflow template (automations.get_template)
[READ] Return one private normal-automation template with its frozen visual graph. Bot-flow templates are not exposed; this read creates nothing and sends no messages.
Save as template (automations.save_as_template)
Save a private frozen copy of one workflow's current visual graph for reuse in this account. This does not activate, run, or send the workflow; later edits to the source do not change the template.
Delete workflow template (automations.delete_template)
[HIGH RISK] Permanently delete one private saved workflow template from this account. Existing workflows installed from it are unaffected, but the frozen template cannot be recovered; built-in Chirply starters cannot be deleted.
Duplicate workflow (automations.duplicate)
Create a separate PAUSED copy of one workflow's current graph in this account. It copies no runs, history, legacy steps, or inbound-webhook secret and sends nothing until separately reviewed and activated.
List available triggers (automations.list_trigger_types)
[READ] Every event an automation can start on or stop on. Start and stop use the same fully wired catalog and the same optional filters. Read this before writing trigger or stop_trigger nodes with automations.set_flow. A workflow may have SEVERAL start triggers (any one begins a run) and any number of stop triggers (any matching event ends the contact's in-flight run). Read-only.
Add a workflow step (automations.add_step)
Append an action to the end of a workflow. Adding a step does not run it; it runs on the next trigger or manual run. The action must be one the shared registry knows — see automations.list_action_types.
Edit a workflow step (automations.update_step)
Change what an existing step does. Both the action type and its config are replaced wholesale — send the complete config, not a patch.
Delete a workflow step (automations.delete_step)
[HIGH RISK] Remove a step from a workflow. The remaining steps keep their order. This cannot be undone.
Reorder a workflow step (automations.move_step)
Move a step one place up or down, swapping it with its neighbour — the arrows in the step list. Moving a step at the top or bottom edge is a no-op.
Replace all workflow steps (automations.set_steps)
[HIGH RISK] Replace a workflow's entire step list in one call, in the order given. Every existing step is deleted first, so this is destructive — pass the complete sequence, not just the changes. Nothing runs until the workflow is triggered.
Open the automation flow (automations.get_flow)
[READ] Fetch a workflow's flow graph — the nodes and connections the visual builder draws, and the exact structure the runtime walks. A workflow that predates the builder is lifted from its stored steps on the way out, so this always returns a graph. Read-only.
Save the automation flow (automations.set_flow)
[HIGH RISK] Replace a normal automation's entire process graph — business triggers, actions, waits, branches and their connections — in one call. Facebook, Instagram and WhatsApp conversation messages live in the separate Bot Flow product. A graph may hold SEVERAL 'trigger' nodes, all leading to the same beginning, plus stop_trigger nodes that cancel an in-flight run. Destructive: pass the complete graph, not just changes. Saving sends nothing; activating only makes future matching events eligible to run real actions through the account's provider accounts. Blocking graphs may be saved as drafts but cannot be active.
Run a workflow now (automations.run_for_contact)
[HIGH RISK] RUNS THE WORKFLOW FOR REAL, RIGHT NOW, against one contact — the 'Run manually' panel. Every step executes immediately through the tenant's own providers: real SMS and email leave, real calls and voicemails are placed, tags and deals change, and the tenant is billed. Works whether or not the workflow is active. Returns the run id and each step's outcome.
Add contacts to an automation (automations.enroll_contacts)
[HIGH RISK] STARTS THE WORKFLOW FOR REAL for every contact given — the bulk 'Add to automation' action. Immediate steps can send real SMS/email/calls and incur real charges; wait steps remain scheduled and resume later. This works even while automatic enrollment is paused. Continues past individual failures and reports the tally.
List automation runs (automations.list_runs)
[READ] Execution history: every time a workflow fired, with its status, how far it got, the contact it ran for and any error. Newest first. Filter by workflow or status.
Open an automation run (automations.get_run)
[READ] Fetch one run with its full context payload and error, for debugging why an automation did or didn't do what was expected.
Fetch sample data (automations.fetch_mapping_sample)
[READ] Read a recent saved contact or a recent Facebook lead submission for data mapping before a workflow has run. Facebook reads use the connected Page and count toward Meta API limits. Creates no contacts, starts no runs, sends no messages and buys no ads. Samples contain only available values; provider samples do not imply a saved contact.
List automation mapping fields (automations.get_mapping_fields)
[READ] List eligible preceding steps and declared or observed output fields for a workflow node. Optionally reads a retained run sample in this account. Resolves no credentials, runs no actions, sends no messages and makes no provider calls.
Inspect automation step data (automations.get_step_data)
[READ] Read bounded, redacted trigger data and executed step inputs, outputs and status for a run in this account. Includes persisted results across waits. No actions execute, messages are sent or provider charges incurred.
Preview automation data mapping (automations.preview_step_data)
[READ] Resolve JSON input mappings against a retained workflow run without executing any step. Preserves whole-value JSON types, reports missing values and leaves existing merge fields untouched. Sends no messages and makes no provider calls.
List automation node events (automations.list_node_events)
[READ] Read the account's durable visual-workflow execution ledger, including run and node starts, waits, resumes, completions, failures, replies and timeouts. Filter it to one workflow, run, node, event type or time window when diagnosing automation behavior. This is read-only and sends no messages.
Saved steps (automations.list_saved_steps)
[READ] List this account's reusable saved automation steps — the pieces of a workflow saved once and inserted into others, such as a configured webhook or a three-email follow-up. Returns each saved step's name, description and how many steps it adds, without the stored graph. Read-only: nothing is created, no automation changes and no messages are sent.
View saved step (automations.get_saved_step)
[READ] Return one saved automation step with the frozen nodes and connections it inserts. Read-only: it creates nothing, changes no workflow and sends no messages.
Save as reusable step (automations.save_steps_as_template)
Save a frozen copy of one or more steps from a workflow so they can be inserted into other automations in this account. Entry points and exit rules cannot be saved, because they say when an automation runs rather than what it does. The source workflow is not changed, nothing runs and no messages are sent; saving over an existing name replaces what that name holds.
Insert saved step (automations.insert_saved_step)
Add a saved step's frozen steps to a workflow's graph in this account, with new node ids. The copy arrives UNCONNECTED — it changes nothing that already runs until it is wired to a path in the builder — and the workflow's live or paused state is untouched. Nothing is sent and no contact is enrolled by this call.
Duplicate steps (automations.duplicate_steps)
Copy one or more of a workflow's steps back into the SAME workflow with new node ids. The copy arrives unconnected, so the sequence that already runs is unchanged until the copy is wired to a path in the builder. Nothing is sent and no contact is enrolled by this call.
Delete saved step (automations.delete_saved_step)
[HIGH RISK] Permanently delete one saved reusable step from this account. Automations that already had it inserted keep their own copies and are unaffected, but the saved entry cannot be recovered.

Actions — backups

8 operations.

Inspect recovery copy (backups.preview_recovery_copy)
[READ · ADMIN ONLY] Inspect one completed backup in the account's current customer-owned Supabase destination. Checks current inventory compatibility, stored row counts, unique IDs and selected CRM references, then proposes an isolated recovery schema in that same project. Limited to 50,000 rows. Reads the external database and may consume its normal query resources; copies nothing, sends nothing and does not restore a running Chirply account. Owner/admin only.
Create isolated recovery copy (backups.create_recovery_copy)
[HIGH RISK · ADMIN ONLY] Copy a completed backup into a new private recovery_<snapshot> schema inside the account's own connected Supabase project. Consumes that customer's storage and database resources. Rechecks counts, unique IDs and selected references within an atomic transaction; refuses incomplete, incompatible or over-50,000-row snapshots and never overwrites an existing schema. Copies text-valued data tables only: no running Chirply account, credentials, triggers, workflow execution or message sending. Repeated calls cannot create duplicate copies. Owner/admin approval required.
Backup destination (backups.get_destination)
[READ · ADMIN ONLY] Shows where this account backs its data up to — which of the account's own connected Supabase projects receives it, the schema the tables land in, the schedule, the retention setting, and when the last and next backups run. Also lists the Supabase projects available to choose from. Reads only; nothing is written anywhere.
Set backup destination (backups.set_destination)
[HIGH RISK · ADMIN ONLY] Points this account's backups at one of its own connected Supabase projects and sets how often they run. Chirply will then write the account's entire business data — contacts, companies, deals, tasks, appointments, conversations and full message bodies, call metadata and transcripts, invoices and orders, forms and their responses, custom objects, the activity log and the unsubscribe lists — into that project as ordinary Postgres tables the customer can query and restore from. The data lands in a database the CUSTOMER owns and pays Supabase for, and each backup consumes their storage. Provider credentials, API keys, encrypted columns and other accounts' data are never included. Replaces any destination already set; an account has one.
Turn off backups (backups.remove_destination)
[HIGH RISK · ADMIN ONLY] Stops backing this account up: removes the destination and cancels any schedule. Snapshots already written to the customer's Supabase project are left exactly where they are — this deletes nothing from their database, and the tables stay queryable. Setting a destination again later resumes with new snapshots alongside the old ones.
Back up now (backups.run_now)
[HIGH RISK · ADMIN ONLY] Starts a backup immediately, writing this account's entire business data into the connected Supabase project set as its destination, as a new snapshot alongside every previous one. The data lands in a database the CUSTOMER owns and pays Supabase for, and consumes their storage. A large account is written across several passes: this call returns as soon as its time budget is spent, reporting status 'running', and the scheduled worker carries the same snapshot forward until it is done. Calling it again while one is in flight continues that snapshot rather than starting a second. Provider credentials, API keys, encrypted columns and other accounts' data are never included.
Backup history (backups.list_runs)
[READ · ADMIN ONLY] Lists this account's backup snapshots, newest first — when each ran, whether it was scheduled or asked for, how many rows and datasets landed, and whether it completed. A snapshot marked 'incomplete' finished with at least one dataset short of the account; 'running' is still in progress. Reads Chirply's own record of the runs and touches the destination database not at all.
View a backup (backups.get_run)
[READ · ADMIN ONLY] One backup snapshot in full: its status, when it ran, and its manifest — the per-dataset row counts, the true account counts beside them so a short dataset is obvious, the table each dataset landed in, and the list of everything deliberately excluded from any Chirply backup. This is the record to check before trusting a snapshot to restore from. Reads only.

Actions — billing

26 operations.

My plan (billing.get_membership)
[READ] The signed-in user's own platform membership: plan name, price and interval, live subscription status, next billing date, whether it's set to cancel, any paid add-ons, and the card on file as brand plus last four digits only. Read-only; nothing is charged. This is the person's personal subscription, not the account's invoicing.
Available upgrades (billing.list_upgrade_offers)
[HIGH RISK] The one-click plan upgrades offered to a founder on the billing page (White-Label Partner, Reseller Partner), their current prices, and how long the founder deal window has left. When the window has closed, `reset` also gives the one-time price to reopen it and, in `restores`, the exact price each upgrade drops back to if they do — the reopen price climbs hourly to a $497 ceiling and is then withdrawn for good at `reset.final_deadline`, after which `reset` is null forever. NOT A FREE READ, despite charging nothing: like opening the billing page, the FIRST call permanently anchors this founder's 24-hour deal window to the moment it runs. Call it on someone's behalf before they are ready and their discount starts counting down without them, and the only way back is to BUY a window reset. Ask before running it.
Plans (billing.list_plans)
[READ] The plan ladder — Spark, Build, Launch, Grow and Scale — with monthly and yearly prices, which one the signed-in user is on, and, for every other rung, whether moving there counts as an upgrade or a downgrade and exactly what that would cost and when. Also reports any plan change already scheduled for the end of the current billing cycle. Read-only; nothing is charged. Use billing.change_plan to actually move.
Change plan (billing.change_plan)
[HIGH RISK] DURING A FREE TRIAL no money moves in either direction: the trial keeps running to its original end date whichever plan is chosen, and the new plan simply decides what is charged on that day. Outside a trial: Moves the signed-in user's membership to another plan. UPGRADING (a bigger plan, or the same plan switched from monthly to yearly) CHARGES THE CARD ON FILE IN FULL IMMEDIATELY and switches them over on the spot; the plan they were on is not refunded or prorated, it simply stops renewing at the end of the cycle already paid for. DOWNGRADING (a smaller plan, or yearly to monthly) charges nothing today — the current plan and everything in it runs to the end of the billing cycle, then cancels, and the cheaper plan starts and takes its first payment that same day. Booking a new change replaces any change already scheduled. Founder and complimentary memberships cannot be switched this way. Check billing.list_plans first to see which direction a given plan is and what it costs.
Keep my current plan (billing.cancel_plan_change)
[HIGH RISK] Calls off a plan change that was scheduled for the end of the current billing cycle and keeps the member on the plan they're on, renewing as normal. Nothing is charged or refunded — the scheduled plan never started. Only affects a booked-but-not-yet-started change; an upgrade that already took effect and was charged cannot be undone this way.
Update payment method (start) (billing.start_card_update)
Begin replacing the card on the caller's membership. Creates a Stripe SetupIntent on their billing account and returns its client secret, which a browser Payment Element uses to collect the new card. Card details are never sent through this platform and nothing is charged. Finish with billing.finish_card_update.
Update payment method (finish) (billing.finish_card_update)
[HIGH RISK] Finish a card update: verifies the confirmed SetupIntent belongs to the caller, then makes its card the default for their billing account and every subscription on it. Nothing is charged now, but all FUTURE membership charges move to this card.
Cancel membership (billing.cancel_membership)
[HIGH RISK] Cancel the caller's membership at the end of the period they've already paid for. Access continues until then and no refund is issued. DURING A FREE TRIAL this costs the member nothing at all — the card is never charged, access simply runs out when the trial would have converted — so it is the correct way to decline before the first payment. A founder who cancels loses their locked-in founder rate — resuming before the end date keeps it. Reversible with billing.resume_membership until the period ends.
Resume membership (billing.resume_membership)
Undo a scheduled cancellation so the membership keeps renewing at its existing rate. Nothing is charged now — the next renewal bills as normal.
Switch to yearly (billing.upgrade_to_yearly)
[HIGH RISK] CHARGES REAL MONEY NOW. Moves a monthly founder membership to the yearly plan at today's yearly ladder price. The switch is immediate: Stripe credits the unused part of the month and invoices the full annual term against the card on file straight away. There is no refund path back to monthly.
Add a plan upgrade (billing.accept_upgrade)
[HIGH RISK] CHARGES REAL MONEY NOW. Adds a paid add-on to the caller's membership — 'partner' (White-Label) or 'reseller' — as a NEW monthly subscription billed off-session to the card already on their founder subscription. The price is decided by the server: the founder deal price while their 24-hour window is open, the regular price after it. Already owning the tier is a no-op rather than a second charge.
Reopen the founder window (billing.reset_upgrade_window)
[HIGH RISK] CHARGES REAL MONEY NOW — a one-time payment to the card on the caller's founder subscription that reopens their 24-hour founder-pricing window, putting the White-Label and Reseller upgrades back at their founding prices. The price is computed on the server and climbs the longer the window has been closed, so pass the price the user was shown as `expected_price_dollars`; if it has moved, nothing is charged. It stops climbing at a $497 ceiling, and 24 hours after it tops out the reopen is withdrawn permanently — calling it then fails and no later call can bring founder pricing back. If the window is still open this is a no-op.
Wallet balance (billing.get_wallet)
[READ] Read the account's prepaid usage wallet: current balance, currency, and the auto-recharge settings. This balance pays for platform-billed usage like SMS and calls — outbound sends pause when it reaches zero. Read-only; nothing is charged.
Wallet activity (billing.list_wallet_transactions)
[READ] List the account wallet's ledger entries, newest first — top-ups (positive cents), usage debits (negative cents), adjustments and refunds. This is the same activity the Billing page shows. Read-only; nothing is charged.
Add wallet funds (billing.topup_wallet)
[HIGH RISK · ADMIN ONLY] CHARGES REAL MONEY: immediately bills the card saved on its own billing account (off-session, via Stripe) for the given amount and credits the wallet once the charge settles. There is no undo — reversing it means a refund. Fails without charging if the account has no saved card yet; a person must add funds once from the Billing page first, which saves one. Also fails without charging on an account provided by an agency: those buy usage credits from that agency on the agency's own Stripe, not from Chirply.
View Capture upgrade offer (billing.get_capture_offer)
[READ] Read the current private upgrade stage of your own Capture purchase. Does not charge your card or change your subscription.
Upgrade Capture to Full Chirply (billing.accept_capture_scale)
[HIGH RISK] Immediately charges your saved card $47 monthly or $365 yearly for Scale and cancels the previous subscription renewal. Previous payments receive no refund or credit; the new subscription renews until canceled.
Accept Capture partnership upgrade (billing.accept_capture_partner)
[HIGH RISK] Immediately charges the saved card $247 monthly for White Label or $97 monthly for Partner, including Scale. Cancels the previous base renewal without refund or credit; renews until canceled.
Decline Capture upgrade offer (billing.decline_capture_offer)
[HIGH RISK] Permanently skips the current private Capture offer without charging a card. Declining White Label opens Partner; declining Full Chirply or Partner ends the offer journey.
View dollar-a-day offer (billing.get_dollar_a_day_offer)
[READ] Reads the availability and exact recurring prices of Chirply's standalone dollar-a-day Scale offer. It grants no access and charges no money. This offer and its optional upgrades are excluded from affiliate commissions.
Check my 24-hour offer (billing.start_dollar_a_day_offer_window)
[HIGH RISK] Records the signed-in buyer's first visit to the dollar-a-day offer and returns their fixed 24-hour claim deadline and signed checkout proof. Later calls return the original window, including after expiry. It creates no order, sends no message and charges no money. Opening secure Checkout before expiry reserves that offer for the Checkout session.
Start my 7-day free trial (billing.start_dollar_a_day_checkout)
[HIGH RISK] Creates a card-backed Stripe Checkout for the signed-in person's own 7-day Scale trial: $0 today, then $365/year unless canceled. The buyer must complete card verification at Stripe. The first Scale payment has a 30-day money-back request window starting at trial signup. Existing memberships are refused; provider usage and optional upgrades are separate, and no affiliate commission is earned.
View my dollar-a-day purchase (billing.get_dollar_a_day_journey)
[READ] Reads the signed-in buyer's Scale trial or paid offer, original trial and guarantee dates, payment and annual renewal status, current optional upgrade step and activation link. It exposes only that person's signup and does not charge a card or change an offer step.
Confirm my dollar-a-day payment (billing.finalize_dollar_a_day_checkout)
[HIGH RISK] Verifies Checkout directly with Stripe before granting a saved-card free trial or paid monthly upgrade. It never initiates a charge. A confirmed new Scale signup emails its contact and signup details to Chirply's owner at jon@tier5.us through the platform Mailgun account. An upgrade starts monthly billing while the original Scale trial continues; future annual renewal stops only after the first Scale annual invoice is paid. Guarantee dates stay anchored to original trial signup, and this action does not issue refunds.
Add my dollar-a-day upgrade (billing.start_dollar_a_day_upgrade)
[HIGH RISK] Creates the current optional upgrade Checkout: White Label at $247/month, or the Partner Program at $97/month after declining White Label. The buyer must pay at Stripe. Only the monthly upgrade is charged now; the original Scale trial and $365 charge at its end remain unchanged. Future annual renewal stops after that first annual payment. The Scale guarantee excludes monthly upgrade payments and no affiliate commission is earned.
Keep my current dollar-a-day plan (billing.decline_dollar_a_day_upgrade)
[HIGH RISK] Declines the buyer's current optional upgrade and permanently advances to the next offer step. White Label leads to the Partner Program downsell; declining that completes the purchase. Any unpaid Checkout for the skipped step is expired first so it cannot charge later. No money is charged or refunded, and the paid Scale subscription remains.

Actions — bookfunnel

4 operations.

Open BookFunnel settings (bookfunnel.get_settings)
[READ · ADMIN ONLY] Read the BookFunnel connection, default and landing-page routing, available destinations, and the latest 100 webhook receipts with processing errors. It never returns the private webhook token or URL credential and changes nothing.
Save mapping (bookfunnel.save_mapping)
[HIGH RISK · ADMIN ONLY] Set the list, tags and automation used for future BookFunnel new_subscriber events, either as the default or for one landing-page id. Saving sends nothing now, but the selected automation may send real email/SMS or spend money as soon as a real reader subscribes. Non-opt-in book_claimed events never use this routing.
Remove BookFunnel page (bookfunnel.forget_page)
[HIGH RISK · ADMIN ONLY] Remove one BookFunnel landing page from this account: its routing override and every stored webhook receipt that names it, which together are what make its section appear. Permanently deletes those receipt records, so the page's delivery history and any failed events waiting to be retried are lost. Contacts, lists, tags and automations are not touched, and no message is sent.
Retry sync (bookfunnel.retry_event)
[HIGH RISK · ADMIN ONLY] Retry one failed BookFunnel webhook receipt. Contact upsert, tags and list membership are idempotent, but a selected automation may reach real people and spend money if the earlier attempt failed after partially starting it, so this always requires confirmation.

Actions — booking

25 operations.

Booking types (booking.list_event_types)
[READ] List this organization's bookable event types (meeting types) — for each: name, public URL slug, kind (one_on_one, group, collective, round_robin), duration in minutes, price, and the shareable public booking URL an invitee visits to pick a time. Read-only; changes nothing and sends nothing. By default only active types are returned.
Open a booking type (booking.get_event_type)
[READ] Fetch one bookable event type by id — its full configuration (kind, duration, buffers, min-notice, location, booking form, reminders, price), the users hosting it, and the shareable public booking URL. This is everything the edit screen shows, so it is what you read before calling booking.update_event_type. Read-only.
Open time slots (booking.get_availability)
[READ] List the open, bookable time slots for an event type over a date range — exactly what an invitee would see on the public booking page, computed live from the hosts' working hours, existing appointments, buffers and minimum notice. Returns slots grouped by day, each an ISO UTC start/end. Read-only; reserves nothing. The range may span at most 62 days.
List appointments (booking.list_appointments)
[READ] List this organization's booked appointments, soonest first, optionally filtered by date range, status (confirmed, canceled, completed, no_show), event type, or contact. Read-only; changes nothing.
Open an appointment (booking.get_appointment)
[READ] Fetch one appointment by id — the event, host, contact, invitee details, start/end time, location, status and payment state, plus the invitee's manage (reschedule/cancel) URL. Read-only.
My availability (booking.list_schedules)
[READ] List the saved weekly availability schedules in this account — for each: its name, whether it is the owner's default, the timezone it is interpreted in, and the full set of working hours keyed by weekday (sun–sat), each day a list of "HH:MM"–"HH:MM" windows. Read this BEFORE calling booking.set_availability: that capability REPLACES the whole week, so editing Tuesday without first reading Monday through Sunday would wipe them. By default you get the calling user's own schedules, which is exactly what the My availability screen shows; an API key with no user attached sees the whole account. Read-only.
Create event type (booking.create_event_type)
[ADMIN ONLY] Create a new bookable event type (a meeting people can book), and return its public booking URL. Nothing is sent to anyone and nobody is charged by this call — but if `is_active` is left on (the default) the event type's public booking page goes live immediately and strangers holding the link can book real time on a host's calendar from that moment. Owners and admins only, matching the Calendars editor. Hosts must be members of this account; when `host_user_ids` is omitted the calling user hosts it, and an API key (which has no user) must name at least one host.
Save event type (booking.update_event_type)
[ADMIN ONLY] Change the configuration of an existing bookable event type. Only the fields you pass are changed; everything omitted is left exactly as it was. Existing appointments already on the calendar are NOT moved or re-priced — changes apply to future bookings. Changing duration, buffers, notice or hosts changes which times the public booking page offers from that moment on. Owners and admins only. Passing `questions`, `reminders` or `host_user_ids` REPLACES that whole list, so read the current one with booking.get_event_type first. To show or hide the public booking page, use booking.set_event_type_active — this capability deliberately cannot.
Accepting bookings (booking.set_event_type_active)
[HIGH RISK · ADMIN ONLY] Turn an event type's PUBLIC booking page on or off. Switching it off takes the page down for everyone holding the link — nobody can book that meeting any more — without deleting the event type or any appointment already on the calendar; switching it back on republishes it instantly and strangers can book real time again. Owners and admins only.
Delete event type (booking.delete_event_type)
[HIGH RISK · ADMIN ONLY] Delete a bookable event type. Its public booking page stops working immediately and it disappears from the Calendars list. This is a soft delete — the record is retained so appointments already booked against it keep their history, and nothing already on anyone's calendar is cancelled or refunded (cancel those separately with booking.cancel_appointment if that's what you mean). There is no undo in the app.
Book a meeting (booking.book_appointment)
[HIGH RISK] Books a real slot on an event type's calendar for an invitee. FREE EVENT TYPES are confirmed immediately: the invitee and the host are emailed/texted a confirmation from the organization's OWN Mailgun/Twilio, reminders are scheduled, and the contact may be enrolled in 'appointment booked' automations. PAID EVENT TYPES (require_payment on, with a price) ARE NOT CONFIRMED HERE — exactly as on the public booking page, the slot is held unconfirmed, nothing is sent to the invitee, and this returns `checkout_url`: a Stripe Checkout link on the business's own account. Give that link to the invitee; the meeting is only confirmed, and the confirmation only sent, once Stripe reports them paid. The requested time is re-validated against live availability, so it fails if the slot was just taken; a round-robin host is assigned automatically. Matches or creates the contact from the invitee's email/phone. Provide the start exactly as one of the ISO UTC starts returned by booking.get_availability.
List booking domains (booking.list_domains)
[READ · ADMIN ONLY] Lists this account's connected domains and their readiness for publishing event types. Returns hostname, status and supported roles; does not change DNS or spend money.
Save booking domain (booking.set_domain)
[HIGH RISK · ADMIN ONLY] Changes the public hostname used in an event type's booking links and appointment-management links. Only active website/app domains connected to this account are allowed. Null restores the account default. Existing booking URLs remain available. Does not modify DNS, replace the domain's website, send messages, or spend money.
Delete appointment (booking.delete_appointment)
[HIGH RISK · ADMIN ONLY] Permanently deletes an appointment and its reminders, including canceled appointments, after removing its linked Google/Outlook Calendar events. Cannot be undone. If calendar cleanup fails the appointment is kept for retry. Does not issue refunds or send Chirply cancellation messages; use booking.cancel_appointment to notify the invitee. Owners and admins only.
Cancel an appointment (booking.cancel_appointment)
[HIGH RISK · ADMIN ONLY] Cancels a booked appointment and immediately notifies the invitee of the cancellation by email/SMS from the organization's own Mailgun/Twilio, drops its pending reminders, and fires 'appointment canceled' automations. This frees the slot for someone else. Owners and admins only. To move an appointment to a new time instead, use booking.reschedule_appointment.
Reschedule an appointment (booking.reschedule_appointment)
[HIGH RISK · ADMIN ONLY] Moves a booked appointment to a new time: the new slot is re-validated against live availability, a fresh appointment is created linked to the old one (reschedule_of) with its payment record carried over, the old one is canceled, and the invitee is emailed/texted the new time from the organization's own Mailgun/Twilio — the customer is always notified, never silently moved. Fires 'appointment rescheduled' automations. Owners and admins only. Provide the new start exactly as one of the ISO UTC starts returned by booking.get_availability, or set allow_outside_availability to book a time the engine wouldn't offer (the host still can't be double-booked). Refuses if the new slot is no longer open, or if the appointment was canceled or has already started.
Mark appointment completed (booking.set_appointment_status)
[ADMIN ONLY] Record how an appointment actually went — 'completed' if it happened, 'no_show' if the invitee never turned up, or 'confirmed' to put it back the way it was. This is a PRIVATE record change: it sends the invitee nothing, changes no times, fires no automations, refunds nothing, and does not free the slot. It is the app's 'Mark completed' / 'Mark no-show' / 'Back to confirmed' menu. To actually call the meeting off and tell the invitee, use booking.cancel_appointment instead. Owners and admins only.
Set your working hours (booking.set_availability)
Set YOUR OWN weekly booking availability — the recurring working hours the slot engine offers to invitees for events you host, interpreted in the account timezone from Business profile. Replaces your existing weekly hours (does not touch teammates' schedules or one-off date overrides). Personal to the calling user; API keys act as the user that issued them.
Connect calendar (booking.connect_calendar)
[HIGH RISK] Start linking a host's own Google Calendar or Microsoft 365 / Outlook account, so their real commitments block booking slots and meetings booked here are written onto their calendar. This does NOT complete the link on its own: connecting requires the account holder to approve access on the provider's own consent screen, so what comes back is the URL that starts that flow. Open it in a browser where the host is already signed in to this account — the link acts as whoever is signed in, so it connects THAT person's calendar, and it grants this account ongoing read/write access to their calendar until it is disconnected. Any member may connect their own; use booking.list_calendar_connections to see what is already linked.
Calendar connections (booking.list_calendar_connections)
[READ] List the external calendars (Google Calendar, Microsoft 365 / Outlook) connected for scheduling — for each: the provider, the connected account's email, whether it feeds busy times into availability (inbound) and receives booked meetings (outbound), when it last synced, and any current sync error. Access tokens are NEVER returned. When called by a specific user (Copilot) only that user's own connections are shown; an API key sees the whole account. Read-only.
Disconnect (booking.disconnect_calendar)
Disconnect a linked external calendar (Google or Outlook) by its connection id, removing this account's stored access for that calendar. After this, its busy times no longer block booking slots — so times the host is actually busy start being offered to invitees — and new meetings are no longer written to it. Restoring sync means going through the provider's consent screen again: booking.connect_calendar returns that link. Does not delete any existing calendar events. A member can only disconnect their own calendar; managers (and API keys) can disconnect any in the account.
Connect Zoom account (booking.connect_zoom)
[HIGH RISK] Start Zoom OAuth authorization for the signed-in host. Returns a browser URL; nothing connects until the host approves Zoom access. Enables automatic meeting creation for opted-in event types, subject to the host's Zoom plan. Requires the platform OAuth app; use booking.save_zoom_credentials for your own Server-to-Server OAuth app instead.
Save Zoom credentials (booking.save_zoom_credentials)
[HIGH RISK] Connect your own Zoom Server-to-Server OAuth app to the calling host. Verifies account access, encrypts credentials at rest, and replaces any existing Zoom connection for that host. Allows opted-in event types to create real Zoom meetings automatically under that account's plan. No meeting is created by this action and secrets are never returned. API key callers must supply a host user ID in this account.
Zoom meetings (booking.list_zoom_connections)
[READ] Read connected Zoom host emails and connection errors for scheduling. Returns only the caller's connection for signed-in users, or all hosts for an account API key. Never returns credentials, tokens, or host-only meeting URLs. Changes nothing and creates no meetings.
Disconnect Zoom (booking.disconnect_zoom)
[HIGH RISK] Remove this host's encrypted Zoom credentials from the account. Future bookings using automatic Zoom links cannot be completed until the host reconnects or the event switches to a pasted link. Existing Zoom meetings are kept; this does not delete rooms or cancel appointments. Signed-in users can disconnect only themselves; API keys must name an account host.

Actions — bot_flows

17 operations.

List bot flows (bot_flows.list)
[READ] List only this account's conversational bot flows, never normal CRM automations, with trigger and paused/live state. This is read-only and sends no messages.
Open a bot flow (bot_flows.get)
[READ] Fetch one conversational bot flow with its complete graph and legacy ordered steps. A normal automation id is treated as not found and no messages are sent.
Create bot flow (bot_flows.create)
Create a new conversational bot-flow draft with one social or manual entry trigger. It is always PAUSED, creates an editable visual graph, sends no messages, and must be activated separately after review.
Edit bot flow details (bot_flows.update)
Update a bot flow's internal name or teammate description. This does not change its graph, activation state, recipients, or message delivery.
Open the bot canvas (bot_flows.get_flow)
[READ] Fetch the complete graph drawn by the bot-flow canvas, including entry triggers, rich messages, AI replies, questions, logic, waits, actions, and handoffs. This is read-only.
Save the bot canvas (bot_flows.set_flow)
[HIGH RISK] Replace a bot flow's complete graph. If the bot is live, future matching people immediately follow the new graph and its real provider messages, AI replies billed to its own OpenRouter account, CRM changes, calls, or paid actions; pass the whole graph, not a partial patch.
Activate bot flow (bot_flows.activate)
[HIGH RISK] ARM A LIVE BOT. Every matching Facebook, Instagram, WhatsApp, comment, ad, link, button, or menu entry can immediately send real provider messages and run paid or mutating actions with no further approval.
Pause bot flow (bot_flows.pause)
Stop a bot flow from accepting new matching entries while retaining its graph and run history. It can be activated again later and this action sends no messages.
Delete bot flow (bot_flows.delete)
[HIGH RISK] Permanently delete one bot flow, its legacy steps, and its complete run history. It can no longer answer connected entry points and this cannot be undone.
List bot templates (bot_flows.list_templates)
[READ] List Chirply's social bot starters and this account's private saved bot-flow templates. Normal automation templates are excluded; this read creates nothing.
View bot template (bot_flows.get_template)
[READ] Return one bot-flow starter or private bot template with its frozen visual graph. Normal automation templates are hidden and this read changes nothing.
Use bot template (bot_flows.create_from_template)
Create a PAUSED bot flow from a social starter or private bot template. It sends nothing until separately reviewed and activated; normal automation templates are rejected.
Save bot template (bot_flows.save_as_template)
Save a private frozen copy of a bot flow's current graph for reuse in this account. It sends nothing, preserves bot-flow identity, and rejects normal automation ids.
Delete bot template (bot_flows.delete_template)
[HIGH RISK] Permanently delete one private saved bot-flow template. Existing bot flows remain intact, normal automation templates are rejected, and the deleted template cannot be recovered.
Duplicate bot flow (bot_flows.duplicate)
Create a separate PAUSED copy of one bot flow's graph without copying runs or history. It sends nothing, preserves bot-flow identity, and rejects normal automation ids.
List bot-flow runs (bot_flows.list_runs)
[READ] List execution history only for bot flows, including status, contact, current step, and errors. Normal automation runs are excluded and this read changes nothing.
Open a bot-flow run (bot_flows.get_run)
[READ] Fetch one bot-flow run with full execution context and error details for debugging. A normal automation run id is treated as not found and nothing is changed.

Actions — browser_agent

9 operations.

View standing approvals (browser_agent.list_automations)
[READ · ADMIN ONLY] List the standing approvals in this account — the automations that let a paired browser run one approved action on one website on a schedule, with nobody watching it happen. Each entry shows the browser that granted it, the exact origin and path it may act on, how many packaged steps it runs, whether it ends by activating an outward control such as Post or Submit and what that control is labelled, its hourly run cap, when it was approved, when it must be re-approved, and whether it has been revoked. Page contents, task text, and field values are never stored and are not returned.
Revoke standing approval (browser_agent.revoke_automation)
[HIGH RISK · ADMIN ONLY] Stop one standing approval from running unattended ever again. The paired browser checks Chirply before every unattended run, so this takes effect on that browser's next sweep — within about five minutes — without anyone touching the machine. Scheduled work that the automation was handling returns to the manual queue for a person to do. The record is kept, not deleted, so the run history still shows what used to run on its own.
Delete standing approval (browser_agent.delete_automation)
[HIGH RISK · ADMIN ONLY] Permanently erase one standing approval and its link to past unattended runs. This cannot be undone, and it removes the audit trail's record of what used to run on its own — prefer revoking, which stops the automation but keeps that history. The paired browser drops its local copy on the next sweep.
View browser runs (browser_agent.list_runs)
[READ · ADMIN ONLY] List the redacted approval and execution audit trail for Browser Agent. It returns page origins, packaged action types, risk classifications, statuses, and result counts; page contents, task text, form values, cookies, credentials, and extracted records are never retained.
Delete browser run (browser_agent.delete_run)
[HIGH RISK · ADMIN ONLY] Permanently delete one redacted Browser Agent approval and execution audit record from this account. This cannot be undone; it does not affect page data or extracted results because Chirply never receives or retains them.
Clear browser history (browser_agent.clear_runs)
[HIGH RISK · ADMIN ONLY] Permanently delete every redacted Browser Agent approval and execution audit record in this account. This cannot be undone; local extracted results remain only in each browser until that browser clears its extension storage.
View paired browsers (browser_agent.list_devices)
[READ · ADMIN ONLY] List the Chrome browsers currently paired with this account's Browser Agent Marketplace app. Returns display names, release channels, extension versions, last-seen times, and non-secret token prefixes; it never returns device credentials.
Create pairing code (browser_agent.create_pairing)
[ADMIN ONLY] Create a single-use Browser Agent pairing code for this account. The code expires in ten minutes and can mint one revocable browser credential; it does not publish, message, or modify any social account by itself. The response also returns installUrl, the Chrome Web Store listing a person adds the extension from before entering the code in its side panel.
Revoke browser (browser_agent.revoke_device)
[HIGH RISK · ADMIN ONLY] Immediately revoke one paired browser's access to this account. The extension keeps only its local task draft and last local result, but it can no longer create audited browser runs, read handoffs, or update Chirply until paired again.

Actions — bulk_jobs

10 operations.

List background jobs (bulk_jobs.list)
[READ] List this account's background bulk jobs — bulk emails, bulk texts, mass tagging, bulk deletes — newest first, with progress and the sending pace of each. Read-only; starting a job is done by the capability for that operation (for example contacts.send_email).
Check a background job (bulk_jobs.get)
[READ] Fetch one background job's progress: how many have been processed, succeeded, failed and skipped, how many are left, and how long the rest will take at the current pace. Polling this also nudges the job along, so it is the right way to wait for one to finish.
See a job's message and sender (bulk_jobs.details)
[READ] Fetch everything about one background job beyond its progress: the exact subject and body it is sending, whether that copy contains merge fields, which address or sending pool it goes out from (and whether those addresses can currently send), when it started, when the last message actually went out, when it is on course to finish at its current pace, who started it, and the full delivery picture so far — delivered, opened, clicked, bounced, reported as spam and unsubscribed, each as a count and as the percentage it is judged on. Read-only. Use this to answer "what exactly did this send, and who is it coming from?" — bulk_jobs.get answers only "how far along is it".
List a job's recipients (bulk_jobs.recipients)
[READ] List who a background job is working through, in the order it sends them, one page at a time. Each row gives the contact, the address the job reaches them on, the position in the queue, and where they stand: already sent (with the address it went out from, the time, and whether it was delivered, opened, bounced or failed), skipped because they had no address, currently being sent, or still waiting. Read-only. This is how to answer "has this person been contacted yet?" and "who has not received it?" for a send that runs over hours or days. Pass `outcome` to get only the people behind one delivery number instead — the handful who reported it as spam, whose address bounced, who unsubscribed — which is otherwise unfindable in a 15,000-contact send, since nothing about someone's position in the queue says what happened to their copy.
Pause a background job (bulk_jobs.pause)
Pause a running bulk job. Anything already sent stays sent; nothing further goes out until it is resumed. Use this to stop a bulk send mid-flight without abandoning it.
Resume a background job (bulk_jobs.resume)
[HIGH RISK] Resume a paused bulk job. It picks up where it stopped and continues at its current pace — for an outbound job this means real emails or texts start going out again, billed to its own provider account.
Stop a background job (bulk_jobs.cancel)
[HIGH RISK] Permanently stop a bulk job. Whatever has already been sent or changed stays that way — this cannot recall sent messages or undo completed updates — but nothing further is processed and the job cannot be restarted.
Change when a job starts (bulk_jobs.reschedule)
[HIGH RISK] Move a bulk job's start time, or start it right now. Only works while the job has not begun sending — once the first messages are out, the rest can be paused or re-paced but not postponed. Passing null for start_at drops the wait and lets the job begin immediately, which for an outbound job means real emails, texts or calls start going out at once.
Change a job's sending pace (bulk_jobs.set_pace)
Change how fast a bulk job sends, while it is running. Applies only to what has not gone out yet. Set a per-minute, per-hour or per-day cap; pass null for a window to remove that cap, and clear all three to send as fast as possible. Slowing a send down is the usual reason to call this — provider rate limits and deliverability.
Edit a job's message (bulk_jobs.edit_message)
[HIGH RISK] Rewrite the subject or body of a bulk email or text job that has not finished. Only contacts who have NOT been reached yet get the new wording — messages already sent cannot be recalled or changed, and the count of what has already gone out with the old wording is returned so it can be checked. Applies to email and text jobs only; jobs that enrol contacts in a workflow or run an action sequence have no message of their own to edit. Merge fields such as {{first_name}} are stored raw and filled in per contact at the moment each one is sent.

Actions — business

2 operations.

View business profile (business.get_profile)
[READ] Read the account's customer-facing business identity (name, logo, contact details, address and tax ID), IANA timezone, display currency, and weekly opening hours. These identity fields appear on invoices. `currency` is what was explicitly set and may be null; `effective_currency` is what the account is actually shown in after falling back to the country and then to usd. Read-only; changes nothing.
Save business settings (business.update_profile)
[ADMIN ONLY] Update the account's business identity used on invoices, hosted logo URL, IANA timezone, display currency, or weekly opening hours. Changing the timezone immediately changes which local calendar day timestamped revenue and activity appear under; it does not alter payment timestamps or money. Changing the currency changes how amounts are LABELLED from then on — it converts nothing, re-prices nothing, and leaves the currency stored on existing deals, invoices and payments exactly as it is.

Actions — call_queues

12 operations.

List call queues (call_queues.list)
[READ] List every call queue in the account with how many people are still waiting to be called, how many have been called, and how many were skipped.
Open a call queue (call_queues.get)
[READ] Fetch one call queue by id, with its live counts of who is still to call, who has been called, and who was skipped.
New call queue (call_queues.create)
Create a call queue — a named list of people for the team to phone through the power dialer. Creating one calls nobody; it only makes the list.
Edit a call queue (call_queues.update)
Rename a call queue, change its description or colour, attach a call script to it, or take it out of use. Taking a queue out of use removes nobody — it just stops being offered when someone picks a queue.
Delete a call queue (call_queues.delete)
[HIGH RISK] Permanently delete a call queue and everyone's place in it. The contacts and their call history are untouched, but the record of who still needed calling is gone and cannot be recovered.
Who is on a call queue (call_queues.list_entries)
[READ] List the people on a call queue in the order they will be dialled, with each one's outcome and note if they have already been called.
Add to call queue (call_queues.add_contacts)
Put contacts on a call queue so a person rings them. This dials nobody and sends nothing — it only adds them to the list a human works through. Anyone already on the queue is moved back to “still to call” instead of being added twice.
Remove from call queue (call_queues.remove_contacts)
Take contacts off a call queue so nobody rings them. Their call history and any outcome already recorded stay on the contact; only their place in this queue is removed.
Who to call next (call_queues.next)
[READ] Read the next people waiting on a call queue, in the order they will be dialled, with their phone numbers. Anyone without a phone number is left out. Reads only — it starts no calls.
Record a call queue outcome (call_queues.record_outcome)
Mark someone on a call queue as called (with the outcome that was chosen) or skipped, so they stop coming up as still-to-call. This only writes the queue entry — it sends nothing to anybody and spends no money. KNOWN GAP: unlike the power dialer in the app, this does NOT fire the 'called from a queue' automation trigger and does NOT stamp the queue onto the call log, so an account whose follow-up texts hang off that trigger will not send them for an outcome recorded this way.
Call everyone again (call_queues.reset)
Put people who have already been called or skipped back to still-to-call, so the queue can be worked through again. Their previous outcome and notes are kept on record.
Empty a call queue (call_queues.clear)
[HIGH RISK] Take everybody off a call queue, keeping the queue itself. The record of who was on it and what happened on those calls is destroyed and cannot be recovered; the contacts are untouched.

Actions — call_tracking

20 operations.

List call-tracking campaigns (call_tracking.list_campaigns)
[READ] List this organization's call-tracking campaigns, newest first. A campaign ties tracking numbers to a routing plan and a conversion rule. Returns each campaign's status, conversion rule, and routing settings — not its call log.
Open a call-tracking campaign (call_tracking.get_campaign)
[READ] Fetch one call-tracking campaign by id, with its full routing list, geo filter, conversion rule, and the signing secret for its external conversion webhook.
Create call-tracking campaign (call_tracking.create_campaign)
[ADMIN ONLY] Create a call-tracking campaign. Set the ordered list of destinations calls should route to (`route_to`), how a call counts as a conversion, and any geo / repeat-caller filters. Creating a campaign costs nothing and places no calls; it starts in 'draft' unless you set a status. Point a tracking number at it with call_tracking.assign_number to go live.
Edit call-tracking campaign (call_tracking.update_campaign)
[HIGH RISK · ADMIN ONLY] Edit a call-tracking campaign — its routing list, conversion rule, filters, recording, or status. Omitted fields are left alone, INCLUDING the four geo fields: sending only geo_states leaves the stored area codes, countries and mode as they were. Passing `route_to` REPLACES the whole destination list, and this campaign may be answering live calls right now: repointing it sends every subsequent caller somewhere else, and setting status to 'paused' stops the campaign's tracking numbers connecting anyone at all.
Pause or resume a campaign (call_tracking.pause_campaign)
[ADMIN ONLY] Pause a call-tracking campaign (stop routing new calls to it) or resume it. A convenience wrapper over the status field.
Archive a campaign (call_tracking.archive_campaign)
[HIGH RISK · ADMIN ONLY] Archive a call-tracking campaign. Its tracking numbers stop routing to it (calls fall through to the team bridge) and it drops out of the active list. The call history is kept. Reversible by setting status back to active.
List tracking numbers (call_tracking.list_numbers)
[READ] List the phone numbers wired as tracking numbers, optionally for one campaign. Each maps a `phone_numbers` row to a campaign (or a DNI pool).
Make a number a tracking number (call_tracking.assign_number)
[HIGH RISK · ADMIN ONLY] Point one of the organization's existing phone numbers at a call-tracking campaign. THIS REPOINTS A LIVE BUSINESS PHONE LINE: it switches that number's inbound routing away from whatever answers it today (the team, an IVR, an AI receptionist) to the campaign engine, so the very next real caller is routed by the campaign's destination list instead. If the number is already assigned elsewhere in call tracking, this silently re-points it. Does not buy a number — provision one first with the telephony tools, then assign it here.
Stop tracking on a number (call_tracking.release_number)
[HIGH RISK · ADMIN ONLY] Detach a tracking number from its campaign or pool and return it to normal team routing. THIS REPOINTS A LIVE BUSINESS PHONE LINE — the next real caller reaches the team instead of the campaign's destinations — and if the number is in a DNI pool, every web visitor currently holding it loses their attribution. The number is not released from Twilio; it just stops being a tracking number. Past calls ARE kept in full: ct_calls rows reference the campaign and the phone number, not this assignment, so reports and recordings survive. What does NOT survive is the tracking-number record itself — its report label ('Billboard I-35') and its publisher attribution are hard-deleted with no undo, and re-assigning the number creates a fresh one.
List tracked calls (call_tracking.list_calls)
[READ] List calls that came through tracking numbers, newest first, with their attribution (campaign, source/UTM/keyword, caller state) and outcome (answered, duration, conversion). Filter by campaign, conversion status, or a date window.
Open a tracked call (call_tracking.get_call)
[READ] Fetch one tracked call by its ct_calls id, with full attribution, routing outcome, and conversion + money fields.
Call-tracking stats (call_tracking.call_stats)
[READ] Headline numbers over a recent window: total tracked calls, how many were answered, how many converted, and the running revenue / payout / margin. Optionally scoped to one campaign. Read-only.
List conversions (call_tracking.list_conversions)
[READ] List conversion signals recorded against tracked calls (duration, webhook, or manual), newest first. Optionally for one campaign or one call.
Mark a call converted (call_tracking.mark_conversion)
[HIGH RISK · ADMIN ONLY] Manually mark a tracked call as converted (or rejected). Records a conversion audit entry and — once the pay-per-call money layer is live — is what bills the buyer and credits the publisher for that call. Use for campaigns whose conversion is decided by a human, or to correct an automatic decision.
List number pools (call_tracking.list_pools)
[READ] List DNI number pools, optionally for one campaign. A pool rotates a set of tracking numbers so each web visitor sees a unique number keyed to their source.
Open a number pool (call_tracking.get_pool)
[READ] Fetch one DNI number pool with the tracking numbers in it and the exact <script> snippet to paste on the page whose calls it should attribute.
Create a number pool (call_tracking.create_pool)
[ADMIN ONLY] Create a DNI number pool for a campaign and mint its public embed key. Add tracking numbers to it with call_tracking.add_number_to_pool, then paste the returned snippet on the page. Creating a pool costs nothing; the numbers you add are real Twilio numbers the tenant already pays for.
Edit a number pool (call_tracking.update_pool)
[ADMIN ONLY] Edit a DNI number pool — its name, status, target size, stickiness, or allowed origins. Omitted fields are left alone. This pool is feeding a live public web page: setting status to 'paused' stops handing out numbers, so visitors fall back to whatever static number the page shows and their calls stop being attributed.
Add a number to a pool (call_tracking.add_number_to_pool)
[HIGH RISK · ADMIN ONLY] Add one of the organization's phone numbers to a DNI pool. It becomes a rotating tracking number: the DNI script hands it to a visitor, and a call to it is attributed to that visitor's source. THIS REPOINTS A LIVE BUSINESS PHONE LINE — the number's inbound routing switches to the campaign engine, so it stops reaching whoever answers it today, and it starts being shown to strangers on a public web page. If the number is already assigned elsewhere in call tracking, this silently moves it. Provision the number first with the telephony tools.
Copy DNI snippet (call_tracking.get_dni_snippet)
[READ] Return the one-line <script> tag that enables dynamic number insertion for a pool. Paste it on the page whose phone numbers should swap per visitor; mark the numbers with data-ct-number.

Actions — campaigns

23 operations.

Generate copy (campaigns.generate_copy)
[READ] Generate or rewrite one email-campaign content block from a plain-language instruction. Returns draft text only; it does not save or send anything. Uses and bills its own OpenRouter account.
Generate image (campaigns.generate_image)
Generate an original campaign image from a prompt, store it in the account's durable R2 asset storage, and return its public URL. Nothing is sent. Uses and bills its own OpenRouter account.
List broadcasts (campaigns.list)
[READ] List the organization's broadcast campaigns, newest first, each with its recipient, sent, delivered, opened and clicked counts. A campaign is a one-off blast on a single channel — email, SMS, an approved WhatsApp template, ringless voicemail, outbound IVR or AI call. Archived campaigns are hidden unless asked for, matching the Campaigns page.
Open a broadcast (campaigns.get)
[READ] Fetch one campaign with its message, its saved audience spec, and its delivery counts — the whole composer in one payload.
Create a broadcast (campaigns.create)
Create a draft broadcast campaign and seed it with an empty audience, exactly like the New campaign dialog. A campaign sends ONE message ONCE — for a multi-step follow-up sequence with delays between messages, build an automation instead. Nothing is sent here: a draft has to be given content, an audience, and then sent or scheduled.
Edit broadcast details (campaigns.update)
Rename a campaign or change its sender overrides (the From email address, or the phone number SMS steps send from). Omitted fields are left alone. Content, audience and schedule have their own capabilities.
Duplicate a broadcast (campaigns.duplicate)
Copy a campaign — its message, channel, audience, send window and throttle — into a new draft named "<name> (copy)". The copy has no recipients and sends nothing until it is sent or scheduled. This is how a sent campaign is edited: duplicate, then change the copy.
Archive a broadcast (campaigns.archive)
[HIGH RISK] Archive a campaign so it disappears from the Campaigns list. Its recipients, send ledger and analytics are kept — this is the app's way of removing a campaign; there is no hard delete.
Save broadcast content (campaigns.set_message)
Write the one message this broadcast sends, and pick which channel it goes out on. Nothing is sent by saving — this only stores the content. Only draft or paused campaigns can be edited. A campaign sends a single message; for a multi-step sequence with delays, build an automation instead.
Save broadcast content (deprecated) (campaigns.save_step)
DEPRECATED — use `campaigns.set_message`. Campaigns are one-off broadcasts now: they carry a single message, so there are no steps to order. This still writes that message, and ignores step_id, delay_amount and delay_unit. For a multi-step sequence with delays, build an automation.
Delete a broadcast step (campaigns.delete_step)
[HIGH RISK] DEPRECATED and no longer possible. A campaign is a one-off broadcast carrying exactly one message, so there are no steps to remove — clear the message with `campaigns.set_message`, or archive the campaign. Multi-step sequences live in automations.
Choose the audience (campaigns.set_audience)
Replace a campaign's audience spec — who it will go to. The spec is resolved to actual contacts only at send/schedule time, so this write sends nothing. Supplying manual_contact_ids overrides the tag/lifecycle/search filters entirely. Use campaigns.preview_audience to see how many people it matches first.
Preview the audience count (campaigns.preview_audience)
[READ] Count how many contacts a campaign would actually reach — channel-reachable and not suppressed — without saving or sending anything. Defaults to the campaign's saved audience; any field you pass overrides that field for the preview only.
Preview combined message (campaigns.preview_voice)
[HIGH RISK] Hear what a ringless-voicemail or outbound-IVR broadcast will actually sound like: the personalized spoken introduction, rendered with real ElevenLabs speech, followed by the pause and the prerecorded audio the contact hears next. COSTS MONEY — each preview is a real text-to-speech render on its OWN ElevenLabs account and spends a small number of its credits, so don't call it in a loop. Nothing is saved to the campaign, and no call, voicemail or message reaches anybody. Returns the spoken introduction as inline base64 MP3 (roughly 100–500 KB — pass include_audio=false if you only need to confirm the render worked and read back what will be spoken), plus a short-lived playback link for the recorded tail.
Save the sending window (campaigns.set_schedule)
Set a campaign's timezone, quiet-hours window, allowed weekdays and per-minute throttle. This governs WHEN queued messages go out; it does not start a send. Replaces the whole schedule — omitted fields fall back to their defaults, matching the Schedule tab.
Send the broadcast now (campaigns.send_now)
[HIGH RISK] SENDS FOR REAL, IMMEDIATELY, to real people. Resolves the saved audience and starts delivering through the org's OWN Mailgun, Twilio, or connected Meta WhatsApp account — potentially thousands of billed emails, texts, approved WhatsApp templates, voicemail drops, or phone calls. WhatsApp enrolls only real customer-initiated threads with durable opt-in, no DNC/suppression, a currently approved template language, and a policy-valid recipient timezone; Meta can bill every accepted template. Voice channels place actual outbound calls. There is no undo; campaigns.pause/cancel can stop only work not already accepted. Campaign-engine channels send a bounded first wave inline and queue the rest; voicemail/call channels use their paced dispatchers. Requires saved content and a non-empty eligible audience, and refuses a campaign that already sent.
Schedule the broadcast (campaigns.schedule)
[HIGH RISK] COMMITS A REAL SEND at a future time. Snapshots the eligible audience now and sets the start time; when it arrives the dispatcher contacts every recipient through the org's OWN Mailgun, Twilio, or connected Meta WhatsApp account — potentially thousands of billed emails, texts, approved WhatsApp templates, voicemail drops, or phone calls, unattended. WhatsApp requires a currently approved template plus a real customer-initiated thread, durable opt-in, no DNC/suppression, and a policy-valid recipient timezone; eligibility is checked again before each provider call and Meta can bill each accepted template. Use campaigns.cancel before the start time to stop queued work. Requires saved content, a non-empty eligible audience, and a future time.
Pause a sending broadcast (campaigns.pause)
Stop a campaign that is mid-blast. Recipients already sent to keep their messages; everyone still queued stays queued until it is resumed. Only a campaign in 'sending' can be paused.
Resume a paused broadcast (campaigns.resume)
[HIGH RISK] RESTARTS A REAL BLAST. Puts a paused campaign back into 'sending' so the dispatcher immediately continues delivering to every recipient still queued — real, billed emails, texts, or Meta-approved WhatsApp templates. WhatsApp consent, DNC/suppression, template approval, timezone, and local-window eligibility are checked again before each provider call, but Meta can bill every template it accepts. Only a paused campaign (including one paused for lack of funds) can be resumed.
Cancel a broadcast (campaigns.cancel)
[HIGH RISK] Halt a campaign for good: every pending and in-flight recipient stops immediately and nothing more goes out. Messages already delivered cannot be recalled, and a canceled campaign cannot be sent again — duplicate it instead.
Enroll contacts in a broadcast (campaigns.enroll_contacts)
[HIGH RISK] ENQUEUES REAL MESSAGES. Adds specific contacts to a campaign's recipient list with delivery due immediately, the same as the bulk 'Enroll in campaign' action on the contacts list. If the campaign is sending, they can receive it on the next dispatch tick — real, billed email, SMS, or an approved WhatsApp template. WhatsApp contacts are enrolled only when the selected business number/template is valid and the person has a real initiated thread, durable opt-in, no DNC/suppression, and a policy-valid timezone; eligibility is checked again before the Meta call. Already-enrolled contacts are skipped.
List broadcast recipients (campaigns.list_recipients)
[READ] The delivery table for a campaign: who is enrolled, which step they are on, when they run next, and why any of them failed. Includes the per-status counts the Recipients page shows.
Broadcast analytics (campaigns.stats)
[READ] The channel-aware delivery funnel for one campaign — recipients, sent and delivered, plus email opens/clicks or WhatsApp reads where supported, and bounced, failed and unsubscribed outcomes — computed from the send ledger exactly as the Analytics page renders it.

Actions — capture

80 operations.

View Capture domains (capture.list_domains)
[READ] List this account's Capture-only custom domains and DNS verification status. No changes or charges occur.
Connect Capture domain (capture.connect_domain)
[HIGH RISK · ADMIN ONLY] Connect an already-owned hostname for public videos, screenshots and guides, and provision TLS. Includes ten Capture-only domains on Spark through Grow and unlimited on Scale and Founder; does not buy a domain, alter DNS records or unlock the white-label app. Returns CNAME instructions for your DNS provider.
Check Capture domain (capture.verify_domain)
[ADMIN ONLY] Check DNS and TLS readiness for a Capture-only hostname and persist its current status. Does not change DNS records, send messages or incur charges.
Disconnect Capture domain (capture.disconnect_domain)
[HIGH RISK · ADMIN ONLY] Remove a Capture-only hostname and its TLS provisioning. Existing links on that hostname stop working; recordings remain available on the platform. Does not delete recordings or remove shared app domains. Stored domain preferences fall back to an available host.
View default share domain (capture.get_default_share_domain)
[READ] Read the account's saved default share hostname and eligible connected app domains, including inherited parent-agency domains. Does not publish recordings or change DNS.
Save default share domain (capture.set_default_share_domain)
[HIGH RISK · ADMIN ONLY] Save the default hostname used when copying video and screenshot share links for this account. Existing tokens and privacy remain unchanged, and old links remain valid. Only account managers can change this; no DNS changes, messages or charges occur.
View recording share domain (capture.get_share_domain)
[READ] Read a recording's saved share hostname override, effective hostname and eligible connected domains. Requires existing recording access; does not publish content or change DNS.
Save recording share domain (capture.set_share_domain)
[HIGH RISK] Save a hostname override for one video or screenshot, or null to use the account default. Only its creator or account managers can change it. Preserves the share token, password and old links; does not publish private content, change DNS, send messages or incur charges.
Edit my comment (capture.edit_comment)
[HIGH RISK] Edit a comment authored by the acting user or this account's API integration. Changes affect existing public readers; editing does not resend the original comment notification. Guest authors use their signed viewer ticket through the public recording endpoint.
Delete my comment (capture.delete_comment)
[HIGH RISK] Remove the acting author's comment body and displayed author identity, preserving a deleted-comment placeholder and replies. This cannot restore the original text and does not retract copies already delivered to readers.
React to comment (capture.react_comment)
[HIGH RISK] Add a like, celebration or question reaction to a visible comment. Public readers see aggregate counts; no email or push notification is sent.
Remove my reaction (capture.remove_comment_reaction)
[HIGH RISK] Remove the acting user's or account integration's own reaction from a comment. Public aggregate counts change; no messages are sent.
Follow discussion (capture.follow_thread)
[HIGH RISK] Subscribe an account member to visible replies in a recording discussion. Enabled email and push channels send real notifications and email provider fees may apply. Every delivery rechecks membership, recording privacy and the subscription.
Unfollow discussion (capture.unfollow_thread)
Stop future reply notifications for the acting account member, or an explicit target member managed by an API credential. Messages already delivered cannot be recalled; no new messages are sent.
Merge guide steps (capture.merge_steps)
[HIGH RISK] Merge two adjacent guide steps and retain the explicitly selected screenshot. Saves the changed guide immediately, including on existing share links. No messages are sent.
Split guide step (capture.split_step)
[HIGH RISK] Split a guide instruction at a text offset into two adjacent steps. The original keeps its screenshot; the new step contains text only. Saves immediately to the guide and existing share links, without sending messages.
Add guide template (capture.append_guide_template)
[HIGH RISK] Append four editable SOP, onboarding or troubleshooting prompts to the guide. Prompts are illustrative placeholders, not generated facts. Saves immediately and changes existing shared guides; no messages are sent.
View recording comments (capture.list_comments)
[READ] Read timestamped recording comments and replies within the caller's account access. Includes pending and hidden comments for moderation; guest names are unverified. No messages are sent.
Post recording comment (capture.comment)
[HIGH RISK] Post a visible recording comment or reply. Existing public viewers can read it, and the recording owner may receive an in-app alert, email and browser push according to preferences. Email provider fees may apply.
Moderate recording comment (capture.moderate_comment)
[HIGH RISK] Approve or hide a comment from public viewers, or resolve its discussion. Restricted to the creator and signed-in account managers. Approval exposes the comment to existing share-link viewers; no new message is sent.
View recording notifications (capture.notification_preferences)
[READ] Read recording comment moderation and owner notification preferences for in-app, email and push channels. Does not send messages or change device permissions.
Save recording notifications (capture.set_notification_preferences)
[HIGH RISK] Set comment visibility and owner alerts for new viewers and comments. Enabling email or push allows future real notifications and email provider charges; existing device permission remains required. Only the creator or signed-in account managers may change these preferences.
Claim recording ownership (capture.claim)
[HIGH RISK] Assign an ownerless legacy recording to the signed-in account manager. Future enabled watch/comment notifications go to that person; existing ownership cannot be replaced. Requires an identified user and does not immediately send messages.
View recording activity (capture.activity)
[READ] Read bounded recent recording activity and 30-day watched-viewer/comment counts, respecting account and personal access. Viewer sessions are not verified people. No messages are sent.
Mark recording notification read (capture.read_notification)
Mark one in-app recording notification read for its signed-in recipient. Cannot mark another person's notification; no messages are sent.
List recordings (capture.list)
[READ] List the account's private Capture video and walkthrough library, including archived recordings. Returns metadata only; no messages are sent.
Open recording (capture.get)
[READ] Read one account recording and its editable guide, transcript and sharing settings. Does not publish content or send messages.
Create recording (capture.create)
Create a private Capture draft for an imported video or browser recording. Upload media separately; creating a draft does not record a person's screen or publish anything.
Save recording details (capture.update)
[HIGH RISK] Change a recording's title, description, transcript or archive state. Existing share links show these changes immediately; this does not send messages.
Save guide (capture.save_steps)
[HIGH RISK] Replace the recording's ordered written guide, removing omitted steps. An existing shared guide immediately shows the saved version. No messages are sent.
Create guide (capture.generate_guide)
[HIGH RISK] Create an editable guide from captured events or an AI interpretation of the transcript. If needed, transcribes the video through the account ElevenLabs account; AI drafting uses its connected AI provider. Provider usage is billed to the connected accounts. Review inferred steps before sharing.
Create share link (capture.share)
[HIGH RISK] Publish the selected video, written guide or both through an unlisted link accessible to anyone holding it. This exposes recording content outside the account; it does not email the link.
Revoke share link (capture.revoke_share)
[HIGH RISK] Disable a recording's current unlisted link immediately. Anyone who already downloaded the video retains their copy. No messages are sent.
Delete recording (capture.delete)
[HIGH RISK] Permanently delete a recording, its stored video, guide and viewer events. This cannot be undone and existing share links stop working.
View recording analytics (capture.analytics)
[READ] Count anonymous viewer sessions, plays and completions. Completion requires at least 90% non-overlapping watched coverage reported by the browser; sessions are not verified unique people. No messages are sent.
Start recording upload (capture.start_upload)
[HIGH RISK] Start or resume an 8 MiB multipart video upload into private account storage, up to 10 GiB. Returns the upload session and completed parts; uploading consumes existing storage capacity and sends no messages.
Finish recording upload (capture.finalize_upload)
[HIGH RISK] Complete a previously uploaded private recording after every multipart receipt is verified. Makes the stored original playable inside the account without publishing or messaging anyone.
Upload recording part (capture.upload_part)
[HIGH RISK] Upload one base64-encoded video part to an existing private recording upload. Parts are 8 MiB except the last; this consumes account storage without publishing or sending messages.
Upload guide screenshot (capture.upload_screenshot)
[HIGH RISK] Upload a JPEG image for one opted-in walkthrough step. The screenshot stays private until its guide is shared, and may contain screen content; no messages are sent.
Download original recording (capture.download)
[READ] Get the authenticated download endpoint for the stored original video. Send your existing API Bearer credential when fetching it; the URL is private and does not publish content.
Export guide (capture.export_guide)
[READ] Export a portable Markdown or HTML guide with authenticated screenshots embedded as JPEG data. Includes up to 20 MiB of images; the resulting file contains recording content and can be shared outside Chirply. Does not publish or send it.
Generate transcript and captions (capture.transcribe)
[HIGH RISK] Send the private recording to the selected account-connected speech provider and replace its saved transcript and captions with provider-timed results. ElevenLabs uses scribe_v2 for videos under 2 GiB; OpenRouter uses the selected Whisper model for WebM/MP4 files up to 16 MiB. Usage is billed to the connected provider account. No automatic retries, messages or publishing; failures may still incur provider charges.
Refresh transcription providers (capture.transcription_options)
[READ] Read connected speech providers, available Capture transcription models and file limits for this recording. Does not send recording data to a provider or incur generation charges.
View Capture storage (capture.storage)
[READ] Read stored recording bytes, in-flight reserved bytes and the account's configured Capture storage cap. A null cap means none is configured, not an unlimited plan entitlement. No messages are sent.
Save version (capture.save_version)
Save an immutable snapshot of the recording's current guide, captions, transcript and descriptive metadata. Original video, ownership and sharing credentials are not copied or changed. No messages are sent.
View recording versions (capture.list_versions)
[READ] List up to 100 saved metadata versions of a recording the caller can access. Personal recordings require their identified creator; version history is never public. No messages are sent.
Restore version (capture.restore_version)
[HIGH RISK] Restore saved guide, transcript, captions and descriptive metadata, first saving the current version. Existing public viewers see the restored content. Sharing tokens, expiration, privacy, ownership and original video are never restored or changed.
Set recording thumbnail (capture.set_thumbnail)
[HIGH RISK] Store a new immutable JPEG thumbnail for the recording. Existing video share viewers see this thumbnail; guide-only shares do not expose it. This consumes storage and sends no messages.
List video collections (capture.list_collections)
[READ] Read accessible personal and account video collections. Collection access does not grant access to its recordings; no content is published or sent.
Open video collection (capture.get_collection)
[READ] Read an ordered playlist of recordings the caller can access within this account. Unavailable items are omitted; no messages are sent.
Create video collection (capture.create_collection)
[HIGH RISK] Create a personal or account video playlist. Account collections are visible to account members, but grant no recording permissions and send no messages.
Save collection details (capture.update_collection)
[HIGH RISK] Change a video collection's title, description or account visibility. Existing account links reflect the change immediately; no messages are sent.
Save playlist order (capture.set_collection_items)
[HIGH RISK] Replace the ordered recording list in a collection, removing omitted entries without deleting source recordings. Account viewers see changes immediately; no messages are sent.
Delete video collection (capture.delete_collection)
[HIGH RISK] Permanently delete a video collection and its playlist ordering. This cannot be undone; source recordings remain and no messages are sent.
List watch later (capture.list_watch_later)
[READ] Read the signed-in member's saved recordings. A userless trusted account API manager must specify target_user_id; paired devices cannot use another member's list. Existing recording access still applies.
Save to watch later (capture.save_watch_later)
Bookmark an accessible recording for a current account member. Does not publish content or send messages; a userless trusted API manager must specify target_user_id.
Remove from watch later (capture.remove_watch_later)
Remove a member's recording bookmark without deleting its video. Does not publish or send anything; only the signed-in member or a userless trusted API manager with target_user_id can select the list.
Review screenshot guide provider (capture.visual_guide_preflight)
[READ] Read the connected vision model, image support, current published token rates and screenshot limits before drafting a guide. Does not send screenshots or charge for generation.
Draft from selected screenshots (capture.draft_visual_guide)
[HIGH RISK] Send up to twelve reviewed screenshots and optional context to the account's connected vision provider, which bills for processing. Returns an evidence-based editable draft without saving or publishing it. Reuse the same request ID and identical input to retrieve an outcome without repeating generation; an uncertain provider outcome may already have incurred a charge.
Refresh publication status (capture.publication_status)
[READ] Read whether the saved recording draft differs from its immutable published version and whether its current share grant is active. Does not publish changes or alter access.
Publish changes (capture.publish_changes)
[HIGH RISK] Publish the saved recording draft as an immutable version. Existing share links immediately show the new title, guide, screenshots and captions permitted by their current audience. Does not create a share link or change its access or expiration.
Restore draft from published (capture.restore_published_draft)
[HIGH RISK] Replace saved draft title, description, guide steps, screenshots, transcript, captions and thumbnail with the currently published version. Discards saved draft edits; leaves source media, ownership, access, share links and expiration unchanged.
Create rendered video (capture.enqueue_render)
[HIGH RISK] Encode selected source clips into a new MP4, WebM or GIF recording. Consumes server compute and reserves account storage up to max_output_bytes; no original is changed and no messages are sent. Failed copies keep their reservation until deleted; reuse the same request_id only for identical input.
View render status (capture.get_render)
[READ] Read an accessible render job's status, output recording and persistent error. Does not start another encode or consume additional output storage.
List render jobs (capture.list_renders)
[READ] Read a bounded page of accessible recording renders in this account. Personal output access is enforced; private source snapshots and provider URLs are never returned.
Cancel render (capture.cancel_render)
Stop a queued or running render from publishing its edited copy. Original recordings remain intact; delete the unfinished output separately to release reserved storage. Completed jobs are returned unchanged and no messages are sent.
Keep selected blocks (capture.plan_keep_transcript_blocks)
[READ] Plan retained clips from selected whole saved caption blocks and return their total duration for review. Does not encode, save a render draft, publish, or spend provider money. This is block timing, not word precision; use the reviewed clips with Create rendered video to encode later.
Remove selected blocks (capture.plan_remove_transcript_blocks)
[READ] Plan a video cut that removes selected whole saved caption blocks while retaining unselected footage and unscripted gaps. Returns clips and duration for review; does not encode, save, publish, or spend provider money. No word-level precision is claimed; overlapping caption boundaries are rejected.
Refresh share security (capture.get_share_security)
[READ] Read recording password protection, public download policy and the current share URL. Returns no password or hash; only the creator or account managers can change these settings.
Set recording password (capture.set_share_password)
[HIGH RISK] Set or replace a recording share password, stored by Capture only as a bcrypt hash. Revokes current viewer tickets and may rotate the share URL; copy the returned current URL. API/MCP clients must protect their own request logs. No messages are sent or provider charges incurred. Use the owner Share security form instead of entering secrets in Copilot chat.
Remove recording password (capture.remove_share_password)
[HIGH RISK] Remove the recording's password so anyone holding the current share URL can view its published content. Revokes existing viewer tickets, preserves the download policy and sends no messages. Only the creator or account managers can change protection.
Save download policy (capture.set_download_policy)
[HIGH RISK] Change whether public viewers can use the recording's original video download control and endpoint. May rotate the share URL and revokes access tickets. Playback remains available to authorized viewers, who can still capture delivered content; this is not DRM. Sends no messages and incurs no provider charge.
Refresh text AI settings (capture.text_ai_preflight)
[READ] Read the account's connected text model, current catalog per-token prices and selection limits for Capture translation and rewriting. No recording content is sent to AI, no generation runs and no provider charge is incurred.
Translate selected content (capture.translate_selected_content)
[HIGH RISK] Send explicitly selected saved guide and caption text to the connected OpenRouter model for translation. The provider bills the account account; reviewed per-million price ceilings and an 8000-token output limit apply, not a guaranteed final invoice cap. Returns a draft only, preserving IDs, screenshots and timing. Reuse the same request UUID to check its receipt; failed or uncertain requests never retry automatically.
Regenerate selected steps (capture.regenerate_selected_steps)
[HIGH RISK] Send selected saved guide steps and rewrite directions to the connected OpenRouter model, billed to the account account. Returns reviewed text patches only; unselected content, screenshots, URLs and timing are preserved. Per-token price ceilings and an 8000-token output limit apply. No draft is saved or published, and failed or uncertain request IDs never trigger an automatic paid retry.
Create Capture pairing code (capture.create_pairing)
[HIGH RISK · ADMIN ONLY] Create a ten-minute one-time code that connects a browser to this account's included Capture recorder. The credential can read and manage account Capture recordings, including edits, sharing, deletion and separately invoked AI operations that bill connected providers. It grants no paid Browser Agent tasks, manager controls or personal-recording access. Creating the code incurs no charge; keep it private.
Refresh Capture browsers (capture.list_devices)
[READ · ADMIN ONLY] List up to100 active browsers of each connection kind in this account. Distinguishes Capture-only credentials from Browser Agent credentials; returns prefixes, never usable tokens. No recordings or permissions are changed.
Revoke Capture browser (capture.revoke_device)
[HIGH RISK · ADMIN ONLY] Immediately revoke the selected browser token. Capture-only revocation affects Capture; choosing browser_agent disables Capture and all Browser Agent tasks using that connection. Its next request fails authentication. Saved recordings remain available; no notifications are sent.
Upload screenshot (capture.upload_image)
[HIGH RISK] Store a private standalone raster screenshot in a Capture project created with mode screenshot. Validates image format and dimensions and consumes account storage. Does not publish or send notifications; original bytes are immutable.
Save screenshot edit (capture.save_image_edit)
[HIGH RISK] Save edited screenshot pixels as a new immutable private image revision. Preserves original bytes and the currently published image until Publish changes. Consumes storage; stale edits cannot overwrite newer changes. No messages are sent.

Actions — cards

5 operations.

Scan a business card (cards.scan)
[HIGH RISK] Reads a photo of a physical business card with AI vision and saves the details as a CRM contact — creating a new contact, or updating the one it matches by phone/email — with the card's front (and optional back) images attached. Uses this account's own OpenRouter/AI key, so the AI cost is billed to the account. Images are supplied as a data URL (data:image/jpeg;base64,…) or an https image URL. AN https IMAGE URL IS FETCHED FROM CHIRPLY'S SERVERS and handed to the vision provider, so everything in it — host, path, query string — is disclosed to whoever operates that address. That, and the AI spend, is why it asks for confirmation.
List digital cards (cards.list_cards)
[READ] Lists the digital business cards in this account — each person's shareable card, whether it's published, its public URL and view count.
Get a digital card (cards.get_card)
[READ] Returns a digital business card and its share links (public page + vCard). Defaults to the calling user's own card; pass user_id for a specific teammate, slug for a card by its public URL segment, or ble_code after discovering a nearby digital business card over Bluetooth.
Save my digital card (cards.save_card)
Creates or updates a person's digital business card (name, title, company, phones, emails, website, socials, bio, theme) and can publish or unpublish it. Publishing makes it world-readable at its public URL. Defaults to the calling user's card; an API key must pass user_id.
Save a shared card to contacts (cards.import_card)
Saves someone's published digital business card (by its public slug) into this account's CRM as a contact. If the person is already a contact (matched by phone/email) they're linked, not duplicated.

Actions — cloud

15 operations.

Cloud launch options (cloud.launch_options)
[READ · ADMIN ONLY] Read live deployment choices from your cloud provider. DigitalOcean returns sizes with prices, regions, images, SSH keys and Kubernetes versions; AWS returns subnet, security group and key-pair IDs; Google returns available project zones. Permission failures are reported per option group. No resources are launched.
Invoke Lambda function (cloud.invoke_lambda)
[HIGH RISK · ADMIN ONLY] Run a Lambda function directly on your connected AWS infrastructure. The function can cause external effects and AWS bills its execution. The request is not automatically retried; inspect uncertain outcomes before invoking again.
Cloud launch catalog (cloud.catalog)
[READ · ADMIN ONLY] List supported customer-owned infrastructure services, deployment examples and provider documentation. Read-only; does not connect accounts or provision resources.
Cloud connections (cloud.connections)
[READ · ADMIN ONLY] List this account’s saved cloud connections and last verified status. Returns no credentials and makes no provider changes.
Connect cloud provider (cloud.connect)
[HIGH RISK · ADMIN ONLY] Verify and encrypt this account’s own cloud credentials. Replaces this provider’s previous connection and changes where future operations run. Verification launches no infrastructure; subsequent launches are billed by the provider.
Test cloud connection (cloud.test_connection)
[ADMIN ONLY] Verify stored cloud credentials with a metadata request and persist the result. Does not launch infrastructure or execute an agent job; individual resource permissions can still differ.
Disconnect cloud provider (cloud.disconnect)
[HIGH RISK · ADMIN ONLY] Remove this account’s encrypted cloud connection. Existing resources and running jobs remain on the provider and continue billing; future Chirply operations require reconnecting.
List cloud resources (cloud.list_resources)
[READ · ADMIN ONLY] Read one page of resources from the connected provider in the requested region. Returns provider pagination metadata; secret configuration is redacted. Does not launch or change resources.
Inspect cloud resource (cloud.get_resource)
[READ · ADMIN ONLY] Read live resource state from the connected cloud provider. Use after a launch to distinguish provider acceptance from readiness. Secret configuration is redacted; no resources are changed.
Launch cloud resource (cloud.create_resource)
[HIGH RISK · ADMIN ONLY] Launches real infrastructure using the connected provider’s deployment specification. The provider bills the customer directly for compute, storage and traffic. Records an idempotent submission receipt; accepted means submitted, not ready. Inspect resources before retrying an uncertain operation.
Update cloud resource (cloud.update_resource)
[HIGH RISK · ADMIN ONLY] Changes a running provider resource; updates may replace resources, interrupt service or change billing. The provider bills the customer directly for compute, storage and traffic. Records an idempotent submission receipt; accepted means submitted, not ready. Inspect resources before retrying an uncertain operation.
Delete cloud resource (cloud.delete_resource)
[HIGH RISK · ADMIN ONLY] Permanently deletes a provider resource and may destroy its stored data. The provider bills the customer directly for compute, storage and traffic. Records an idempotent submission receipt; accepted means submitted, not ready. Inspect resources before retrying an uncertain operation.
Cloud activity (cloud.activity)
[READ · ADMIN ONLY] Read the latest fifty cloud submission receipts for this account. Includes accepted, rejected and uncertain outcomes; excludes deployment specifications, credentials and job payloads.
Run on my infrastructure (cloud.submit_job)
[HIGH RISK · ADMIN ONLY] Submit an agent or registered HTTP job directly to your connected execution server. Its own durable queue, compute and disk hold the work and result; it never enters Chirply’s shared job queue. Uses your server’s configured AI/tool credentials and can spend provider money or cause external effects. Core Chirply application data remains in Chirply.
Inspect my infrastructure job (cloud.get_job)
[READ · ADMIN ONLY] Read a job’s current state and result directly from your connected execution server. The payload, queue and result are stored on that server. Does not start or retry work.

Actions — cms

14 operations.

List collections (cms.list_collections)
[READ] List the structured content collections owned by a website, including each collection's field schema, public path, and visual template page.
Create blog (cms.create_blog)
[ADMIN ONLY] Create an SEO-ready Blog collection and a draft visual article template inside an existing website. Publish the template with the website before publishing articles. This publishes nothing and sends nothing externally.
Create collection (cms.create_collection)
[ADMIN ONLY] Create a structured content collection for one website. Its entries remain drafts until individually published; nothing becomes public from this action.
Save collection (cms.update_collection)
[HIGH RISK · ADMIN ONLY] Update a collection's name, URL prefix, field schema, status, or visual template page. Changing fields does not delete stored entry data; published entry URLs may change when path changes.
Delete collection (cms.delete_collection)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete a collection and every draft and published entry inside it. All of its public entry URLs stop resolving immediately. This cannot be undone.
List entries (cms.list_entries)
[READ] List draft, scheduled, published, or archived entries in a collection with their structured data and SEO settings.
Create entry (cms.create_entry)
[ADMIN ONLY] Create a CMS entry as a private draft. Structured values are validated against the collection schema and nothing becomes public until Publish entry is run.
Save entry (cms.update_entry)
[ADMIN ONLY] Save an entry's working draft, slug, excerpt, or SEO settings. Published visitors continue seeing the previous published snapshot until Publish entry is run again.
Publish entry (cms.publish_entry)
[HIGH RISK · ADMIN ONLY] Publish the current draft data and SEO as a public snapshot. Real visitors can immediately open the entry at the collection path on the website; the collection must have a published visual template page.
Schedule entry (cms.schedule_entry)
[HIGH RISK · ADMIN ONLY] Freeze the current saved draft and SEO as a public snapshot that automatically becomes available at the specified future time. Real visitors can open it after that time; later draft edits do not change the scheduled snapshot.
Unpublish entry (cms.unpublish_entry)
[HIGH RISK · ADMIN ONLY] Take a published CMS entry offline immediately while preserving its working draft and last published snapshot for later republishing.
Import WordPress posts (cms.import_wordpress)
[HIGH RISK · ADMIN ONLY] Fetch up to 100 posts from a public WordPress REST API and add them as private drafts in an existing collection. Existing entries with the same slug are preserved; this publishes nothing. THIS MAKES AN OUTBOUND REQUEST FROM CHIRPLY'S SERVERS to whatever address is given, so everything in the URL — host, path, query string — is disclosed to whoever operates it, and whatever it answers with is stored in this account. That is why it asks for confirmation.
Audit SEO (cms.audit_seo)
[READ] Audit every CMS entry on a website for missing or oversized search metadata, missing social images, thin content, long slugs, and published no-index mistakes. This read-only check changes nothing.
Delete entry (cms.delete_entry)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete a CMS entry, including its working draft and published snapshot. Its public URL stops resolving immediately and this cannot be undone.

Actions — commerce

34 operations.

Open store (commerce.get_store)
[READ] Fetch this account's storefront branding, publishing status, payment routing and public address.
Create store (commerce.create_store)
Create the account's storefront in draft. It remains private until Publish store is run.
Save storefront (commerce.update_store)
[HIGH RISK] Update customer-facing storefront branding, merchandising copy, support details or payment routing. Omitted fields are unchanged. Two of these fields move real money and are the reason this needs approval: changing stripe_account_id redirects where every future sale is PAID INTO, and setting payment_mode to 'test' makes a live public storefront stop collecting real money entirely while still appearing to take orders.
Publish store (commerce.publish_store)
[HIGH RISK] Publish the storefront to the open internet, or pause an already-public store. Publishing immediately exposes all active products and enables real checkout when payment mode is live.
Connect domain (commerce.connect_domain)
[HIGH RISK · ADMIN ONLY] Connect a customer-owned hostname through the platform's Cloudflare for SaaS service and make it this store's public address. This changes public routing and may automatically create a CNAME in its connected Cloudflare account; it does not purchase a domain.
Use this domain (commerce.attach_domain)
[HIGH RISK · ADMIN ONLY] Make an already-connected, unused account domain the store's public address. This immediately changes public routing when the domain is active and replaces any prior custom address on this store; it does not modify registrar ownership.
Check again (commerce.verify_domain)
[ADMIN ONLY] Recheck the store domain's Cloudflare hostname and SSL status, then save the latest verification state. This does not change DNS or spend money.
Set up with connected Cloudflare (commerce.setup_domain_dns)
[HIGH RISK · ADMIN ONLY] Create or repair the store hostname's CNAME in its connected Cloudflare account and recheck SSL. This writes a real public DNS record but does not purchase a domain or charge money.
Remove from store (commerce.detach_domain)
[HIGH RISK · ADMIN ONLY] Stop serving the native store from its custom hostname. The store remains available at its built-in platform address and the domain remains connected to the account for reuse; no registrar or DNS ownership is deleted.
List products (commerce.list_products)
[READ] List products shared by storefronts and funnels, with price, visibility, SKU, product type and stock state.
Open product (commerce.get_product)
[READ] Fetch one catalog product with pricing, inventory, fulfillment and storefront fields.
Create product (commerce.create_product)
Create a reusable catalog product for storefronts and funnels. Active products become sellable immediately when the storefront is published.
Save product (commerce.update_product)
[HIGH RISK] Update a catalog product. This edits an item that may be ON SALE RIGHT NOW on a published storefront: a new price_amount is what real customers are charged from the moment it saves, and storefront_status can put the product on sale or pull it off in public immediately. Price changes affect future purchases only; completed order snapshots are never rewritten.
Adjust inventory (commerce.adjust_inventory)
[HIGH RISK] Add or remove sellable product inventory and record the manual adjustment in the stock ledger. This can make an item available or sold out immediately on a live storefront. IMPORTANT SIDE EFFECT: it also switches stock tracking ON for that product permanently, even if it was selling with tracking off — so from then on the count is enforced, and a product whose inventory policy is 'deny' will REFUSE real customer orders as soon as the count reaches zero.
List product variants (commerce.list_variants)
[READ] List the sizes, colors or other purchasable variants for one product, including option values, price overrides and stock.
Add variant (commerce.create_variant)
Add a purchasable size, color or option combination to an existing product, with optional SKU, price override and independent inventory.
List collections (commerce.list_collections)
[READ] List storefront collections used to merchandise related products into browsable groups.
Create collection (commerce.create_collection)
Create a storefront collection. Products can be assigned separately without changing or duplicating them.
Delete collection (commerce.delete_collection)
[HIGH RISK] Permanently delete a storefront collection and its product arrangement. Products themselves and completed orders are not deleted.
List discounts (commerce.list_discounts)
[READ] List discount codes, eligibility, limits, active dates and redemption counts.
Activate discount (commerce.create_discount)
[HIGH RISK] Create a discount code and put it LIVE immediately. Every code created here starts ACTIVE, applies to EVERY product in the store, and — unless you set usage_limit — can be redeemed an UNLIMITED number of times by anyone who learns the code. It comes straight off what real customers pay at storefront checkout, so a percentage value of 10000 basis points is a 100%-off code that gives the whole catalogue away for free. There is no draft state and no approval step after this call: use commerce.pause_discount to stop one.
Pause discount (commerce.pause_discount)
Pause or reactivate a discount code. Pausing prevents it from reducing any new customer checkout immediately.
List store orders (commerce.list_orders)
[READ] List storefront orders with customer, payment totals and fulfillment state. Funnel-only orders are excluded.
Open store order (commerce.get_order)
[READ] Fetch one storefront order with payment, customer, delivery and fulfillment fields.
Mark fulfilled (commerce.fulfill_order)
[HIGH RISK] Mark a paid storefront order fulfilled and record optional carrier/tracking details. This is an outward operational claim that the seller has shipped or delivered the order.
List subscriptions (commerce.list_subscriptions)
[READ] List the recurring orders (subscriptions) sold through this account's storefront and funnels: buyer, amount, billing state (active, past_due after a failed renewal, canceled) and the Stripe subscription id on the seller's own Stripe account. Read-only.
Cancel subscription (commerce.cancel_subscription)
[HIGH RISK · ADMIN ONLY] Cancel a customer's recurring subscription on the seller's OWN Stripe account. This stops REAL future charges to a real customer's card: with at_period_end (the default) they keep what they paid for until the current billing period runs out and are never charged again; with at_period_end false the subscription ends IMMEDIATELY, any member access the purchase granted is revoked right away, and no refund of the current period is issued by this action. It does not delete the customer, the order history, or any member data.
List open carts (commerce.list_carts)
[READ] List persistent storefront carts, including identified buyers, discounts, totals and last activity, for abandoned-cart recovery and support.
Open store cart (commerce.get_cart)
[READ] Fetch one shopping cart on the public storefront by its token: every line with its product, chosen variant, quantity, unit price and whether it is still in stock, plus the server-calculated subtotal, discount, shipping, tax and total in the smallest currency unit. Prices are recalculated live from the catalogue, so this is the authority on what checkout will actually charge. Reads only — it holds no stock and charges nothing. Returns nothing if the cart has expired or was already checked out.
Add to cart (commerce.add_to_cart)
Add a product to a shopping cart on the public storefront, starting a new cart when no token is given. The product must be active and published on the storefront, a product with options requires a variant_id, and the request is refused when tracked stock would be exceeded. Nothing is charged and no stock is held — this only builds the cart; money moves at commerce.checkout. ALWAYS keep the cart_token it returns: it is how every later call finds this cart.
Update cart quantity (commerce.update_cart_item)
Change how many units of one line are in a storefront cart, or remove that line entirely by setting the quantity to 0. Totals are recalculated on the server. The change is refused when tracked stock would be exceeded. Nothing is charged and no stock is held.
Apply discount code (commerce.apply_discount_code)
Apply a discount code to a storefront cart, or clear the one already on it. The code is checked against the store's active discounts on the server and rejected if it isn't valid, so this is also how you test whether a code works. The saving is recalculated into the cart's totals and will really be taken off the customer's charge at checkout. Nothing is charged here.
Checkout (commerce.checkout)
[HIGH RISK] Place a REAL order for the contents of a storefront cart. This is the point of no return on the buyer's path: it re-prices every line, HOLDS the tracked stock so nobody else can buy it, creates a real pending order in the seller's books, creates or updates a CRM contact for the buyer from their email, and opens a live Stripe payment for the full total on the seller's OWN Stripe account (test mode only if the store is set to test). It returns that payment's client secret — the card is charged the moment that secret is confirmed, which for a shopper is them clicking Pay. Use only with a real buyer's real details and a total they have agreed to.
Open order receipt (commerce.get_order_by_token)
[READ] Fetch a storefront order using the order token from its confirmation link — the receipt page a buyer is sent to after checkout. Returns the order's number, payment status (whether Stripe has confirmed it yet), fulfilment status, buyer details, totals and every line item. Use this to poll whether a checkout you started has actually been paid. Reads only. Staff who have the order's internal id should use commerce.get_order instead.

Actions — communications

7 operations.

Mark as spam (communications.mark_spam)
Mark one email, text, or phone call as spam so it leaves normal communication views. This is reversible and sends nothing.
Communication log (communications.list)
[READ] Read the communication log: every call, text, email, social message, and website live chat in this account on one timeline, newest first, with both sides of each exchange named. Calls carry duration, recording URL and transcript; messages and chats carry their latest content. Outbound email also carries an `engagement` object — when it was first opened and how many times, when a link was clicked, when it bounced, and when the recipient reported it as spam — each null until the email provider reports it, and all null when that provider has open tracking switched off, so a missing open never means the message went unread. Read-only. Archived entries are excluded unless `archived` is true, and entries marked as spam are excluded unless `spam` is true; live chats are always read from their dedicated inbox and have neither an archive nor a spam state. ONE DELIBERATE DIFFERENCE FROM THE SCREEN: the /communications page and the dashboard's Recent Communication column both collapse the timeline to the newest entry per contact, and this returns every entry by default so a machine caller can page the raw history. Pass `group_by_contact: true` to see exactly what the screen shows.
My channels (communications.channels)
[READ] List the account's OWN ends of a conversation — the phone numbers it calls and texts from, the email addresses it sends from, and the Facebook Pages and Instagram accounts it answers DMs on. Read-only, and the companion to `communications.list`: each entry's `address` is exactly the string to pass as that tool's `address` filter (E.164 for a number, the bare address for email, Meta's numeric id for a Page or Instagram account), which is the same list the communication log's channel filter shows. The far side of a conversation is not here — that is every contact the account has ever spoken to, and `communications.list`'s `search` is how you find those.
New since you last looked (communications.unread)
[READ] Count what has come in on each channel since the caller last opened the communication log — the numbers the log's filter pills and the top-bar badge show. Inbound only, archived entries excluded, and CALLS ARE COUNTED ONLY WHEN MISSED (no answer, busy, failed or canceled), because an answered call was already handled by a person. Never reaches further back than 30 days. Read-only — this does not mark anything as seen. The read line is per person: an API key has no personal one, so for key callers this returns everything inbound in the whole 30-day window rather than anything about a particular user.
Mark the log as seen (communications.mark_seen)
Clear the caller's unread counts by moving their read line up to now — the same thing that happens automatically when they open the communication log in the app. Pass `types` to clear only some channels (reading the Emails view shouldn't dismiss missed calls). Destroys nothing: every call and message stays exactly where it was, and only this one person's badge changes. Requires a signed-in user; an API key has no personal read line to move.
Archive (communications.archive)
Take one entry out of the communication log once it's been dealt with. NOT a delete: the call or message stays on file with its recording, transcript and body intact, still visible in its conversation thread and on the contact's timeline — it just stops appearing in the log and in the dashboard's Recent Communication column. Reversible with communications.unarchive.
Restore to log (communications.unarchive)
Put a previously archived call, text or email back into the communication log, where it returns to its original place in the timeline.

Actions — community

17 operations.

List spaces (community.list_spaces)
[READ] List the spaces (feed categories, e.g. 'General', 'Wins') in one community group, in display order — including each space's access rules (level gate, required access product, staff-only posting).
Create a space (community.create_space)
[ADMIN ONLY] Add a space (feed category) to a community group. Members see it in the feed sidebar immediately. Optionally gate it behind a member level or an access product, or lock posting so only staff can start threads (an announcements space).
Edit a space (community.update_space)
[ADMIN ONLY] Update a space's name, description, emoji, position, access rules (level gate / required access product), or staff-only posting. Omitted fields are left alone. Tightening access hides the space from members who no longer qualify immediately.
Delete a space (community.delete_space)
[HIGH RISK · ADMIN ONLY] Permanently delete a space AND every post, comment, and reaction inside it. Members lose that content immediately and it cannot be recovered. To hide a space without destroying content, gate it with update_space instead.
Community settings (community.get_settings)
[READ] Read one group's community configuration: whether the community is enabled, the description and welcome message, the level curve (level names + point thresholds), and the points awarded for post/comment likes. Also returns the EFFECTIVE levels and points rules (defaults applied), which is what members actually experience.
Update community settings (community.update_settings)
[ADMIN ONLY] Create or update a group's community configuration. Turning `enabled` on makes the community live at the site's /c URL for signed-in members (a default 'General' space is created if none exists); turning it off takes it away immediately. Levels and points rules are member-visible: changing thresholds can re-rank existing members' levels at once. Omitted fields keep their current value.
List posts (community.list_posts)
[READ] List a community group's feed — pinned posts first, then most recent activity. Optionally narrow to one space, or include removed (moderated-away) posts to review moderation history.
Open a post (community.get_post)
[READ] Fetch one community post with its full body, media, counters, and every published comment (threaded one level).
Post as staff (community.create_post)
[ADMIN ONLY] Publish a staff post (announcement) into a community space. Members see it in their feed immediately, marked as coming from the team, and any 'Community post created' automations fire. Authored as the acting user's contact — so this needs a signed-in user (Copilot), not an API key.
Remove a post (community.remove_post)
[HIGH RISK · ADMIN ONLY] Moderate a post away: it disappears from every member's feed immediately (comments go with it). The content is kept and can be brought back with community.restore_post — but members see it vanish, so treat it as a public moderation act.
Restore a post (community.restore_post)
[ADMIN ONLY] Bring a removed post back — it reappears in members' feeds immediately.
Pin a post (community.pin_post)
[ADMIN ONLY] Pin a post to the top of the feed for every member (or unpin it with pinned=false). Newest pin sits highest.
Remove a comment (community.remove_comment)
[HIGH RISK · ADMIN ONLY] Moderate a comment away: it disappears from the post for every member immediately. The row is kept (status 'removed') and can be brought back with 'Restore a comment'.
Restore a comment (community.restore_comment)
[ADMIN ONLY] Bring back a comment that was removed by moderation. It reappears on its post for every member immediately.
Leaderboard (community.leaderboard)
[READ] The top point earners for a community group (or the whole account when no funnel is given), over the last 7 days, 30 days, or all time — the same board members see. All-time entries include each member's level.
Award points (community.award_points)
[HIGH RISK · ADMIN ONLY] Add community points to a contact's score, or subtract them with a negative number. Points are MEMBER-VISIBLE: they move leaderboards and can change the member's level, which may unlock (or re-lock) level-gated spaces and course content, and a level-up fires the org's 'Member levels up' automations.
Member activity (community.member_activity)
[READ] One contact's community footprint: their points total and level (in one group or org-wide), plus their most recent posts and comments — including removed ones, so moderators see the whole picture.

Actions — companies

5 operations.

List companies (companies.list)
[READ] List the organization's companies, A–Z. Search matches the company name.
Open a company (companies.get)
[READ] Fetch one company by id, with all of its fields. Use contacts.list with company_id for the people who work there.
Create a company (companies.create)
Create a company record. Only a name is required; attach contacts to it afterwards with contacts.update.
Edit a company (companies.update)
Update fields on an existing company. Omitted fields are left alone; an explicit null clears one.
Delete a company (companies.delete)
[HIGH RISK] Permanently delete a company and its activity timeline. Contacts at the company are kept but are detached from it. This cannot be undone.

Actions — compliance

51 operations.

Business profile (trust.get_profile)
[READ · ADMIN ONLY] Read the organization's Twilio business profile: the business details on file, whether Twilio has approved it, and anything still missing. This profile is the foundation — SMS brand registration and every voice-trust product depend on it being approved first.
Save business details (trust.save_profile)
[ADMIN ONLY] Save the legal business details Twilio and the carriers require: registered name, business type, tax/registration number, address, website, and the authorized representatives. Saved locally only — nothing is sent to Twilio until the profile is submitted, so this can be filled in over several sittings. Editing an already-submitted profile stages the change for the next resubmission.
Find my Twilio profile (trust.link_profile)
[ADMIN ONLY] Look on the organization's own Twilio account for the business profile they created in the Twilio Console, and link it to this account. Twilio provides no API to CREATE that primary profile — it has to be started in their Console — so this is how the two sides get connected. Prefers an already-approved profile when several exist.
Check before submitting (trust.check_profile)
[ADMIN ONLY] Run Twilio's own free requirement check against the business profile and return which requirements pass and which fail. Costs nothing and does not submit anything. Worth running before every submission — a rejection costs days of review time for problems this check reports instantly.
Submit for review (trust.submit_profile)
[HIGH RISK · ADMIN ONLY] Send the business profile to Twilio for review. Pushes the saved details to Twilio, runs the free pre-check, and refuses to submit if that check fails. Review typically takes up to 72 hours and the profile can't be edited freely while it's in review. Free, but it gates everything else: no SMS brand and no voice-trust product can be registered until this is approved.
Refresh profile status (trust.refresh_profile)
[ADMIN ONLY] Re-read the business profile's review status from Twilio right now, instead of waiting for the background check that runs every 15 minutes.
Carrier trust products (trust.list_products)
[READ · ADMIN ONLY] List every carrier-trust product — SHAKEN/STIR call signing, CNAM caller-ID name, Voice Integrity spam protection, Branded Calling, and the A2P messaging profile — with the organization's registration status for each, what each one costs, and how long Twilio takes to review it.
Add another caller ID name (trust.add_cnam_name)
[ADMIN ONLY] Start an additional CNAM registration, so different phone numbers can display different business names — useful when one organization trades under more than one name. Each registration carries exactly one name and covers whichever numbers are added to it. Creates a draft only; nothing is sent to Twilio and nothing is charged until it's registered.
Delete a registration (trust.delete_registration)
[HIGH RISK · ADMIN ONLY] Delete a carrier-trust registration that was never submitted. Only works while it is still a draft — once Twilio holds it, the bundle exists on the organization's Twilio account and has to be removed there instead.
Save trust product details (trust.save_product)
[ADMIN ONLY] Save the extra answers a specific trust product needs before it can be registered. CNAM needs the caller-ID name to display (15 characters maximum — carriers cut it off past that). Voice Integrity needs what the organization uses calling for, its employee count, and its average calls per business day. SHAKEN/STIR and the A2P messaging profile need nothing beyond the business profile. Saved locally; nothing is sent to Twilio until the product is submitted.
Register with the carriers (trust.submit_product)
[HIGH RISK · ADMIN ONLY] Register a carrier-trust product with Twilio: creates the bundle, attaches the approved business profile and the product's own details, runs Twilio's free pre-check, and submits it. SHAKEN/STIR, CNAM and Voice Integrity are all free to register and take roughly 24–72 hours. Requires the business profile to be approved first. Branded Calling cannot be registered this way — Twilio has no API for it and it needs a signed Letter of Authorization, so it has to be started in the organization's own Twilio Console.
Link an existing registration (trust.link_product)
[ADMIN ONLY] Adopt a trust bundle that already exists on the organization's own Twilio account, by its bundle SID (starts with BU). This is how a Branded Calling registration — which has to be done in the Twilio Console — becomes visible here so its phone numbers can be managed in this account.
Refresh registration status (trust.refresh_product)
[ADMIN ONLY] Re-read one carrier-trust product's review status from Twilio right now, instead of waiting for the background check that runs every 15 minutes.
Cover a number (trust.add_number)
[ADMIN ONLY] Add one of the organization's phone numbers to an approved trust product, so calls from that number get its benefit — the highest SHAKEN/STIR attestation, the registered caller-ID name, or Voice Integrity's spam protection. The product must be approved first. Free.
Uncover a number (trust.remove_number)
[HIGH RISK · ADMIN ONLY] Remove a phone number from a trust product. Calls from it immediately lose that product's benefit — a number pulled off CNAM stops showing the business name, and one pulled off SHAKEN/STIR drops to a lower attestation and is more likely to be labeled spam.
SMS brand registration (a2p.get_brand)
[READ · ADMIN ONLY] Read the organization's A2P 10DLC brand: its registration status with the carriers, its trust score (which sets how many texts a day it can send), and whether a sole-proprietor phone verification is still outstanding.
Register SMS brand (a2p.submit_brand)
[HIGH RISK · ADMIN ONLY] Register the organization as an A2P 10DLC brand with The Campaign Registry, which US carriers require before any business texting. COSTS REAL MONEY on the organization's own Twilio account: $4.50 to register, plus $41.50 for secondary vetting unless skipped. Both are NON-REFUNDABLE and are charged even if the carriers reject the brand. Requires an approved business profile and an approved A2P messaging profile. Sole proprietors must additionally give the owner's personal mobile — Twilio texts it and the owner has to reply YES within 24 hours, which no software can do for them.
Refresh brand status (a2p.refresh_brand)
[ADMIN ONLY] Re-read the SMS brand's status from Twilio right now, instead of waiting for the background check that runs every 15 minutes.
Resend owner verification text (a2p.resend_verification)
[HIGH RISK · ADMIN ONLY] Send the sole-proprietor verification text again. This sends a REAL text message to the business owner's personal mobile, and they must reply YES to it. Only applies to sole-proprietor brands. The whole verification expires 30 days after the brand was created.
Buy secondary vetting (a2p.request_vetting)
[HIGH RISK · ADMIN ONLY] Order third-party secondary vetting for the SMS brand. COSTS $41.50 on the organization's own Twilio account, NON-REFUNDABLE, and it cannot be undone or repeated. In exchange the brand gets a trust score, which raises how many messages a day the carriers will accept from it. Only worth doing for a brand registered without vetting that is now hitting its daily limit.
List messaging campaigns (a2p.list_campaigns)
[READ · ADMIN ONLY] List the organization's A2P 10DLC campaigns — the registered descriptions of what it texts people about — with each one's carrier-approval status.
Open a messaging campaign (a2p.get_campaign)
[READ · ADMIN ONLY] Read one A2P 10DLC campaign in full: its use case, the description and opt-in wording registered with the carriers, its sample messages, its status, and anything still missing before it can be submitted.
New messaging campaign (a2p.create_campaign)
[ADMIN ONLY] Start a new A2P 10DLC campaign as a draft. This only creates a row in this account — it does NOT create anything in Twilio, nothing reaches the carriers, and nothing is charged. The Twilio Messaging Service the campaign's numbers will send through is created later, the first time something needs it (a2p.list_use_cases or a2p.submit_campaign). Fill the draft in with a2p.update_campaign, then a2p.submit_campaign, which is the step that costs money.
Edit messaging campaign (a2p.update_campaign)
[ADMIN ONLY] Edit a draft campaign's registration details. What goes here is read by human carrier reviewers, and vague answers are the single most common reason campaigns get rejected — describe what the business actually texts people and how those people asked for it. Saved locally; nothing reaches the carriers until the campaign is submitted.
Available campaign types (a2p.list_use_cases)
[ADMIN ONLY] List the campaign use cases this organization's brand is actually eligible for, with each one's monthly carrier fee and whether it needs extra carrier approval. Always read this before setting a campaign's use case — the list depends on the brand's type and trust score, so a hardcoded guess gets rejected. NOT READ-ONLY despite the name: the eligibility list has to be queried through a Messaging Service, so if this campaign does not have one yet this CREATES a real Messaging Service in the organization's own Twilio account and saves it to the campaign. Twilio does not charge for a Messaging Service, but the resource is real, it persists, and it is the one the campaign's numbers will later send through. Nothing reaches the carriers and no registration fee is incurred here — that is a2p.submit_campaign.
Submit campaign to carriers (a2p.submit_campaign)
[HIGH RISK · ADMIN ONLY] Submit an A2P 10DLC campaign to the carriers for approval. COSTS REAL MONEY on the organization's own Twilio account: a $15 NON-REFUNDABLE vetting fee charged once per campaign, plus a recurring monthly fee of $1.50 to $30 depending on the use case, billed for as long as the campaign exists. Carrier review takes 10–15 days and sometimes longer. Requires an approved brand. If a campaign is rejected it must be fixed and RESUBMITTED — deleting it and creating a new one is charged the $15 again.
Refresh campaign status (a2p.refresh_campaign)
[ADMIN ONLY] Re-read a campaign's carrier-approval status from Twilio right now, instead of waiting for the background check that runs every 15 minutes.
Add number to campaign (a2p.add_campaign_number)
[ADMIN ONLY] Put one of the organization's phone numbers behind a registered campaign. From then on texts sent from that number route through the campaign's Messaging Service, which is what makes them A2P-compliant and stops US carriers filtering them. A Messaging Service holds at most 400 numbers.
Remove number from campaign (a2p.remove_campaign_number)
[HIGH RISK · ADMIN ONLY] Take a phone number off a campaign. Its texts immediately go back to sending unregistered, which US carriers routinely filter or block — do this only when moving the number to a different campaign.
Opt-in site answers (a2p.get_kit)
[READ · ADMIN ONLY] Read the questionnaire behind this account's generated opt-in website, and the addresses it published — the sign-up page, privacy policy, terms and contact page that carrier reviewers open when judging an A2P 10DLC campaign. Read-only; returns nulls when nothing has been generated yet.
Save opt-in site answers (a2p.save_kit)
[ADMIN ONLY] Save the answers used to write this account's opt-in page, privacy policy, terms and A2P campaign wording. Saving alone changes nothing a visitor or a carrier can see — a2p.generate_site is what builds and publishes the pages. Omitted fields keep their current value. Fields left blank on the business profile (legal name, address, notification email) are filled in from it at generate time rather than asked for twice.
Generate opt-in site (a2p.generate_site)
[HIGH RISK · ADMIN ONLY] Build and PUBLISH four public web pages from the saved answers — a sign-up page with an unticked SMS consent checkbox, a privacy policy carrying the mobile-data clause carriers require, terms carrying the full messaging disclosures, and a contact page — then write the matching description, opt-in flow, sample messages and policy links onto the A2P campaign draft (and its campaign type, once the brand is approved and its real eligibility can be read). The pages go live immediately at the account's own domain when one is given, or on its Chirply address otherwise, and are visible to anyone with the URL. RUNNING IT AGAIN OVERWRITES those four pages, discarding any edits made to them in the page builder. Free: nothing here contacts Twilio or the carriers and nothing is charged — submitting the campaign, which costs $15, is still a separate deliberate step (a2p.submit_campaign).
Fill campaign from the kit (a2p.apply_kit_to_campaign)
[ADMIN ONLY] Rewrite an A2P campaign draft's description, opt-in flow, sample messages, policy links and confirmation text from the saved answers and the already-published opt-in site. Use it after editing the answers when the pages themselves have not changed. Only ever touches a draft or a rejected campaign — one already accepted by the carriers keeps the wording they reviewed. The campaign type is set too, but only once the brand is approved and the campaign already has a Messaging Service through which its real eligibility can be read; before that it is left blank rather than guessed, because an ineligible code looks answered and is rejected. Nothing is submitted and nothing is charged.
Set up texting for me (a2p.start_autopilot)
[HIGH RISK · ADMIN ONLY] Run the whole US texting registration end to end, unattended. From an account that has done nothing at all it will: adopt the Twilio business profile, submit the business details for review, register the A2P messaging profile, publish the opt-in website and policy pages, register the brand, write and register the campaign, and finally put the account's phone numbers behind it — each step starting automatically as the previous review is approved, over the days or weeks the carriers take. IT SPENDS THE ORGANIZATION'S OWN MONEY: Twilio bills their Twilio account $4.50 for the brand and $15 for the campaign, both non-refundable and charged even if the carriers reject. Nothing is charged unless approve_spend is true; without it the run still does everything free and stops before the first charge. It stops and asks for a human whenever a fact is missing, a review is rejected, the Twilio Console business profile does not exist yet (Twilio has no API for creating that one), or a sole proprietor has not replied YES to Twilio's verification text.
Pause texting setup (a2p.stop_autopilot)
[ADMIN ONLY] Stop the unattended registration run and withdraw its permission to spend, so nothing further is submitted to the carriers and nothing further is charged to the organization's Twilio account. Anything already submitted keeps its own course — a registration under carrier review cannot be recalled — and its status goes on being tracked. Deliberately not gated behind a confirmation: stopping is the safe direction.
Texting setup progress (a2p.autopilot_status)
[READ · ADMIN ONLY] Where the unattended registration run has got to: which link of the chain it is on, whether it is working, waiting on a carrier review, blocked on a human, or finished, and the plain-language reason. Read-only, and it never contacts Twilio — safe to poll while waiting out a review.
Texting registration checklist (a2p.preflight)
[READ · ADMIN ONLY] The whole path to sending registered business texts in one read — business profile, A2P messaging profile, opt-in site, brand, campaign and the numbers behind it — each marked done, waiting on a review, still to do, or blocked, with the reason and where to go next. Read-only: it reports what is already stored and never contacts Twilio, so it is safe to poll.
Find existing Twilio registrations (a2p.discover_existing)
[READ · ADMIN ONLY] Read what US texting registration the organization's own Twilio account ALREADY has: its A2P 10DLC brand registrations with their carrier status and trust score, its Messaging Services, and the 10DLC campaign registered on each service. Strictly read-only — it issues GET requests to Twilio and nothing else, so it registers nothing with the carriers, submits nothing for review and costs nothing. Use it before a2p.submit_brand or a2p.submit_campaign on any account that connected an established Twilio account, because those two do spend real money and would be paying to register a duplicate. It takes a few seconds: Twilio caps campaign lookups at one per second, so at most ten Messaging Services are checked for campaigns per call and any beyond that are returned without their campaign details.
Import existing SMS brand (a2p.adopt_brand)
[ADMIN ONLY] Link this account to an A2P 10DLC brand that already exists on the organization's own Twilio account, instead of registering a second one. Reads the brand from Twilio to confirm it is real and takes its live carrier status; registers nothing and charges nothing — no $4.50 registration fee and no $41.50 vetting fee. The imported brand is read-only afterwards: its status is refreshed from Twilio, and a2p.submit_brand and a2p.request_vetting refuse it rather than charging again for a registration the organization already owns. Brand SIDs come from a2p.discover_existing. Refused when this account already registered its own brand through Chirply, because importing over that would orphan a registration somebody paid for.
Import existing Messaging Service (a2p.adopt_messaging_service)
[ADMIN ONLY] Link this account to a Twilio Messaging Service that already exists on the organization's own account, so its phone numbers can be routed through it. When the service carries a 10DLC campaign, that campaign is mirrored here as well with the status Twilio reports — which is what replaces the misleading 'No campaigns yet' on the texting registration screen for a customer who registered before arriving. Creates nothing in Twilio, submits nothing to the carriers and costs nothing, in particular no $15 campaign fee. The imported campaign is read-only afterwards: a2p.submit_campaign and a2p.update_campaign refuse it. Safe to run again on the same service — it re-reads Twilio and refreshes the stored status rather than creating a second record.
Imported Messaging Services (a2p.list_messaging_services)
[READ · ADMIN ONLY] List the Twilio Messaging Services this account has imported from the organization's own Twilio account, each with the 10DLC campaign status and number count last read from Twilio. These are the services a2p.attach_number_to_service can route a phone number through. Read-only, and it reads only what is already stored here — it does not contact Twilio, so it is safe to poll.
Send a number through an imported service (a2p.attach_number_to_service)
[HIGH RISK · ADMIN ONLY] Route one of the organization's phone numbers through an imported Twilio Messaging Service, so its texts send under the A2P registration the organization already holds on its own Twilio account. THIS CHANGES HOW REAL OUTBOUND MESSAGES LEAVE that number, immediately and for every message after it. Unlike a2p.add_campaign_number it does not require a campaign registered through Chirply, which is the whole point — an account that completed 10DLC before it arrived here has no such campaign, and until now could not get its numbers behind its own verified service at all. A number belongs to exactly one Messaging Service, so attaching one that already sits on another service MOVES it. The service must have been imported first with a2p.adopt_messaging_service, and a Messaging Service holds at most 400 numbers. Nothing is charged.
Stop sending a number through a service (a2p.detach_number_from_service)
[HIGH RISK · ADMIN ONLY] Take a phone number off whatever Twilio Messaging Service it currently sends through. Its texts immediately go back to sending from a bare From number, which US carriers routinely filter or block outright — do this only when moving the number elsewhere or deliberately stopping its US texting. Nothing is charged and no registration is cancelled; only this one number's sending path changes.
Unsubscribed (unsubscribe.list)
[READ] List everyone the organization can no longer contact, with what each person is excluded from, whether they actually opted out (STOP, an unsubscribe link, the opt-out page, or a call keypress) or were excluded by staff, a provider, an import, or a connected app such as Stripe, and when. Read-only.
Unsubscribe totals (unsubscribe.counts)
[READ] How many people are unsubscribed, broken down by what they're unsubscribed from. Useful for checking how much of an audience a campaign will actually reach before sending it.
Communication preferences (unsubscribe.get_contact)
[READ] Read one contact's communication preferences: which kinds of message they can still be sent, which they've been unsubscribed from, who unsubscribed them and how, plus the full history of every opt-out and resubscribe on their record. Check this before sending anyone anything one-to-one.
Unsubscribe (unsubscribe.add)
Stop contacting someone. Immediately blocks every campaign, automation, and bulk send on the channels given — real messages that would otherwise have been sent are not sent. Works on a contact, or on a bare email address or phone number for someone who isn't in the CRM. Recorded with who did it and when, and reversible with unsubscribe.remove.
Unsubscribe selected contacts (unsubscribe.bulk_add)
[HIGH RISK] Unsubscribe a whole list of contacts at once, on the channels given. Immediately blocks every campaign, automation and bulk send to those people on those channels — real messages that would otherwise have gone out do not go out. Recorded as a bulk sweep rather than a series of one-offs, so the unsubscribed list shows it as one action. Reversible per person with unsubscribe.remove, which asks for confirmation.
Resubscribe (unsubscribe.remove)
[HIGH RISK] Put someone back on the list, so campaigns and automations can contact them again on the channels given. ONLY do this when the person has actually asked to be contacted again — resubscribing someone who opted out is how a business ends up messaging people who told it to stop, which in the US carries statutory penalties per message. The original opt-out stays in the record permanently either way.
Can we contact them? (unsubscribe.check)
[READ] Check whether one email address or phone number is unsubscribed, before sending to it. Returns which kinds of message are still allowed and which are blocked. Cheap, read-only, and worth calling before any one-to-one outreach.
Proof of consent (unsubscribe.consent_proof)
[READ] The consent trail for one phone number or email address: every time it was opted in or out, how, and — for a tick-box on a web form — the exact wording that was displayed, the page it was on, the IP address and the timestamp. This is the evidence a mobile carrier, a complainant, or a TCPA claim asks for, and the reason to keep it in one place rather than in a form submission nobody can find. Read-only.

Actions — concepts

2 operations.

Browse the glossary (concepts.list)
[READ] List every Chirply concept the product explains in plain language — accounts and client accounts (client accounts), contacts, companies, lists, smart segments, tags, custom fields, lifecycle stages, unsubscribes, deals, campaigns and workflows — each with the one-line summary shown in the app. Read-only, costs nothing, and returns the same wording the user sees on screen.
Explain a concept (concepts.explain)
[READ] Explain one Chirply concept in full: what it is, why a business would use it, how the rest of the product uses it, a worked example, and — most usefully — what it is NOT, so a list is not confused with a smart segment or a company with a client account. Accepts the user's own words ('smart segments', 'dynamic list', 'what's a tag'). Read-only and free.

Actions — connections

9 operations.

Connect Stripe (your own) (connections.submit_stripe_credentials)
[HIGH RISK · ADMIN ONLY] Complete a pending Stripe key-entry link in this account. Verifies the live secret key with Stripe, encrypts it, registers the account and closes the link atomically. May register a payment-events webhook for CRM sync. The first Stripe account becomes the fallback seller; existing sellers are preserved. Does not charge anyone, send messages, or move money.
Submit client API credentials (connections.submit_api_credentials)
[HIGH RISK · ADMIN ONLY] Complete a pending custom API connection request in this account. Stores the supplied credential encrypted and closes the link atomically. Does not call the external API or publish an agent tool; the connection becomes available for account tools to use.
Get setup instructions (connections.prepare_webhook_setup)
[HIGH RISK · ADMIN ONLY] Prepare the private BookFunnel webhook URL for a pending client connection link. Creates or reuses the account's webhook connection; no subscribers are imported or messages sent by this action. The returned URL is a credential and must only be shared with the intended account owner.
List connection link domains (connections.list_domains)
[READ · ADMIN ONLY] List the active, verified web domains this account can use for client connection links, including its parent agency's domains. Read-only; no DNS changes are made.
List connectable providers (connections.providers)
[READ · ADMIN ONLY] List supported client connection targets and their availability. Each entry includes available and reason: platform setup or approval must be complete before creating a link. Mode oauth uses the provider's consent screen, form collects a key, and setup gives guided instructions. Use the returned target when creating a link. Read-only; no accounts are connected.
Links you've sent (connections.list_links)
[READ · ADMIN ONLY] List this account's client connection links, newest first, with whether each one is still waiting, already connected, expired or cancelled. The link URL itself is NOT included — fetch a single link with connections.get_link to get it.
Open a connection link (connections.get_link)
[READ · ADMIN ONLY] Fetch one client connection link by id, INCLUDING the URL to send. Anyone holding that URL can connect an account into this account until it is used, expires, or is cancelled — treat it as a credential and send it only to the intended person.
Create link (connections.create_link)
[HIGH RISK · ADMIN ONLY] Create a named link that lets someone OUTSIDE this account — a client, a business owner — connect their own provider account into it. Returns a URL. Anyone who holds that URL can attach an account to this account until it is used once, expires, or is cancelled, so send it only to the person it is meant for. No message is sent by this action; delivering the link is up to you.
Cancel link (connections.revoke_link)
[HIGH RISK · ADMIN ONLY] Cancel a connection link that hasn't been used. It stops working immediately, including for someone part-way through the provider's login screen. This cannot be undone — issue a new link instead. Any connection the link ALREADY produced keeps working; disconnecting that is a separate action on the integration itself.

Actions — contacts

66 operations.

Load contact action options (contacts.bulk_options)
[READ] Read the account's available bulk contact actions, message templates, sending addresses, sender pool capacity, and automation options. Does not send messages, enroll contacts, or spend money.
Block contact (contacts.set_blocked)
Block or unblock a contact. Blocked contacts and their communications are hidden from normal CRM and inbox views; no data is deleted and unblocking restores visibility.
List contacts (contacts.list)
[READ] List the organization's contacts, newest first unless you pass `sort`. Filter by one or many static lists, tags, lifecycle stages, companies, owners, and lead sources; values inside one field are ORed while different fields stack with AND. You can also filter customer status and search names, business name, email and phone. Each contact carries its source and customer designation. Set `include_revenue` to also get each contact's lifetime value. Sort by any list column with `sort` + `direction` — `sort: "ltv"` ranks the whole organization by money received, highest first, so the first page is its most valuable contacts.
Open a contact (contacts.get)
[READ] Fetch one contact by id, with every field, assigned tags, phone numbers, and a Facebook profile URL when a valid ID or username is saved. Read-only; sends no messages and spends no money.
List phone numbers (contacts.list_phone_numbers)
[READ] List every phone number saved for one contact, including whether each is mobile, landline or VoIP and which one is primary. Read-only; the primary number is the one existing calling, SMS and merge-token flows use.
Add phone number (contacts.add_phone_number)
Add a phone number to a contact. It becomes primary automatically when it is the contact's first number; pass primary=true to make it the number used by existing calls, texts and merge tokens. This saves CRM data but sends nothing and costs nothing.
Edit phone number (contacts.update_phone_number)
Change a contact phone number and/or classify it as mobile, landline or VoIP. If this row is primary, changing the number immediately changes the destination used by calls, SMS and merge tokens. Nothing is sent and there is no charge.
Make primary (contacts.set_primary_phone)
Make one of a contact's saved phone numbers primary. Existing calling, SMS, automations and merge tokens immediately use this number instead. This changes routing data but sends nothing and costs nothing.
Remove phone number (contacts.delete_phone_number)
[HIGH RISK] Permanently remove one phone number from a contact. If it is primary, the oldest remaining number is promoted automatically; if none remain, calling and SMS flows can no longer reach this contact. This cannot be undone and sends nothing.
List contact email addresses (contacts.list_email_addresses)
[READ] List every email address saved for one contact, including its optional label and which one is primary. Read-only; the primary address is the one campaigns, automations, merge tokens and one-off sends all use.
Add contact email address (contacts.add_email_address)
Add an email address to a contact. It becomes primary automatically when it is the contact's first address; pass primary=true to make it the address campaigns, automations and merge tokens send to. Saves CRM data only — it sends nothing and costs nothing. Refused if the address already belongs to a different contact in this account, since one address identifies one person.
Edit contact email address (contacts.update_email_address)
Change a saved email address and/or its label. If this row is primary, changing the address immediately changes where campaigns, automations and one-off emails are delivered. Nothing is sent and there is no charge.
Make contact email primary (contacts.set_primary_email)
Make one of a contact's saved addresses primary. Campaigns, automations, merge tokens and one-off emails immediately go to this address instead; the previous primary is kept as a secondary address. This changes routing data but sends nothing and costs nothing.
Remove contact email address (contacts.delete_email_address)
[HIGH RISK] Permanently remove one email address from a contact. If it is primary, the oldest remaining address is promoted automatically; if none remain, email can no longer reach this contact at all. This cannot be undone and sends nothing.
List connected profiles (contacts.list_linked_profiles)
[READ] List the Facebook Messenger and Instagram profiles that resolve to one contact, with the Page each belongs to. Read-only. A contact can hold several: the same person has a different Page-scoped id on every Page they message, and another one on Instagram.
Unlink profile (contacts.unlink_profile)
[HIGH RISK] Detach one Messenger or Instagram profile from a contact. The existing conversation is kept, but the next message from that profile arrives as a NEW contact instead of landing on this one — so this is how you undo a merge that joined up two people who were not the same person. It cannot be undone directly; re-linking means merging the new contact back in.
Contact automations (contacts.list_automations)
[READ] List every automation a contact has entered, newest automation first. Returns the latest run status, the human-readable current step, when a waiting run resumes, any error, and the total number of times the contact entered each automation. Reads only; it does not start or change a run.
Contact broadcasts (contacts.list_broadcasts)
[READ] List the email, SMS, ringless voicemail and voice broadcasts sent or attempted for one contact, including campaign name, channel, delivery status, time and any error. Read-only; it sends nothing and costs nothing.
Lead sources (contacts.list_sources)
[READ] Break this organization's contacts down by where they came from — the channel each lead arrived through, with a count, commonest first. Only sources that actually occur are returned, so an empty result means the org has no contacts. Use the returned `source` values to filter contacts.list. Reads nothing outside this org and changes nothing.
Columns (contacts.get_column_layout)
[READ] Read which columns you see on the contacts list and in what order, plus every column this organization could show (built-ins and its custom fields). Personal to you — it does not affect what teammates see. Returns the defaults when you have never changed them.
Save columns (contacts.set_column_layout)
Choose which columns you see on the contacts list and in what order — the array order IS the left-to-right order, and any column you leave out is hidden. Personal to you; teammates' lists are unaffected. Unknown keys are dropped and 'name' is always kept (it is the link into each record), so the list can never be left unusable. Call contacts.get_column_layout for the valid keys.
Reset columns (contacts.reset_column_layout)
Forget your saved column choices for the contacts list so it goes back to the default columns (name, contact details, source, company, tags, owner, lifecycle, customer status, lifetime value, and first-added date). Personal to you, and affects only which columns are displayed — no contact data is changed or deleted.
Find a contact by Facebook ID (contacts.find_by_facebook_id)
[READ] Look up the org's contact by the stable Facebook person/friend id supplied by Friender or another integration. Returns null when no contact holds that id.
Find a contact by phone number (contacts.find_by_phone)
[READ] Look up the org's contact at a phone number, matched on any spelling of it ('4098930064', '+14098930064' and '(409) 893-0064' are the same person). Returns null when nobody holds that number. Use this before creating a contact from a call or a text.
Create a contact (contacts.create)
[HIGH RISK] Create a contact. Requires at least a name, business name, or email. Email addresses and normalized phone numbers are unique within the organization: if another contact already holds either identity, this fails with a conflict naming that contact rather than creating a duplicate — update that one instead. SECOND-ORDER EFFECT: a successful create fires the org's 'Contact created' automations, so a 'welcome every new lead' workflow can send this person a real email or SMS on the org's own Mailgun/Twilio account, at the org's own cost, with no further step.
Validate now (contacts.validate_email)
[HIGH RISK] Immediately validate this contact's current email address through the account's configured Mailgun or NeverBounce account. This makes a real provider request that may consume a paid validation credit, then stores the result beside the contact's email. It does not send email or change the address.
Edit a contact (contacts.update)
Update fields on an existing contact. Omitted fields are left alone; an explicit null clears one. Moving an email address or phone number onto this contact fails with a conflict when it is already someone else's in this organization.
Delete a contact (contacts.delete)
[HIGH RISK] Permanently delete a contact and everything that cascades off them — tags, notes and the whole activity timeline. This cannot be undone.
Delete selected contacts (contacts.bulk_delete)
[HIGH RISK] Permanently delete every listed contact, along with their tags, notes and activity timelines. This cannot be undone.
Set lifecycle stage (contacts.set_lifecycle)
[HIGH RISK] Move every listed contact to a lifecycle stage (lead, trial, active, customer, churned). The stage change itself is reversible — set it back to change your mind — but its SECOND-ORDER EFFECT is not: a database trigger enqueues a 'Lifecycle changed' automation event for EVERY contact in the list, so moving 200 contacts can start 200 automation runs that send real email and SMS to real people, billed to the org's own Mailgun/Twilio account. Setting the stage back does not unsend those.
Hide from Activity Log (contacts.set_feed_visibility)
Mute or unmute contacts in the dashboard's org-wide Activity Log — the same switch on a contact's Activity tab. Hidden contacts' events (calls, texts, website visits, and the rest) stop appearing in that shared feed for everyone, while their own timeline and every other screen are untouched. Deal stage changes are the one exception: they stay in the feed whoever the deal belongs to, because the pipeline's audit trail is not something a mute is allowed to erase. Fully reversible; set `hidden` false to show them again.
Mark as customer (contacts.mark_customer)
Mark every listed contact as a customer, or clear it. `is_customer` is a durable fact meaning they have bought from us — it is SEPARATE from the lifecycle stage (a churned contact can still be a customer) and it survives churn. Marking sets `customer_since` to now and records the source as 'manual'; already-marked contacts are left untouched. Clearing removes the flag and its date. Reversible, changes nothing outside the CRM. Note the Stripe sync also marks customers automatically when a real purchase is seen, and a later sync will re-mark anyone you clear if it still finds a paid charge or active subscription for them.
Import contacts (contacts.import)
[HIGH RISK] Bulk-create contacts from a list of records — the machine intake path (CSV/lead imports). Unlike contacts.create, a row whose email or phone already matches an existing contact does NOT error and does NOT duplicate: it is reported as matched. First added is replaced on matches only when created_at_overwrite is explicitly supplied. New contacts enqueue Contact created automation events. Applying tags or joining lists can also trigger active automations that send real email or SMS at the account's provider cost. Review active automations before importing.
Import contacts from a file (contacts.import_csv)
[HIGH RISK] Queue a durable background contact import from raw CSV text — the same job the Contacts screen starts. Returns immediately with a job id; the import continues if the caller disconnects and progress is available through contacts.list_import_jobs. The first row must be headers; obvious contact columns are matched automatically and explicit mapping can override them. A full_name column is split at the first word into first_name and the remaining last_name. Street, city, state, and postal-code columns populate the structured contact address. Existing contacts are matched by email or phone. Map created_at for original First added on new contacts, or created_at_overwrite to replace this date on matches too; other existing fields stay unchanged. New contacts enqueue Contact created automation events. Applying tags or joining lists can also trigger active automations that send real email or SMS at the account's provider cost. Review active automations before importing. The job continues after the caller disconnects.
View contact imports (contacts.list_import_jobs)
[READ] List recent CSV contact-import jobs for this account, including queued/running/completed/failed state, rows processed, contacts created, existing contacts matched, skipped rows, and any terminal error. Read-only and safe to poll.
List duplicate phone numbers (contacts.list_duplicates)
[READ] DEPRECATED — the Duplicates tab it was built for no longer exists, and neither does the problem: the `contacts_absorb_duplicate` trigger folds a duplicate into the surviving contact the moment it is written, so this always returns empty in practice. Kept only so a machine can verify that. It lists contacts in this org that share a phone number, grouped, oldest first inside each group; read-only. A non-empty result means two contacts were created on the same number simultaneously, neither insert able to see the other — run contacts.merge_duplicates to repair that one case.
Merge duplicate contacts (contacts.merge_duplicates)
[HIGH RISK] DEPRECATED — the Duplicates tab it was built for no longer exists, and the database now does this on its own: `contacts_absorb_duplicate` merges a duplicate as it is written, so there is normally nothing for this to do. Kept as the repair for the one case the trigger cannot see: two simultaneous inserts of the same new number, neither transaction able to see the other's row. It permanently collapses every set of contacts in this org that share a phone number down to one. The newest record of each set survives and absorbs the others — their calls, messages, tasks, invoices, notes, tags and list memberships all move onto it, and any field it was missing is filled in from the older record. The older rows are then DELETED and their contact ids stop resolving. This cannot be undone.
Merge into one contact (contacts.merge)
[HIGH RISK] Fold two or more contacts into one, for when the same person exists more than once — they messaged two of your Facebook Pages (a different Page-scoped id each time), replied on Instagram, bought under a work email and were imported under a personal one. Everything moves onto the contact you keep: every phone number and email address (kept as secondary rather than discarded), every Messenger and Instagram profile, tags, list memberships, conversations, calls, notes, deals, invoices and automation history. The kept contact fills any blank field from the others, takes the earliest first-seen date and the source that came with it, joins their notes, and stays a customer if any of them was one. The other contacts are then PERMANENTLY DELETED and their contact ids stop resolving — links and integrations pointing at them will 404. This cannot be undone. Nothing is sent and there is no charge.
List tags (contacts.list_tags)
[READ] List the org's contact tags, with the colour each one renders in.
Create a tag (contacts.create_tag)
Create a contact tag. Tag names are unique per organization — creating one that already exists fails.
Rename a tag (contacts.update_tag)
Rename a tag or change its colour. Every contact carrying it is updated at once.
Delete a tag (contacts.delete_tag)
[HIGH RISK] Permanently delete a tag and strip it from every contact that carries it. This cannot be undone; the contacts themselves are kept.
Tag contacts (contacts.add_tags)
[HIGH RISK] Add one or more existing tags to one or more contacts. Idempotent — a tag a contact already has is left alone, and fires nothing. SECOND-ORDER EFFECT: every tag that is genuinely new on a contact enqueues a 'Tag added' automation event, so tagging 200 contacts can start 200 automation runs that send real email and SMS to real people, billed to the org's own Mailgun/Twilio account. Removing the tag afterwards does not unsend them. 'Tag added' is the single most common automation trigger in this product, so assume something is listening.
Untag contacts (contacts.remove_tags)
[HIGH RISK] Remove one or more tags from one or more contacts. The tags themselves are kept — use contacts.delete_tag to remove a tag entirely. SECOND-ORDER EFFECT: each removal enqueues a 'Tag removed' automation event, which can start workflows that message real people on the org's own Mailgun/Twilio account, and untagging can also drop contacts out of tag-based audiences and stop campaigns aimed at them.
List custom fields (contacts.list_fields)
[READ] List the org's custom-field definitions — the keys, labels and types that the `custom` blob on contacts, companies and deals is made of.
Create a custom field (contacts.create_field)
Define a new custom field on contacts, companies or deals. The storage key is derived from the label and is unique per record type — a second field with the same derived key fails.
Create custom fields for unmapped columns (contacts.create_fields)
Create several contact custom fields in one operation, primarily for CSV headers that have nowhere to map. Existing contact fields with the same derived key are returned instead of duplicated; no contact values are changed.
Edit a custom field (contacts.update_field)
Change a custom field's label, type, choices or required flag. The storage key never changes, so values already recorded stay attached.
Delete a custom field (contacts.delete_field)
[HIGH RISK] Permanently delete a custom-field definition. The app stops showing and collecting it; values already stored in each record's `custom` blob become unreachable. This cannot be undone.
Add a note (contacts.add_note)
Add a free-text note to a contact's, company's or deal's activity timeline. Attach it to at least one of them.
Open the activity timeline (contacts.list_activity)
[READ] Read the activity timeline — notes, calls, texts, emails, tasks, automation steps, website visits and pipeline stage changes, newest first. Name a contact, company or deal for that record's timeline, or omit all three for the WHOLE account's activity feed (the same stream the dashboard's Activity Log widget shows). Read-only.
Text contacts (contacts.send_sms)
[HIGH RISK] SEND A REAL TEXT MESSAGE to each listed contact from one of the org's active Twilio numbers. Costs money per message and reaches real people immediately; there is no undo. `{{token}}` merge fields are rendered per contact and each text lands in that contact's own conversation. Contacts with no phone number are skipped.
Email contacts (contacts.send_email)
[HIGH RISK] SEND A REAL EMAIL to each listed contact through the org's own Mailgun account. Reaches real inboxes immediately and cannot be recalled. Subject and body both render `{{token}}` merge fields per contact, and each email lands in that contact's own conversation. Contacts with no email address are skipped.
Add contacts to automation (contacts.enroll_in_automation)
[HIGH RISK] Start a durable automation run for each listed contact. The first step begins immediately, waits resume later, and later steps may send real texts, emails, voicemails, calls, or API requests at the org's expense. Paused automations may be started manually; pausing only prevents event-triggered enrollment.
Email many contacts at once (contacts.bulk_email)
[HIGH RISK] Immediately queues a personalized email to every listed contact that has an email address, each into their own conversation thread — real email, sent through this account's own connected provider (Mailgun/Resend) and billed to it. Subject and body support {{merge_fields}} and are rendered per contact. Send from one address, or from an email POOL to rotate across several. The send runs as a background job so it can be paced, watched, paused or stopped; pass start_at to schedule it for later instead of sending now. Through a pool, the members' warmup allowance is a HARD ceiling on today's volume whatever pace is requested — the job sends what the ramp permits and resumes after midnight UTC, so a large list cannot burn a set of new mailboxes on day one. Contacts without an email address are skipped, not failed.
Text many contacts at once (contacts.bulk_sms)
[HIGH RISK] Immediately queues a personalized SMS to every listed contact that has a phone number, each into their own conversation thread — real texts, sent and billed through its own Twilio account. The body supports {{merge_fields}} and is rendered per contact. The send runs as a background job so it can be paced, watched, paused or stopped; pass start_at to schedule it for later instead of sending now. Contacts without a phone number are skipped, not failed.
Run actions on contacts (contacts.run_actions)
[HIGH RISK] Run a list of shared-registry actions against each listed contact — the same actions the contacts bulk bar and a single contact's 'Reach out' panel offer. Actions can text, email, drop a ringless voicemail, place an outbound IVR, AI-agent or sales-bridge call, enroll in a campaign, send an invoice, move a deal, create a task, call a webhook, or delete the contact — so this can spend money, reach real people, and destroy data depending on what you pass. Runs immediately by default; pass start_at to schedule it for later, or a per_minute/per_hour/per_day cap to pace it — either turns the run into a background job you watch with bulk_jobs.get.
Detect line type (contacts.lookup_line_type)
[HIGH RISK] Queue a Twilio Lookup for each listed contact's phone number to learn whether it is mobile, landline or VoIP. Twilio BILLS the org per number looked up. Results land asynchronously in the shared line-type cache, so numbers already known cost nothing and are not re-queued. Returns how many NEW paid lookups were queued.
Summarize a contact (contacts.summarize)
[HIGH RISK] Generate a short situational summary plus two or three next-best actions for a contact, grounded in their profile, deals and recent activity. It changes no data, but it SPENDS MONEY: the request is billed to the account's own OpenRouter key, which must be connected. Same standard as contacts.validate_email, which is gated for a paid validation credit.
Draft a follow-up (contacts.draft_follow_up)
[HIGH RISK] Draft a ready-to-send follow-up message body for a contact, grounded in their history. Returns the text only — it does NOT send anything; pass it to contacts.send_sms or contacts.send_email to actually reach them. It SPENDS MONEY: the request is billed to the account's own OpenRouter key.
Get AI context (contacts.ai_context)
[READ] Assemble everything this account knows about one contact into a single AI-ready bundle for generating a page, email, or reply personalized to this exact person: their profile and custom fields, tags, open deals and tasks, recent messages, their website behavior (first-touch source, page-view totals, recent pages viewed), and their call history INCLUDING past-call transcripts and AI-call summaries. Also returns `prompt` — a ready-to-paste plain-text briefing, the same caller file the AI phone agent uses — so a server can drop it straight into a model prompt. Read-only and spends NO AI credit (it only reads stored data). The response is SENSITIVE: it contains call transcripts and private notes, so treat it exactly like the contact record itself and never expose it to an unauthenticated browser. A `context_token` can also name a contact owned by a DIFFERENT account — an affiliate who sent their own contact to this account's page — and that only resolves while the owning account has contact-context sharing switched on for this one; revoking it takes effect on the next call.
List lifecycle stages (contacts.list_lifecycles)
[READ] List the lifecycle stages this organization can assign to contacts, in display order. Keys are stable values used by filters and automations; labels are the editable wording people see.
Create lifecycle stage (contacts.create_lifecycle)
[ADMIN ONLY] Add a lifecycle stage this organization can assign to contacts. This changes CRM configuration only and does not move any contacts.
Rename lifecycle stage (contacts.rename_lifecycle)
[ADMIN ONLY] Change the visible name of a lifecycle stage while preserving its stable key, existing contact assignments, filters, and automations.
Delete lifecycle stage (contacts.delete_lifecycle)
[HIGH RISK · ADMIN ONLY] Permanently remove a custom lifecycle stage, but only when no contacts still use it. System stages cannot be removed. This cannot be undone.
Set contact sender defaults (contacts.set_sender_defaults)
Choose the account email identity and Twilio phone number normally used when contacting one CRM contact. Either value can be cleared to resume account defaults; sends nothing.

Actions — conversations

28 operations.

List conversations (conversations.list)
[READ] List the inbox's conversation threads, most recent activity first. Filter by the inbox's own tabs (unread, needs reply, starred), by channel, Facebook Page or linked Meta asset, status, the direction of the newest message, assigned teammate, whether nobody owns it yet, or contact, and search subjects and last-message previews. Each thread reports whether it is unread, which way the last message went, and when it was starred. This only reads conversations — it sends nothing and does NOT mark anything read.
Open a conversation (conversations.get)
[READ] Open one thread and read its history. Returns the conversation, the contact, and — exactly like the inbox — EVERY message exchanged with that contact across all channels and threads plus their calls, merged chronologically oldest to newest, not just this thread's own messages. By default it returns as much of that history as one answer can hold: the newest 700 timeline items, messages and calls counted together. A long-lived contact can exceed that, so the result always reports `has_older` and, when there is more, a `next_before` cursor: pass it back as `before` to read the page immediately older than the one you just got, and keep going until `has_older` is false. Every page is one unbroken run of history, so following the cursor to the end reads the whole thread with nothing skipped and nothing repeated. `limit` returns only the newest N items instead — the same tail-first window the inbox itself opens on. Read-only; nothing is sent, marked read, or changed.
Open latest messages (conversations.latest)
[READ] Open one inbox thread for a fast mobile view. Returns the conversation and only its newest messages, newest first, so a phone can start at the latest reply without downloading the contact's complete cross-channel history. Read-only.
Resync messages (conversations.sync_meta)
Check Facebook or Instagram for messages missing from one existing inbox thread and import up to the latest 500. This repairs missed webhooks, including replies written directly in Facebook or Instagram. It does not send anything or alter provider data.
Recent Communication (conversations.recent)
[READ] DEPRECATED — use `communications.list`, which this now calls and which adds direction/type filters, paging and the archive. Returns the newest entries of the communication log (calls, texts and emails merged, newest first) — the same rows the dashboard's Recent Communication column shows. Read-only.
Start a conversation (conversations.start)
[HIGH RISK] Open a new SMS or email thread with a contact. If `body` is supplied it is SENT IMMEDIATELY as the first message — a real text or email leaves the org's own Twilio, Mailgun, or Resend account, reaches the recipient, and bills the tenant. Leave `body` empty to open an empty thread without sending anything. Merge tokens like {{first_name}} are rendered against the contact.
Assign a conversation (conversations.assign)
Assign a thread to a teammate, or pass assigned_to = null to leave it unassigned. The user must be a member of this organization.
Set conversation status (conversations.set_status)
Move a thread between open, snoozed, and closed — the Status section of the inbox's Manage menu. Use it to close a resolved thread or reopen a closed one; nothing is deleted either way.
Count the inbox (conversations.inbox_counts)
[READ] Count how much is waiting in the inbox right now: threads nobody has read, threads whose last message came from the contact and so are waiting on a reply, and threads a teammate starred. These are the three numbers on the Conversations tabs. Read-only — it changes nothing and marks nothing read.
Mark read (conversations.mark_read)
Clear the unread badge on one or more conversations, exactly as opening them in the inbox does. Read state is shared across the whole account — a team inbox, not a personal one — so this clears the badge for every teammate, not just the caller. Nothing is sent and no message is changed.
Mark unread (conversations.mark_unread)
Put conversations back in the unread pile so they badge again — the inbox's Mark unread button, for a thread you looked at but did not deal with. Shared across the account, so every teammate sees it return. A thread nobody has ever written into has nothing to be unread about and is left alone. Nothing is sent.
Star this conversation (conversations.star)
Star or unstar conversations so they collect on the inbox's Starred tab — the account's own shortlist of threads worth coming back to. Visible to everyone in the account. Nothing is sent and the thread is not otherwise changed.
Mark all read (conversations.mark_all_read)
[HIGH RISK] Clear EVERY unread conversation in the account at once — the inbox's Mark all read button. This is not undoable: which threads were unread is not recorded anywhere afterwards, so anything nobody had got to yet stops badging for the whole team. Use it for a deliberate inbox-zero, not as a way to tidy up before reading. Nothing is sent and no message is deleted.
Take over automation (conversations.take_over)
[HIGH RISK] Pause every automated responder on this conversation so a real teammate can handle it without the bot speaking over them. Active conversation workflow runs are canceled; no customer message is sent.
Resume automation (conversations.resume_automation)
[HIGH RISK] Release a human takeover and allow future automated replies and conversation workflows in this thread again. This does not restart canceled runs, but later inbound messages can trigger real outbound messages.
Delete conversation (conversations.delete)
[HIGH RISK] Permanently delete one conversation thread and every message in that thread. The CRM contact and their call history are kept. This cannot be undone.
Summarize a thread (conversations.summarize)
[READ] Summarize a conversation into a few bullets — what the customer wants, the key facts, and the next step. Grounded only in that thread's own messages. Runs on the org's own OpenRouter connection and fails with a plain message when AI isn't connected. Reads only; nothing is sent or saved.
List messages (messages.list)
[READ] List individual SMS and email messages, newest first. Narrow to one conversation or contact, or filter by channel, direction, or delivery status to find what failed. Use conversations.get instead to read a thread in order.
Send a reply (messages.send)
[HIGH RISK] SENDS A REAL MESSAGE. For email, supply reply_to_message_id to reply to a specific email with threading headers, or email_mode=new plus subject for an independent email. Replies on an existing SMS, email, Facebook Messenger, Instagram DM, or WhatsApp thread. SMS/email use the org's own billable Twilio, Mailgun, or Resend account; Meta replies use the connected Page or WhatsApp Business number and are limited to Meta's 24-hour messaging window. It reaches an actual person with no draft or undo. Merge tokens like {{first_name}} are rendered against the contact before sending. Files from the account media library can be attached — note that attaching one to an SMS makes it an MMS, which the org's carrier bills at a higher rate than a text.
Send it again (messages.resend)
[HIGH RISK] SENDS A REAL MESSAGE. Takes one outbound SMS or email that failed and sends the same text to the same recipient again, through the account's own billable Twilio, Mailgun or Resend account. It reaches an actual person with no draft or undo, and it is billed again — the original attempt may already have been charged for. This is the honest way to confirm a settings fix worked: after a country is switched on in Twilio's console, a text that came back 21408 either goes through now or comes back with the same refusal. Only outbound messages that actually failed can be resent, so a delivered message cannot be duplicated through this.
Send approved template (messages.send_whatsapp_template)
[HIGH RISK] SENDS A REAL WHATSAPP MESSAGE. Sends a live Meta-approved template on an existing customer-initiated WhatsApp thread, including after the 24-hour reply window. The connected account is billed by Meta; delivery reaches a real person immediately with no draft or undo. Chirply re-checks the exact template language and current APPROVED status, the account phone DNC and WhatsApp opt-out lists, and durable WhatsApp consent plus the recipient's valid stored timezone and local messaging hours for marketing templates before every send.
Draft, improve, or retone a reply (messages.assist_reply)
[READ] The composer's AI buttons. mode='draft' writes the next reply from the thread so far, 'improve' polishes the draft you pass in, and 'tone' rewrites it in the requested tone. Returns TEXT ONLY — nothing is sent; pass the result to messages.send when the human approves it. Runs on the org's own OpenRouter connection.
List autoresponders (conversations.list_autoresponders)
[READ] List the org's named, phone-attachable autoresponders and the number of keyword/default cases inside each one.
Open an autoresponder (conversations.get_autoresponder)
[READ] Fetch one named autoresponder with its ordered keyword cases, default fallback, replies, direct actions, and attached automations.
Create an autoresponder (conversations.create_autoresponder)
[HIGH RISK] Create a named autoresponder containing ordered keyword/default cases. Once active and attached to a number, matching cases can SEND REAL MESSAGES, modify CRM data, and PLACE BILLABLE CALLS such as sales bridges with no human in the loop. Create it inactive to stage it safely.
Edit an autoresponder (conversations.update_autoresponder)
[HIGH RISK] Replace or update a named autoresponder's ordered cases. Changes take effect on the next inbound message; active cases may immediately send real messages, change CRM data, or place billable calls.
Activate or pause an autoresponder (conversations.toggle_autoresponder)
[HIGH RISK] Flip an auto-reply rule's Active checkbox. Activating it arms real automatic sends on the next matching inbound message; pausing it stops them without deleting the rule.
Delete an autoresponder (conversations.delete_autoresponder)
[HIGH RISK] Permanently delete an auto-reply rule and all of its keyword cases, replies and actions. Inbound messages on any phone number it was attached to stop getting an automatic reply immediately. Messages already sent are unaffected, but the rule itself cannot be recovered — pause it with conversations.toggle_autoresponder instead if you may want it back.

Actions — copywriting

10 operations.

Browse frameworks (copywriting.list_frameworks)
[READ] List the 45 built-in email copywriting frameworks — AIDA, PAS, Soap Opera Sequence, SPIN Selling and the rest — each with the reader awareness it assumes, the psychological levers it pulls, and how many emails its own arc runs to. Read-only and free; nothing is generated or sent.
Open a framework (copywriting.get_framework)
[READ] Read one copywriting framework in full — its origin, the psychology it relies on, its step-by-step arc, strategic notes, the mistakes it warns against, the objections it pre-handles, a worked example email, and its campaign breakdown (the email-by-email brief used to generate a sequence). Read-only and free.
Suggest a framework (copywriting.suggest_framework)
[READ] Rank the frameworks that fit a particular audience and goal, with the reason for each. Say where the audience stands with the business (cold, engaged, customer, gone quiet) and what the email is for, and this matches that against the reader-awareness stage each framework was built for. Read-only and free — it picks nothing and writes nothing.
View brand voice (copywriting.get_brand_voice)
[READ] Read the account's writing rules — audience, what it sells, tone, reading level, whether it speaks as 'I' or 'we', sign-off, banned words, emoji policy and any pasted writing sample. These shape every AI-generated email, subject line and sequence. Read-only.
Save brand voice (copywriting.set_brand_voice)
[ADMIN ONLY] Replace the account's writing rules. Every field is overwritten with what you pass, so send the whole voice, not just the parts you are changing. This changes how all future AI-generated copy sounds; it does not rewrite anything already written, and sends no email.
Write an email (copywriting.write_email)
[READ] Write one complete email — subject line, preheader and body blocks — following a chosen copywriting framework, in the account's brand voice, grounded in the facts stored in its AI Brain. Returns a draft for review: nothing is saved to a campaign and nothing is sent. Runs on its own OpenRouter account and bills it for the tokens used.
Write a sequence (copywriting.write_series)
[READ] Write a complete multi-email sequence from a framework's own campaign breakdown — each email written to its role in the arc ('Episode 2 - High Drama'), with a sending delay chosen to suit the framework's pacing. Returns drafts for review: no automation is created, nothing is scheduled and nothing is sent. Pass the result to copywriting.build_series_workflow to turn it into a real automation. Runs on its own OpenRouter account and bills it for the tokens used; a long sequence is a large generation.
Grade an email (copywriting.grade_email)
[READ] Score an existing email against a copywriting framework, step by step: what the draft does at each stage of the arc, the specific fix for each, a subject-line score with three stronger alternatives, and which of the framework's known mistakes the draft is making. Read-only — it changes nothing and sends nothing. Runs on its own OpenRouter account and bills it for the tokens used.
Rewrite an email (copywriting.rewrite_email)
[READ] Rewrite an existing email so it follows a chosen framework, keeping every fact, offer, price and link from the original and changing only the structure and language. Returns a draft for review: the original is untouched, nothing is saved and nothing is sent. Runs on its own OpenRouter account and bills it for the tokens used.
Build the sequence (copywriting.build_series_workflow)
[HIGH RISK] Turn a generated sequence into a real automation: one 'send email' step per email with a genuine wait between them, saved onto an existing workflow's flow graph so it can be edited in the visual builder. DESTRUCTIVE — it replaces that workflow's entire flow, so use an empty or throwaway workflow unless you mean to overwrite. The automation is left PAUSED with a manual start trigger: no contact is enrolled and no email is sent until someone chooses a trigger and turns it on.

Actions — courses

21 operations.

List courses (courses.list_courses)
[READ] List the account's courses in display order, with status (draft/published/archived), which group's classroom each is mounted in, access rules, and gamification settings. Optionally filter by status or by the funnel a course is mounted on.
Open a course (courses.get_course)
[READ] Fetch one course with its full outline — every module and lesson in order, including drafts and each lesson's quiz — the builder's view, not the member's.
Create a course (courses.create_course)
[ADMIN ONLY] Create a new course as a DRAFT (members can't see it until you publish). Optionally mount it in a group's classroom right away. The URL slug is generated from the title.
Edit course settings (courses.update_course)
[ADMIN ONLY] Update a course's settings: title, description, cover, which group's classroom it's mounted in (funnel_id; null unmounts it), access rules (level gate / required access product), the points members earn per lesson and on completion, and the completion certificate. Omitted fields are left alone. Changes affect what enrolled members see immediately.
Publish a course (courses.publish_course)
[HIGH RISK · ADMIN ONLY] Publish a course so members who qualify (mounted group + access rules) can see and take it. This is outward-facing: the moment it lands, everyone with access sees the course in their classroom, half-finished modules included — only published LESSONS are visible, and publishing the course does not publish its draft lessons.
Archive a course (courses.archive_course)
[ADMIN ONLY] Archive a course: members can no longer open it, but every enrollment, progress record, and certificate is kept. Re-publish it to bring it back. Use this instead of delete when people have taken the course.
Delete a course (courses.delete_course)
[HIGH RISK · ADMIN ONLY] Permanently delete a course AND everything under it: modules, lessons, quizzes, every member's enrollment and progress, and their issued certificates (public certificate links stop working). This cannot be undone — archive instead if anyone has taken it.
Add a module (courses.create_module)
[ADMIN ONLY] Add a module (section) to a course, appended at the end. Optionally drip it (unlock N days after each member's enrollment) or gate it behind a community level.
Edit a module (courses.update_module)
[ADMIN ONLY] Update a module's title, description, position, drip delay, or level gate. Omitted fields are left alone. Gate changes apply to enrolled members immediately.
Delete a module (courses.delete_module)
[HIGH RISK · ADMIN ONLY] Permanently delete a module AND every lesson in it, including members' completion records for those lessons. Members' overall course progress recalculates without them. Cannot be undone.
Add a lesson (courses.create_lesson)
[ADMIN ONLY] Add a lesson to a module, appended at the end. A lesson can carry an embedded video, rich HTML content, downloadable attachments, and an optional multiple-choice quiz (set quiz_required to make passing it the only way to complete the lesson). New lessons start as DRAFTS members can't see until you set status to 'published'.
Edit a lesson (courses.update_lesson)
[ADMIN ONLY] Update a lesson's content, video, attachments, quiz, position, duration, or status. Omitted fields are left alone; pass quiz null to remove the quiz. Publishing/unpublishing changes what counts toward every enrolled member's completion percentage.
Delete a lesson (courses.delete_lesson)
[HIGH RISK · ADMIN ONLY] Permanently delete a lesson, including every member's completion record and quiz attempts for it. Members' course progress recalculates without it. Cannot be undone.
Enroll a contact (courses.enroll_contact)
[HIGH RISK · ADMIN ONLY] Enroll a contact in a course. They see it in their classroom right away (once they can sign in), drip timers start counting from now, and the org's 'Enrolled in a course' automations fire — which can send that real person a real welcome email or SMS, billed to the org's own Mailgun/Twilio account, without any further step. Idempotent — enrolling someone already enrolled changes nothing and fires nothing.
Unenroll a contact (courses.unenroll_contact)
[HIGH RISK · ADMIN ONLY] Remove a contact from a course AND delete their progress — every completed-lesson record and quiz attempt for this course is destroyed and cannot be recovered (re-enrolling starts them from zero). An already-issued certificate is kept.
List enrollments (courses.list_enrollments)
[READ] List who is enrolled in a course, newest first, with each person's name, how they were enrolled, completion percentage, and whether (and when) they finished.
A contact's course progress (courses.get_contact_progress)
[READ] One contact's progress through one course: their enrollment (when, how, finished or not), the completion percentage, exactly which lessons they've completed, and their certificate serial if one was issued.
Mark a lesson complete (courses.complete_lesson)
[HIGH RISK · ADMIN ONLY] Mark a published lesson complete for a contact, exactly as if they finished it themselves: it awards the course's per-lesson community points, enrolls them if they weren't yet, and — when it's their last remaining lesson — completes the whole course, awards the completion bonus, ISSUES A REAL SERIAL-NUMBERED CERTIFICATE in that person's name (if enabled), and fires the 'Lesson completed' / 'Course completed' automations, which can email or text them for real on the org's own provider accounts. It falsifies a learning record on someone's behalf and there is no un-issue for a certificate, so it always asks first. If the lesson requires a passed quiz, this refuses unless skip_quiz_gate is set.
List certificates (courses.list_certificates)
[READ] List completion certificates this account has issued, newest first — each with its public serial (the verification token printed on the certificate), recipient, and course. Optionally filter by course or contact.
Look up a certificate (courses.get_certificate)
[READ] Verify a completion certificate by its serial (the public token printed on it). Returns the recipient, course, and issue date if the serial is genuine and belongs to this account.
Generate quiz with AI (courses.generate_quiz)
[HIGH RISK · ADMIN ONLY] Draft a 5-question multiple-choice quiz from a lesson's title and content using the account's own AI connection. This SPENDS MONEY: the request is billed to the org's own AI provider key (requires one under Settings → AI), so it is not a free read despite saving nothing. Returns the quiz for review — NOTHING is stored; persist it by passing the result to 'Update a lesson' as its quiz.

Actions — credits

1 operation.

My credits (credits.get_balance)
[READ] Your account's prepaid credit balance for usage that runs on your provider's pooled account (calls, texts, email, AI, leads). Shows your remaining balance, any monthly allowance, whether you're paused for running out, your per-item prices, and recent activity. Read-only.

Actions — custom_objects

8 operations.

Custom objects (custom_objects.list_types)
[READ] List this account's custom object types — the user-defined record types beyond contacts, companies and deals (e.g. Properties, Pets, Policies) — including each type's field definitions.
New object type (custom_objects.create_type)
[ADMIN ONLY] Create a custom object type — a new kind of record this account can store (e.g. "Property"). Takes the singular and plural names plus the typed fields records of this kind carry. The type immediately appears in the app's navigation and its records become creatable everywhere. Owners and admins only: a type is account SCHEMA, not a record — it changes the sidebar and the shape of everyone's data.
Edit object type (custom_objects.update_type)
[ADMIN ONLY] Rename a custom object type or change its icon, and optionally add new fields to it. Existing fields and records are untouched; the URL name (key) never changes. Owners and admins only, same as creating one.
List records (custom_objects.list_records)
[READ] List the records of one custom object type, most recently updated first. Optionally filter to the records linked to a specific contact, or text-search across each record's stored values.
Open a record (custom_objects.get_record)
[READ] Fetch one custom-object record by id, with all of its stored field values and the contact it's linked to.
New record (custom_objects.create_record)
[HIGH RISK] Create a custom-object record with validated field values and optional contact linkage. Queues custom_record_created for enabled workflows, which may send messages or incur provider charges according to their configured steps.
Edit a record (custom_objects.update_record)
[HIGH RISK] Update supplied fields or contact linkage on a custom record, validating its field definitions. Actual changes queue custom_record_updated for enabled workflows, which may send messages or incur provider charges according to their configured steps. Unchanged values do not emit events.
Delete a record (custom_objects.delete_record)
[HIGH RISK] Permanently delete one custom-object record and all of its stored values. This cannot be undone.

Actions — dashboard

9 operations.

List dashboard tabs (dashboard.tabs_list)
[READ] Read your personal custom dashboard tabs in this account. Each has an independent widget layout accessible with tab_id in dashboard.get_layout. Does not reveal teammates' tabs or change data.
Add dashboard tab (dashboard.tabs_create)
Create a personal empty dashboard tab in this account. Add widgets with dashboard.set_layout using its tab_id. Reuse id on retries. Changes only your saved view; sends no messages and spends no money.
Rename dashboard tab (dashboard.tabs_rename)
Rename one of your personal custom dashboard tabs. Preserves its widgets and affects no teammate's view. Sends no messages and spends no money.
Delete dashboard tab (dashboard.tabs_delete)
[HIGH RISK] Permanently delete your custom dashboard tab and its saved widget arrangement. The underlying contacts, ads and activity remain intact. Built-in tabs and teammates' views are unaffected. No messages are sent and no money is spent.
Read Active Ads (dashboard.active_ads)
[READ · ADMIN ONLY] Read which ads are ACTUALLY RUNNING across connected Meta and Google advertiser accounts, including ads created outside Chirply. Every ad carries a `delivery` verdict: `running` is true only when the campaign, the ad set and the ad itself are all switched on, the ad set's schedule is open, and the ad account can spend — and `label`/`detail` say which of those is blocking it when it is not. A separate `delivering` flag is true only when the advertiser actually reported impressions for that ad in the reporting window: `running` is what the switches and the schedule permit, `delivering` is evidence that it happened, and only a delivering ad is labelled "Delivering" rather than "Running now". This matters because Meta never revokes `ACTIVE`: a boosted post whose run window closed months ago still reports ACTIVE at all three levels, so a raw enabled/active status from the Marketing API means almost nothing on its own. Also returns internal links to each Meta ad in Chirply, creative details, publishing page and shared budgets when available; Meta includes last-30-days ad performance in each advertiser timezone. Running ads sort first. Defaults to running ads only — pass filter `all` for every loaded ad. Filters apply to up to 100 loaded ads and 100 Performance Max groups per account; truncation and reporting errors remain explicit. Reads only, without changing ads or spending money; independent of dashboard date filters.
What needs attention (dashboard.operations)
[READ] What needs attention in this account right now — the triage cards on the default dashboard, read in one call. Returns up to six: Attention Required (everything currently failing, reconciled across appointments, automation runs, unpaid and failed invoices, broken provider connections and AI sessions, with the same total the red badge shows), Automation Health (active workflows, runs, failures and anything stuck running), Inbox & Response Queue (open and unassigned conversations, split by SMS and email), Account & Provider Health (which connected providers — telephony, email, payments — are healthy and which are broken), Lead Capture & Conversion (form views, responses, completion rate and funnel opt-ins), and Campaign Performance (attempted, delivered, opened and clicked). Each card comes back as headline metrics plus named rows, every row carrying the exact screen that resolves it. These are CROSS-DOMAIN reductions, which is why they live here and not in one of the feature domains — no per-domain capability can produce the reconciled attention total. Counting windows: the failure and health cards are as-of-now, while the volume cards (campaigns, lead capture) count over the requested day range. Read-only — it inspects, changes nothing, and sends nothing.
Dashboard layout (dashboard.get_layout)
[READ] Read how your dashboard is arranged — which widgets are on it, in what order, how wide each one is (in columns of a 12-column grid), and which you have hidden. Also returns every widget this account could show and the widths each one supports, which is what dashboard.set_layout accepts. Personal to you: it does not affect or reveal what teammates see. Omit tab_id for Overview or pass a personal custom tab ID. Custom tabs start empty; Overview starts with its default widgets. Changes nothing.
Save dashboard layout (dashboard.set_layout)
Rearrange your dashboard: the array order IS the top-to-bottom, left-to-right order of the widgets, `span` is how many of the 12 grid columns each one takes, `half_height` selects compact height so the card hugs its content instead of stretching to the tallest card in its row, and `hidden` drops it off the page without deleting anything. Width also selects the LAYOUT — most widgets have a compact build and a roomier one (Phone Numbers is a list at a third and a table at two-thirds), so dashboard.get_layout publishes which build each span renders. Personal to you; teammates' dashboards are unaffected, and no contact, call or pipeline data is touched. Unknown widget ids are ignored, a span the widget has no layout for is snapped to its nearest supported width, and any widget you leave out is kept HIDDEN (available to re-add, not deleted) — so a partial list shows exactly the widgets it names and nothing it doesn't. Call dashboard.get_layout for the valid ids and spans. Pass tab_id to arrange a custom tab, or omit for Overview. An empty layout hides all widgets.
Reset dashboard layout (dashboard.reset_layout)
Forget the saved arrangement for tab_id, or Overview when omitted. Custom tabs reset to an empty canvas; Overview goes back to the default: Activity and Overview full width, the Activity Log at two-thirds beside Tasks Due, then Live Visitors, Phone Numbers, Pipeline, Recent Communication, Revenue and Call Volume side by side, then New Contacts, the Activity Calendar beside Generate Leads, and Client accounts where entitled. Personal to you, and affects only where the widgets sit — nothing on them is changed or deleted. Widgets you had hidden come back if they are part of the default; widgets that launched hidden stay off the page until you add them.

Actions — data_subject

5 operations.

Everything held about one person (data_subject.export_person)
[READ · HIGH RISK · ADMIN ONLY] Collects everything this account holds about one contact, across all 89 tables that can reference them — their profile, every message and conversation, calls and recordings metadata, page views and session recordings, form submissions, orders and invoices, course and community activity, and their suppression status. This is what you send someone who makes a GDPR Article 15 access request or an Article 20 portability request. Returns the rows themselves as JSON, capped per table. Nothing is changed or deleted.
Erase one person permanently (data_subject.erase_person)
[HIGH RISK · ADMIN ONLY] PERMANENTLY DESTROYS everything this account holds about one contact and CANNOT BE UNDONE. Deletes their profile, messages, conversations, calls, session recordings, page views, IP addresses, form submissions and community activity outright; unlinks them from financial records (invoices, payments, orders), which survive without a name because the account needs them for its own accounting; and deliberately KEEPS their unsubscribe and do-not-contact entries, because deleting those is how you start messaging them again. This is how you answer a GDPR Article 17 erasure request. Writes an audit record proving it was done. Every affected table is reported, and if any table fails the result says the erasure is incomplete — re-running it is safe.
What an erasure does to each table (data_subject.erasure_policy)
[READ] Explains, table by table, what erasing a person destroys, what it keeps but unlinks, and what it deliberately retains — with the reason for each. Read this before running data_subject.erase_person if you need to tell someone exactly what will happen to their data, or to answer an auditor asking how erasure is implemented. Read-only and takes no arguments.
How long this account keeps data (data_subject.get_retention)
[READ] Reports the account's own automatic-deletion windows: how many days website visitor data, session recordings, call recordings and transcripts, message content and form submissions are kept before being deleted. A value of 0 means that kind is kept forever, which is the default for all of them. Read-only.
Change how long this account keeps data (data_subject.set_retention)
[HIGH RISK · ADMIN ONLY] Sets the account's automatic-deletion windows. SWITCHING A WINDOW ON PERMANENTLY DESTROYS DATA ON A TIMER and cannot be undone: anything already older than the window you set is deleted on the next nightly run. Pass a number of days per kind, or 0 to keep that kind forever. Contacts, deals, invoices and orders are never affected. Call retention removes the audio and transcript but keeps the call record itself. A value below a kind's documented minimum or above its maximum is stored as 0 (keep forever) rather than being clamped, so a mistyped number never becomes a deletion schedule nobody chose.

Actions — deal_templates

5 operations.

List deal templates (deal_templates.list)
[READ] List the saved starting points for new cards. Pass pipeline_id to get exactly what the Add-deal form on that board offers: the templates tied to it plus the org-wide ones. Values come back as integer cents.
New deal template (deal_templates.create)
Save a starting point for new cards on a board: a title, value, starting stage, owner, custom fields and how many days out the expected close should be. Leave pipeline_id off to offer it on every board. Setting is_default makes the Add-deal form on that board open pre-filled with it, and clears the flag from any other template on the same board. Creates nothing on the board itself — it's a form pre-fill.
Edit a deal template (deal_templates.update)
Change a saved template. Omitted fields are left alone. Existing deals created from it are untouched — a template is a pre-fill, not a link. Setting is_default clears the flag from any other template on the same board.
Add a deal from a template (deal_templates.use)
Create a real deal on the board using a template as the starting point — the same thing as picking it under 'Start from' and submitting. The template's title, value, stage, owner, custom fields and 'close in N days' are applied, and anything you pass here overrides them. The template itself is unchanged.
Delete a deal template (deal_templates.delete)
[HIGH RISK] Permanently delete a saved template. Deals already created from it are NOT affected — a template is only a form pre-fill. Cannot be undone.

Actions — deals

12 operations.

List deals (deals.list)
[READ] List and search deals, newest first. Filter by pipeline, stage, status, owner, contact, or company, and search deal titles with `query`. Values come back as integer cents.
Open a deal (deals.get)
[READ] Fetch one deal by id, with all of its fields including custom fields.
Create a deal (deals.create)
Create a deal on a pipeline board. Only a title is required: without pipeline_id it lands on the org's default pipeline, and without stage_id it goes in that pipeline's first stage. The status is derived from the stage — creating straight into a won/lost stage closes the deal.
Edit a deal (deals.update)
Update any field on a deal — title, value, currency, expected close date, links, custom fields, stage, or status. Omitted fields are left alone. Moving it with stage_id re-derives the status from that stage; passing status explicitly wins and stamps or clears closed_at accordingly. Changing the stage also writes one stage-change entry on the deal's timeline and the account Activity Log, recording the previous and new stage and naming the caller honestly — an API key is recorded as the API, not as a person.
Move a deal to another stage (deals.move)
Drop a deal card into a stage of its own pipeline — the drag gesture on the board. Without `position` it lands at the bottom of the target column; with one it lands at that slot and the rest of the column shifts down. Moving to a new stage re-derives the deal's status from that stage's outcome (won/lost stages close the deal and stamp closed_at) and logs a stage-change entry on the deal's timeline. Passing the stage the deal is already in just reorders it inside that column — no status change, no timeline entry.
Mark a deal won (deals.mark_won)
Close a deal as won and stamp its close time. If the pipeline has a stage flagged as won, the deal is moved into that column and a stage-change entry is logged, exactly as dragging it there would.
Mark a deal lost (deals.mark_lost)
Close a deal as lost and stamp its close time. If the pipeline has a stage flagged as lost, the deal is moved into that column and a stage-change entry is logged.
Mark a deal abandoned (deals.mark_abandoned)
Close a deal as abandoned (walked away, not a loss) and stamp its close time. No stage carries an 'abandoned' flag, so the deal keeps its current column but stops counting as open.
Reopen a deal (deals.reopen)
Put a closed deal (won, lost, or abandoned) back to open and clear its close time. Pass stage_id to also move it back into a working column — otherwise it stays where it is, which may be a won/lost column.
Assign a deal owner (deals.assign)
Set the org member who owns a deal, or pass owner_id=null to leave it unassigned. The user must already be a member of this organization.
Link a deal to a contact or company (deals.link)
Attach a deal to a contact and/or a company so it shows on that record, or pass null to unlink. Supply at least one of contact_id or company_id; both must belong to this organization.
Delete a deal (deals.delete)
[HIGH RISK] Permanently delete a deal. DESTRUCTIVE: its activity timeline (notes, stage changes) is deleted with it, and any task pointing at it loses the link. The contact and company survive. Cannot be undone.

Actions — designs

6 operations.

List designs (designs.list)
[READ] List the organization's Design Studio projects, most recently edited first, with canvas size and thumbnail URL.
Open a design (designs.get)
[READ] Fetch one design with its full document: pages of positioned text, image and shape elements on a fixed-size canvas. PNG export happens in the browser editor; machines read the doc here and the thumbnail URL from designs.list.
Browse design templates (designs.list_templates)
[READ] List the built-in design templates — slug, name, category and canvas size — plus the size presets for a blank canvas. Pass include_documents to also get each template's full starter document, which is the actual arrangement of text, image and shape elements it would create; that payload is large, so it is off by default. Use a template's slug, or a preset's width and height, with designs.create. Read-only.
New design (designs.create)
Create a Design Studio project — blank at a given size, from a built-in template slug, or as a copy of an existing design (an org template, say). Returns the new design; edit its doc with designs.update.
Edit a design (designs.update)
Rename a design, replace its document, or promote/demote it as a reusable org template. `doc` REPLACES the whole document — there is no per-element patch and NO VERSION HISTORY, so whatever was on the canvas before is gone the moment this returns. Always read the current document with designs.get, change what you need, and send the whole thing back. The document is normalized on save: unrecognised element types are dropped and every number is clamped (20 pages, 200 elements per page, 10000 px canvas), so an element that silently disappears is one the schema did not recognise.
Delete a design (designs.delete)
[HIGH RISK] Permanently delete a design project. Exported PNGs already in the media library are kept. This cannot be undone.

Actions — developers

11 operations.

List API keys (api_keys.list)
[READ · ADMIN ONLY] List this account's API keys — name, display prefix, scopes, last-used time, and whether each is revoked. The secret itself is never stored in readable form and is never returned here.
Create an API key (api_keys.create)
[HIGH RISK · ADMIN ONLY] Mint a new API key for this account and return the full secret — this is the ONLY time it can ever be read, so hand it to the user immediately. The key can do anything an owner can within this org, limited only by its scopes. Treat it as a live credential.
Revoke an API key (api_keys.revoke)
[HIGH RISK · ADMIN ONLY] Revoke an API key immediately. Any integration authenticating with it starts failing on its next request, and the key can never be un-revoked.
Delete an API key (api_keys.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete an API key row, removing it from the list entirely. Same live effect as revoking — anything using it breaks — but it also loses the audit trail, so prefer api_keys.revoke unless the row is genuinely unwanted.
List Connected Apps (connected_apps.list)
[READ · ADMIN ONLY] List the third-party applications connected to this account over OAuth — which app, who approved it, what it is allowed to do, and when it last made a request. Tokens themselves are stored only as hashes and are never returned.
Disconnect an App (connected_apps.revoke)
[HIGH RISK · ADMIN ONLY] Disconnect a third-party application from this account. Its access stops immediately and every token it holds is destroyed, so any automation running through it — Zaps, scripts, scheduled syncs — stops working at once and cannot be resumed without the owner approving the connection again. There is no undo.
Subscribe a webhook (webhooks.subscribe)
[HIGH RISK · ADMIN ONLY] Register an HTTPS endpoint to receive platform events as they happen — the automation trigger names (contact_created, message_received, deal_won, invoice_paid, …). From then on this account POSTs every occurrence of the subscribed events to that URL, HMAC-signed, with retries — account data (contact ids, event context) flows to whoever controls the endpoint until the subscription is deleted. Returns the signing secret exactly ONCE; it cannot be read back, so hand it to the user immediately.
List webhook subscriptions (webhooks.list)
[READ · ADMIN ONLY] List this account's outbound webhook subscriptions — each event × endpoint pair with its status and creation time — plus the full catalog of event names that can be subscribed to. Signing secrets are never returned here.
Delete a webhook subscription (webhooks.unsubscribe)
[HIGH RISK · ADMIN ONLY] Delete one outbound webhook subscription. Event deliveries to its endpoint stop immediately and its delivery log is removed with it. This cannot be undone — re-subscribing mints a NEW signing secret, so the integration on the other end must be reconfigured.
View webhook deliveries (webhooks.list_deliveries)
[READ · ADMIN ONLY] The delivery log for one webhook subscription, newest first: each attempt's status (pending, delivered, failed, or dead once retries run out), attempt count, last error, and timestamps — for debugging an endpoint that isn't receiving events. Read-only.
Read the event stream (webhooks.read_events)
[READ · ADMIN ONLY] Read the platform events this account's webhook subscriptions have produced — oldest first, with each event's full payload — and walk forward with a cursor. This is the PULL side of webhooks, for a caller that cannot receive a POST: an AI agent connected over MCP has no HTTPS endpoint to deliver to, so it asks what happened since it last looked instead. Subscribe with webhooks.subscribe first (an endpoint URL is still required to register the subscription); every event that matches then shows up here whether or not that endpoint answered. Pass the previous reply's next_cursor as `after` to continue without re-reading or skipping. Read-only and costs nothing.

Actions — devices

8 operations.

List desk phones (devices.list)
[READ · ADMIN ONLY] List the physical VoIP/SIP desk phones registered to this account — each with its label, SIP username, assigned seat, enabled state, assigned phone-number ids, and exact *1 through *9 outbound caller-ID codes — plus the SIP server address. Read-only, costs nothing, and NEVER returns SIP passwords.
Save keypad order (devices.set_outbound_order)
[ADMIN ONLY] Choose the per-phone order behind the *1 through *9 outbound caller-ID shortcuts. This changes which owned business number a future desk-phone call presents when its prefix is dialed; it does not place a call, send a message, change inbound ringing, or spend money by itself. Active assigned numbers omitted from the list are appended after the listed numbers.
Add a desk phone (devices.provision)
[ADMIN ONLY] Provision a new physical VoIP/SIP desk phone on its OWN Twilio account and return the SIP server, username, and password to enter into the handset. The password is shown ONCE and can never be retrieved again (only regenerated). The account's SIP domain is created automatically on the first device. This spends no money by itself; once registered, the phone rings the account's numbers and can dial out, billed as ordinary Twilio calls.
Enable or disable a desk phone (devices.set_enabled)
[ADMIN ONLY] Turn a registered desk phone on or off. A disabled phone keeps its credential but stops ringing on inbound calls and can't dial out. Fully reversible.
Assign a desk phone to a seat (devices.assign)
[ADMIN ONLY] Assign a desk phone to an account member (seat), or clear the assignment by passing null. This records who the phone belongs to; it does not change which numbers ring it.
Save phone numbers (devices.set_numbers)
[ADMIN ONLY] Set exactly which account phone numbers belong to a desk phone. These numbers ring the phone on inbound team calls and become its allowed outbound caller IDs; on the handset, dialing normally uses the available account default and prefixes *1 through *9 select a listed number for one call. Pass an empty list to use EVERY team-routed number. Inbound routing still does not override numbers sent to an AI receptionist, IVR, blind forward, or conference.
Reset a desk phone's password (devices.regenerate_password)
[ADMIN ONLY] Generate a new SIP password for a desk phone and return it ONCE, along with the SIP server and username. The old password stops working immediately, so the handset must be updated with the new one to keep working. Use if a password may have leaked or was lost (it can't be read back any other way).
Remove a desk phone (devices.remove)
[HIGH RISK · ADMIN ONLY] PERMANENTLY remove a desk phone: its SIP credential is deleted on Twilio, so the handset can no longer register, ring, or dial. This CANNOT be undone — setting the phone up again means provisioning a fresh device with new credentials.

Actions — dialer_settings

3 operations.

Dialer settings (dialer_settings.get)
[READ] Read how the power dialer and the predictive dialer are set to behave — pace, whether an outcome is required, voicemail drop, lines per rep, answering-machine screening, whether AI answers first, and the calling window. Omit queue_id for the account defaults; pass one to see what that queue actually uses, which is the defaults with its own overrides applied.
Change dialer settings (dialer_settings.update)
[HIGH RISK · ADMIN ONLY] Change how the dialers behave. Only the fields you pass are changed; everything else keeps its current value. Omit queue_id to move the WORKSPACE defaults — which also moves every queue that has never disagreed with the setting you're changing. Pass queue_id to change one queue only. This spends nothing by itself, but it decides how hard the dialer works: raising lines_per_agent reaches more people per hour and drops more calls, and turning the AI on puts a synthetic voice in front of every person who answers. A session already running keeps the settings it started with.
Follow the account settings again (dialer_settings.follow_workspace)
Drop a call queue's own dialer settings so it goes back to using the account defaults — and keeps following them as they change. Nothing about the account defaults themselves is altered.

Actions — directories

31 operations.

View directory (directories.get)
[READ] Return one directory website's configuration, publication state, paid-license state, branding, and public address.
Save website settings (directories.update_settings)
[HIGH RISK · ADMIN ONLY] Update one directory website's name, niche, geography, description, logo, brand color, and public listing terminology without changing its paid license or running data acquisition.
View categories (directories.list_categories)
[READ] List the public browse categories configured for one directory website.
View listing fields (directories.list_fields)
[READ] List the niche-specific structured fields and public filter settings configured for one directory.
View listings (directories.list_listings)
[READ] List business or entity listings in one directory, including draft, published, claimed, and archived records.
View listing (directories.get_listing)
[READ] Return one directory listing with its public details, niche-specific values, and visibility state.
Save listing (directories.update_listing)
[HIGH RISK · ADMIN ONLY] Update a directory listing's public content, category, niche-specific values, and visibility. Publishing or archiving changes what visitors can see immediately on a live directory.
View articles (directories.list_posts)
[READ] List draft, scheduled, and published CMS articles for one directory website.
View article (directories.get_post)
[READ] Return one directory CMS article with its Markdown body, publication schedule, image, and search metadata.
Save article (directories.update_post)
[HIGH RISK · ADMIN ONLY] Update a directory CMS article and set it to draft, scheduled, or published. Publishing makes the content immediately public; scheduling publishes it when its timestamp arrives.
Delete article (directories.delete_post)
[HIGH RISK · ADMIN ONLY] Permanently delete one directory CMS article. The article and its public URL cannot be recovered after this action.
View acquisition coverage (directories.get_acquisition_status)
[READ] Return budget, spend, completion, saturation, unique-result, and duplicate counts for one directory's tracked Outscraper campaigns without submitting any paid searches.
Connect domain (directories.connect_domain)
[HIGH RISK · ADMIN ONLY] Connect and provision a custom hostname for one directory website through Cloudflare, including SSL setup. This changes live DNS routing and may replace a conflicting record when the account connected its Cloudflare account.
Increase acquisition limit (directories.add_acquisition_budget)
[HIGH RISK · ADMIN ONLY] Increase the hard Outscraper spend ceiling on an existing resumable acquisition campaign so it can continue through its still-uncovered cells without repeating completed searches.
Add listing field (directories.create_field)
[ADMIN ONLY] Add a structured niche-specific field to one directory, optionally exposing it as a public browse filter.
Add category (directories.create_category)
[ADMIN ONLY] Add a public browse category to one directory website. This changes that directory's taxonomy without affecting other directory instances.
Create listing (directories.create_listing)
[ADMIN ONLY] Create a directory listing and create or reuse its canonical company in the CRM. Publishing makes it immediately visible on an already-live directory website.
Create article (directories.create_post)
[HIGH RISK · ADMIN ONLY] Create a CMS article for one directory. Publishing immediately makes the article publicly accessible and indexable on a live directory website.
Submit claim (directories.submit_claim)
[HIGH RISK] Submit a public ownership claim for one published directory listing and email a real 24-hour verification link to the claimant. The claim reaches the directory review queue only after that email is verified. The verification is sent from THIS account's own verified sending address (or its parent agency's), billed to its own Mailgun/Resend account — never from Chirply, because the claimant is the account's user and not Chirply's. If the account has no verified sending address, nothing is written and the call fails: connect one under Settings → Email routing first (see the "directories" feature in readiness.status).
Send request (directories.submit_lead)
Create a real inbound CRM contact and lead from a visitor request on one published directory listing. This stores the visitor's submitted contact details and message but sends no outreach.
View listing claims (directories.list_claims)
[READ] List email-verified ownership claims submitted against listings in one directory so staff can review them without exposing unverified submissions.
Review claim (directories.review_claim)
[HIGH RISK · ADMIN ONLY] Approve or reject a pending listing claim. Approval marks the listing claimed and creates or reuses the claimant as a CRM contact; rejection leaves the listing ownership unchanged.
View directory leads (directories.list_leads)
[READ] List visitor inquiries captured by one directory website, including their linked CRM contact when available.
Update lead status (directories.update_lead_status)
[ADMIN ONLY] Move a directory inquiry between new, contacted, and closed while retaining its CRM contact and source attribution.
Publish (directories.publish)
[HIGH RISK · ADMIN ONLY] Publish a paid directory website immediately, making its homepage, listings, categories, and published CMS articles available to the public and search engines.
View directories (directories.list)
[READ] List every independently configured directory website owned by this account, including its publication and billing status.
Create another directory (directories.create)
[ADMIN ONLY] Create a new independently configured directory website in draft state. This prepares the site but does not publish it, run Outscraper, or spend money.
Save acquisition plan (directories.plan_acquisition_from_geography)
[HIGH RISK · ADMIN ONLY] Resolve a plain-language market with one request to its connected Outscraper account, then create a budget-capped coordinate grid and permanent query ledger. The geography lookup may consume provider usage; this does not purchase any business records.
Plan data acquisition (directories.create_acquisition_campaign)
[ADMIN ONLY] Create a budget-capped Outscraper acquisition plan for one directory. This records the strategy and search terms but does not submit paid searches or spend money.
Retry failed queries (directories.retry_failed_acquisition_queries)
[HIGH RISK · ADMIN ONLY] Requeue every failed Outscraper query in one directory acquisition campaign and resume its worker. Retries can purchase real Google Maps records from the organization's Outscraper account, but the campaign's approved budget remains enforced.
Run next uncovered cell (directories.run_acquisition_query)
[HIGH RISK · ADMIN ONLY] Submit one planned Google Maps query to Outscraper for a tracked geographic cell. This returns real billable records, publishes net-new directory listings, records duplicates and cost, and refuses to exceed the campaign's approved budget.

Actions — documents

5 operations.

List documents (documents.list)
[READ] List the account's proposals, estimates, and contracts, including delivery and signature status. This only reads data and sends nothing.
Open document (documents.get)
[READ] Fetch one proposal, estimate, or contract with its linked invoice, signature certificate data, and audit trail. This only reads data.
New document (documents.create)
[ADMIN ONLY] Create a draft proposal, estimate, or contract. This saves a private draft only; it does not email the recipient or create a charge.
Save changes (documents.update)
[ADMIN ONLY] Edit a draft or outstanding commercial document. Signed, declined, expired, and archived records are immutable. This saves changes but sends no email and creates no charge.
Send for signature (documents.send)
[HIGH RISK · ADMIN ONLY] Immediately emails the real recipient a private link to review and electronically sign this document through a connected email identity. Sending email can incur the account's provider charges. No payment is taken until the recipient separately completes the linked invoice.

Actions — domain_leads

7 operations.

Search domain leads (domain_leads.search)
[READ] Search the 26,086,322-record historical domain-registration dataset by a keyword in the domain name and return the person or business who registered each one, with their name, company, phone, email and postal address. Registration dates span 1985 through 2024; this is a historical dataset, not live WHOIS. Domains registered behind privacy/proxy services may not carry reachable contact details. Costs nothing to run. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Get a domain's registrant (domain_leads.get)
[READ] Look up one specific domain and return everything known about who registered it — name, company, phone, email, full postal address, registrar, and registration/expiry dates. Returns null when the domain isn't in the database or was registered behind a privacy proxy. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
List a registrant's other domains (domain_leads.registrant_portfolio)
[READ] Given a registrant's email address, list the other domains that same person or business registered. Useful for gauging whether a lead is a real business (a handful of domains) or a domain speculator (hundreds). Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
List domain endings and countries (domain_leads.list_filters)
[READ] List the domain endings (TLDs) and registrant countries available as search filters, each with how many domains carry it, most common first. Use this to discover valid values for the tld and country arguments of domain_leads.search. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
View Domain Leads inventory (domain_leads.get_inventory)
[READ] Return the exact number of records currently available in the shared Domain Leads dataset, plus its earliest and latest valid registration dates. Read-only and costs nothing. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Export Domain Leads CSV (domain_leads.export_csv)
[READ] Search Domain Leads and return the matching registration records as CSV text for download or downstream processing. Read-only and costs nothing. One machine call returns at most 5,000 rows; use offset to page through larger result sets. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Import domain leads into contacts (domain_leads.import_to_contacts)
[HIGH RISK] Run a domain-leads search and copy the matching registrants into this organization's CRM as contacts, with their name, company, email, phone and website. Creates up to 500 contact records in one call — these are real people's contact details and will appear in the org's contact list, where they can then be called, texted or emailed. Does not send anything by itself and spends no money, but bulk-importing thousands of contacts is tedious to undo, so it asks for confirmation. Requires the Domain Leads app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.

Actions — domains

26 operations.

Domains (domains.list)
[READ] List every custom domain this account has connected, with what is currently published on each one — the site or funnel at its root, how many short links point at it, and how many invoices are served from it. Includes whether each domain was bought through this platform or brought from another registrar, its DNS/certificate status, and its renewal date.
Domain details (domains.get)
[READ] Read one domain: its status, how it was obtained, the DNS record required (if any), its expiry and auto-renew setting, and a breakdown of everything published on it.
Connect a domain (domains.connect)
[HIGH RISK · ADMIN ONLY] Connect a domain the organization ALREADY OWNS at another registrar (e.g. go.acme.com) and request a public TLS certificate for it. Does not buy anything and costs no money. If the account has its Cloudflare account connected (the cloudflare integration), the required CNAME is CREATED AUTOMATICALLY in the organization's own Cloudflare zone — replacing whatever DNS record previously answered at that exact hostname. Otherwise the domain does not serve traffic until the owner adds the returned CNAME record at their DNS provider; use domains.verify afterwards to check. Once live it can serve short links, a funnel or site, and invoices at the same time.
Set up DNS automatically (domains.setup_dns)
[HIGH RISK · ADMIN ONLY] Create the CNAME for an already-connected domain inside the organization's OWN Cloudflare account (requires the cloudflare integration). WRITES to the organization's live DNS: any A/AAAA/CNAME record answering at that exact hostname is REPLACED with the platform CNAME, which changes where that hostname resolves for everyone on the internet. Touches only that one hostname, never the rest of the zone. Use on domains stuck 'Waiting for DNS' that were connected before Cloudflare was, or whose record was removed.
Cloudflare DNS status (domains.cloudflare_status)
[READ · ADMIN ONLY] Report whether its own Cloudflare account is connected for automatic DNS, and list the zones (domains) that account can manage — each with Cloudflare's status for it and whether records written there would actually govern the domain (a zone Cloudflare has marked moved/deactivated accepts writes that change nothing). Read-only — changes nothing in Cloudflare. Zone names reveal which domains the organization runs, so this is manager-only like the integration itself.
Check again (domains.verify)
[ADMIN ONLY] Re-check a domain's DNS and certificate with Cloudflare and store the result. Safe to call repeatedly; changes nothing except the recorded status. Owners and admins only, matching the button on /domains.
Visitors can't reach this domain (domains.health)
[READ] Read the stored reachability verdict for the account's custom domains — whether real HTTP requests to each hostname actually arrive at the platform, which Cloudflare's own status checks cannot see (a domain can show 'active' with a valid certificate while every visitor dies at the customer's misconfigured DNS proxy). Verdicts come from the automatic sweep that runs every few hours; a broken domain also carries plain-language fix steps. Reads stored state only — probes nothing and changes nothing.
Domain settings (domains.update)
[HIGH RISK · ADMIN ONLY] Change what a domain does: which website answers at its root, where the bare domain redirects when nothing is attached, where unknown paths go, and whether short links are allowed on it. Additional funnels use domains.add_funnel_route. Turning links off instantly stops every short link on this domain from resolving.
Add route (domains.add_funnel_route)
[HIGH RISK · ADMIN ONLY] Publish an additional funnel on a named route of a connected domain. The funnel home becomes /route and its pages live below it (for example /summer/checkout). If the funnel is already published, this makes it reachable at the new address immediately. The route is rejected if a website page, short link, another funnel, or a reserved system route already uses it.
Remove (domains.remove_funnel_route)
[HIGH RISK · ADMIN ONLY] Remove one funnel route from a custom domain. The funnel and all of its pages remain in this account, but every URL below this domain route stops working immediately until the route is added again.
Disconnect (domains.disconnect)
[HIGH RISK · ADMIN ONLY] Stop serving a domain and release its certificate. Every short link, funnel page and invoice published on it stops working immediately and falls back to the platform's own address. Link names are unique platform-wide on that shared address, so a link whose name is already taken there is renamed with a numeric suffix as it moves — its old URL stops working either way. If the domain's CNAME was created in the organization's own Cloudflare, that record is removed too. A domain BOUGHT through this platform stays registered to the organization — this only stops serving it, it does not give up the domain or refund anything.
Find a domain (domains.search)
[READ] Search for domain names that are available to buy, with the price the organization would pay. Read-only — nothing is reserved or charged. Returns first-year and yearly renewal prices, which often differ.
Check a domain (domains.check_availability)
[READ] Check whether specific domain names are available and what they would cost. Read-only — nothing is reserved or charged.
Buy a domain (domains.purchase)
[HIGH RISK · ADMIN ONLY] START buying a domain. THIS DOES NOT COMPLETE A PURCHASE and nothing is registered by this call: it prices the domain, creates a PENDING order, and puts an UNCAPTURED hold on a card in Stripe. No money is taken, the domain is NOT registered, and the organization does not own it when this returns — so do not report the domain as bought. Finishing requires a HUMAN in a browser at the returned /domains/buy link to confirm the card in Stripe's payment form, which no machine surface can do; that is what the returned requires_card_confirmation flag means. Only after that confirmation is the domain registered, the hold captured, and DNS configured automatically. Registration is non-refundable once it completes, and it renews yearly at the quoted renewal price unless auto-renew is turned off. Note the hold itself can reduce the card's available balance until it is captured or released.
Auto-renew (domains.set_auto_renew)
[HIGH RISK · ADMIN ONLY] Turn yearly auto-renewal on or off for a domain bought through this platform. With it on, the organization's card is charged about 30 days before expiry at the current renewal price. With it OFF the domain will EXPIRE at the end of its term and everything published on it will stop working.
Pixels (pixels.list)
[READ] List the organization's retargeting pixels. A pixel is defined once and can fire on any public surface — link interstitials, funnel pages, invoice pay pages — either everywhere or only where attached.
Add a pixel (pixels.create)
[HIGH RISK · ADMIN ONLY] Add a retargeting pixel. THIS PUTS THIRD-PARTY TRACKING CODE ON LIVE PUBLIC PAGES that real visitors load, and it starts collecting their behaviour for the ad platform the moment it is live — so it is a privacy and consent decision, not just a setting. For a known provider give the ID from their ads manager and the snippet is generated safely; for anything else use provider 'custom', which injects the RAW SNIPPET verbatim and will run whatever JavaScript it contains. Setting all_surfaces fires it on every public page the organization serves — every funnel, link interstitial and invoice pay page at once — which is usually what's wanted. Attaching a pixel to a short link forces that link's interstitial page on, because a bare redirect renders no page for a pixel to fire on.
Edit a pixel (pixels.update)
[HIGH RISK · ADMIN ONLY] Change a pixel's name, ID, snippet, placement, or whether it fires on every public page. Every change takes effect on LIVE public pages on the next page load: replacing custom_html swaps the JavaScript running in real visitors' browsers, and turning all_surfaces on starts firing it across every funnel, link interstitial and invoice pay page the organization serves. Pointing it at a different pixel ID sends visitor data to a different ad account.
Delete a pixel (pixels.delete)
[HIGH RISK · ADMIN ONLY] Delete a pixel and remove it from everything it was attached to. It stops firing immediately and the audience it was building stops growing.
Attach a pixel (pixels.attach)
[HIGH RISK · ADMIN ONLY] Attach or detach a pixel from one specific link, funnel, page or invoice. Attaching starts firing it for real visitors to that live surface immediately, and on a SHORT LINK it also FORCES THE INTERSTITIAL PAGE ON — a link that used to redirect straight through now shows a page first, which changes what every existing recipient of that link experiences. Detaching stops the pixel there and the audience it was building stops growing. Not needed for pixels marked all_surfaces — those already fire everywhere.
Where a pixel fires (pixels.attachments)
[READ] List everything one pixel is currently attached to.
Tracking scripts (scripts.list)
[READ] List the organization's tracking scripts — Google Tag Manager, heatmaps, chat widgets, affiliate tags. Defined once and reusable on any public page, rather than pasted into each invoice or funnel separately.
Add a tracking script (scripts.create)
[HIGH RISK · ADMIN ONLY] Add a tracking snippet that runs on the organization's public pages. The snippet executes in visitors' browsers on pages the organization controls. Setting all_surfaces runs it on every public page. Maximum 8000 characters.
Edit a tracking script (scripts.update)
[HIGH RISK · ADMIN ONLY] Change a tracking script's name, snippet, placement, or whether it's active. Setting active to false stops it running everywhere at once.
Delete a tracking script (scripts.delete)
[HIGH RISK · ADMIN ONLY] Delete a tracking script and remove it from everything it was attached to. It stops running immediately, and anything it was measuring stops being recorded.
Attach a tracking script (scripts.attach)
[HIGH RISK · ADMIN ONLY] Attach or detach a tracking script from one specific link, funnel, page or invoice. Attaching STARTS RUNNING THAT JAVASCRIPT in real visitors' browsers on that live page from the next page load; detaching stops it and anything it was measuring stops being recorded. Not needed for scripts marked all_surfaces.

Actions — email

30 operations.

List email providers (email.list_connections)
[READ · ADMIN ONLY] List the account's connected Mailgun and Resend accounts, their verified domains, connection state, and whether inbound authentication is configured. Read-only; returns no provider secrets.
List email addresses (email.list_identities)
[READ] List every ready or pending account email identity — the From addresses this account can send as — with its Mailgun/Resend routing, display name, reply-to and which one is the account default. This is the list the inbox and broadcast composers' sender pickers show, so any member can read it. Read-only; returns no provider secrets.
Connect email provider (email.connect_provider)
[ADMIN ONLY] Connect another Mailgun or Resend account to this account. The supplied API key is verified with the provider and encrypted before storage. This does not send email or create provider charges by itself.
Show my sending domains (email.discover_domains)
[READ · ADMIN ONLY] List every sending domain that already exists inside a Mailgun or Resend account, using an API key supplied with the call, and mark which of them this account has already connected. This is the lookup behind 'paste one key, pick your domains': the key is used for this read and discarded, nothing is stored, and no provider secret is returned. Costs nothing and sends nothing.
Connect sending domains (email.connect_domains)
[ADMIN ONLY] Connect several sending domains from ONE Mailgun or Resend account in a single call, and optionally create the From addresses to send as on each. Every domain is verified with the provider before it is saved; the API key is encrypted at rest. This also changes settings inside its own provider account — it registers delivery webhooks, switches open tracking on, and, for domains marked to receive, points the provider's inbound route at this account so replies land in Conversations. Sends no email and spends no money by itself; the account's provider still bills any mail later sent through it.
List provider accounts (email.list_provider_accounts)
[READ · ADMIN ONLY] List the Mailgun and Resend ACCOUNTS this account holds credentials for, with the domains from each one that are currently connected and the account addresses on them. Connections are stored one per domain, so this groups them back into the account a person actually connected — which is the unit email.review_account_domains re-queries. Each account is identified by a non-reversible fingerprint of its API key; no key or secret is ever returned. Read-only.
Re-check provider domains (email.review_account_domains)
[READ · ADMIN ONLY] Ask a connected Mailgun or Resend account what sending domains it holds RIGHT NOW, and report each one beside whether this account has it connected. Uses the API key already stored for that account, so nothing needs pasting; the key is used for the provider call and never returned. Also names domains this account still holds that the account no longer lists at all — deleted at the provider, or no longer covered by that key. Read-only: it changes nothing here and nothing in the provider account. Use email.apply_account_domains to act on the result.
Set which domains Chirply uses (email.apply_account_domains)
[HIGH RISK · ADMIN ONLY] Make this account's domains for one provider account match the list given — connecting the ones that are missing and REMOVING every connected domain from that account that is not in the list. The omission is the instruction, so sending a partial list silently drops the rest: read email.review_account_domains first and send back the full set you want to end up with. Connecting a domain registers Chirply on that domain's delivery-event webhooks inside the customer's own provider account, alongside anything already there; removing one takes those webhooks and the inbound route Chirply added back out, while leaving the customer's own webhooks and their open and click tracking untouched. Domains stay in the provider account either way — only their connection to this account changes. A domain being removed that still has account addresses is SKIPPED and reported rather than removed, unless remove_addresses is set. Never turns receiving on: a newly connected domain sends only until someone chooses where its mail should arrive. Each domain succeeds or fails on its own and the response reports both.
Remove domain (email.disconnect_domain)
[HIGH RISK · ADMIN ONLY] Remove one sending domain from this account and undo what connecting it did inside the customer's own Mailgun or Resend account. This is not only a local delete: it takes Chirply's delivery-event webhooks off that domain and deletes the inbound route this account added, so the provider stops sending that domain's traffic here. Registrations Chirply did not create — the customer's own application's webhooks, another account's — are preserved, and open and click tracking are left exactly as they are. The domain itself stays in the provider account, verified and able to send; only its connection to this account ends. Refuses while account addresses still send through the domain unless remove_addresses is set, in which case those addresses are deleted too and drop out of any rotation pools they belong to, shrinking those pools. Past conversations and campaigns keep their history and fall back to the account default sender. Cannot be undone from here — reconnecting means pasting the provider API key again.
Add email address (email.create_identity)
[ADMIN ONLY] Create a selectable account From address on a verified Mailgun or Resend connection and optionally route inbound mail through a different connected provider. Sends nothing.
Save sender details (email.update_identity)
[ADMIN ONLY] Update the visible From address, friendly From name, and Reply-to address for an existing account email identity. A changed From address must stay on the identity's connected sending domain (and its receiving domain when inbound mail is enabled). This changes what future recipients see and where their replies are delivered; it sends nothing.
Make default sender (email.set_default_identity)
[ADMIN ONLY] Make this address the account's default From. It is used for two things: any email that doesn't name its own sender, and the account's authentication email — password resets, invitations and address confirmations are branded with it, so recipients see this address on the messages that get people into the account. Existing conversations keep their sticky identity, and contact-specific preferences still win. Only one address can be the default, so this replaces the current one. Sends nothing.
Change email routing (email.update_identity_routing)
[ADMIN ONLY] Change which connected provider sends and receives for an existing account email identity. Sends nothing.
Check incoming email (email.check_receiving)
[READ · ADMIN ONLY] Check whether every account address that is set to receive replies can actually be reached, and report the ones that cannot. A saved inbound provider is not enough on its own: if the domain's MX records still deliver mail to Google, Microsoft or its own mail server, incoming mail never reaches the platform and every reply is silently lost while the address still reads as receiving. Names where each broken domain's mail is going today and whether the DNS can be repaired automatically. Read-only — reads public DNS and the account's own Cloudflare zone list, changes nothing, and returns no provider secrets.
Point a domain's mail here (email.fix_receiving_dns)
[HIGH RISK · ADMIN ONLY] Rewrite a receiving domain's MX records in its own connected Cloudflare account so incoming mail is delivered to the platform instead of wherever it goes now. THIS TAKES OVER ALL MAIL FOR THAT DOMAIN AND IS NOT LIMITED TO THIS ONE ADDRESS: every existing mailbox behind the domain's current mail servers — staff inboxes, a helpdesk, anything else — stops receiving the moment DNS propagates, and the displaced records are deleted, not kept. Only run this when the person owning the domain understands they are moving its mail. Requires a connected Cloudflare account that holds the zone; it fails cleanly with the records to add by hand otherwise. Changing the MX back is a manual DNS edit at their provider.
Save AI replies (email.set_ai_replies)
[HIGH RISK · ADMIN ONLY] Choose who answers email sent to one account address: nobody, or one of the account's AI agents. In draft mode the agent writes a reply that waits in the conversation until a person reads it and presses Send — nothing leaves the address on its own. In send mode the agent answers real people from that address, unattended, with nobody checking first; those replies are real email billed to its own Mailgun or Resend account and cannot be recalled. The agent never answers bounces, out-of-office notices, mailing lists or no-reply addresses, and never someone who asked to unsubscribe. The address must already be set up to receive mail, and the agent must be active. Changes take effect on the next email that arrives.
AI replies waiting for approval (email.list_ai_drafts)
[READ] List the email replies an AI agent has written that are still waiting for a person to approve or discard, with the agent that wrote each one, the address it would go out from, and the full text. Read-only; sends nothing.
Send AI reply (email.send_ai_draft)
[HIGH RISK] Approve one AI-written email reply and send it immediately to the contact, as real email from its own Mailgun or Resend account — billed to them, and impossible to recall once gone. Optionally replace the subject or body first, in which case the edited text is what is sent and what is kept on the record.
Discard AI reply (email.discard_ai_draft)
Throw away one AI-written email reply so it is never sent. The contact hears nothing back from the agent on that message; a person can still write their own reply. The text is kept on the record as what the agent wanted to say.
Delete email address (email.delete_identity)
[HIGH RISK · ADMIN ONLY] Permanently delete one account From address. The provider connection, its domain and every other address on it are left alone — only this sender is removed. Past conversations, campaigns and messages keep their history but lose their pinned sender, so their next reply goes out from the account default instead, changing what those recipients see. If the address belongs to any sending pool it is dropped from that rotation, concentrating the volume on the pool's remaining members. The account default sender cannot be deleted while another address could take over, because it is what brands authentication email such as password resets.
Send test (email.send_test)
[HIGH RISK · ADMIN ONLY] Immediately sends one real test email through the selected account Mailgun or Resend identity to the requested recipient. The account's provider may charge for this delivery.
Check open tracking (email.tracking_status)
[READ · ADMIN ONLY] Report, for each connected Mailgun or Resend account, whether the provider is currently tracking email opens and clicks. Read-only; asks the provider directly rather than reporting a stored value, so it is the way to tell 'nobody opened it' apart from 'nothing was tracking it'. Returns no provider secrets.
Turn on open tracking (email.enable_open_tracking)
[HIGH RISK · ADMIN ONLY] Switch open tracking on for the account's connected Mailgun or Resend accounts, so the provider inserts its tracking pixel and reports opens. This changes a setting inside its OWN provider account and applies to every email that account sends, including mail sent by other tools using the same domain. Click tracking is deliberately left alone. Sends nothing and costs nothing.
Set email tracking (email.set_tracking)
[HIGH RISK · ADMIN ONLY] Turn open tracking and click tracking on or off for ONE connected Mailgun or Resend account. This changes the setting inside its own provider account, so it applies to every email that account sends from that domain — including mail sent by other tools using the same domain, and including mail already queued. Turning open tracking off stops the provider inserting its invisible tracking pixel, so opens stop being recorded for recipients from that moment on; turning it on starts recording them. For Resend this also names the tracking subdomain and publishes its CNAME in the account's own DNS, because Resend applies neither flag until that record verifies. Sends no email and costs nothing.
Set sender warmup (email.set_warmup)
[ADMIN ONLY] Turn a warmup ramp on or off for one account email address. While warming, pool rotation caps that sender at its current daily allowance (start volume + increment per elapsed day, leveling off at the maximum, counted per UTC day). Direct sends from the address are still counted but not blocked. Changes future pacing only; sends nothing.
Sender usage today (email.sender_usage)
[READ · ADMIN ONLY] Show today's send count for every account email address alongside its effective bulk daily cap (warmup allowance and any automatic reputation slow-down combined; null when uncapped), so you can see which senders have headroom left and which have been slowed down for high bounce/complaint rates — and exactly why. Counts reset at midnight UTC. Read-only. Owner/admin only, matching the Email pools settings screen this table appears on.
Check sending-domain health (email.check_domain_health)
[READ · ADMIN ONLY] Run a deliverability health check on the account's connected email sending domains: provider verification, SPF, DKIM, DMARC policy, whether the domain can receive replies (MX), and its sending reputation. SPF/DKIM come from the provider's own verification; DMARC and MX are looked up in public DNS. Reputation is graded from bounce, spam-complaint and open rates over the last 30 days — from this account's own send history where there is enough of it, otherwise from the provider's own totals for the domain, which cover ALL mail sent from it including mail not sent through Chirply. Read-only and free — it queries DNS and the provider API, sends nothing.
Sender health (email.sender_health)
[READ · ADMIN ONLY] Show how warm and how healthy every account sending address is, from what the email provider actually reported over the last 30 days. Each address gets a temperature — cold (no recent history, inbox providers have nothing to go on), warming (ramping, or sending below the volume of an established sender), warm (established and safe for normal campaign volume) or hot (sustaining high daily volume) — plus its bounce rate, spam-complaint rate, open rate, a reputation verdict, and a one-line answer to 'is this good to send from?'. Also reports any address currently resting. Read-only and free: it reads the account's own send history, contacts no provider and sends nothing. Owner/admin only, matching the Email pools settings screen.
Rest a sender (email.rest_sender)
[ADMIN ONLY] Take one sending address out of pool rotation for a few days so its reputation can recover — the right response to a spiking bounce or spam-complaint rate. While resting, bulk sends through any pool skip this address and lean on the pool's other members, which concentrates the same volume on them; one-to-one replies and direct sends from the address still go out, so nobody mid-conversation is cut off. Pass 0 days to end a rest immediately and put the address straight back in the rotation. Reversible at any time; sends nothing and costs nothing.
DMARC report summary (email.dmarc_summary)
[READ · ADMIN ONLY] Show what mailbox providers have reported back about mail claiming to be from this account's sending domains, over the last 30 days. DMARC aggregate reports come from the RECEIVERS — Google, Microsoft, Yahoo and everyone else — so unlike delivery statistics they cover every provider and include mail this account did not send. For each domain: how many messages were seen, how many passed authentication, how many were sent to spam or rejected, the DMARC policy currently published, which receivers reported, and the sending IPs that FAILED authentication with the domains they signed as. A failing source is usually a legitimate service missing from the domain's SPF or DKIM records; one nobody recognises is someone sending as the domain. Read-only and free — it reads reports already received, contacts nobody and sends nothing. Owner/admin only, matching the Email pools settings screen.

Actions — email_policy

2 operations.

View email preferences (email_policy.get)
[READ] Read the account's unsubscribe-link and double-opt-in preferences, its org-wide daily email sending limit, and the automatic reputation slow-down thresholds. Changes nothing and sends no email.
Save settings (email_policy.update)
[ADMIN ONLY] Update whether account opt-out links are appended to email, which subscriber sources require double opt-in (including the confirmation email copy), the org-wide daily email sending limit, and the automatic slow-down thresholds for senders whose bounce/complaint rates spike. Saves configuration only and sends no email immediately — but a daily limit changes when bulk campaigns pause, and throttle thresholds change how fast struggling senders may send.

Actions — email_pools

8 operations.

List email pools (email_pools.list)
[READ · ADMIN ONLY] List the account's email sending pools — named sets of From addresses that bulk sends rotate across — with each pool's member count, reply-to address, active/paused status, warmup plan, and how many emails it has sent today. Read-only. Owner/admin only, matching the Email pools settings screen.
View email pool (email_pools.get)
[READ · ADMIN ONLY] Show one email pool in full: its reply-to, status, the warmup plan applied to its members, and every member address with today's send count, its current warmup allowance, and whether it is resting. Read-only. Owner/admin only, matching the Email pools settings screen.
Create email pool (email_pools.create)
[ADMIN ONLY] Create an email sending pool. Bulk sends addressed to the pool rotate across its member addresses (least-used-today first, respecting each member's warmup allowance). The pool's reply-to overrides every member's individual reply-to; leave it blank and replies return to whichever address sent each message. Creating a pool sends nothing.
Update email pool (email_pools.update)
[ADMIN ONLY] Rename an email pool, change or clear its reply-to, pause or reactivate it, or replace its member list. A paused pool refuses new sends; in-flight campaigns pointing at it park until it is active again. Omitted fields are left alone. Sends nothing.
Add to pool (email_pools.add_sender)
[ADMIN ONLY] Add ONE account email address to a sending pool, appended to the end of the rotation. Use this instead of replacing the whole member list when a single sender is joining. The address must already be ready to send, since a pending sender in a pool is skipped at send time. Re-adding an existing member does nothing and keeps its place in the rotation. If the pool has a warmup plan with auto-enrol switched on, the new member starts that ramp from its own day one rather than joining at the volume the established members already send. From the next bulk send onward, some recipients will see this address as the From — it does not send anything by itself.
Remove from pool (email_pools.remove_sender)
[ADMIN ONLY] Take ONE email address out of a sending pool's rotation. The address itself is not deleted and keeps working on its own; every other member of the pool is left in place. Later bulk sends through this pool stop coming from this address, which concentrates the same volume on the remaining members — worth checking against their warmup allowances. Sends nothing.
Delete email pool (email_pools.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete an email pool and its member list. The member email addresses themselves are NOT deleted and keep working individually. Any broadcast still pointing at this pool falls back to the account default sender on its next send, which changes what recipients see — that is why this asks for confirmation.
Warm up pool (email_pools.set_warmup)
[ADMIN ONLY] Put every address in a sending pool onto one warmup ramp, in a single call. While warming, pool rotation caps each member at its own daily allowance (day-one volume, plus the increment for each elapsed day, levelling off at the maximum, counted per UTC day) and parks the rest of a campaign until the next day rather than failing it. Pick a named plan — gentle (5/day +5, up to 100), standard (10/day +10, up to 200) or fast (25/day +25, up to 500) — or 'custom' with your own numbers. Staggering starts each member's ramp a few days after the last, so a pool of new mailboxes does not step up in lockstep. Members that are not ready to send are skipped rather than enrolled, since their ramp clock would otherwise run down while they sat idle. Changes future pacing only; sends nothing and costs nothing.

Actions — email_signatures

7 operations.

List signatures (email_signatures.list)
[READ] List every email signature in the account — shared ones and each teammate's own — with the rendered HTML each would append. Reads only.
Open a signature (email_signatures.get)
[READ] Fetch one signature by id, with its fields and the exact HTML and plain text it appends to an email.
Create signature (email_signatures.create)
Create an email signature and render it. Nothing is sent — but the FIRST signature in a scope automatically becomes that scope's default, so an account signature created here starts appending to outbound email from the next send. Image URLs (logo, portrait, banner) must be publicly reachable: mail clients fetch them directly and a login-protected URL shows as a broken image in every inbox.
Save changes (email_signatures.update)
Update an existing signature and re-render it. Omitted fields are left alone, except socials, which replaces the whole list when supplied. Sends nothing — but this signature is appended to email from the next send onwards, so a change here changes what recipients see.
Make default (email_signatures.set_default)
Make one signature the default within its own scope, demoting the current default there. An account default is what signs email from anyone who has not made their own, so this changes what recipients see on the next send.
Delete signature (email_signatures.delete)
[HIGH RISK] Permanently delete a signature. This cannot be undone. Email already sent keeps the signature it went out with; new email stops using this one, and if it was a default the oldest remaining signature in that scope takes over.
Preview a signature (email_signatures.preview)
[READ] Render signature HTML and plain text from a set of fields WITHOUT saving anything. Use it to check a layout before creating a signature, or to produce markup to paste into Gmail, Outlook or Apple Mail. Changes nothing and sends nothing.

Actions — email_validation

5 operations.

View email validation settings (email_validation.get)
[READ] Read whether automatic email validation is enabled, which provider it uses, and which contact-capture channels are covered. Never returns provider credentials and performs no billable validation. Any member can read this, exactly as /settings/email-policy shows the panel to everyone and only disables the inputs for non-managers. `never_bounce_key_saved` says whether a NeverBounce key is on file; it is reported as false to members, because the page withholds that one fact from them too.
Save settings (email_validation.save)
[ADMIN ONLY] Save automatic email-validation settings for the account. When enabled, each selected contact-capture channel can make a real single-address request to its own Mailgun or NeverBounce account and may incur that provider's validation charges. An explicit invalid or disposable result blocks that email from entering the CRM; provider errors and timeouts fail open.
Validate email (email_validation.start_bulk)
[HIGH RISK] Start a background job that validates each listed contact's email address through its own Mailgun or NeverBounce account and stamps the verdict (valid, catch-all, unknown, invalid, disposable) on each contact. Every check is a real provider request that can use a paid validation credit; by default contacts whose current address was already checked are skipped. Returns the job id immediately — poll email_validation.job_status for progress.
Validation run progress (email_validation.job_status)
[READ] Read the progress of background email-validation runs: processed/total, live verdict counts, skips, failures, and final status. Pass an id for one run, or omit it for the most recent runs. Reading progress also nudges an unfinished run forward.
Cancel validation run (email_validation.cancel_job)
Stop a queued or running background email-validation run. Contacts already checked keep their stamped verdicts; no further provider credits are spent.

Actions — enrichment

2 operations.

Enrich contact (enrichment.run)
[HIGH RISK] Fill a contact's EMPTY fields by cascading through data sources the account already has, cheapest first: facts captured about them as a tracked website visitor, the company domain inferred from a business email, the Domain Leads WHOIS database (only when the account owns that app), and a queued line-type lookup on the account's own Twilio (~$0.008). With allow_paid=true it may additionally spend ONE Outscraper Google-Maps lookup per contact (~$0.003, billed to its own Outscraper account) for business contacts still missing phone/address details. Existing values are never overwritten — this only fills blanks — and every step is recorded in the enrichment history with what it filled and what it cost.
Enrichment history (enrichment.history)
[READ] List what enrichment has done to a contact, newest first: for each run and step, which fields were filled with what values, which steps were skipped and why (paywall, paid lookups off, cap reached), and the estimated cost of any paid lookups.

Actions — events

1 operation.

Emit an app event (events.emit)
Fire one of your app's own events into the account. Any automation whose trigger is 'App event' (matched to your app + this event key) runs. Use it to let people build workflows that start when something happens in your app. Needs the events:write scope.

Actions — forms

21 operations.

List forms (forms.list)
[READ] List the account's standalone forms, surveys, quizzes, and applications, newest first. This only reads data.
Open a form (forms.get)
[READ] Fetch one standalone form in full: its draft question definition, behavior settings, design theme, and the separate published snapshot visitors currently see. The `definition.questions[].id` values in the result are what a response's `answers` object is keyed by, so this is where you get them before submitting an answer — and `definition`/`settings`/`theme` here are exactly the objects forms.update expects back, so read this first whenever you intend to edit one. This only reads data.
Create form (forms.create)
Create a new draft standalone form from a built-in starting point. This does not publish it or contact anyone.
Save form (forms.update)
Save a form's draft name, description, question definition, behavior, or design. WHOLE-OBJECT REPLACEMENT: `definition`, `settings` and `theme` are each stored as a single JSON blob, so passing one REPLACES it outright — send a definition with two questions and a form that had ten now has two, and the eight you left out are gone along with any logic rules that referenced them. Never assemble one of these from just the parts the request mentioned; read the current object with forms.get, change what you need, and send the whole thing back. Fields you omit entirely are untouched. Published visitors keep seeing the prior snapshot until Publish is run, so a mistake here is recoverable right up until then.
Publish (forms.publish)
[HIGH RISK] Publish the current draft as a new public snapshot at the form's hosted URL. Real visitors can immediately submit it, create CRM contacts, and trigger configured workflows.
Unpublish (forms.unpublish)
[HIGH RISK] Take a public form offline. Existing responses remain available, but its hosted link stops accepting new ones.
Duplicate form (forms.duplicate)
Create a private draft copy of a form's questions, rules, settings, and design. Responses are not copied and nothing is published.
Delete form (forms.delete)
[HIGH RISK] Permanently delete a form and every partial and completed response it collected. This cannot be undone.
Share a form (forms.get_share_links)
[READ] Get everything needed to put a form in front of people: its hosted public URL, the ready-to-paste <iframe> embed snippet for someone else's website, and whether it is actually published yet. This is the app's Share tab, which until now was the only place the slug was ever joined into a URL. A DRAFT form still returns its would-be link, but that link does not work for visitors until forms.publish has been run — check `published` before handing the URL to anyone. This only reads data and shares nothing on your behalf.
Form results (forms.stats)
[READ] Get the four headline numbers from a form's Results screen: how many times the public form was VIEWED, how many responses were completed, how many were left partial, and the conversion rate (completed as a percentage of views, rounded). forms.list_responses returns the responses but has no view count, so conversion cannot be worked out from it — this is the only place that number exists. Counts cover the form's whole lifetime. This only reads data.
Export responses CSV (forms.export_responses)
[READ] Export a form's responses as CSV text, byte-for-byte what the Results screen's Export CSV button downloads: a header row of Status, Started, Completed, Score followed by one column per question (statement blocks are skipped because nobody answers them), then one row per response. Multi-select answers are joined with '; ' and an uploaded file shows as its filename. Columns follow the DRAFT question list, so a question added since a response came in appears as an empty column for that row. Returns the CSV as a string for you to save — nothing is emailed or uploaded anywhere. This only reads data.
List responses (forms.list_responses)
[READ] List partial or completed responses for a form, including answers, score, outcome, and linked CRM contact. This only reads data.
Open response (forms.get_response)
[READ] Fetch one form response with its answers, completion status, score, outcome, and linked CRM contact. This only reads data.
Submit response (forms.submit_response)
[HIGH RISK] Submit answers to a published form as a real completed response. This can create or update a CRM contact and immediately start any workflows listening for this form, which may send real email, SMS, or calls billed to the account.
Save form progress (forms.save_partial_response)
Save a respondent's answers SO FAR as a partial (unfinished) response — what the public form does in the background while someone is still typing, so a half-filled form is not lost. Deliberately quiet: unlike forms.submit_response this creates NO CRM contact and starts NO workflows, so nothing is emailed, texted, called or billed. The response is stored against your session_id and is upserted, so calling this repeatedly with the same session_id updates the same row as the person progresses; finish with forms.submit_response using that SAME session_id and the partial becomes the completed response. Required questions are not enforced until then. The form must be published. Note that the app only auto-saves partials when the form's 'Save partial responses' setting is on, whereas this capability — like the public route behind it — writes one either way.
Upload response file (forms.upload_response_file)
[HIGH RISK] Upload one file as the answer to a form question of type 'file' — the only way to answer that question type, since an answer to it is a stored file rather than text. Limits match the public form exactly: at most 10 MB, and only JPEG, PNG or WebP images, PDFs, plain text, or Word documents (.doc/.docx). THE SERVER DECIDES THE FILE'S TYPE, from the extension on `filename` plus the uploaded bytes' own signature — nothing you declare is stored or served, and a file whose contents do not match its extension (an HTML page named .png) is refused outright rather than filed away under the type it claimed. The file is written to the account's private form-uploads storage and STAYS THERE permanently, counting against the account's storage; there is no capability that deletes it. This does not answer the question by itself — take the object it returns and put it in `answers` under that question's id when you call forms.save_partial_response or forms.submit_response.
Closing message (forms.set_closed_message)
Set what the form's public link says once it stops taking answers — after Unpublish, or after Archive. Visitors who already hold the link see this instead of a 'not found' page, under the account's own branding, and submissions are still refused. Changing it takes effect immediately and does NOT republish the form: the closing message is read from the draft settings precisely so a closed form can be re-worded without accidentally reopening it. Harmless on a live form — it simply sits unused until the form is closed.
Archive form (forms.archive)
[HIGH RISK] Retire a finished form. Every partial and completed response is KEPT, the form id does not change, and any workflow pointed at it stays connected — nothing is deleted. What changes is two things: it leaves the main Forms list for the Archived tab, and its public link stops accepting submissions and serves the form's closing message instead of the form. Use forms.restore to bring it back as a draft.
Restore to draft (forms.restore)
Take a form back out of the archive. It returns as a DRAFT, never straight to live: reopening a form to the public is a deliberate act, so nothing is published and the link keeps showing the closing message until someone calls forms.publish. Nothing about the responses, the id or the connected workflows changes.
Question mapping (forms.set_question_mapping)
[HIGH RISK] Point one question at the CRM: which contact field its answer fills, whether a later submission may REPLACE what is already stored there, and — for a consent question — which marketing permission switches its latest answer controls. Configuration only; it writes nothing to any contact by itself, but it decides what every future submission of this form does. Mapping a consent question to a permission means a ticked box switches that channel on and an UNTICKED box switches it off and records a withdrawal, so the newest answer always wins.
Record consent answer (forms.record_consent_answer)
[HIGH RISK] Record one person's answer to a form's consent question as if they had just submitted it, and apply it to their real marketing permission. THIS SENDS OR STOPS REAL MESSAGES BY CONSEQUENCE: granted true switches the channel back on so campaigns and automations can reach them again, granted false switches it off immediately and every campaign, automation and bulk send on that channel stops. It is written to the same switch the unsubscribe center uses, filed as the CONTACT's own answer on a public form, and recorded on their communication-preferences history with the date and the exact wording the question shows. Use it for consent captured outside the hosted form — a paper form, a phone call against the same wording, an import — not as a way to opt people in without an answer. A granted SMS consent never overrides a carrier-level STOP: that opt-out stands until the person texts START, and the response says so.

Actions — funnels

81 operations.

Save plan and continue (site_builds.revise_plan)
[HIGH RISK] Apply a reviewed sitemap revision and continue building added or explicitly selected pages. Preserves existing page content by default and keeps excluded pages intact. Changes draft routes and shared navigation; nothing is published. Resumed generation SPENDS REAL MONEY within the existing AI call and dollar allowances.
Approve resource setup (site_builds.approve_resources)
[HIGH RISK] Approve the exact reviewed CMS draft entries, local membership access definitions and paused manual follow-up workflows for a site build. CMS and access setup requires account management permission. Reviewed access setup enables native login for an unpublished new site; an existing published site requires explicitly enabling login first. Creates no member grants, sends no messages, activates no workflow and publishes no pages. Continuing the build SPENDS REAL MONEY within its already approved AI allowance.
Save AI spending limit (site_builds.set_budget)
[HIGH RISK] Change the total authorized AI provider spending limit for a saved build. This authorizes REAL MONEY spending when the build resumes. Explicit null removes the dollar cap while retaining its AI call allowance. The new cap must cover recorded charges and outstanding reservations. Pause active work before changing it; this action does not resume the build.
Refresh provider charges (site_builds.reconcile_spend)
Retrieve authoritative provider receipts for uncertain requests already sent by this build, updating actual charges and releasing only reconciled reservations. Makes no new AI generation request and incurs no generation charge. Missing provider receipts remain explicitly uncertain.
Choose build connections (site_builds.input_resources)
[READ] List up to 200 active products and booking events in this account for resolving a site's build plan. Returns resource ids and names only; makes no paid calls and changes no records.
Published release history (funnels.list_releases)
[READ] List the last 50 immutable public releases for this site, including publications and rollbacks. This reads history without changing drafts or what visitors see.
Restore live release (funnels.restore_release)
[HIGH RISK] Restore a previously published site's page content, routes, SEO, access presentation and design tokens together for real visitors. Keeps current working drafts and saves the outgoing live state. Running A/B tests are paused. This changes the live site immediately; it does not grant entitlements, change current product prices or charge anyone.
List AI site builds (site_builds.list)
[READ] List saved AI site builds in this account, including progress, remaining call allowance and unresolved issues. Reads only; it does not run a model or change any page.
View AI build progress (site_builds.get)
[READ] Read a saved site's build plan, task progress, issues and activity. Reports partial and failed work explicitly. This polling call never spends money or drives the runner.
Pause build (site_builds.pause)
Pause an AI site build at its saved checkpoint. A provider request already sent may still be billed, but its late result cannot overwrite the draft after this control takes effect. Completed draft pages are kept.
Resume build (site_builds.resume)
[HIGH RISK] Resume an AI site build from saved progress, retrying unfinished work. SPENDS REAL MONEY on the account's connected AI provider within the remaining call allowance. Optionally authorize additional paid attempts; completed pages are preserved and nothing is published.
Cancel build (site_builds.cancel)
[HIGH RISK] Cancel the remaining AI work for a site build. Completed draft pages and activity stay available. No more tasks can commit results; provider requests already sent may still be billed. Cancelling does not unpublish or delete any site.
Inspect native page components (funnel_pages.component_schema)
[READ] Read the native editor's actual component fields, defaults, layout slots and limits. Use this contract to create fully editable documents. No custom code is executed and no model is called.
Validate a page document (funnel_pages.validate)
[READ] Check a proposed native document against the same strict field and layout contract used by saves and publishing. Returns precise issues without removing unsupported content. No page changes or paid calls occur.
Apply native page changes (funnel_pages.patch)
Apply an atomic batch of native component operations to a page draft with revision checking and an automatic restore point. Nested slots and property paths are supported. A failed operation or stale revision rejects the entire batch. Nothing is published and no AI is called.
List funnels (funnels.list)
[READ] List the organization's funnels, most recently edited first. Each funnel is a sequence of landing pages served at /f/<slug>.
Open a funnel (funnels.get)
[READ] Fetch one funnel with its steps (pages), connected custom domains, theme, and total form submissions. Page documents are omitted — use funnel_pages.get for a page's content.
Create a site (funnels.create)
Create a draft funnel, standalone website, or members-only member site and seed its home page with a ready-made layout. A member site (kind 'course', kept for compatibility) enables member login but does not publish or grant anyone access. Nothing is visible until funnels.publish is called. Actual courses (modules/lessons/quizzes) are built with the courses.* capabilities and mounted on a member site.
Rename a funnel (funnels.update)
[HIGH RISK] Rename a funnel or change its description or public slug. CHANGING THE SLUG MOVES THE FUNNEL'S PUBLIC URL: every link already shared at the old /f/<slug> — in sent emails, in live ads, on printed material, in other people's posts — breaks immediately and there is no redirect from the old address. Renaming alone is internal and safe; the slug is the irreversible part. Omitted fields are left alone.
Duplicate a funnel (funnels.duplicate)
Copy a funnel — its theme and every page's working draft — into a brand-new DRAFT funnel on a fresh URL. Component ids are regenerated so the copy and the original can never interfere. Nothing is published, and the original is untouched.
Publish a funnel (funnels.publish)
[HIGH RISK] PUT THIS FUNNEL ON THE PUBLIC INTERNET. Every validated draft page and the draft theme are published together and become reachable at /f/<slug> (and on any active custom domain) to anyone with the link, with no login. Publish only when the content is ready to be seen by customers.
Take a funnel offline (funnels.unpublish)
[HIGH RISK] Take a live funnel off the public internet. Visitors on /f/<slug> and on any custom domain immediately stop being able to reach it. Content and pages are kept — publish again to restore it.
Delete a funnel (funnels.delete)
[HIGH RISK] PERMANENTLY DESTROY a funnel and everything under it: every page and its published content, every saved version, the funnel's captured submissions, and its connected custom domains. This cannot be undone. Templates already saved from it, and funnels built from those templates, are unaffected.
List theme presets (funnels.list_theme_presets)
[READ] List complete design themes and color-only schemes for websites and funnels. The presets array includes typography and spacing; color_schemes changes only colors and preserves the design. Pass a color_schemes id as color_scheme.preset to funnels.set_theme or funnel_templates.use. This read saves or publishes nothing.
Change a funnel's theme (funnels.set_theme)
Save site-wide design tokens as an unpublished draft. To change only colors and preserve fonts, spacing, buttons and content, pass color_scheme with a preset or custom brand/background colors. Alternatively pass a complete theme preset, overrides, or both. Every page uses the changes after the next publish; no live page changes or messages are sent now.
Funnel performance (funnels.stats)
[READ] Conversion stats per step for a funnel over the last N days: views, unique visitors, form submissions, paid orders and revenue (cents, net of refunds). This is what the Performance report on the funnel page shows.
List funnel submissions (funnels.list_submissions)
[READ] Read website inquiries and funnel opt-in submissions, newest first, including every submitted answer and the linked CRM contact. Filter by website, page or contact. This is read-only; it does not contact anyone or run automations.
List A/B tests (funnels.list_ab_tests)
[READ] List the A/B tests in this account — per test: the page it runs on, label, traffic weight, lifecycle status (draft/running/paused/winner/archived), and when it started or concluded. Filter by funnel, page, or status. Use funnels.ab_test_results for the numbers.
Test a different version (funnels.create_ab_variant)
Create an A/B test on a funnel page: a full, independently editable copy of the page's current live content ("version B"). Created as a DRAFT — no visitor sees it and nothing changes on the live page until funnels.start_ab_test is called. A page can hold one active test at a time; creating a second returns an error naming the existing one.
Edit an A/B test variant (funnels.update_ab_variant)
[HIGH RISK] Change an A/B test's challenger: its document (same Puck shape as a page's content), its label, or the share of traffic that sees it. Pause a running test before editing it. Concluded tests cannot be edited.
Start an A/B test (funnels.start_ab_test)
[HIGH RISK] PUT THE TEST IN FRONT OF REAL VISITORS. From the moment this runs (within about a minute of cache), the chosen percentage of visitors to the page is served the challenger document instead of the live page. Assignment is deterministic and sticky per visitor. Also resumes a paused test. The variant must not have concluded.
Pause an A/B test (funnels.stop_ab_test)
Pause a running A/B test: within about a minute every visitor sees the original page again. Results collected so far are kept, and the test can be resumed with funnels.start_ab_test or concluded with funnels.declare_ab_winner.
A/B test results (funnels.ab_test_results)
[READ] Per-arm results for an A/B test: visitors, views, form submissions, paid orders, revenue (cents), conversion rate, and a plain-language statistical readout. Conversions = submissions + orders. A verdict is only called "confident" at p < 0.05 with at least 100 visitors in each arm; below that the readout says to keep collecting.
Discard an A/B test (funnels.discard_ab_test)
[HIGH RISK] Archive a draft or paused A/B test without adopting it: the challenger document stops being served or editable, its collected results are closed out, and the test cannot be restarted. The LIVE PAGE IS NOT TOUCHED — visitors keep seeing it exactly as published. A running test must be paused (funnels.stop_ab_test) or concluded (funnels.declare_ab_winner) instead.
Declare an A/B test winner (funnels.declare_ab_winner)
[HIGH RISK] CONCLUDE AN A/B TEST, IRREVERSIBLY CHANGING WHAT VISITORS SEE. Declaring 'b' OVERWRITES the live page's published content (and its draft) with the challenger's document — every visitor sees it immediately; the beaten version is kept only as a restore point in the page's version history. Declaring 'a' keeps the page exactly as it is and archives the challenger. Either way the traffic split stops and the test cannot be restarted.
Build with AI (funnels.generate)
[HIGH RISK] Start a durable AI site build that plans, writes and checks native editable pages in the background. Returns a build id immediately; use site_builds.get for progress, issues and the saved draft. Nothing is published. SPENDS REAL MONEY on the account’s connected AI provider, up to max_calls model attempts. The run pauses on missing input or its call limit and can resume without rebuilding completed pages.
Match a screenshot (funnels.match_screenshot)
[HIGH RISK] Analyze a reference website screenshot and restyle a supplied page document to match its visual direction using only structured, editable builder components. Returns the revised draft document but does not save or publish it — pass it to funnel_pages.save_content to keep it. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good. TWO billed calls per run: the vision pass over the screenshot, then the page edit.
Rewrite page copy (funnels.rewrite_copy)
[HIGH RISK] Rewrite one snippet of page copy — a headline, a subhead, a button label — and return the new text. No page is changed; write the result back with funnel_pages.save_content yourself. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good.
Generate a page image (funnels.generate_image)
[HIGH RISK] Generate an image from a description, store it in the organization's media bucket, and return its permanent URL for use in a page component's image prop. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good.
List funnel steps (funnel_pages.list)
[READ] List a funnel's pages in step order. Page documents are omitted — call funnel_pages.get for a page's content.
Open a funnel page (funnel_pages.get)
[READ] Fetch one page with BOTH documents: `content` is the working draft you edit, `published_content` is what visitors currently see. Read this before editing a page — funnel_pages.save_content expects a document in the same shape.
Save SEO (funnel_pages.update_seo)
Save a page's search title, meta description, canonical URL, social image, and search-index visibility. This changes metadata on the working page record; published pages retain their metadata until the next publish.
Add a funnel step (funnel_pages.create)
Add a page to the end of a funnel, seeded with a ready-made starter layout for the chosen step type. It is created as a draft; publish it separately with funnel_pages.publish.
Rename a funnel step (funnel_pages.update)
[HIGH RISK] Rename a page, change its draft URL path, or change its step type with revision checking. Path changes update the site's native draft links, redirects and shared sections together, and require whole-site publication. Live content keeps its old routes until then. Publishing moves the public URL; external inbound links require an explicit redirect. Pause running A/B tests before renaming routes. The home page remains fixed at the site root.
Build the page (funnel_pages.generate)
[HIGH RISK] Use AI to write and design a complete new page, then append it to an existing funnel or website as a private DRAFT. It does not publish the page and contacts nobody. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good.
Redirect a page (funnel_pages.set_redirect)
[HIGH RISK] Make a published page send visitors somewhere else instead of rendering. Takes effect after the next publish, on every address it is served at, including the funnel's custom domain. The page's content is kept untouched — pass an empty redirect_url to switch it back on. Works on the home page too, which is how a whole single-page site gets redirected.
Reorder funnel steps (funnel_pages.reorder)
Set the order visitors move through a funnel's steps. Pass every page id of the funnel in the order you want; the first one must be the funnel's home page. Order only — no content or URL changes.
Save a page draft (funnel_pages.save_content)
Save a strictly validated native page document as the working draft. Invalid components and props are rejected with paths, never discarded. The prior draft is snapshotted atomically. Pass expected_revision from the last read to reject stale writes. Live visitors keep the published snapshot.
Publish a page (funnel_pages.publish)
[HIGH RISK] PUT THIS PAGE ON THE PUBLIC INTERNET. Copies the working draft over the live version, so whatever the draft currently says becomes what visitors see at /f/<slug>/<path>. If the funnel itself is still a draft it is published too, because a live page inside an offline funnel is unreachable. A restore point is saved first, so this is undoable via funnel_pages.restore_version.
Take a page offline (funnel_pages.unpublish)
[HIGH RISK] Take one live page off the public internet — visitors on its URL immediately stop being able to reach it. The rest of the funnel stays live. The draft and the last published content are kept, so publishing again restores it.
Delete a funnel step (funnel_pages.delete)
[HIGH RISK] PERMANENTLY DESTROY a page, its live content and its entire version history. This cannot be undone. The home page cannot be deleted — it is the funnel's entry point; delete the funnel instead.
List page versions (funnel_pages.list_versions)
[READ] List a page's saved restore points, newest first — every publish, every AI edit, and every manual snapshot. Documents are omitted; funnel_pages.restore_version brings one back.
Save a restore point (funnel_pages.snapshot)
Save a named restore point for a page. Nothing about the page changes — this only records what the draft looks like now so it can be brought back later.
Restore a page version (funnel_pages.restore_version)
Bring a saved version back into the page's WORKING DRAFT. The live page is not touched — publish afterwards if you want visitors to see it. The draft being replaced is snapshotted first, so a restore is itself undoable.
Generate a page with AI (funnel_pages.generate_content)
[HIGH RISK] Generate a complete page document from a prompt and RETURN it for review — no page is created or changed. Pass the result to funnel_pages.save_content to keep it. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good.
Edit a page with AI (funnel_pages.ai_edit)
[HIGH RISK] Apply a natural-language change to a page's draft document ("make the headline punchier", "add a testimonial section") and RETURN the new document — nothing is saved, so pass it to funnel_pages.save_content to keep it. The pre-edit document is snapshotted automatically. If the instruction implies a restyle, the funnel's theme IS changed immediately — that write is not held back for review, and it restyles every page of the funnel including any already published. SPENDS REAL MONEY: it runs on the organization's OWN OpenRouter API key, so the model charge lands directly on the tenant's OpenRouter bill. There is no credit pool and no free allowance — every call is billed and metered against this account, whether or not the result is any good.
List custom domains (funnel_domains.list)
[READ] List the custom domains connected to the organization's funnels, with their verification and TLS status and the CNAME record the tenant has to create.
Connect a custom domain (funnel_domains.attach)
[HIGH RISK · ADMIN ONLY] Point a real hostname the organization owns (e.g. offers.acme.com) at a funnel and register it for a public TLS certificate. This publishes the funnel on a NEW address on the open internet as soon as the tenant's CNAME resolves. Returns the DNS record they must create; use funnel_domains.verify afterwards.
Verify a custom domain (funnel_domains.verify)
Re-check a connected domain with Cloudflare and update its status. Run this once the CNAME record exists — certificate issuance is asynchronous and completes on its own within a few minutes.
Disconnect a custom domain (funnel_domains.detach)
[HIGH RISK · ADMIN ONLY] Disconnect a custom domain and release its Cloudflare hostname and certificate. Everything served on that address STOPS immediately — the funnel, any single pages, and every LinkWizard link hosted on it, including copies already shared. The funnel itself, its /f/<slug> URL, and the links themselves are kept and can be moved elsewhere.
List templates (funnel_templates.list)
[READ] List the funnel and website templates available to start from: the organization's own saved ones plus the built-in niche library. Returns each template's niche, tags, page names and paths, and setup checklist so you can choose a complete starting point. Every template is a frozen, fully editable copy of its theme and pages; listing creates and publishes nothing.
Open a template (funnel_templates.get)
[READ] Fetch one funnel or website template with its theme, niche, tags, setup checklist, and the full editable document of every page it carries. Use funnel_templates.use to copy all its pages as a private draft, then funnel_pages.ai_edit and funnel_pages.save_content to customize them. This read creates and publishes nothing.
Save a funnel as a template (funnel_templates.save_from_funnel)
Freeze a funnel's theme and every page's WORKING DRAFT into a reusable template. It is a snapshot, not a link — editing the funnel afterwards never changes the template, and funnels built from it are never coupled back to it.
Save page as template (page_templates.save_from_page)
Freeze one funnel page's current working draft as a reusable individual-page template. It is a private snapshot; later edits to either the source page or a copied page never change the other.
Add page from template (page_templates.add_to_funnel)
Add a new draft page to an existing funnel or website from an individual-page template. Complete multi-page website templates must use funnel_templates.use so no pages are discarded. The copied builder document receives fresh component ids, stays fully editable, and is never published automatically.
Save section as template (section_templates.save_from_page)
Freeze one top-level section from a page's working draft as a reusable section template, including its nested columns, copy, images, and styles. Creating the template publishes nothing.
Add saved section (section_templates.insert_into_page)
Append a fresh editable copy of a saved section to the bottom of a page's working draft. The public page is unchanged until someone publishes it.
Use template (funnel_templates.use)
Create a new funnel or website from a template — theme and every page copied in, with fresh component ids. Optionally pass color_scheme to change colors across every page while keeping fonts and layout. Returns each new page id and builder link, plus a setup checklist. Every section remains editable in the builder and by AI: call funnel_pages.ai_edit with a page id, then funnel_pages.save_content to keep the returned document. Everything lands as a DRAFT and is never published automatically; installation sends no messages and charges no payments.
Delete a funnel template (funnel_templates.delete)
[HIGH RISK] PERMANENTLY DESTROY one of the organization's saved funnel templates, including every page document frozen inside it. This cannot be undone. Funnels already built from it are unaffected. Built-in platform templates can't be deleted.
List products (products.list)
[READ] List what the organization's funnels sell. A product can be the main offer on one funnel's order form and the order bump or one-click upsell on another. Amounts are integer cents.
Open a product (products.get)
[READ] Fetch one product with its pricing, currency and billing interval.
Create a product (products.create)
Add a sellable product to the catalogue so it can be attached to an order form, an order bump or a one-click upsell inside the builder. Creating a product charges nobody — checkouts run on the organization's own connected Stripe account, and nothing can be sold until Stripe is connected.
Edit a product (products.update)
[HIGH RISK] Update a product's name, price, currency, billing kind, artwork, or which Stripe account and live/test mode it charges on. THIS CHANGES WHAT REAL BUYERS ARE CHARGED: a new price takes effect at the next checkout on every funnel offering this product, and switching payment_mode to 'test' means live customers' cards stop actually being charged while the pages carry on looking like they are working (switching to 'live' does the reverse). Past orders are never rewritten — an order item copies the amount at purchase time. Omitted fields are left alone.
Archive or restore a product (products.archive)
Take a product out of the builder's pickers (archive) or put it back (restore). Products are archived rather than deleted because past orders reference them and a sold product has to stay resolvable for reporting.
List funnel orders (funnels.list_orders)
[READ] List orders taken through the organization's FUNNEL checkouts — the Orders screen under Funnels — newest first, each with buyer, payment status, amount, refunded amount and, unless you turn them off, its line items (main product, order bump, upsells and downsells). This is the funnel side of the business and it has no other reader: commerce.list_orders answers only for the storefront and hard-excludes everything here. Amounts are in the smallest currency unit (cents), and collected revenue is total minus refunded counting ONLY orders whose status is 'paid' — a 'pending' order is an abandoned checkout, not a sale. Read-only. The order token is never returned: it is a bearer credential that can charge a buyer's saved card.
Open a funnel order (funnels.get_order)
[READ] Fetch one FUNNEL checkout order with its buyer, payment status, amount and refunded amount, plus every line item — the main product, any order bump, and each upsell or downsell that was accepted, with what each was charged. commerce.get_order refuses anything that is not a storefront order, so this is the only reader for these. Amounts are in the smallest currency unit (cents). Read-only. The order token is never returned: it is a bearer credential that can charge the card saved on this order.
Save payment settings (funnels.set_payment_route)
[HIGH RISK] Choose which connected Stripe account collects the money for a funnel, and whether it charges in live or test mode. THIS DECIDES WHERE REAL CUSTOMER MONEY LANDS. Pointing it at the wrong account sends this funnel's takings to another business's Stripe; setting mode to 'test' means every checkout on the funnel's LIVE published pages silently stops charging anyone — the pages keep working and buyers keep getting confirmation, and nothing is collected. It applies from the next checkout onward: orders already placed keep the account and mode pinned onto them at the time, so nothing in the past moves. The equivalent for a storefront is commerce.update_store; funnels.update deliberately does not accept these two columns, so this is the only way to set them.
Submit form (funnels.submit_form)
[HIGH RISK] Submit a real opt-in form on a PUBLISHED funnel page, exactly as a visitor filling it in would. THIS IS NOT A TEST: it creates or updates a REAL CRM CONTACT from the email and phone in the answers, stores a funnel submission against the page, counts toward that page's conversion stats, and immediately fires every `form_submitted` automation in the account — which can send real email, SMS or ringless voicemail to that person and bill the tenant's own provider accounts for it. There is no draft and no undo. Field names and which are required are read from the form's OWN published definition, not from what you send, so an answer for a field the form does not have is ignored and a missing required field is an error. Deduplication is the platform's: one phone number is one contact, matched on email first and then phone in any spelling it might be stored under, so submitting twice updates one person rather than creating two. Use funnels.list_submissions to read what has already come in.
Complete my order (funnels.checkout)
[HIGH RISK] Start a REAL purchase through a published funnel's order form: creates the order, creates or matches a Stripe customer on the seller's own account, and returns a PaymentIntent client secret for collecting the card. THIS IS THE LIVE CHECKOUT — unless the funnel is set to test mode (funnels.set_payment_route), the card charged is charged for real, on the tenant's own Stripe, and Stripe's fees apply. What is being sold and what it costs come from the ORDER FORM'S OWN published definition and from the product table, never from this call: you name the block, and the price is re-derived server-side, so there is no way to buy a $997 offer for $1. Nothing is collected yet at this point — the order is created as 'pending' and the card still has to be confirmed by whoever holds the client secret; call funnels.complete_checkout with the returned token once it clears. The returned `token` is a BEARER CREDENTIAL: for the next two hours it alone authorises funnels.accept_upsell to charge the saved card again with no further card entry, so treat it like a password and never store it where a reader of orders could reach it.
Settle a funnel order (funnels.complete_checkout)
[HIGH RISK] Settle a funnel order once its card payment has cleared: asks STRIPE whether the payment actually succeeded — the caller's word is never taken for it — and, if it did, marks the order paid, saves the card for one-click upsells, links or creates the buyer's CRM contact, records the revenue against the page, and fires the account's `purchase_made` automations, which can send real email, SMS or voicemail billed to the tenant's own provider accounts. Idempotent: an order already settled (by this call or by Stripe's webhook, which is authoritative and will settle it either way) simply reports 'paid' and does nothing again. This exists because the very next funnel step is usually a one-click upsell, which needs the order to be paid with a saved card NOW rather than whenever the webhook lands. It does not charge anything itself.
Yes, add it to my order (funnels.accept_upsell)
[HIGH RISK] Accept a one-click upsell or downsell on a funnel — the button on the offer page after a purchase. THIS CHARGES MONEY IMMEDIATELY AND WITH NO CARD ENTRY: it creates a NEW Stripe PaymentIntent and confirms it off-session against the card already saved on the original order, so the buyer is charged again the moment this returns. The only credential involved is the order token, which is why the window is short — the original order must be PAID and less than two hours old, or the charge is refused. What is sold and what it costs come from the upsell block's OWN published definition and the product table, never from this call, so a token buys that page's offer at that page's price and nothing else. Charging the same offer twice on the same order is prevented by a unique constraint, so a repeat call is a no-op rather than a double charge. On success it records the revenue against the page and fires the account's `upsell_accepted` automations, which can send real messages billed to the tenant's own provider accounts. There is no undo — reversing it means refunding in Stripe.

Actions — github

24 operations.

Summarize repository contributions (github.repository_work_summary)
[READ] Read one compact daily contributor summary for an explicit selection of this account's tracked repositories. Combines saved mirror and remote-branch commits, deduplicates SHAs across forks, separates merges and unknown authors, and returns measured line coverage, contributor member IDs when unambiguously linked, current members and completed branch-index coverage. Reads at most 1,000 rows per source within a time budget; incomplete reads are explicit lower bounds. Makes no GitHub or model requests, sends no messages and changes nothing. Use this first for a group report, then request only bounded member_work_report patch samples. Lines and commits do not measure hours, value or employment performance.
Index remote branch activity (github.start_branch_backfill)
[ADMIN ONLY] Queue a resumable scan of current remote branches in this account's tracked repositories for a date window. Saves commit metadata and line totals once so member reports can query an index, including unfinished branches without pull requests. Uses the account's GitHub API quota and Chirply background processing, sends no messages and modifies no remote repositories. Active identical date-and-repository requests reuse one job. Optional repositories creates a separate selected-repository job; omitted selection retains account-wide indexing. Neither changes shared tracking or an existing job. Historical evidence proves reachable commits by commit date, not exact push times or deleted/local branches. Inspect progress with github.branch_backfill_status.
Check remote branch indexing (github.branch_backfill_status)
[READ] Read saved indexing progress, inspected branches, pending repositories and failures for one account-scoped backfill, or the latest account-wide job when both ID and repositories are omitted. An optional repository selection matches only that exact scoped job; an explicit ID without repositories may read any job in this account. Returns not_started if no job matches the requested scope. Makes no GitHub requests and starts no work. Partial or unfinished indexing is unknown coverage, not zero work.
Review a team member’s code (github.member_work_report)
[READ] Resolve a Chirply member's linked GitHub logins or self-reported profile username, search default-branch commits across connected accounts, reconcile stored evidence, and aggregate up to 1,000 unique commits with independent stats-only batches, per-repository totals and up to 60 listed commit details plus bounded sample diffs. Also finds up to 20 authored pull requests updated in the window, with current diff snapshots for up to two, separating merged work from work in progress. All evidence is restricted to this account's tracked repositories, optionally narrowed by exact repository names without changing shared tracking. Selected searches use bounded repository batches; unsearched batches remain explicit partial coverage. PR snapshots may include older work and other contributors and are not added to daily line totals. The calling AI gives a concise scorecard and evidence-based light review; large workloads can skip patch review. Sends no messages, makes no model call, and modifies no repositories. Reports missing identity, partial coverage and search failures explicitly; line counts do not measure time or productivity.
Check the GitHub connection (github.status)
[READ] Report whether this account has a GitHub connection, which organization it points at, how many repositories are mirrored and followed, how many commits are stored, and when the last sync ran. Read-only, touches GitHub's API not at all (it reads the local mirror), and costs nothing. Start here when a code report comes back empty — the usual causes are no connection, no followed repositories, or a token that can't see the organization.
List connected GitHub accounts (github.list_accounts)
[READ] List every GitHub account this Chirply account has connected, with the GitHub login each token belongs to and how many repositories it reaches. Read-only; costs nothing. Worth checking whenever a repository seems missing: a personal access token only reaches what ITS OWN GitHub user can see, so work living under a second GitHub account is invisible until that account is connected too — no scope change on the first token will ever reveal it.
Connect another GitHub account (github.add_account)
[ADMIN ONLY] Connect an ADDITIONAL GitHub account alongside the ones already linked, using a personal access token belonging to that GitHub user. This is the fix when repositories are missing and no permission change reveals them: a token can only ever reach what its own GitHub user can see, so a second account needs a second token. The token is verified against GitHub before it is stored and is encrypted with AES-256-GCM; it is never returned. Give each account a short label so it can be told apart later. Costs nothing.
Disconnect a GitHub account (github.remove_account)
[HIGH RISK · ADMIN ONLY] Disconnect one of the connected GitHub accounts by its label, deleting its stored token. Repositories and commits already mirrored through it are KEPT, so past reports keep their numbers — they simply stop updating. The first account's label is 'default'. Irreversible: the token cannot be recovered and has to be pasted again to reconnect.
Sync GitHub now (github.sync)
[ADMIN ONLY] Pull the repository list and any new commits from GitHub into this account's code-activity mirror, then link any GitHub accounts whose commit email exactly matches a team member's. Reads GitHub only — it never pushes, comments, or changes anything in a repository. Spends some of the token's hourly GitHub rate limit, and fetches per-commit line counts up to a fixed budget per run, so a very large backlog fills in over several runs rather than all at once. Runs hourly on its own; call this when you want the numbers current right now.
List repositories (github.list_repositories)
[READ] List the repositories mirrored for this account, most recently pushed to first, with whether each one is followed (followed repositories are the ones whose commits are ingested and counted in reports). Read-only from the local mirror; costs nothing and calls GitHub not at all.
Follow or unfollow a repository (github.set_repository_tracking)
[ADMIN ONLY] Choose whether a repository's commits are ingested and counted in this account's code reports. Unfollowing stops future syncs from reading it and drops it out of new reports; commits already stored stay stored, so old digests keep their numbers. Nothing on GitHub changes — this is a local preference only.
List commits (github.list_commits)
[READ] List stored commits, newest first, with author, message, line counts and whether an AI review exists. Filter by repository, by GitHub login, or to a time window. Merge commits are included but flagged — their diff is the whole branch they bring in, so they are excluded from every total this integration reports. Read-only from the local mirror; costs nothing.
Open a commit (github.get_commit)
[READ] Fetch one stored commit with its repository, author, line counts and its AI code review if one has been generated. Read-only from the local mirror; costs nothing and generates nothing — use github.review_commit to produce a review that doesn't exist yet.
List contributors (github.list_contributors)
[READ] Who wrote code in a window, with commits, lines added and removed, repositories touched, and the Chirply team member each GitHub account is linked to (null when nobody has linked it yet). Merge commits are excluded so nobody is credited with a branch they merged. Read-only from the local mirror; costs nothing.
List GitHub accounts (github.list_identities)
[READ] Every GitHub account seen pushing to this workspace's repositories, and which Chirply team member each one is linked to. An unlinked account still appears in reports under its GitHub login — linking is what lets a report say a person's name. Read-only from the local mirror; costs nothing.
Link teammate (github.link_member)
[ADMIN ONLY] Record a manager-confirmed link between a GitHub username and a current team member, including usernames with no synced commits yet. Existing commits are re-pointed to the identity. This changes work attribution; confirm the username belongs to this person. It does not verify GitHub ownership, grant repository access, send messages or cost money.
View team GitHub usernames (github.list_member_profiles)
[READ] Read current account members and the GitHub usernames they entered in their own profiles. These are self-reported hints, not verified ownership; explicit manager mappings are listed separately by github.list_identities. Read-only, sends no messages and costs nothing.
Unlink a GitHub account (github.unlink_member)
[ADMIN ONLY] Remove the link between a GitHub login and a team member. Reports go back to showing the GitHub handle for that account; no commits are deleted and no numbers change. Use it when a link was made to the wrong person.
Summarize code activity (github.activity_summary)
[READ] The whole picture for a window in one call: commits, lines added and removed, the repositories that moved, every contributor's totals, and the AI review scores for that period. Every line total carries how many commits it was measured from, because GitHub's commit list has no line counts and the mirror fills them in progressively — read the two together or you will under-report. Read-only from the local mirror; costs nothing and generates nothing.
AI review a commit (github.review_commit)
Have an AI read one commit's actual diff and score it for correctness, security, data safety and clarity, returning a 0-100 score, a risk level, specific findings and what the change did well. Runs on this account's own OpenRouter key, so it costs the account a model call — one per commit, and a stored review is returned instead of re-billing unless you force a re-review. A very large diff is reviewed from the largest slice that fits and flagged as partial. Merge commits are refused: a merge's diff is the whole branch it brings in, which was already reviewed commit by commit.
Build the code activity digest (github.daily_digest)
Produce and save the report for a window — what shipped, in which repositories, written by whom, and how the code scored — with a plain-English summary a non-engineer can read. Optionally audits some not-yet-reviewed commits first so the quality section rests on real reviews; each audit is a model call billed to this account's own OpenRouter key, and `review_commits` is the spend control. The figures are computed and saved whether or not AI is connected — without it the report is the numbers plus a factual summary rather than a narrative. Re-running a window replaces that window's saved digest.
List saved digests (github.list_digests)
[READ] The code activity digests already built for this account, newest first, each with its window, its figures and its summary. Read-only from the local mirror; costs nothing and generates nothing — use github.daily_digest to build one that doesn't exist yet.
Enable push tracking (github.setup_push_tracking)
[HIGH RISK · ADMIN ONLY] Enable ongoing signed push tracking for this account's tracked GitHub repositories. Saves an encrypted signing secret, then background workers create or repair only hooks pointing at this account's exact Chirply callback. GitHub will send future push metadata to Chirply; existing unrelated hooks and subscriptions are preserved. Uses the connected GitHub tokens and API quota, with no AI generation charge. A repository administrator's token needs Webhooks write permission. Work resumes automatically in bounded batches, including newly tracked repositories; this does not recover past push times. Calling again retries setup without creating duplicate hooks. Read github.push_tracking_status for progress, inaccessible repositories and errors.
Push tracking status (github.push_tracking_status)
[READ] Read durable repository webhook setup progress for this account: tracked repositories and current verification sweep's processed, active, unavailable and failed counts, recent setup errors and last received signed push. Counts restart during the hourly verification sweep. An active hook means GitHub confirmed its push subscription, not that delivery coverage is gap-free. Sends nothing, changes nothing and incurs no AI charge.

Actions — gmail

12 operations.

Gmail accounts (gmail.connections)
[READ] List Gmail accounts explicitly shared with this account, their connecting user and reconnect status. Does not expose tokens, read mailbox contents or send mail.
Connect Gmail (gmail.connect)
[READ · ADMIN ONLY] Get an account-bound browser link to connect another Gmail account. A manager must sign in and consent in Google to share reading and sending access with account members and authorized integrations. This call sends no email.
Disconnect Gmail (gmail.disconnect)
[HIGH RISK · ADMIN ONLY] Remove the saved Gmail authorization from this account and stop its sync and sending. Retains already imported Conversations and delivery receipts; does not delete anything in Google or revoke Calendar/Sheets grants.
Search Gmail (gmail.search)
[READ] Search the selected shared Gmail account using Gmail query syntax. Returns message bodies, attachment references and a next-page token; does not mark messages read in Gmail or send mail.
Read Gmail message (gmail.read_message)
[READ] Read one Gmail message's sender, recipients, subject, plain text, HTML and attachment references from the chosen account account. Does not alter Gmail read status or send mail.
Read Gmail thread (gmail.read_thread)
[READ] Read all messages in a thread from the selected Gmail account, including Sent messages and attachment references. Does not modify the mailbox or send mail.
Read Gmail attachment (gmail.attachment)
[READ] Download one attachment, up to 10 MB, from a message in the chosen Gmail account. Returns standard base64 bytes, filename and MIME type; sends no messages and makes no public file.
Send Gmail message (gmail.send)
[HIGH RISK] Send real email through the selected shared Gmail account, appearing in Gmail Sent. Google sending limits and account recipient opt-outs apply. Reuse idempotencyKey on retries; ambiguous deliveries are reconciled, never automatically resent.
Reply through Gmail (gmail.reply)
[HIGH RISK] Send a real reply through the selected Gmail account to the original sender or Reply-To address. Preserves Gmail thread ID, original subject and RFC reply headers. Appears in Gmail Sent; opt-outs and Google sending limits apply.
Sync new Gmail mail (gmail.sync)
[HIGH RISK] Process one durable page of new mail for this Gmail connection. Adds incoming messages to Conversations and queues matching enabled workflows, which may send real mail or perform other configured actions. Replayed pages are deduplicated.
Import Gmail history (gmail.import_history)
[ADMIN ONLY] Import one page of historical incoming Gmail mail into Conversations. Only mail older than the initial connection is imported. Historical mail never emits incoming-mail automation triggers. Returns nextPageToken for continuing the import; sends no email itself.
Gmail delivery receipts (gmail.deliveries)
[READ] Read the last thirty Gmail send receipts for this account account, including failed and uncertain deliveries. Does not retry or send mail.

Actions — gohighlevel

19 operations.

HighLevel history archive (gohighlevel.read_history_archive)
[READ · ADMIN ONLY] Read locally archived HighLevel conversations and messages for this account. Returns twenty threads or a hundred messages per selected thread, with original IDs, dates, source status and attachment links. Imports cover mapped contacts only; partial threads are labeled. Original email HTML is displayed as text, attachment links can expire, and source-provided bodies may omit full email headers/content. This is an archive, not live inbox synchronization. Reading makes no provider calls, sends no messages and changes nothing. Owner/admin only.
Check free GHL client account (gohighlevel.provisioning_status)
[READ · ADMIN ONLY] Check whether the platform's own GoHighLevel agency can provide this account a free client account and whether one is already provisioning, linked, or failed. Returns no platform or tenant OAuth credentials and changes nothing.
Get free GHL client account (gohighlevel.provision_subaccount)
[HIGH RISK · ADMIN ONLY] Create a real GoHighLevel client account under the platform's own Agency Pro account and immediately attach encrypted location-level API access to this account. This consumes one of the platform's agency client account slots and creates persistent external CRM infrastructure, but sends no customer messages and charges the account nothing.
List GHL integration coverage (gohighlevel.catalog)
[READ] List the official HighLevel API families covered by the universal request action and every named HighLevel Marketplace webhook trigger currently shown in the automation builder. Changes nothing.
Check GHL webhook status (gohighlevel.webhook_status)
[READ · ADMIN ONLY] Read recent signed HighLevel webhook delivery status for this account, including received, processed, and failed totals. Returns no API token and changes nothing.
Check GHL connections (gohighlevel.connection_status)
[READ · ADMIN ONLY] Check the connected HighLevel client account and agency grants, their granted scope counts, token expiry metadata, and a live read against each available authority. Returns no token and changes nothing.
Browse GHL resources (gohighlevel.browse)
[READ · ADMIN ONLY] Browse a guided, read-only HighLevel resource collection using the correct connected authority and account identifier. Supports contacts, pipelines, calendars, workflows, campaigns, conversations, products, forms, surveys, users, client accounts, and snapshots; changes nothing.
Run a guided GHL action (gohighlevel.run_guided_action)
[HIGH RISK · ADMIN ONLY] Run one of the named HighLevel CRM or agency actions using guided fields instead of an endpoint path or JSON. Depending on the selected operation, this can send real messages, create or alter CRM and agency records, spend provider funds, or permanently delete data in HighLevel; the side effect happens immediately.
Run GHL read request (gohighlevel.read)
[READ · ADMIN ONLY] Run any GET endpoint in the official GoHighLevel/LeadConnector API with this account's encrypted token. The request is pinned to services.leadconnectorhq.com; the token itself is never returned. HighLevel may expose sensitive CRM or agency data, limited by the token's own scopes.
Run GHL write request (gohighlevel.write)
[HIGH RISK · ADMIN ONLY] Run any POST, PUT, PATCH, or DELETE endpoint in the official GoHighLevel/LeadConnector API with this account's encrypted token. This can create client accounts, send real messages, charge money, change live CRM data, or delete data depending on the path and token scopes; HighLevel applies the real side effect immediately.
Scan GHL account (gohighlevel.inventory)
[READ · ADMIN ONLY] Read a migration inventory from the connected GHL client account: contacts, pipelines, calendars, workflows, forms, surveys, and custom fields. Missing token scopes are reported per resource instead of aborting the scan. Changes nothing in either system.
List GHL snapshots (gohighlevel.list_snapshots)
[READ · ADMIN ONLY] List snapshots owned or imported by the connected GHL agency. GHL's API exposes snapshot metadata, share links, and push status, but does not expose a downloadable snapshot payload; this read changes nothing.
Import GHL contacts (gohighlevel.import_contacts)
[HIGH RISK · ADMIN ONLY] Copy up to 100 contacts from the connected GHL client account into this account. THIS CAN SEND REAL MESSAGES TO REAL PEOPLE: every contact it genuinely creates fires this account's 'contact created' automations, so if any workflow is set to greet new contacts, importing 100 people sends up to 100 real SMS or emails — billed to its own Twilio/Mailgun account — the moment the import lands. Check the account's automations before running it on a list you have not seen. Existing contacts here are matched by normalized phone or email and are never overwritten or re-triggered; by default, contacts previously deleted here stay deleted. New contacts retain their GHL ids, tags, and custom-field payload in source metadata. Nothing in GHL is changed.
View GHL migration and sync status (gohighlevel.sync_status)
[READ · ADMIN ONLY] Read the connected account's HighLevel migration mode, continuous-sync settings, mapped-record count, supported resource coverage, and ten most recent durable jobs — each with per-resource counts and a per-item report of every record that was skipped or degraded, with the reason. This returns no OAuth credentials and changes neither system.
Configure GHL synchronization (gohighlevel.configure_sync)
[HIGH RISK · ADMIN ONLY] Choose whether supported records are copied once, synchronized inbound from HighLevel, synchronized outbound to HighLevel, or kept synchronized both ways, and which resources the inbound migration moves (contacts, pipelines & stages, opportunities → deals, booked appointments). Enabling outbound or two-way mode changes live HighLevel CRM records during future sync runs; only contacts sync outbound. This never sends messages or charges customers.
Start GHL migration (gohighlevel.start_migration)
[HIGH RISK · ADMIN ONLY] Start a durable, restartable HighLevel migration using the configured direction, conflict policy, and resource selection. Inbound mode creates or updates real contacts, pipelines & stages, deals (from opportunities), and booked appointments in this account — created deals and contacts can fire this account's own automations, which may send real messages if those automations are configured to. Outbound and two-way modes also create or update real HighLevel contacts. A background cron advances the job every few minutes, so it finishes even after the browser closes. The migration itself sends no customer messages and performs no cross-system deletions.
Run GHL sync now (gohighlevel.run_sync_now)
[HIGH RISK · ADMIN ONLY] Queue and immediately advance the configured HighLevel synchronization. Depending on direction and configured resources, this creates or updates real contacts, pipelines, deals, and appointments in this account, or real contacts in HighLevel, or both. It sends no messages, charges nothing, and does not propagate deletions.
Retry GHL migration job (gohighlevel.retry_sync_job)
[HIGH RISK · ADMIN ONLY] Retry a failed or canceled HighLevel migration/synchronization job from its saved cursor and phase. The job is idempotent through permanent HighLevel-to-account record mappings, but it can create or update real contacts, pipelines, deals, and appointments here — or real contacts in HighLevel — according to the job's direction and resources.
Cancel GHL migration job (gohighlevel.cancel_sync_job)
[HIGH RISK · ADMIN ONLY] Stop an active HighLevel migration/synchronization job before its next leased batch. Records already copied or updated remain in place; this does not roll back or delete anything in either system.

Actions — google_ads

18 operations.

Read Google audiences (google_ads.audiences)
[READ · ADMIN ONLY] Read existing audience lists, their estimated sizes and network eligibility from the authorized advertiser account for observation or retargeting. Returns no audience members, uploads no personal data and spends no money.
Launch Google campaign (google_ads.launch)
[HIGH RISK · ADMIN ONLY] Validate the saved Search, YouTube, Display, Standard Shopping or Performance Max campaign and create it ENABLED in its advertiser account. Starts real paid advertising subject to Google's review and eligibility, billed by Google under the saved daily budget. Reuse the same draft ID after errors; submitted or uncertain drafts cannot create duplicates. No separate activation is needed.
Choose a published campaign page (google_ads.landing_pages)
[READ · ADMIN ONLY] List this account's published funnels and their public URLs to use as an advertising destination. Reads only; does not publish pages or spend money.
Build matching campaign funnel (google_ads.build_funnel)
[HIGH RISK · ADMIN ONLY] Start a durable AI build for the campaign's matching landing page and thank-you flow. Uses billed AI with a $10 ceiling and 48 model-call limit. Returns a build link; pages remain drafts until separately reviewed and published. Reuse requestId after a timeout to avoid duplicate builds.
Build paused campaign follow-up (google_ads.build_followup)
[ADMIN ONLY] Create a PAUSED follow-up workflow scoped to form submissions on the selected account landing page. Adds a review task and, when a ready sender exists, the supplied email. Sends no messages until a manager reviews and activates the workflow separately; later email delivery is billed normally.
Load Google logo images (google_ads.logo_assets)
[READ · ADMIN ONLY] List existing image assets and dimensions in the authorized advertiser account for YouTube, Display or Performance Max creative. Reads image metadata; does not upload assets, change campaigns or spend money.
Refresh Google campaign status (google_ads.refresh_status)
[ADMIN ONLY] Read the current Google campaign state and update its saved receipt in this account. Can recover a creation receipt after a timeout. Never creates or activates campaigns and spends no money.
Activate Google campaign (google_ads.activate)
[HIGH RISK · ADMIN ONLY] Enable a Google campaign created from this account's saved draft. This starts real paid advertising subject to Google's review and eligibility; Google bills the advertiser account under the campaign's current budget. Review the budget in Google before activation if changed externally.
Pause Google campaign (google_ads.pause)
[HIGH RISK · ADMIN ONLY] Pause a Google campaign created from this account's saved draft to stop new ad delivery. Google may still report or bill already incurred traffic; this does not refund past spend or delete the campaign.
Generate Google and YouTube ad plan (google_ads.generate_plan)
[HIGH RISK · ADMIN ONLY] Generate Search ad copy, keyword suggestions and a YouTube video script using the account's brand voice, AIDA framework and selected Knowledge Brain. Uses billed AI generation; does not render a video, publish a campaign or buy advertising.
Save Google campaign draft (google_ads.save_draft)
[ADMIN ONLY] Save an immutable Search, YouTube, Display, Standard Shopping or Performance Max campaign draft after verifying advertiser access. Stores copy, targeting, asset references and budget; creates no Google campaign and spends no advertising money. Audience lists and images must already exist; Shopping requires a linked Merchant Center feed. Performance Max uses signals, never retargeting-only delivery.
Connect Google campaign management (google_ads.connection)
[READ · ADMIN ONLY] Get an organization-bound browser link for Google Search and YouTube campaign authorization. Returns no credentials and buys no advertising. An account manager must approve access in Google.
Load Google advertiser accounts (google_ads.accounts)
[READ · ADMIN ONLY] List advertiser accounts accessible through this account's Google authorization, including manager-account routes and account currencies. Reads account metadata without changing campaigns or spending money.
Read Google campaign results (google_ads.campaigns)
[READ · ADMIN ONLY] Read campaign status and the last thirty days of impressions, clicks, cost and conversions for an authorized Google advertiser. Includes YouTube campaigns; changes nothing and spends no money.
Find Google campaign locations (google_ads.locations)
[READ · ADMIN ONLY] Search Google's geographic targeting catalog by place name. Returns candidate places to select explicitly; does not change targeting or spend money.
Read saved Google campaigns (google_ads.drafts)
[READ · ADMIN ONLY] Read this account's saved Search and YouTube campaign drafts, validation receipts and creation errors. Makes no changes and spends no money.
Validate saved Google campaign (google_ads.validate)
[ADMIN ONLY] Ask Google to validate the exact saved campaign in validate-only mode. Stores the validation result but creates no advertising objects and spends no money. Does not guarantee later policy approval or delivery.
Create paused Google campaign (google_ads.create_paused)
[HIGH RISK · ADMIN ONLY] Create a previously validated Search or YouTube campaign in the connected Google advertiser account. Creates real advertising objects with the campaign PAUSED, so this action alone buys no traffic. Activation is a separate action. Duplicate submissions of a saved draft are blocked.

Actions — google_insights

6 operations.

Connect Google Insights (google_insights.connect)
[READ · ADMIN ONLY] Return an account-bound Google consent link. An account manager must approve read-only Analytics and Search Console access in Google. Does not install tracking, change Google data or spend money.
Google Insights connections (google_insights.status)
[READ] Read this account's Google Insights connection status and selected reporting properties. Excludes credentials; does not change data or spend money.
Load Google properties (google_insights.choices)
[READ · ADMIN ONLY] List GA4 properties and verified Search Console sites accessible through this account's Google Insights grant. Uses Google API quota, changes nothing and incurs no advertising spend.
Save reporting properties (google_insights.save)
[ADMIN ONLY] Verify property access and save this account's GA4 and/or Search Console dashboard selection. Reports are shared with account members. Does not change Google properties, install tracking or spend money.
Refresh Google reports (google_insights.report)
[READ] Read aggregate GA4 users, sessions, page views and key events, plus Search Console web clicks, impressions, CTR and position for this account's saved properties. Includes daily trends and top ten channels, queries and pages. Uses Google API quota. Omits the newest three days, requests final Search Console data, and exposes partial failures rather than zeroing failed reports. Query rows may omit anonymized searches. No Google data is changed and no money is spent.
Disconnect Google Insights (google_insights.disconnect)
[HIGH RISK · ADMIN ONLY] Remove the stored Google Insights refresh token from this account and stop its reports until reconnected. Keeps property selection for reconnection. Does not delete Google data or revoke other Google integrations; Google-side app permissions can be removed separately in Google.

Actions — google_sheets

14 operations.

Find or create contact (google_sheets.find_create_contact)
[HIGH RISK] Finds or creates a real contact in this account by email and applies supplied name or phone fields. May queue normal contact-created workflows. Returns the saved contact for downstream field mapping; no email or SMS is sent directly.
Connect Google Sheets (google_sheets.connect)
[READ · ADMIN ONLY] Returns the Google consent link for an account-shared Sheets account. A signed-in account manager must open it and explicitly grant Google access; no spreadsheet is changed.
Sheets accounts (google_sheets.list_connections)
[READ] Lists Google Sheets accounts shared with this account, including durable connection errors and the connecting user. Returns no tokens and does not change Google data.
Disconnect Sheets account (google_sheets.disconnect)
[HIGH RISK · ADMIN ONLY] Removes this account's stored Sheets authorization. Workflows using it fail until a manager reconnects; Google spreadsheets are not deleted or edited.
Browse spreadsheets (google_sheets.list_spreadsheets)
[READ] Lists up to 100 spreadsheets visible to the selected account Sheets account. Follow nextPageToken for more; consumes Google read quota without changing files.
Browse worksheet tabs (google_sheets.list_tabs)
[READ] Reads the selected spreadsheet's worksheet IDs, names and dimensions. Does not download cell values or change files; consumes Google read quota.
Load Sheets columns (google_sheets.columns)
[READ] Reads the header row and returns unique positional mapping keys with display labels. Duplicate and blank headers remain distinct. No writes; consumes Google read quota.
Read Sheets rows (google_sheets.read_rows)
[READ] Reads one bounded page of physical rows, omitting fully blank rows. Numbers and booleans stay typed; dates are Google serial numbers. Follow next_row; pagination is not a concurrent-edit snapshot. No writes.
Find Sheets rows (google_sheets.find_rows)
[READ] Finds typed exact matches in a unique-key column across a bounded table of at most 5,000 rows and 100 columns. Returns all matches with cells for guarded updates. No writes; refuses partial scans.
Append Sheets rows (google_sheets.append_rows)
[HIGH RISK] Immediately appends up to 100 rows to the real Google spreadsheet. Writes literal RAW values, not formulas. An uncertain response must be checked before retrying because Google does not provide append idempotency; retrying may duplicate rows.
Update matched Sheets row (google_sheets.update_row)
[HIGH RISK] Immediately changes specified cells in exactly one uniquely matched real Sheet row. Re-finds its immutable key and checks expected cells, refusing ambiguity or stale data. Requires exclusive editing during the write: Google has no conditional row write, so simultaneous sorting/insertion is unsupported.
Sheets row watches (google_sheets.list_watches)
[READ] Lists account row-watch cursors, last successful poll, change counts and durable failures. Does not expose saved row contents or trigger workflows.
Watch Sheets rows (google_sheets.create_watch)
[HIGH RISK · ADMIN ONLY] Starts bounded polling for this account's worksheet. The first successful poll establishes a silent baseline; later new or changed unique keys queue native workflow triggers, which may run real actions. Never backfills historical rows automatically. Requires immutable nonblank unique keys.
Update Sheets watch (google_sheets.set_watch)
[HIGH RISK · ADMIN ONLY] Pauses or resumes a row watch. Resume compares with the last successful baseline and may queue workflows for changes while paused. reset_baseline discards that history and makes the next poll silent; use after reviewing header changes.

Actions — gym

24 operations.

Programs (gym.list_programs)
[READ] List the gym's training programs (BJJ, Muay Thai, Kids Karate…) with their colors and active/archived state. Archived programs are included only when requested. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Add program (gym.create_program)
[ADMIN ONLY] Create a training program. Optionally seed its belt ladder from a preset (BJJ adults/kids, Karate/TKD, or generic levels) so ranks with real class/time requirements exist immediately; without a preset the ladder starts empty and ranks are added one by one. Creates only records inside this account — nothing outward-facing. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Edit program (gym.update_program)
[ADMIN ONLY] Update a program's name, description, color, sort order, or active state. Omitted fields are left alone. Setting is_active to true restores a previously archived program. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Archive program (gym.archive_program)
[HIGH RISK · ADMIN ONLY] Archive a program — it disappears from the schedule and program pickers across the app, though its classes, enrollments, belt ladder and history all remain and it can be restored later with gym.update_program. Asks for confirmation because members and staff stop seeing it immediately. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Belt ladder (gym.list_belt_ranks)
[READ] List belt ranks in ladder order (lowest first), each with its color and the class/time-in-grade minimums required to earn it from the rank before. Filter to one program to see that program's ladder. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Add belt rank (gym.create_belt_rank)
[ADMIN ONLY] Add one rank to a program's belt ladder. Minimums are advisory eligibility hints shown to instructors — they never hard-block a promotion. Appends to the end of the ladder unless a sort_order is given. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Edit belt rank (gym.update_belt_rank)
[ADMIN ONLY] Update a belt rank's name, color, ladder position, or eligibility minimums. Omitted fields are left alone. Members already holding the rank keep it — only the rank's own definition changes. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Delete belt rank (gym.delete_belt_rank)
[HIGH RISK · ADMIN ONLY] Permanently delete a rank from a program's ladder. This cannot be undone. Members currently holding it are left with no rank (fix them with gym.update_enrollment), and past promotions to it keep their history but lose the rank name. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Members & Belts (gym.list_members)
[READ] List the gym's members — each enrollment with the member's name and contact details, the program, their current belt rank and stripes, and status. Filter by program, enrollment status, or current rank. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Enroll member (gym.enroll_member)
[ADMIN ONLY] Enroll a CRM contact in a program as a training member. Unless a starting rank is given, they start at the first belt of the program's ladder (worn on day one). A contact can hold one enrollment per program; enrolling again returns a conflict rather than a duplicate. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Edit enrollment (gym.update_enrollment)
[ADMIN ONLY] Correct an enrollment: pause, resume or end a membership, or fix the recorded rank/stripes when they're wrong. This is the corrections path — it does NOT write a promotion record; award an earned rank with gym.promote_member so the member's history stays true. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Promote member (gym.promote_member)
[HIGH RISK · ADMIN ONLY] Award a member a new belt rank, or add a stripe to their current belt. Writes a PERMANENT promotion record to the member's history (visible on their belt card forever) and updates their enrollment. Promoting to a new belt resets stripes to 0. Asks for confirmation because promotion history is append-only — a mistaken award stays in the record. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Promotion history (gym.list_promotions)
[READ] The append-only promotion history — who was awarded which belt or stripe, when, by whom, and any grading notes. Newest first. Filter by member or program. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Ready for promotion (gym.promotion_eligibility)
[READ] List active members who meet the next rank's minimums — enough classes attended since their last promotion AND enough months at their current rank, per the next rank's min_classes/min_months. Advisory only (the instructor always decides); members whose ladder has no higher rank are skipped. Scans up to `limit` active enrollments per call. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Schedule (gym.list_classes)
[READ] The weekly recurring class schedule, ordered by day then start time — each class with its day of week (0 = Sunday … 6 = Saturday), start time, duration, instructor, location, capacity, and program. These are recurring weekly slots, not calendar events. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Add class (gym.create_class)
[ADMIN ONLY] Add a recurring weekly class to the schedule — it repeats every week on its day at its start time and appears on the schedule and the check-in kiosk immediately. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Edit class (gym.update_class)
[ADMIN ONLY] Update a scheduled class — move it to a different day or time, change its duration, instructor, location, capacity, or program, or toggle it off the live schedule with is_active. Omitted fields are left alone. Past check-ins are unaffected. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Delete class (gym.delete_class)
[HIGH RISK · ADMIN ONLY] Permanently remove a class from the weekly schedule. This cannot be undone; members can no longer check in to it. Past check-ins keep the class name as a snapshot, so attendance history survives. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Check in (gym.check_in_member)
Record that a member attended — the same thing the lobby kiosk does when they tap their name. Recorded with source 'api' and the class name snapshotted onto the record. If the member is already checked in to that class today, this reports success with an already-checked-in note instead of failing, so double-taps are harmless. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Attendance log (gym.list_checkins)
[READ] List check-ins, newest first — who attended, which class (name preserved even if the class was later deleted), the date, and whether it came from the kiosk, staff, or the API. Filter by member, class, or a date range. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Attendance (gym.attendance_report)
[READ] The attendance overview: total check-ins and distinct members this calendar week (Sunday start) and this calendar month, plus the going-quiet list — actively enrolled members with no check-in in more than 14 days, the people worth a retention call before they cancel. Dates are computed in UTC. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Kiosk link (gym.get_kiosk_link)
[READ · ADMIN ONLY] Get the check-in kiosk URL for the lobby tablet. TREAT IT LIKE A KEY: anyone holding this link can open the kiosk with no login and check any member in (or see the member roster the kiosk shows). Links stay valid until rotated with gym.rotate_kiosk_link. Creates the gym's settings row on first use. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Rotate kiosk link (gym.rotate_kiosk_link)
[HIGH RISK · ADMIN ONLY] Revoke every kiosk link ever issued and mint a fresh one — the 'lost or stolen tablet' action. EVERY tablet currently running the kiosk disconnects immediately and stays down until someone opens the new link on it, so check-ins stop until the tablets are re-set-up. Asks for confirmation for exactly that reason. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Kiosk welcome message (gym.update_settings)
[ADMIN ONLY] Set or clear the welcome message shown at the top of the lobby check-in kiosk (for example 'Welcome to Apex Martial Arts — tap below to check in'). Takes effect the next time a kiosk screen refreshes; changes nothing else about the kiosk or its link. Requires the Martial Arts Gym app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.

Actions — helpdesk

7 operations.

List tickets (helpdesk.list)
[READ] List the account's help desk tickets (support requests from its OWN customers), most recently updated first. Optionally filter by status, priority, assignee, queue, or the linked contact.
Open a ticket (helpdesk.get)
[READ] Fetch one help desk ticket by id, with its full thread — public replies the customer can see and internal agent-only notes, each marked by its `internal` flag.
New ticket (helpdesk.create)
Create a help desk ticket on the customer's behalf. Stamps a first-response SLA deadline from the account's per-priority policy, links (or creates) the CRM contact from the requester's email/phone, and notifies the assignee — or the desk's default assignee, or the whole account. Sends no email or SMS to the customer (the 'we got your request' confirmation email goes out only for the customer's own public-portal submissions).
Reply on ticket (helpdesk.reply)
[HIGH RISK] Post an agent message on a ticket. A public reply (internal=false) is shown to the customer on their ticket status page, stops the first-response SLA clock, and moves a new/open ticket to 'waiting' — and when the account's help desk email updates are on (the default while an email provider is connected) and the ticket has a requester email, the reply is ALSO emailed to that real customer through its own connected email account, with a reply-to address that threads their answer back onto the ticket. It is outward-facing customer communication. An internal note (internal=true) stays agent-only and is never emailed.
Set ticket status (helpdesk.set_status)
Move a ticket between statuses. Setting 'solved' stamps the solve time and makes the customer's ticket page offer a one-time 1–5 CSAT rating; reopening a solved/closed ticket clears the solve stamp. Reversible at any time.
Set ticket priority (helpdesk.set_priority)
Change a ticket's priority. While the first-response SLA clock is still running, the deadline is recomputed under the new priority's target.
Assign ticket (helpdesk.assign)
Assign a ticket to a team member (they get a notification), or unassign it by omitting the assignee.

Actions — hosting

2 operations.

Check DigitalOcean connection (hosting.digitalocean_status)
[READ] Checks whether this account has authorized a DigitalOcean team and, when connected, verifies the live account without returning OAuth credentials.
Disconnect DigitalOcean (hosting.disconnect_digitalocean)
[HIGH RISK · ADMIN ONLY] Revokes the stored DigitalOcean OAuth token and removes the account connection. Refuses while any WordPress server still exists so live sites are not stranded.

Actions — intelligence

10 operations.

List analyzed calls (intelligence.list_calls)
[READ] List calls that have been analyzed by AI, newest first, with each call's summary, outcome, sentiment, objections raised, lead score and agreed next step. Read-only and free — it returns analysis that already exists and never runs a model. Calls only appear here if the number they came in on has call analysis turned on.
Open a call's analysis (intelligence.get_call)
[READ] Fetch the full AI analysis of one call by the CALL's id: summary, what the call was about, objections raised, sentiment, the commitments made on it, coaching for the rep, and the lead score with its reasoning. Read-only and free. Returns not-found when that call has never been analyzed.
Analyze a call (intelligence.analyze_call)
[HIGH RISK] Run AI analysis on one completed call right now, instead of waiting for the background sweep. COSTS MONEY: this makes a model call billed to the organization's own OpenRouter account. Use `force` to re-analyze a call that already has analysis — otherwise an already-analyzed call is left alone. Fails cleanly when the call has no transcript, which is the case unless transcription was enabled on the number.
Objection & topic breakdown (intelligence.breakdown)
[READ] Rank what the organization's calls have been about and what keeps stopping them, over a window of days: objections raised, topics discussed, how calls ended, sentiment, and the average lead score. Read-only and free. The counts describe the analyzed calls in the window and say so — an unanalyzed call is invisible to this.
Pipeline forecast (intelligence.forecast)
[READ] The revenue forecast for open deals, showing both numbers side by side: what the pipeline is worth weighted by each stage's historical win rate, and what it is worth weighted by the AI's per-deal probability, which is informed by what was actually said on the calls. Also returns deals broken down by health, the riskiest deals by value, and the most common risks. Read-only and free.
Open a deal's risk assessment (intelligence.get_deal)
[READ] Fetch the AI assessment of one open deal: its adjusted win probability against the stage's historical one, its health, the specific risks on it, the recommended next step, and the evidence the assessment rests on — call counts, objections raised, sentiment over time, days since anyone made contact. Read-only and free.
Score a deal (intelligence.score_deal)
[HIGH RISK] Run the AI risk assessment on one open deal right now. COSTS MONEY: this gathers the deal's evidence and makes a model call billed to the organization's own OpenRouter account. Re-scores a deal that already has a score.
Intelligence settings (intelligence.get_settings)
[READ] Read the organization's intelligence settings: whether open deals are scored automatically, and how many days without contact makes a deal count as stalled. Read-only and free.
Change intelligence settings (intelligence.update_settings)
[HIGH RISK · ADMIN ONLY] Turn automatic deal scoring on or off and set how many days of silence makes a deal stalled. ONGOING COST: with scoring on, every open deal that changes is re-scored by a background job at most once a day, each one a model call billed to the organization's own OpenRouter account.
Turn call analysis on for a number (intelligence.set_call_analysis)
[HIGH RISK · ADMIN ONLY] Turn AI call analysis on or off for one phone number. ONGOING COST: with it on, every completed call on that number is analyzed by a background job — one model call each, billed to the organization's own OpenRouter account. Analysis reads the transcript, so it does nothing unless transcription is also enabled on the number; this capability reports that rather than silently doing nothing.

Actions — invoices

27 operations.

All invoices (invoices.list)
[READ] List the organization's invoices and checkout pages, newest first. Filter by invoice kind (standard, product, group, ascending, plan, trial_ascending) or status, and search names. Archived invoices are hidden, exactly as in the app.
Open an invoice (invoices.get)
[READ] Fetch one invoice with its line items, pricing rules, pay-page settings and public link.
Copy the invoice link (invoices.get_public_link)
[READ] Get the public pay-page URL for an invoice, plus the iframe snippet for embedding it. The link only takes payments once the invoice is published.
Price this invoice now (invoices.quote)
[READ] Run the invoice through the pricing engine and return what a buyer would pay right now: priced lines, discount, scarcity increase, tax, total, what's due at checkout, and every future scheduled charge. This is the same calculation the public pay page and the scheduler use — never compute invoice totals yourself.
Invoice line items (invoices.list_line_items)
[READ] List the line items on one invoice, in display order, with their unit prices in integer cents.
Payments (orders) (invoices.list_orders)
[READ] List buyers' orders across every invoice, newest first — who bought, what they owe, and what they've paid. Filter to one invoice or one order status.
Open a payment (invoices.get_order)
[READ] Fetch one buyer's order with everything the payment page shows: totals, charges taken so far, the remaining schedule, the timeline, and the buyer's private receipt link.
Payment history (invoices.list_payments)
[READ] List individual charges taken across the organization's invoices — succeeded, failed and refunded — newest first. Filter to one order or one status.
Scheduled charges (invoices.list_schedules)
[READ] List the future charges queued against orders — payment-plan installments, a group offer's close, a standard invoice's capture date, and dunning retries. Filter by invoice, order, or status to find what's due or what has failed.
Invoice timeline (invoices.list_events)
[READ] The activity timeline for one invoice — created, published, paid, failed, canceled — newest first.
Invoicing overview (invoices.summary)
[READ] The money view from the Invoices dashboard: total invoiced, collected, outstanding and failed, plus collections per day for the last N days. Reads real orders and cleared payments, not cached counters.
New invoice (invoices.create)
[ADMIN ONLY] Create a draft invoice of the chosen kind. It starts empty with that kind's default pricing rules; add line items and then publish it to make its pay page live. Nothing is charged and nobody is emailed. For an ongoing subscription until canceled, use standard (one customer) or product (reusable checkout page) and add a recurring line item; plan is only a finite total split into a fixed number of installments. Other kinds: group (price drops as more join), ascending (price rises per buyer). For trial_ascending: A reusable signup link starts a separate free trial for every buyer, anchored to that buyer's enrollment time. Enrollment saves a card but charges nothing. During the initial discount window they can end the trial and pay the starting price immediately; after that, the price rises once per selected time unit in equal increments until it reaches full price at the trial deadline. Paying early cancels the deadline charge. If they do not pay early, their saved card is charged the full price when their own trial ends.
Edit invoice details (invoices.update)
[HIGH RISK · ADMIN ONLY] Update an invoice's name, memo, currency, tax rate, billed contact, connected pay-page domain, pricing rules or pay-page settings. Omitted fields are left alone; `pricing` and `settings` are merged over what's stored, then normalized for the invoice's kind. Money values are integer cents. TWO THINGS HERE REACH THE PUBLIC IMMEDIATELY. (1) `pricing` and `tax_rate` re-price a LIVE pay page — if the invoice is published, the next buyer is charged the new amount with no notice. (2) `settings.headerScript` and `settings.footerScript` inject ARBITRARY JAVASCRIPT into the page where buyers type their card details, and `settings.redirectUrl` sends them anywhere after paying; nothing reviews either. Line items are edited with the invoices.add_line_item / update_line_item / remove_line_item capabilities.
Search Stripe subscription prices (invoices.list_stripe_prices)
[READ · ADMIN ONLY] List every active fixed recurring Price in the Stripe account and live/test environment selected by an invoice. Use a returned price_id with Add a line item or Edit a line item to reuse that Stripe Product and Price instead of creating a new catalogue entry. This only reads Stripe and does not charge anyone.
Add a line item (invoices.add_line_item)
[HIGH RISK · ADMIN ONLY] Append a line item to an invoice and recompute its cached totals. `unit_amount` is integer cents. Set item_kind to 'recurring' with an interval to bill it as a subscription line; leave it 'one_time' for a single charge. THIS RE-PRICES A PAY PAGE: once the invoice is published its page is public, so the new line is what the very next buyer is charged, and a 'recurring' line signs them up to be charged again every interval until someone cancels. No confirmation reaches the buyer — the amount on the page is simply different from then on.
Edit a line item (invoices.update_line_item)
[HIGH RISK · ADMIN ONLY] Update one line item's name, price, quantity, taxability, ordering or recurrence, and recompute the invoice's cached totals. Omitted fields are left alone. THIS RE-PRICES A LIVE PUBLIC PAY PAGE: if the invoice is published, the new amount is what the very next buyer is charged, immediately and with no notice to anyone. Changing item_kind to 'recurring' turns a one-off purchase into a subscription that keeps charging. People who already paid are not affected — the change only reaches buyers from now on.
Remove a line item (invoices.remove_line_item)
[HIGH RISK · ADMIN ONLY] Delete one line item from an invoice and recompute its totals. Orders already placed keep the price they were quoted.
Publish (invoices.publish)
[HIGH RISK · ADMIN ONLY] Publish a draft invoice so its public pay page goes LIVE and starts taking real payments on the organization's own Stripe account. Anyone with the link can then buy. Requires at least one line item.
Stop accepting payments (invoices.close)
[ADMIN ONLY] Close an invoice so its pay page stops taking new payments. Nothing is deleted and charges already scheduled against existing orders still run. Publishing it again reopens it.
Archive (invoices.archive)
[HIGH RISK · ADMIN ONLY] Archive an invoice: it leaves every list, its pay page stops working, and it can no longer be opened. Orders and payments are kept so its financial history remains auditable. Use permanent deletion only for invoices with no financial history.
Delete invoice (invoices.delete)
[HIGH RISK · ADMIN ONLY] Permanently deletes an invoice and its failed or canceled $0 checkout attempts. This destroys data and cannot be undone. Refuses to delete any invoice with a paid, refunded, active, pending, or otherwise in-flight order; archive those invoices instead.
Delete payment attempt (invoices.delete_payment_attempt)
[HIGH RISK · ADMIN ONLY] Permanently deletes one failed or canceled $0 invoice checkout attempt from the Payments list. This destroys data and cannot be undone. Any attempt with a successful or refunded payment is preserved and cannot be deleted.
Duplicate (invoices.duplicate)
[ADMIN ONLY] Copy an invoice and all of its line items into a fresh draft with a new public link. The copy takes no payments until it's published.
Send the invoice (invoices.send)
[HIGH RISK · ADMIN ONLY] SENDS A REAL EMAIL to a customer with a link to a published invoice's pay page, from the organization's own email provider. The invoice must be published. Give either a contact_id (uses that contact's email and renders merge fields like {{first_name}}) or an explicit `to` address.
Mark paid outside Stripe (invoices.mark_paid)
[HIGH RISK · ADMIN ONLY] Record that an order's outstanding balance arrived OUTSIDE Stripe — cash, a bank transfer, a legacy invoice. Writes a real payment row for the full outstanding amount, marks the order paid, and cancels anything still scheduled against it. No card is charged; this changes the revenue record, so only use it when the money genuinely arrived.
Cancel an order (invoices.cancel_order)
[HIGH RISK · ADMIN ONLY] Cancel a buyer's order and every charge still scheduled against it, so their card is never charged again. Payments already taken are left untouched — this does NOT refund anything.
Charge a scheduled payment now (invoices.charge_saved_card)
[HIGH RISK · ADMIN ONLY] CHARGES REAL MONEY. Runs a scheduled charge immediately against the card the buyer already authorized, on the organization's own Stripe account — the same off-session charge the invoice scheduler makes when an installment, a group close or a capture date comes due. Use it to collect early or to retry a failed installment. The amount comes from the schedule row; it cannot be changed here.

Actions — klaviyo

10 operations.

List Klaviyo API coverage (klaviyo.catalog)
[READ] Search the generated catalog of every operation in Klaviyo's current stable OpenAPI revision. This reads local documentation only and does not call or change the connected Klaviyo account.
Run Klaviyo API read (klaviyo.read)
[READ · ADMIN ONLY] Run any GET endpoint under Klaviyo's fixed a.klaviyo.com /api or /client origin using this account's encrypted credential. This can read customer profiles, consent, events, campaigns, flows, reports, catalogs, custom objects, reviews, and other protected account data but does not modify Klaviyo.
Run Klaviyo API write (klaviyo.write)
[HIGH RISK · ADMIN ONLY] Run any official Klaviyo POST, PUT, PATCH, or DELETE endpoint under the fixed Klaviyo API origin. Depending on the path, this can create or delete profiles and custom objects, change consent, schedule campaigns, send messages or template previews to real recipients, publish flows, or alter live account data; provider charges may apply.
Check Klaviyo connection (klaviyo.connection_status)
[READ · ADMIN ONLY] Read the connected Klaviyo account identity, authentication mode, granted scope count, sync health, and webhook health stored for this account. No secret or token value is returned and Klaviyo is not modified.
List synced Klaviyo records (klaviyo.list_mirrored_resources)
[READ · ADMIN ONLY] List bounded, tenant-scoped Klaviyo JSON:API resources mirrored into this account for browsing and automations. This may return protected customer or marketing data but does not call or change Klaviyo.
List Klaviyo events (klaviyo.list_webhook_events)
[READ · ADMIN ONLY] List signed Klaviyo webhook deliveries and their processing state for this account. Payload bodies are omitted because they may contain message content and profile data. This does not call or change Klaviyo.
Sync Klaviyo data (klaviyo.start_sync)
[HIGH RISK · ADMIN ONLY] Start a resumable import of Klaviyo profiles, consent, predictive analytics, events, audiences, campaigns, flows, forms, templates, catalogs, coupons, custom objects, reviews, tags, tracking settings, and webhooks. It creates missing contacts here without overwriting existing contacts and does not modify Klaviyo.
Continue Klaviyo sync (klaviyo.run_sync_now)
[HIGH RISK · ADMIN ONLY] Advance queued or interrupted Klaviyo synchronization jobs by one resumable batch. This may create missing contacts here but does not overwrite existing contacts or modify Klaviyo.
Enable Klaviyo events (klaviyo.enable_webhook)
[HIGH RISK · ADMIN ONLY] Create a signed system webhook in the connected Klaviyo account and subscribe it to the selected live account event topics. Real customer messaging and commerce activity will begin flowing into this account's automations; this does not send messages or charge customers, but Klaviyo Webhooks API eligibility is required.
Disable Klaviyo events (klaviyo.disable_webhook)
[HIGH RISK · ADMIN ONLY] Delete the system webhook from the connected Klaviyo account. New Klaviyo events will stop entering this account's automations; events already received and existing data remain stored.

Actions — knowledge

7 operations.

Search knowledge base (knowledge.search)
[READ] Browse or search product help guides and references by topic and category. Returns article summaries and links, with pagination. Reads documentation only; does not change records, send messages or incur AI charges. Vendor pricing articles are hidden for white-label brands.
Read help article (knowledge.read)
[READ] Read a complete product help article, including setup instructions and troubleshooting. Uses the same knowledge base users browse in Help & setup. Read-only, with no AI charge or account changes; hides vendor pricing under white-label brands.
Ask an admin (knowledge.ask_admin)
Save an unresolved product question or answer correction in the responsible admin's private learning inbox. Product questions follow support ownership; account policy questions go to the account admin. No customer message or email is sent, no model is called, and no answer becomes shared until reviewed.
Your clarification requests (knowledge.my_questions)
[READ] Read the signed-in person's latest 50 clarification requests in the active account, including review status. Private evidence from other users is excluded. Returns an empty list for API keys without a person; does not contact anyone or change records.
Learning inbox (knowledge.learning_list)
[READ · ADMIN ONLY] Read automatically captured bug reports, chat corrections, human support replies and unresolved assistant questions for the admin's support team. Private review evidence never becomes public through this read. Platform admins see Chirply-owned items; account admins see their own account or client support queue.
Review learning item (knowledge.learning_read)
[READ · ADMIN ONLY] Read one authorized learning item's private source evidence, current answer and last 20 review decisions. Allows an admin to verify a proposed correction before reusing it. Does not publish guidance, contact customers or change report statuses.
Save learning review (knowledge.learning_review)
[HIGH RISK · ADMIN ONLY] Publish an admin-verified reusable answer, dismiss an item, require a code correction, or retire previously approved guidance. Publication changes what future users and AI chats read; global publication is platform-admin-only, and commercial terms must be corrected in code. Records an immutable review with evidence and expiry; sends no customer message and spends no money.

Actions — leads

11 operations.

Check the Outscraper connection (leads.outscraper_status)
[READ] Report whether the organization has connected its own Outscraper account, plus its remaining credit and this cycle's usage. Read-only — call it before a paid search to see what the tenant has to spend.
List lead searches (leads.list_searches)
[READ] List past lead searches, newest first, with each one's status, result count, duplicates skipped and estimated cost — plus the org's running totals. Purely historical; it runs nothing and spends nothing.
Open a lead search (leads.get_search)
[READ] Fetch one lead search by id — its query, status, result and duplicate counts, estimated cost, and any provider error.
Search and filter lead search results (leads.list_results)
[READ] Page through the businesses one lead search found — name, phone, email, website, rating, phone line type, and whether each is already in the CRM — narrowing them exactly as the results table does. Use the filters to isolate the leads actually worth importing: `q` free-text matches name, phone, email, address, city, category and website; `has_phone`/`has_email`/`has_website` drop the unreachable ones; `line_type: "mobile"` keeps only numbers that can receive a text or voicemail drop; `min_rating` keeps the well-reviewed ones. Reads staged results only — nothing is fetched from Outscraper, so this costs nothing. Feed the returned ids straight into leads.import.
Search Google Maps for leads (leads.search_maps)
[HIGH RISK] Scrape Google Maps for businesses matching a category and location, via the organization's OWN Outscraper account. THIS SPENDS THE TENANT'S MONEY: Outscraper bills per record returned (roughly $3 per 1,000 Maps records after the first 500 free each cycle, more with the emails enrichment), and duplicates already in the CRM are still scraped and still billed. Set the limit deliberately. Jobs over 80 results, or any search with emails on, are submitted in the background and finish later — poll with leads.check_status.
Search Yelp for leads (leads.search_yelp)
[HIGH RISK] Scrape Yelp for local businesses matching a category and location, via the organization's OWN Outscraper account. THIS SPENDS THE TENANT'S MONEY: Outscraper bills per listing returned, and duplicates already in the CRM are still scraped and still billed. Know what you get: business name, phone, street address, rating, review count, categories, price range, neighborhood, a link to the Yelp listing, and the business's own website when Yelp has one on file — but NEVER an email address. Set `emails: true` to chain the website-finder and contact-scraper enrichments on top, which is the only way a Yelp lead becomes emailable; it costs several times more per record. EVERY Yelp search runs in the background — Yelp is slow (about 90 seconds for ten listings) — so this returns a search id immediately and you collect the results with leads.check_status or leads.list_results a couple of minutes later.
Search the business database for leads (leads.search_database)
[HIGH RISK] Search Outscraper's B2B business database with structured filters (category, country/state/city/postal, name, minimum rating or review count, has-website/has-phone/verified). Instant and cursor-paginated. THIS SPENDS THE TENANT'S MONEY: Outscraper bills per record returned (roughly $2 per 1,000 for the first 5,000 each cycle, more above that, plus a surcharge per record for the emails or insights enrichments), and duplicates already in the CRM are still billed. At least one filter or a keyword query is required so the whole database isn't scanned.
Load more results (leads.load_more)
[HIGH RISK] Fetch and append the next page of an existing business-database search using its stored cursor. THIS SPENDS THE TENANT'S MONEY exactly like a new search — another page of records is billed to the organization's Outscraper account. Only database ('b2b') searches can load more.
Check a running search (leads.check_status)
Poll a background Google-Maps or Yelp search and stage its results if Outscraper has finished. Costs nothing extra — the scrape was already billed when it was submitted; this only collects what was paid for.
Delete a lead search (leads.delete_search)
[HIGH RISK] Permanently delete a lead search and every staged result under it. Contacts already imported into the CRM are kept, but the un-imported leads are gone and re-finding them means paying Outscraper for the search again.
Import leads into the CRM (leads.import)
[HIGH RISK] Import staged lead-search results into the CRM as contacts, and optionally run actions on them in the same pass. Pass result_ids for specific leads, or just search_id to import every not-yet-imported result of that search — which can create hundreds of contacts in one call and is not undoable in bulk. Deduped by phone and email: a lead matching an existing contact links to it instead of creating a duplicate. The import itself costs nothing extra (the search was already billed), BUT the optional `actions` run once per imported contact and are a real mass send — depending on the actions chosen they text, email, drop ringless voicemails, place automated or AI calls, or enroll people into campaigns, immediately and irreversibly, billed through the organization's own Twilio/Mailgun accounts. Actions also hit the existing contacts that leads deduped onto, not just the newly created ones. Optionally add every imported contact to a list.

Actions — lists

10 operations.

List lists (lists.list)
[READ] List the organization's contact lists with each one's member count. Lists are named STATIC segments — membership is explicit, not a saved filter.
Open a list (lists.get)
[READ] Fetch one list by id, with its description and current member count.
Create a list (lists.create)
Create an empty contact list. Only a name is required, and it must be unique within the organization. Add contacts afterwards with lists.add_contacts.
Edit a list (lists.update)
Rename a list or change its description. Omitted fields are left alone; membership is untouched.
Delete a list (lists.delete)
[HIGH RISK] Permanently delete a list and every membership row on it. The contacts themselves are NOT deleted, but the segment is gone and cannot be restored.
View list members (lists.members)
[READ] Page through the contacts on a list, newest addition first, with each member's name, email and phone.
Add contacts to a list (lists.add_contacts)
Add one or more existing contacts to a list. Idempotent — a contact already on the list is silently kept, not duplicated. Contact ids that don't belong to this organization are ignored.
Remove contacts from a list (lists.remove_contacts)
Remove one or more contacts from a list. This only drops the membership — the contacts themselves are untouched.
Browse runnable actions (lists.action_types)
[READ] List the action types lists.run_actions accepts, with each one's configurable fields. Call this before lists.run_actions so the action config is built with the right keys.
Run actions on a list (lists.run_actions)
[HIGH RISK] Run one or more actions against EVERY contact on a list — the same 'Run actions' bulk surface the app offers. This is a mass send: depending on the actions chosen it texts, emails, drops ringless voicemails, places automated or AI calls, enrolls people into campaigns, emails invoices, or deletes contacts, once per member, immediately and irreversibly, billed through the organization's own Twilio/Mailgun accounts. Pass contact_ids to restrict it to specific members. Confirm the list's exact member count with lists.get before calling. Runs on up to 2,000 members.

Actions — live_chat

13 operations.

List live-chat widgets (live_chat.list_widgets)
[READ] List this account's branded website live-chat widgets and their publication, AI, placement, and appearance settings. Reads only and sends nothing.
Open live chat (live_chat.get_widget)
[READ] Fetch one branded website live-chat widget with everything its builder shows: its publication status, the AI agent connected to it, which devices the launcher appears on, its full normalized live-chat settings (brand colors, launcher label and position, panel heading, welcome/offline/handoff messages, visitor name/email/phone intake, white-label powered-by link, and every piece of editable visitor-facing copy), the websites it is allowed to appear on, and its install snippet. Live chat only — a click-to-call widget's id returns not-found here, because its settings are a completely different shape; read those with widgets.get. Read-only: it changes nothing, sends nothing, and returns no visitor transcripts (use live_chat.get for those).
Install live chat (live_chat.embed_snippet)
[READ] Get the one-line script tag that installs a live-chat widget on a website — paste it into the site's HTML just before </body> — plus the widget's standalone chat page URL. This is the LIVE-CHAT loader (/embed/chat.js and /c/<key>); the click-to-call loader returned by widgets.embed_snippet is a different script and will not open a chat panel, so do not substitute one for the other. The launcher only renders once the widget is published and the site has been added as an allowed origin, so the returned status and origin list are the two things to check when it does not appear. Read-only.
Create live chat (live_chat.create_widget)
[ADMIN ONLY] Create a draft branded live-chat widget. It does not appear on a website until it is configured, given an allowed site, installed, and published.
Save changes (live_chat.configure_widget)
[ADMIN ONLY] Update a live-chat widget's complete branding, visitor intake, AI handoff, white-label link, and device placement. Existing live conversations keep their transcript; published embeds use the changes immediately.
Publish widget (live_chat.set_widget_status)
[HIGH RISK · ADMIN ONLY] Publish or unpublish a live-chat widget. Publishing makes the installed launcher visible on every allowed website; unpublishing removes it on the loader's next refresh without deleting conversations.
Delete widget (live_chat.delete_widget)
[HIGH RISK · ADMIN ONLY] Permanently delete a live-chat widget, all visitor sessions, and every message transcript it collected. The installed launcher stops working and this cannot be undone.
List live chats (live_chat.list)
[READ] List website live-chat sessions, newest activity first, including visitor identity, current AI/human ownership, assignee, source page, and connected widget. Reads only.
Read live chat (live_chat.get)
[READ] Read one website chat and its complete ordered transcript, including visitor, AI, teammate, and system messages. Reads only and does not change ownership.
Take over (live_chat.take_over)
Move a waiting or AI-handled website chat to human control and assign it to the acting user when there is one. AI stops answering until someone explicitly hands the chat back.
Hand to AI (live_chat.hand_to_ai)
Return a human-controlled website chat to its connected AI agent. The AI will answer the visitor's next message using that agent's persona and Brain.
Send reply (live_chat.reply)
[HIGH RISK] SENDS A REAL LIVE-CHAT MESSAGE to the website visitor immediately. The reply appears in their open widget, moves ownership to the human team, assigns the acting user when there is one, and pauses AI. When the widget's "keep the conversation going by text" setting is on and the visitor shared a phone number but has since left the page, the reply is ALSO delivered to them as a real SMS from the account's own number — billed to the org's own Twilio account (the result reports texted_to when that happened; visitors still on the page, or numbers opted out of SMS, are never texted). There is no draft or undo.
Close (live_chat.close)
[HIGH RISK] Close a website live-chat conversation and prevent more visitor, AI, or teammate messages. Its transcript is retained, but the current UI cannot reopen it.

Actions — marketplace

8 operations.

Browse marketplace (marketplace.browse)
[READ] Searches snapshots other users have published, by keyword and category. Installing one still requires buying or being granted it.
Submit template for review (marketplace.submit_template)
[HIGH RISK · ADMIN ONLY] Submit one of this account's saved funnel, page, or section templates for marketplace review. This exposes the frozen builder document to platform reviewers but does not make it public until a platform admin approves it.
Unlist template (marketplace.unlist_template)
[HIGH RISK · ADMIN ONLY] Withdraw this account's funnel, page, or section template from marketplace browsing. Copies already created in other accounts remain intact.
My listing (marketplace.get_my_listing)
[READ · ADMIN ONLY] This account's marketplace listing for a snapshot, including its review state and any note the reviewer left.
Edit listing (marketplace.upsert_listing)
[HIGH RISK · ADMIN ONLY] Creates or edits the marketplace listing copy for a snapshot — the title, tagline, description and category buyers read. Editing does NOT publish an unpublished listing; submit it for review separately. But it does NOT re-enter review either: if the listing is already public, the new copy replaces the approved copy immediately and everyone browsing the marketplace sees it, with no moderator in between. Treat it as editing live public text.
Submit for review (marketplace.submit_listing)
[HIGH RISK · OWNER ONLY] Sends the listing to the platform team for review and public publication. A platform admin reads the whole configuration first, including every outbound URL it would contact.
Unlist (marketplace.unlist)
[HIGH RISK · OWNER ONLY] Removes a listing from public browsing. Existing licences and anything already installed are unaffected.
Report a listing (marketplace.report_listing)
[HIGH RISK] Flags a marketplace listing to the platform team as spam, malicious, broken or infringing. Three open reports suspend a listing pending review.

Actions — members

15 operations.

List site members (members.list)
[READ] List the site members (end users with login access to this account's funnels/websites), newest first. Optionally filter by status or search by email. These are the tenant's own customers/leads who signed up for a members area — not platform staff accounts.
Open a site member (members.get)
[READ] Fetch one site member by id, with the CRM contact it's linked to.
Add a site member (members.invite)
[HIGH RISK · ADMIN ONLY] Create a member (login) account for an email address, linking or creating the CRM contact behind it. Optionally email them a sign-in link right now — that sends a REAL email from the account's own email provider. Passwordless: they set no password unless they choose to.
Email a sign-in link (members.send_login_link)
[HIGH RISK · ADMIN ONLY] Email an existing member a fresh passwordless sign-in code and magic link for a given funnel/site. Sends a REAL email from the account's own email provider.
Suspend or reactivate a member (members.set_status)
[ADMIN ONLY] Set a member's status. 'suspended' immediately blocks new sign-ins (existing sessions stop resolving too); 'active' restores access. Reversible.
Sign a member out everywhere (members.sign_out)
[ADMIN ONLY] Revoke all of a member's active sessions, forcing them to sign in again on every device. Does not delete the account.
Remove a site member (members.remove)
[HIGH RISK · ADMIN ONLY] Delete a member's login account and revoke access. The linked CRM contact is kept — only the ability to log in is removed. Cannot be undone.
Set a page's access (members.set_page_access)
[ADMIN ONLY] Set who can view a funnel page: 'public' (anyone), 'members' (any signed-in site member), or 'entitlement' (only members who hold a specific access product — pass product_id). A gated page shows the sign-in or no-access card instead of its content.
List access products (members.list_products)
[READ] List this account's access products — the named units of access you gate pages behind and grant to members. Excludes archived ones unless include_archived is set.
Create an access product (members.create_product)
[ADMIN ONLY] Create an access product — a named unit of access (e.g. 'Gold Course') you can gate pages behind and grant to members. Creating it grants no one anything on its own.
Archive an access product (members.archive_product)
[ADMIN ONLY] Archive an access product so it can no longer be granted or chosen. Existing grants and any pages already gated on it keep working; archived just hides it from the pickers.
Grant a member access (members.grant_access)
[ADMIN ONLY] Grant a contact an access product, unlocking every page gated on it. Idempotent — re-granting a revoked one turns it back on. Identify the person by contact_id or by member email.
Revoke a member's access (members.revoke_access)
[HIGH RISK · ADMIN ONLY] Revoke a contact's access product. Pages gated on it lock again immediately. Identify the person by contact_id or member email.
List a member's access (members.list_entitlements)
[READ] List the access products a contact currently holds (and any revoked ones), newest first.
Turn member login on/off for a site (members.set_site_login)
[ADMIN ONLY] Enable or disable the member login area for a funnel/website. Turning it on exposes the /member sign-in routes and the Members management for that site; it does not by itself gate any page (use members.set_page_access for that).

Actions — memory

6 operations.

Write a note to memory (memory.remember)
[ADMIN ONLY] Save one note in an AI employee's own memory, so it still knows this on a later run. Each run otherwise starts from nothing — this is what lets a duty know it already replied to someone, or notice that the same problem has come up four times. Writing the same path again replaces that note rather than adding a duplicate. Notes are the employee's own recollection, NOT instructions: they are shown to it ranked below the duties its owner set and can never change what it is allowed to do. Memory is capped per employee: when it is full the write is REFUSED and names the least recently updated notes, so something has to be deleted first. Costs nothing. Anyone in the account can read what an employee has written about them, so do not write anything here you would not put in writing.
Search memory (memory.recall)
[READ] Search an AI employee's own notes by text or tag, newest first. Notes whose expiry has passed are hidden unless you ask for them. Read-only and costs nothing. Use this before assuming you have never seen something — a run starts with only the most recent notes in view, so anything older has to be looked up deliberately.
Open a note (memory.read)
[READ] Read one note's full text by its path. Your prompt carries only the INDEX — every note's path and one-line summary — so this is how you see what a note actually says once you have decided it matters. Read-only and costs nothing; it stamps when the note was last read so notes nothing ever opens can be retired later.
How full is memory (memory.usage)
[READ] Report how many notes an AI employee is holding against the maximum it is allowed. Read-only and costs nothing. Worth checking before writing a batch of notes: at the limit, writes are refused until something is deleted.
Delete a note from memory (memory.forget)
[HIGH RISK · ADMIN ONLY] Permanently remove one note from an AI employee's memory, by its key. Use it when a note turned out to be wrong — a wrong note is worse than no note, because the employee will keep acting on it. Gone for good; there is no undo.
Clear expired notes (memory.sweep_expired)
[ADMIN ONLY] Delete every note in this account whose expiry has already passed, across all AI employees. Housekeeping only — expired notes are filtered out of every read anyway, so this changes what is stored rather than what any employee believes. Costs nothing.

Actions — meta

170 operations.

View source ad (meta.source_ad_read)
[READ] Resolve a recorded Facebook or Instagram ad ID to its exact ad report in Chirply. Verifies that the ad and campaign belong to an ad account connected to the active account. Returns a link to the correct campaign screen; unavailable or unconnected ads return an error. Does not change ads, send messages or spend money.
Start a fresh launch (meta.launch_reset)
[HIGH RISK · ADMIN ONLY] Reset a failed campaign launch after verifying that its old Meta campaign is archived or deleted. Preserves the draft, settings, creative assets and prior launch history. Does not delete Meta objects, create ads, activate delivery or spend money. A separate launch action and budget approval are still required. Refuses active, uncertain, successful or concurrently changed attempts.
Launch status (meta.launch_progress_read)
[READ] Read saved launch steps, created Meta object IDs, and the latest failure for a campaign draft in this account. Shows completed, running and uncertain outcomes without creating ads, changing delivery, or spending money. Completed provider steps are reused when the existing launch action is retried with identical settings.
View leads (meta.ad_contacts_read)
[READ] Read a page of existing Chirply contacts with this exact Meta ad ID recorded in first or last website attribution or synced Facebook lead-form metadata. Returns names, email, phone and match evidence, scoped to this account and verified ad account/campaign. All-time recorded matches, independent of Meta insight dates; distinct contacts are not equivalent to Meta's aggregate lead events. Does not import contacts, send messages, change ads or spend money.
View comments (meta.ad_comments_read)
[READ] Read the public comments people left on the Facebook and Instagram posts one Meta ad runs on, newest first, with each comment's author, text, time, like count, the replies underneath it, and whether the advertiser's own Page or Instagram account answered. Read live from Meta on every call, all-time rather than a reporting window, and reported per underlying post because a dynamic-creative ad has one post per placement and Meta never merges their comments. Posts whose Facebook Page is not connected to this account, or whose connection lacks permission to read Page content, are returned as unreadable with the reason rather than as zero comments. Publishes nothing: no reply is sent, nothing is hidden, liked or deleted, and no money is spent.
View ad sets and ads (meta.campaign_hierarchy_read)
[READ] Read one page of ad sets or ads within a connected campaign, with individual configured and effective delivery status, creative images, ad counts and performance for the chosen account-timezone date range. Optionally restrict ads to one ad set. Does not change delivery or spend money.
Turn campaign, ad set or ad on or off (meta.ad_object_status_set)
[HIGH RISK · ADMIN ONLY] Turn exactly one campaign, ad set or ad on or off in its connected Meta account. Turning on can immediately spend the existing real ad budget. Parent and child switches are preserved; paused parents still block delivery. Verifies ownership, hierarchy and the resulting status. No budgets or targeting are changed.
Campaign delivery controls (meta.account_campaign_control)
[HIGH RISK · ADMIN ONLY] Pause a campaign in a connected Meta account, or resume it and its eligible ads and ad sets, including individually paused ads. Resume can immediately spend the existing real advertising budget. Works for Chirply-built and other Facebook campaigns; preserves budgets and targeting. Returns verified campaign status; partial errors require a refresh before retrying.
Refresh from Facebook (meta.account_campaigns_read)
[READ] Read a page of campaigns with delivery status, exact ad/ad-set counts, a representative creative image, live purchases, attributed revenue, ROAS and ad-spend return from a connected Meta ad account. Ad-spend return excludes non-ad costs and is not profit ROI. Filter source to chirply for campaigns created or duplicated in this account, or external for other Facebook campaigns. Omit source for both. Pass campaign_id to read its ads. A filtered page can be empty with a next cursor. Does not change ads or spend money.
Saved analysis & copies (meta.campaign_operations_list)
[READ] Read the latest thirty saved AI analyses and campaign duplication outcomes for one connected Meta ad account in this account. Does not generate new analysis, change ads, or spend money.
Generate AI recommendations (meta.campaign_analyze)
[HIGH RISK · ADMIN ONLY] Fetch a campaign's current Meta performance and send it to the account's OpenRouter reasoning model for saved recommendations. Billed to its own OpenRouter account. Advice only: never changes ads or budgets. Reuse request_id on retries.
Copy campaign (meta.campaign_duplicate)
[HIGH RISK · ADMIN ONLY] Create a real paused copy of an existing Meta campaign including its ad sets and ads. Permanently creates external advertising objects, but does not activate delivery or spend ad budget. Requires ads management access. Reuse request_id on retries; an uncertain outcome must be checked in Ads Manager before attempting another copy.
All campaigns (meta.campaign_drafts_list)
[READ] List every unarchived Magic Ads campaign in the current account, including drafts and launched campaigns, their objective, destination, creative count, and whether a companion funnel or automation exists. This is read-only and does not contact Meta or change delivery.
Archive draft (meta.campaign_draft_archive)
[ADMIN ONLY] Move one unpublished Magic Ads draft out of the current campaign list and into the reversible archive. This does not delete creative records, contact Meta, change delivery, publish anything, message anyone, or spend money. Published campaigns cannot be archived here.
Restore draft (meta.campaign_draft_restore)
[ADMIN ONLY] Restore one archived Magic Ads draft to the current campaign list with its brief, creative records, and saved builder state intact. This does not contact Meta, change delivery, publish anything, message anyone, or spend money.
Delete permanently (meta.campaign_draft_delete)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete one unpublished or archived Magic Ads draft and cascade-delete its saved creative metadata from Chirply. This cannot be undone. Generated image files, funnels, and automations remain in their own libraries, and this does not delete or pause anything in Meta. Published campaign records are refused.
Resume campaign (meta.campaign_draft_get)
[READ] Load one tenant-scoped Magic Ads campaign account exactly where it was saved, including its brief, generated plan, creative versions, delivery settings, funnel choice, and automation choice. This is read-only and does not contact Meta or change delivery.
Save draft (meta.campaign_draft_save)
[ADMIN ONLY] Create or update a private, tenant-scoped Magic Ads draft with the exact resumable builder state. This stores data in Chirply only; it does not generate media, publish a funnel, contact Meta, launch ads, message leads, or spend money.
Build the rest of this campaign (meta.campaign_system_build)
[HIGH RISK · ADMIN ONLY] Optionally generate and immediately PUBLISH a complete public conversion funnel for one saved Magic Ads draft, mount it below a route on a connected domain, and/or create a PAUSED editable follow-up automation using the exact Facebook Page/form and funnel triggers. AI generation consumes the account's OpenRouter credits. Publishing makes the generated pages public; the workflow does not contact anyone until a person reviews and activates it.
Use what I said (meta.lead_campaign_from_spoken_brief)
[HIGH RISK · ADMIN ONLY] Turn one natural-language or dictated advertising brief into three editable, durably saved Meta ad concepts and recommend the best awareness, traffic, engagement, leads, sales, or app-promotion objective. The offer, audience, location, desired next step, differentiator, and tone are extracted without requiring form fields. Optionally ad hack a reference screenshot: keep its offer or adapt its format to a new offer, with an additional billed OpenRouter vision call. This uses the account's own OpenRouter model and may incur that provider's text-generation charge; it does not create anything in Meta, contact anyone, or spend ad money.
Compare ad performance (meta.ad_performance_list)
[READ] Compare each ad's last-30-day spend, impressions, reach, clicks, leads, and cost per lead in one connected Meta ad account. This reads Meta reporting data and does not change delivery or spend money.
How my ads are doing (meta.campaign_results)
[READ] Report how every Facebook and Instagram campaign this account launched through the app is actually doing: whether each one is still in Meta's review queue, live and delivering, paused, or rejected, plus impressions, people reached, clicks, click-through rate, cost per click, amount spent, leads, and cost per lead for the chosen window — broken down per creative version. Campaigns run directly in Ads Manager are deliberately excluded, because this account did not launch them here. Read-only: it never changes delivery, never turns anything on or off, and never spends money.
View ad accounts and Pages (meta.advertising_identity_get)
[READ · ADMIN ONLY] Read its connected ad accounts with account IDs and business portfolio details, and Pages with advertising permission and current profile photos. Inbox routing ownership does not restrict website advertising. Read-only; spends no money and changes no ads or messaging routes.
Search target locations (meta.locations_search)
[READ · ADMIN ONLY] Search Meta for whole countries, states/regions, cities and postal codes within the supplied country. Returns exact location keys and labels to choose before launching ads. Pass the chosen key and original query to launch. Read-only; does not create ads or spend money.
Pixels and conversions (meta.conversion_sources_list)
[READ] List Meta Pixels (datasets), received custom Pixel events from the last 28 days when pixel_id is supplied, and custom conversions on one connected ad account, with each Pixel's name and whether it has ever received an event. These are what a website campaign optimizes around: the Pixel watching the site, and the thing happening on it that counts as success. Read-only — it creates nothing, changes no delivery, and spends no money.
Saved audiences (meta.audiences_list)
[READ] List every custom audience on one connected Meta ad account — website visitors, lead-form activity, Page and Instagram engagement, and uploaded customer lists — with its rough size and whether Meta considers it ready to advertise to. Use it to pick an audience to retarget or to exclude. Read-only: it creates no audience, changes no delivery, and spends no money.
Build a retargeting audience (meta.retargeting_audience_create)
[HIGH RISK · ADMIN ONLY] Create a real, durable custom audience on the connected Meta ad account for people who already showed interest — visited the website (needs a Pixel), opened or submitted a lead form, or engaged with the Facebook Page or Instagram account. Meta backfills it from history, so it is populated with real people and is immediately usable for targeting or exclusion. It costs nothing and shows no ads by itself, but it permanently creates an advertising object on the advertiser's account and counts against Meta's per-account audience limits. An audience Chirply already built for the same source and window is reused rather than duplicated.
Build my campaign (meta.lead_campaign_plan)
[HIGH RISK · ADMIN ONLY] Generate and durably save 3–10 editable Meta ad concepts from a truthful business brief and recommend the best awareness, traffic, engagement, leads, sales, or app-promotion objective. Optionally ad hack a reference screenshot: keep its offer or adapt its format to a new offer, with an additional billed OpenRouter vision call. This uses the account's own OpenRouter model and may incur that provider's text-generation charges; it does not create anything in Meta or contact anyone.
Generate with AI (meta.lead_campaign_image_generate)
[HIGH RISK · ADMIN ONLY] Generate one real square advertising image through its own OpenRouter account and store it as a public asset that Meta can fetch. This incurs the image model's provider charge and permanently stores the generated image, but does not create or launch a Meta ad.
Edit this image (meta.lead_campaign_image_edit)
[HIGH RISK · ADMIN ONLY] Edit a saved image in this campaign using change instructions and optional reference images. The original image is sent as the source, and the result is saved as a new version without overwriting it. Charges its own OpenRouter account and stores the result as a public image; does not launch or change a live ad.
View saved versions (meta.lead_campaign_assets_list)
[READ] List the account's saved Meta campaign creative versions, including every generated image, its ad copy snapshot, creative direction, reference images, model, cost, and launched Meta ad id. This is read-only.
Save uploaded creative (meta.lead_campaign_asset_save)
[ADMIN ONLY] Save an already-public image URL as a durable creative version in a saved Meta campaign draft, preserving the exact copy, direction, and references. This stores metadata but does not generate an image, contact anyone, create a Meta object, or spend ad money.
Create lead form (meta.instant_form_create)
[HIGH RISK · ADMIN ONLY] Create and activate a real Meta instant lead form on a connected Facebook Page, collecting full name, email, and phone. New submissions enter this account and may trigger its contact-created automations. This permanently creates an external Meta object but does not launch an ad or spend ad money.
Complete test launch (meta.lead_campaign_simulate)
[ADMIN ONLY] Validate a complete Meta awareness, traffic, engagement, leads, sales, or app-promotion campaign in test mode, including its CTA and placement rules. This creates no Meta objects, contacts no one, incurs no ad spend, and does not require a live Meta connection.
Launch lead campaign (meta.lead_campaign_launch)
[HIGH RISK · ADMIN ONLY] Create and activate one real Meta awareness, traffic, engagement, leads, sales, or app-promotion campaign with a validated destination, CTA, and placement strategy. This immediately makes the campaign eligible to reach real people and spend the selected ad account's money up to the daily budget; Meta bills the advertiser directly. The campaign is created paused and activated last so an incomplete setup cannot spend.
Launch selected ads (meta.lead_campaign_variations_launch)
[HIGH RISK · ADMIN ONLY] Create and activate one real Meta campaign using the selected awareness, traffic, engagement, leads, sales, or app-promotion objective, then launch every selected saved creative as a separate real ad using the shared CTA and placement strategy. If an instant-form lead destination uses form_id __auto__, this also permanently creates an active Meta form. The campaign becomes eligible to reach real people and spend the selected ad account's money up to the shared daily budget; Meta bills the advertiser directly.
View Facebook connection (meta.connection_get)
[READ · ADMIN ONLY] Show whether Facebook, Instagram, and WhatsApp are connected to this account, which permissions were granted, and whether Meta requires the owner to reconnect. Tokens and other secrets are never returned.
List WhatsApp numbers (meta.whatsapp_accounts_list)
[READ] List the WhatsApp Business phone numbers assigned to this account, including verified display names, quality ratings, webhook delivery status, setup errors, and current grounded-AI routing. This is read-only and sends no messages.
Discover business numbers (meta.whatsapp_accounts_discover)
[ADMIN ONLY] Read the connected Meta businesses, discover their WhatsApp Business accounts and phone numbers, subscribe this account to inbound WhatsApp Cloud API webhooks, and refresh this account's saved number catalog. This changes webhook configuration but sends no message and incurs no messaging charge.
Save WhatsApp AI (meta.whatsapp_ai_automation_update)
[HIGH RISK · ADMIN ONLY] Turn the tenant-grounded AI fallback on or off for one connected WhatsApp Business number. Turning it on causes future inbound messages that no visual workflow handles to receive REAL AUTOMATIC REPLIES from the selected agent, spending the account's own OpenRouter credits and WhatsApp provider resources; unknown, sensitive, upset, or human-requested conversations are handed to the team.
List WhatsApp templates (meta.whatsapp_templates_list)
[READ] List approved and pending WhatsApp message templates for one WhatsApp Business account assigned to this account. This is read-only and sends no message.
List Instagram profiles (meta.instagram_accounts_list)
[READ] List Instagram Professional profiles linked to this account's Facebook Pages, including current usernames, follower counts, media counts, webhook delivery, and live direct-message access status. This is read-only.
List Instagram media (meta.instagram_media_list)
[READ] List recent posts from one Instagram Professional profile assigned to this account, including captions, permalinks, likes, and comment counts. This is read-only.
Publish image (meta.instagram_image_publish)
[HIGH RISK · ADMIN ONLY] Publish a REAL PUBLIC IMAGE POST to one Instagram Professional account assigned to this account. The image and caption become visible to that account's audience immediately; this does not buy ads but permanently creates external content until someone deletes it in Instagram.
List Facebook Pages (meta.pages_list)
[READ] List Facebook Pages and linked Instagram Professional accounts available to this account, including permissions, inbound delivery health, and whether a Page is also connected to another account. Other account identities are never exposed.
List Lead Ads forms (meta.lead_forms_list)
[READ] List the Facebook Lead Ads forms discovered for this account, optionally narrowed to one Page or searched by form name, including questions, field mappings, capture status, and latest sync health. This only reads the saved form catalog and does not contact leads.
Discover forms (meta.lead_forms_discover)
[ADMIN ONLY] Read the connected Facebook Pages' Lead Ads form catalogs and questions, then refresh the tenant-scoped form list. Newly discovered forms stay paused until an account manager enables them. This makes Graph API reads but does not create ads, spend money, or contact anyone.
Save form settings (meta.lead_form_update)
[ADMIN ONLY] Turn CRM capture on or off for one connected Facebook Lead Ads form and map each submitted question into a contact field. Pausing a form causes future submissions from it to be retained as ignored webhook events instead of contacts.
Sync recent leads (meta.leads_sync_recent)
[HIGH RISK · ADMIN ONLY] Import up to 25 recent real submissions from one connected Facebook Lead Ads form. This creates or enriches real CRM contacts; every newly created contact immediately enters the account's contact-created automations, which may send real SMS, email, calls, or other configured follow-up and incur the account's provider charges.
List Page automation (meta.page_automations_list)
[READ] List each Facebook Page's current Messenger, linked Instagram Direct, and public-comment autoresponder settings, including which AI agents are assigned. This does not send any replies.
Page activity (meta.page_activity_get)
[READ] Report recent Messenger, linked Instagram Direct, and public-comment activity for each connected Facebook Page: how many messages and visitor comments arrived, how many an AI agent answered on its own, how many a person answered, how many threads are still waiting on a human, and how many comment replies were skipped or failed. Read-only — it sends nothing and spends nothing.
Save automation (meta.page_automation_update)
[HIGH RISK · ADMIN ONLY] Set how one connected Facebook Page handles incoming Messenger messages, linked Instagram Direct messages, and public post comments. Enabling a channel causes the assigned AI agent to send REAL REPLIES TO REAL PEOPLE automatically using the business identity and its own OpenRouter account. Public comment replies are visible to everyone who can see the post.
List Meta ad accounts (meta.ad_accounts_list)
[READ] List the account's connected Meta ad accounts, their currency, Business Manager owner, account status, and minimum daily budget. This does not spend money.
List Facebook activity (meta.social_events_list)
[READ] List recent Facebook and Instagram comments, mentions, feed changes, and message reactions captured for this account. This is read-only.
Re-subscribe (meta.page_resubscribe)
[ADMIN ONLY] Reinstall the webhook subscription on one Facebook Page. For Instagram accounts connected through Facebook Login, that Page installation is also the delivery link. This changes Meta configuration but does not publish content or send a message.
Disconnect Facebook (meta.connection_disconnect)
[HIGH RISK · ADMIN ONLY] Disconnect Facebook and Instagram from this account, uninstall Chirply from its Pages, revoke the Meta user grant, and remove locally stored Page/ad assets. Existing CRM contacts and messages remain. Reconnecting is required to restore service.
View comment-to-DM (meta.comment_dm_get)
[READ · ADMIN ONLY] Show the comment-to-DM settings for one connected Instagram account: whether it is on, the keyword a comment must contain, the message that gets sent, and whether each commenter is messaged only once.
Save comment-to-DM (meta.comment_dm_update)
[HIGH RISK · ADMIN ONLY] Set whether an Instagram direct message is sent automatically to people who comment on this account's posts. Turning this on causes REAL DIRECT MESSAGES TO BE SENT AUTOMATICALLY TO REAL PEOPLE who have not messaged the business first, every time a matching comment is posted, with no further human approval. Instagram permits one such message per comment, within 7 days of it being posted.
List posts you can automate (meta.comment_posts_list)
[READ] List the recent posts from one connected Facebook Page and its linked Instagram account, with the id each one is identified by. Use it to find the post id a per-post comment rule targets.
View comment rules (meta.comment_rules_list)
[READ] List the comment automation rules on one connected Facebook Page: what each one matches (every post or one post, which keywords), what it replies publicly, and whether it sends a private message or starts a flow. Rules cover Messenger and the Page's linked Instagram account together.
Save comment rule (meta.comment_rule_save)
[HIGH RISK · ADMIN ONLY] Create or update one comment automation rule on a connected Facebook Page. An active rule causes REAL PUBLIC COMMENT REPLIES and REAL PRIVATE MESSAGES TO BE SENT AUTOMATICALLY TO REAL PEOPLE, from its own connected account, every time a matching comment is posted and with no further human approval. Meta permits one private reply per comment within 7 days, so a rule either sends a fixed message or starts a flow, never both. When several rules match, the most specific one runs: a rule for one post beats a rule for every post, and a keyword rule beats a catch-all.
Delete comment rule (meta.comment_rule_delete)
[HIGH RISK · ADMIN ONLY] Permanently delete one comment automation rule. It stops running immediately and cannot be recovered; comments it used to handle fall through to the next matching rule, or to the Page's own comment settings.
Add sample conversations (meta.sample_threads_seed)
[ADMIN ONLY] Add a small set of clearly-labelled example Instagram or WhatsApp conversations to this account's inbox so the messaging features can be demonstrated before real customers write in. The threads are fictional, are shown with a “Sample” badge, and replies sent to them are recorded but never delivered to anyone. It also creates matching CRM contacts marked as sample data. Running this again replaces the existing samples for that channel.
Remove sample conversations (meta.sample_threads_clear)
[HIGH RISK · ADMIN ONLY] Delete this account's seeded sample conversations and the sample contacts created alongside them. Only ever removes demonstration data — real customer conversations and contacts are untouched. Omit the channel to clear both Instagram and WhatsApp samples.
List Meta campaigns (meta.campaigns_list)
[READ] List campaigns in one connected Meta ad account. This reads campaign configuration and does not spend money.
Create paused campaign (meta.campaign_create)
[HIGH RISK · ADMIN ONLY] Create a real campaign in Meta Ads Manager in PAUSED state. It cannot spend until separately activated, but it permanently creates an external advertising object.
Activate campaign — can spend (meta.campaign_activate)
[HIGH RISK · ADMIN ONLY] Activate a real Meta campaign. If its ad sets and ads are eligible, this may immediately begin spending the connected organization's money according to their budgets.
Pause campaign (meta.campaign_pause)
[ADMIN ONLY] Pause a real Meta campaign, stopping new delivery and spend as Meta applies the status change. The campaign and its configuration remain available to reactivate later.
Create paused ad set (meta.ad_set_create)
[HIGH RISK · ADMIN ONLY] Create a real PAUSED Meta ad set with a daily budget and targeting. It cannot spend until activated, but its budget becomes live if its campaign and delivery are later activated.
Create link ad creative (meta.creative_create_link)
[HIGH RISK · ADMIN ONLY] Create a real unpublished Meta link-ad creative for a connected Facebook Page. This does not deliver or spend until attached to an active ad.
List Meta ad sets (meta.ad_sets_list)
[READ] List ad sets, budgets, optimization goals, schedules, and delivery status in one connected Meta ad account. This does not spend money.
Activate ad set — can spend (meta.ad_set_activate)
[HIGH RISK · ADMIN ONLY] Activate a real Meta ad set. If its campaign and ads are also active, it may immediately begin spending the connected organization's money up to its configured budget.
Pause ad set (meta.ad_set_pause)
[ADMIN ONLY] Pause a real Meta ad set, stopping new delivery and spend as Meta applies the change while retaining its budget, targeting, and ads.
Create paused ad (meta.ad_create)
[HIGH RISK · ADMIN ONLY] Create a real Meta ad in PAUSED state from an existing ad set and creative. It cannot deliver or spend until separately activated in Meta.
List Meta ads (meta.ads_list)
[READ] List ads, delivery status, parent campaign/ad set, and creative in one connected Meta ad account. This does not spend money.
Activate ad — can spend (meta.ad_activate)
[HIGH RISK · ADMIN ONLY] Activate a real Meta ad. If its campaign and ad set are also active, it may immediately deliver to real people and spend the connected organization's money.
Pause ad (meta.ad_pause)
[ADMIN ONLY] Pause a real Meta ad, stopping new delivery and spend as Meta applies the change while retaining the ad and creative.
Connected assets (meta.connected_assets)
[READ] Read this account's connected Facebook profile name, saved permission snapshot, ad accounts and business portfolios, Pages and Instagram IDs. Read live Meta Pixels for the selected connected ad account, including each ID, last-event date, availability and copyable website installation code. The code reports browser PageView events to Meta when installed and allowed by the site's marketing consent; installation and lead/purchase event setup are separate. Returns explicit read errors and a cursor for more than 100 pixels. This read installs nothing, changes no ads, sends no messages and spends no money. Never returns credentials.
Resume ads (meta.campaign_resume_ads)
[HIGH RISK · ADMIN ONLY] Resume a campaign launched by this account together with all its resumable ads and their ad sets, including individually paused ads. Can immediately spend real money from the connected Meta ad account at existing budgets. Leaves targeting, schedules, rejected and archived ads unchanged; reports partial failures.
Resume ad (meta.ad_resume_delivery)
[HIGH RISK · ADMIN ONLY] Resume one ad from a campaign launched by this account, also enabling its ad set and campaign. Can immediately spend real money at existing Meta budgets; other already-enabled ads under these parents may deliver too. Other individually paused ads stay paused. Review and schedules still apply.
View Messenger setup (meta.messenger_profile_get)
[READ] Read the live localized greetings, Get Started action, ice breakers, persistent menus and composer state, commands, account-linking URL, complete webview settings, and whitelisted domains for one connected Facebook Page. This reads Meta's live Messenger Profile configuration and sends no message.
Publish Messenger setup (meta.messenger_profile_update)
[HIGH RISK · ADMIN ONLY] Immediately publishes current Messenger Profile controls on a real connected Facebook Page: localized greetings, Get Started or ice breakers, localized persistent menus and composer state, URL webview behavior, commands, HTTPS account linking, and optionally the domain whitelist. Chirply postbacks are bound to exact Page Bot Flows. Get Started takes display priority over ice breakers. This changes a live customer-facing surface but sends no message by itself.
Remove from Messenger (meta.messenger_profile_delete)
[HIGH RISK · ADMIN ONLY] Immediately removes Get Started, greetings, ice breakers, persistent menus, commands, and account linking from a real connected Facebook Page. Existing Chirply Bot Flows remain. Messenger Extensions domains stay saved unless remove_whitelisted_domains is explicitly true.
List Messenger capabilities (meta.messenger_capabilities)
[READ] List Meta's current Facebook Messenger Platform features and Chirply's exact implementation state for each one, including supported controls, permission-gated products, Meta previews, policy limits, known build gaps, and retired legacy features. This is read-only and sends no message.
Get Messenger link (meta.messenger_bot_flow_link_generate)
[READ] Get the permanent m.me URL, QR value, and current Page delivery readiness for one saved Messenger-compatible Bot Flow. Opening the URL does not immediately send a message; after a person enters Messenger and taps Get Started when required, the link starts exactly that live flow and its real outbound messages. Draft flows remain inert until published.
Generate Messenger link (meta.messenger_referral_link_generate)
[READ] Generate a Page-scoped m.me Messenger link for a connected Facebook Page, optionally carrying a Bot Flow referral and attribution value. This is read-only, creates no Meta object, and sends no message.
Generate Message Us embed (meta.messenger_message_us_embed_generate)
[READ] Generate Meta's Page-scoped Message Us JavaScript SDK embed for a connected Facebook Page. This only returns website code; it creates no Meta object and sends no message.
Check Login Connect setup (meta.messenger_login_connect_status_get)
[READ] Check the connected Page, pages_messaging grant, Page messaging task, messaging_optins webhook subscription, and Chirply server configuration for Meta Login Connect with Messenger. Meta exposes no API for App Review or its Login Connect App Dashboard toggle, so those remain explicitly manual; this sends no message.
Generate Login Connect setup (meta.messenger_login_connect_setup_generate)
[READ] Generate Meta's documented Login Connect OAuth URL and JavaScript SDK call for a connected Facebook Page. This returns setup code only; it creates no Meta object, sends no message, never exposes the server-only Meta client token, and cannot replace App Review or the manual App Dashboard Page toggle.
Prepare Login Connect contact (meta.messenger_login_connect_identity_prepare)
[ADMIN ONLY] Derive Meta's Page-specific Login Connect login_id on Chirply's server and attach the website's authenticated app-scoped user id to one CRM contact. This stores no PSID and sends no message; the identity remains unable to send until Meta's signed user_messenger_contact opt-in webhook is captured.
Attach Login Connect opt-in (meta.messenger_login_connect_optin_attach)
[ADMIN ONLY] Attach a previously captured, signed messaging_optins.login_id webhook to one authenticated CRM contact through Chirply's opaque identity handle. Meta's login_id remains server-only; this does not accept an unverified opt-in, does not create a PSID, and sends no message.
Send Login Connect message (meta.messenger_login_connect_initial_message_send)
[HIGH RISK · ADMIN ONLY] Immediately sends one real Facebook Messenger message to the CRM contact through Meta recipient.login_id. Chirply requires a signed user_messenger_contact opt-in for the same Page and contact, enforces Meta's 24-hour first-message deadline, records the consent basis, and permanently fences duplicate or indeterminate sends.
List Messenger personas (meta.messenger_personas_list)
[READ] List the named human and bot personas currently available on one connected Facebook Page. This reads Meta's live Persona API, changes nothing, and sends no message.
Create Messenger persona (meta.messenger_personas_create)
[ADMIN ONLY] Create a named human or bot identity on a real connected Facebook Page using a public profile-picture URL. Creating it does not send a message, but it becomes available for future Page messages and is stored by Meta.
Remove Messenger persona (meta.messenger_personas_delete)
[HIGH RISK · ADMIN ONLY] Soft-delete one persona from a real connected Facebook Page. It can no longer send new messages, while historical messages retain their attribution; this cannot be undone in Chirply.
List Messenger sticker packs (meta.messenger_sticker_packs_list)
[READ] Browse Meta's public free first-party Messenger sticker packs with localized names, descriptions, previews, and counts. This is read-only, does not include custom/paid/avatar/GIF catalogs, and sends no sticker.
List stickers in pack (meta.messenger_stickers_list)
[READ] List every public free first-party Messenger sticker in one Meta sticker pack, including preview image, dimensions, and animation state. This is read-only and sends no sticker.
Search Messenger stickers (meta.messenger_stickers_search)
[READ] Search Meta's public free first-party Messenger sticker catalog by a localized keyword of at least two characters. This is read-only and sends no sticker; custom, paid, avatar stickers and GIF search are not available through this API.
View reusable attachment upload (meta.messenger_attachment_upload_info)
[READ] Check whether one connected Facebook Page is ready to create reusable Messenger image, video, audio, and file attachment ids. This reads Page readiness and Meta's provider limits, sends no message, returns no previous attachment ids, and makes no change. Meta's Attachment Upload API does not provide supported list or delete operations, and reusable ids expire after 90 days.
Create reusable attachment (meta.messenger_attachment_create)
[HIGH RISK · ADMIN ONLY] Ask Meta to fetch one public HTTPS image, video, audio, or file and create a real reusable attachment id owned by a connected Facebook Page. This sends no message and Chirply persists neither the source URL nor returned id, but the external Meta asset cannot be listed or deleted through the supported Attachment Upload API; copy the returned id immediately and expect it to expire after 90 days.
View Messenger routing (meta.messenger_routing_get)
[READ] Read Meta's live Conversation Routing feature status for one connected Facebook Page, Chirply's own Meta app id, the granted pages_messaging permission, Page messaging task, and required routing webhook subscriptions. This does not reveal a selected default-app id or a live per-thread owner because Meta's current status API does not return either; it sends no message and changes nothing.
View Messenger thread owner (meta.messenger_thread_owner_get)
[READ] Read Meta's current owner for one account-owned Facebook Messenger conversation, including the owning app id, expiration, idle state, and whether Chirply owns it. This sends no message and changes nothing.
Send and pass Messenger conversation (meta.messenger_routing_pass)
[HIGH RISK · ADMIN ONLY] Send one real customer-visible Facebook Messenger RESPONSE message, then pass that conversation to a specified connected Meta app or the Page's default app. This immediately pauses Chirply automation for the local thread so a bot cannot speak after control leaves; Meta may reject the send unless pages_messaging has Advanced Access through App Review, the authorizing person retains Page messaging access, Chirply currently owns the thread, or the Page explicitly allows Chirply to take control.
Send and release Messenger conversation (meta.messenger_routing_release)
[HIGH RISK · ADMIN ONLY] Send one real customer-visible Facebook Messenger RESPONSE message, then release the conversation to the Page's default app without asking Meta to notify that app. This immediately pauses Chirply automation for the local thread so a bot cannot speak after release; Meta may reject the send unless pages_messaging has Advanced Access through App Review, the authorizing person retains Page messaging access, Chirply currently owns the thread, or the Page explicitly allows Chirply to take control.
Pass Messenger thread control (meta.messenger_thread_control_pass)
[HIGH RISK · ADMIN ONLY] Immediately pass one account-owned Facebook Messenger conversation to a specified connected Meta app without sending a customer message. Chirply automation is paused before the provider call so it cannot speak after ownership leaves, and Meta emits a messaging_handovers webhook to subscribed apps.
Release Messenger thread control (meta.messenger_thread_control_release)
[HIGH RISK · ADMIN ONLY] Immediately release one account-owned Facebook Messenger conversation to idle/default routing without sending a customer message or notifying another app. Chirply automation is paused before the provider call so it cannot speak after ownership leaves.
Take Messenger thread control (meta.messenger_thread_control_take)
[HIGH RISK · ADMIN ONLY] Immediately take control of one account-owned Facebook Messenger conversation for Chirply without sending a customer message. This changes the live owner at Meta and resumes Chirply automation after Meta confirms success.
Request Messenger thread control (meta.messenger_thread_control_request)
[HIGH RISK · ADMIN ONLY] Ask the current Meta app owner to pass one account-owned Facebook Messenger conversation to Chirply without sending a customer message. This request is supported when Chirply is the Page's default receiver; ownership and automation do not change until Meta later delivers the handover.
Extend Messenger thread control (meta.messenger_thread_control_extend)
[HIGH RISK · ADMIN ONLY] Extend Chirply's current control of one account-owned Facebook Messenger conversation by a chosen duration without sending a customer message. Meta allows at most 604,800 seconds (7 days); this changes live routing but does not alter the local automation pause state.
Search Messenger people (meta.messenger_people_search)
[READ] Search known Facebook Messenger people and Page conversations in this account by name, email, business name, or Page-scoped person id. This is read-only, sends no message, and never returns Login Connect login ids.
View person menu (meta.messenger_user_menu_get)
[READ] Reads Meta's live person-specific persistent-menu override and the inherited Page-level menu for one known Facebook Messenger PSID. It sends no message and does not support Instagram or WhatsApp identities.
Publish person menu (meta.messenger_user_menu_publish)
[HIGH RISK · ADMIN ONLY] Immediately replaces the live persistent menu for one real Facebook Messenger person on one connected Page, including localized composer state and complete webview behavior. Chirply postbacks are bound to exact Page Bot Flows. This changes a customer-facing surface but sends no message.
Remove person menu (meta.messenger_user_menu_remove)
[HIGH RISK · ADMIN ONLY] Immediately deletes one real Facebook Messenger person's custom persistent-menu override. The person falls back to the Page-level menu; existing Bot Flows remain and no message is sent.
List Messenger custom labels (meta.messenger_custom_labels_list)
[READ] Read the live custom-label catalog for one connected Facebook Page. This changes nothing and sends no message.
View Messenger custom label (meta.messenger_custom_label_get)
[READ] Read one Page-owned Messenger custom label after verifying that the label belongs to the connected Facebook Page. This changes nothing and sends no message.
Create Messenger custom label (meta.messenger_custom_label_create)
[HIGH RISK · ADMIN ONLY] Immediately creates a real Page-owned Messenger custom label in Meta. It sends no message, but the new label becomes available to every app and teammate managing that Page.
Delete Messenger custom label (meta.messenger_custom_label_delete)
[HIGH RISK · ADMIN ONLY] Immediately deletes a real Page-owned Messenger custom label from Meta, removing it from every person who has it. This cannot be undone and sends no message.
View conversation labels (meta.messenger_conversation_labels_list)
[READ] Read the live custom labels attached to one Page-scoped Messenger person on one connected Facebook Page. This changes nothing and sends no message.
Assign Messenger custom label (meta.messenger_conversation_label_assign)
[HIGH RISK · ADMIN ONLY] Immediately assigns one real Page-owned Messenger custom label to one known Page-scoped person in Meta. This changes shared inbox organization but sends no message.
Remove Messenger custom label (meta.messenger_conversation_label_remove)
[HIGH RISK · ADMIN ONLY] Immediately removes one real Page-owned Messenger custom label from one known Page-scoped person in Meta. This changes shared inbox organization but sends no message.
Block Messenger person (meta.messenger_conversation_block)
[HIGH RISK · ADMIN ONLY] Immediately applies Meta's block_user moderation action to one real Page-scoped Messenger person on one connected Facebook Page. This changes the live Page conversation and may prevent further interaction; it sends no message. Meta exposes no current moderation-state read, so verify the intended person and Page before confirming.
Unblock Messenger person (meta.messenger_conversation_unblock)
[HIGH RISK · ADMIN ONLY] Immediately applies Meta's unblock_user moderation action to one real Page-scoped Messenger person on one connected Facebook Page. This changes the live Page conversation and may allow interaction again; it sends no message. Meta exposes no current moderation-state read, so verify the intended person and Page before confirming.
Ban Messenger person (meta.messenger_conversation_ban)
[HIGH RISK · ADMIN ONLY] Immediately applies Meta's ban_user moderation action to one real Page-scoped Messenger person on one connected Facebook Page. This changes the live Page conversation and may prevent further interaction; it sends no message. Meta exposes no current moderation-state read, so verify the intended person and Page before confirming.
Unban Messenger person (meta.messenger_conversation_unban)
[HIGH RISK · ADMIN ONLY] Immediately applies Meta's unban_user moderation action to one real Page-scoped Messenger person on one connected Facebook Page. This changes the live Page conversation and may allow interaction again; it sends no message. Meta exposes no current moderation-state read, so verify the intended person and Page before confirming.
Move Messenger conversation to spam (meta.messenger_conversation_move_to_spam)
[HIGH RISK · ADMIN ONLY] Immediately applies Meta's move_to_spam action to one real Page-scoped Messenger person's conversation, moving it to Spam in Meta Business Suite Inbox. This changes a live external inbox and sends no message. Meta documents no restore-from-spam action on this API, so confirm the intended person and Page first.
View reviewed messaging setup (meta.messenger_reviewed_messaging_status)
[READ] Read one connected Facebook Page's live permission and webhook readiness for Utility Messages, the non-inspectable App Review gate for HUMAN_AGENT, and the separate paid limited-beta onboarding status for Marketing Messages. This sends no message, spends no money, and explicitly identifies retired Messenger products that Chirply will not call.
List reviewed-message recipients (meta.messenger_reviewed_conversations)
[READ] List recent account-owned Facebook Messenger conversations for one connected Page and show which are inside Meta's 24-hour standard window or seven-day HUMAN_AGENT window. This reads local inbox state only, exposes no Page access token or PSID, and sends no message.
List utility templates (meta.messenger_utility_templates_list)
[READ] Read Meta's live Page-owned Utility Message template library, including language, review status, components, and whether a template was cloned from Meta's library. This requires page_utility_messaging, changes nothing, sends no message, and incurs no Meta messaging charge.
Search Meta utility templates (meta.messenger_utility_library_search)
[READ] Search Meta's current prebuilt Utility Message template library by name or content and language for one connected Page. This is read-only, sends no message, creates no template, and incurs no Meta messaging charge.
Create utility template (meta.messenger_utility_template_create)
[HIGH RISK · ADMIN ONLY] Submit a Page-owned transactional Utility Message template to Meta for real review. This creates external Page configuration but sends no customer message and incurs no send charge. Marketing or promotional content is prohibited; Meta can reject or later disable the template, and Utility Messages currently require page_utility_messaging plus supported Page and recipient geography.
Clone Meta utility template (meta.messenger_utility_template_clone)
[HIGH RISK · ADMIN ONLY] Clone one current prebuilt Meta Utility Message template into a real Facebook Page's reviewed library, with optional documented body and URL-button inputs. This changes external Page configuration but sends no customer message and incurs no send charge; Meta still controls review status and availability.
Send utility message (meta.messenger_utility_send)
[HIGH RISK · ADMIN ONLY] SENDS A REAL FACEBOOK MESSENGER MESSAGE outside or inside the standard reply window using one live Meta-approved UTILITY template. Delivery reaches the selected account-owned conversation immediately with no undo and may be billed or rate-limited by Meta. The message must be a transactional order, account, appointment, or event update—not marketing—and Meta enforces page_utility_messaging plus Page and recipient geography.
Send human support reply (meta.messenger_human_agent_send)
[HIGH RISK] SENDS A REAL FACEBOOK MESSENGER HUMAN_AGENT REPLY. This is only for a literal support reply written and approved by a real person within seven days of that person's last Page message; it pauses automation on the conversation, reaches the recipient immediately with no undo, and must never carry automated, unrelated, or marketing content. Chirply requires an explicit human-authored attestation, while Meta separately requires HUMAN_AGENT App Review approval.
View Messenger Calling (meta.messenger_calling_get)
[READ] Read one connected Facebook Page's live Meta Calling eligibility, current audio/video/icon/hours/routing settings, webhook and permission readiness, known Messenger people, and recent call events. This sends no message and changes nothing; Meta's messenger_api_calling status remains the authoritative review/availability gate.
Update Messenger Calling (meta.messenger_calling_update_settings)
[HIGH RISK · ADMIN ONLY] Immediately replace the connected Facebook Page's live Messenger Calling audio, video, call-icon, weekly-hours, timezone, and ring-target settings. META rings Meta's native surface; PARTNERS sends real inbound calls to Chirply's browser softphone and requires the calls webhooks. Meta rejects this operation until the Page and app pass its Calling access/review gate.
Check Messenger call permission (meta.messenger_calling_permission_get)
[READ] Read Meta's live outbound-calling permission and per-action limits for one known person in a connected Facebook Page's Messenger thread. This sends no message and does not infer permission from Chirply data.
Request Messenger call permission (meta.messenger_calling_permission_request)
[HIGH RISK · ADMIN ONLY] Send a real Messenger calling_optin template to one known person, asking them to approve outbound calls from the connected Facebook Page. Meta allows at most two permission requests per thread in 24 hours and grants expire after seven days; the person may reject the request.
Send Messenger call prompt (meta.messenger_calling_prompt_send)
[HIGH RISK · ADMIN ONLY] Send a real Messenger call_prompt template that lets one known person call the connected Facebook Page for one to seven days, including when its persistent call icon is hidden. This immediately messages a real person and Meta rejects it until Calling is enabled.
Start Messenger call (meta.messenger_calling_connect)
[HIGH RISK · ADMIN ONLY] Immediately place a real outbound Messenger audio/video call from the connected Facebook Page to one known person using the supplied WebRTC SDP offer. The person must have live call permission and Meta must report start_call is allowed; the calling client must remain connected to carry the media.
Accept Messenger call (meta.messenger_calling_accept)
[HIGH RISK · ADMIN ONLY] Accept a real inbound Messenger call to the connected Facebook Page using the provider call id and supplied WebRTC SDP offer. Meta requires acceptance within 60 seconds, and the calling client must remain connected to carry the media.
Decline Messenger call (meta.messenger_calling_reject)
[HIGH RISK · ADMIN ONLY] Immediately decline a real inbound Messenger call to the connected Facebook Page. The caller's ringing attempt ends and this action cannot be undone.
End Messenger call (meta.messenger_calling_terminate)
[HIGH RISK · ADMIN ONLY] Immediately terminate a real active Messenger call on the connected Facebook Page. The other participant is disconnected and this action cannot be undone.
Prepare Messenger DTMF tone (meta.messenger_calling_dtmf_prepare)
[HIGH RISK · ADMIN ONLY] Validate and prepare one RFC4733 touch tone for a real active Messenger call. The returned browser command always uses Meta's required 500 ms duration and 100 ms inter-tone gap; it does not falsely claim that the server injected RTP because the live WebRTC sender exists only in the open softphone, which must consume the command. Meta emits no DTMF webhook.
Update Messenger call media (meta.messenger_calling_media_update)
[HIGH RISK · ADMIN ONLY] Renegotiate the live audio/video tracks of a real active Messenger call using increasing media versions, the actual browser MediaStreamTrack ids, and a new WebRTC SDP offer containing those ids. This can immediately mute, unmute, enable, or disable camera media for both participants' live call experience.
Update Messenger screen share (meta.messenger_calling_screen_share_update)
[HIGH RISK · ADMIN ONLY] Immediately start, stop, or restore screen-share video in a real active Messenger call by sending Meta's current media_update contract with increasing versions, a browser-created SDP offer, and the exact getDisplayMedia or restored-camera MediaStreamTrack ids. The browser must obtain the person's screen-sharing permission and keep the live WebRTC peer connected; this operation changes what the other participant sees.
Submit Messenger call metrics (meta.messenger_calling_metrics_submit)
[HIGH RISK · ADMIN ONLY] Submit the finished real Messenger call's end reason and optional browser audio-quality counters to Meta. Meta accepts this once per call, only after the call ends, and only within 24 hours; it changes provider analytics rather than contacting the person.
View Messenger performance (meta.messenger_measurement_get)
[READ] Read one connected Facebook Page's Bot Flow entries, completions, node drop-offs, human handoffs, entry attribution, message delivery/read receipts, customer-shared native cart events, and current Meta Messaging Insights. This sends no message, records no conversion, and changes nothing; Meta Insights can remain unavailable until the Page grants ANALYZE plus the documented permissions and Advanced Access.
Report conversion to Meta (meta.messenger_app_event_log)
[HIGH RISK · ADMIN ONLY] Immediately sends a real Messenger App Event to Meta for one Page-scoped person, including the Page id, that person's PSID, the event name, optional purchase value and currency, and the two supplied tracking declarations. It sends no Messenger message and charges no money, but the signal can affect Meta analytics, attribution, optimization, and advertising, so an account owner or admin must confirm it.
Check Marketing Messages (meta.messenger_marketing_status)
[READ · ADMIN ONLY] Inspect one connected Facebook Page's current paid Marketing Messages readiness: required Meta permissions, access-token lifetime, spendable ad accounts, subscriber API probe, required delivery webhooks, documented business and recipient geographies, and honest boundaries for One-Time Notification, NPI news, Sponsored Messages, and legacy Recurring Notifications. This sends nothing and spends nothing; Meta does not expose Tech Provider review, Terms acceptance, or geography as a single inspectable flag.
Enable Marketing delivery tracking (meta.messenger_marketing_webhooks_enable)
[HIGH RISK · ADMIN ONLY] After Meta proves this exact Facebook Page is onboarded for Marketing Messages, add the five current paid-product delivery, failure, echo, read, and click webhook fields to both the app and Page subscriptions while preserving all existing Page fields. This changes external Meta webhook configuration but sends no person a message and creates no paid delivery; Chirply deliberately keeps these gated fields out of the base subscription so an ineligible Page cannot break its working webhooks.
List customer-list audiences (meta.messenger_marketing_audiences_list)
[READ · ADMIN ONLY] List the live Messenger Marketing Messages Custom Audiences for one connected Page and ad account using Meta's exact subtype-1010 filter. This requires a non-expiring Flow 1/3 system-business access token; it sends nothing, uploads no customer data, and spends nothing.
Create customer-list audience (meta.messenger_marketing_audience_create)
[HIGH RISK · ADMIN ONLY] Create a real external Meta Custom Audience dedicated to Messenger Marketing Messages for one Page and ad account. This requires a non-expiring Flow 1/3 system-business access token and changes external ad-account configuration, but uploads no customer data, sends no message, and spends nothing.
Upload audience customers (meta.messenger_marketing_audience_users_add)
[HIGH RISK · ADMIN ONLY] UPLOAD CUSTOMER IDENTIFIERS TO META for matching into one real Messenger Marketing Custom Audience. Chirply normalizes and SHA-256 hashes every email/phone before transmission, sends at most 10,000 rows per confirmed request, and Meta may take up to 24 hours to match them; only matched people with valid marketing consent should be included, and subscription tokens remain hidden until Meta's 100-match privacy threshold is met. This sends no Messenger message and creates no paid delivery.
Remove audience customers (meta.messenger_marketing_audience_users_remove)
[HIGH RISK · ADMIN ONLY] REMOVE SHA-256-HASHED CUSTOMER IDENTIFIERS FROM ONE REAL META CUSTOM AUDIENCE. This changes external audience membership after a confirmed request, but does not unsubscribe the people at Page level or remove them from other audiences; call the Page-level unsubscribe operation when marketing permission itself must end. It sends no Messenger message and spends nothing.
Unsubscribe Marketing audience (meta.messenger_marketing_audience_unsubscribe)
[HIGH RISK · ADMIN ONLY] UNSUBSCRIBE REAL PEOPLE FROM THIS PAGE'S ENTIRE MESSENGER MARKETING MESSAGES AUDIENCE using Meta's current Page-level unsubscribe API. Each row must use phone/email, PSID, or an opaque subscriber handle; this ends Page-level marketing eligibility rather than merely removing one Custom Audience membership. It sends no Messenger message and spends nothing, but the person must opt in again before another paid Marketing Message.
List marketing subscribers (meta.messenger_marketing_subscribers_list)
[READ · ADMIN ONLY] Read up to 1,000 current Marketing Message subscription records for one connected Facebook Page directly from Meta, deduplicating recipients and optionally filtering Custom Audiences. Raw subscription tokens are encrypted into opaque Chirply handles before being returned; this sends nothing and incurs no delivery charge, but the result contains sensitive subscriber status and eligibility data.
View marketing subscriber (meta.messenger_marketing_subscriber_get)
[READ · ADMIN ONLY] Read one live Marketing Message subscriber token's status, expiration, next eligible send time, re-opt-in state, timezone, Page-scoped recipient id when Meta exposes it, and matched Custom Audiences. The input and output use an opaque encrypted handle rather than the raw Meta send token; this sends nothing and spends nothing.
List Marketing campaigns (meta.messenger_marketing_campaigns_list)
[READ] Read the live direct Marketing Message campaigns owned by one connected Facebook Page and billed through one connected Meta ad account, including the underlying campaign, message-set, and message statuses, budget, schedule, and Pixel attribution. This sends nothing and spends nothing.
View Marketing campaign (meta.messenger_marketing_campaign_get)
[READ] Read one live direct Marketing Message campaign after proving its Page and billed ad-account ownership, including all three Meta delivery objects, budget, schedule, status, and Pixel attribution. This sends nothing and spends nothing.
Create Marketing campaign (meta.messenger_marketing_campaign_create)
[HIGH RISK · ADMIN ONLY] Create a real paid Marketing Messages campaign for one connected Facebook Page and billed Meta ad account. Creating it does not send a message or create a charge, but it creates external ad infrastructure and establishes a real daily, lifetime, or Meta-estimated spend cap; the campaign remains inert until explicitly resumed and the send API is called.
Update Marketing campaign (meta.messenger_marketing_campaign_update)
[HIGH RISK · ADMIN ONLY] Update the name, same-mode budget, or schedule of a real direct Marketing Message campaign after proving its Page and ad-account ownership. This changes external paid-campaign configuration and can raise how much a later approved send may spend, but it does not itself send a message; Meta does not document switching a live campaign between daily and lifetime budget modes, so Chirply refuses that guess.
Pause Marketing campaign (meta.messenger_marketing_campaign_pause)
[HIGH RISK · ADMIN ONLY] Pause the real message, message set, and campaign behind one direct Messenger Marketing campaign, stopping future paid sends from being accepted. This changes external Meta state but does not recall messages already delivered.
Resume Marketing campaign (meta.messenger_marketing_campaign_resume)
[HIGH RISK · ADMIN ONLY] Activate the real campaign, message set, and message behind one direct Messenger Marketing campaign. Activation does not itself send, but it enables later approved sends that message real subscribers and charge the billed ad account; Meta requires about 10 minutes after activation before sending.
Delete Marketing campaign (meta.messenger_marketing_campaign_delete)
[HIGH RISK · ADMIN ONLY] Permanently delete one real direct Marketing Message campaign after proving its connected Page and billed ad-account ownership. This cannot be undone, removes external campaign history/configuration, and does not recall messages already delivered.
Preview Marketing message (meta.messenger_marketing_preview)
[READ · ADMIN ONLY] Ask Meta to render a safe hosted preview for one documented rich Marketing Message against a connected Page and ad account. This sends nothing to a subscriber, changes no campaign, and incurs no delivery charge; Chirply returns only Meta's verified facebook.com preview URL, never executable iframe HTML.
Estimate Marketing delivery (meta.messenger_marketing_delivery_estimate)
[READ · ADMIN ONLY] Ask Meta for the estimated lower and upper number of paid Messenger Marketing send calls supported by one daily or lifetime budget for a connected Page/ad account. This is an estimate, not a guarantee; it sends nothing, changes no budget, and incurs no delivery charge.
Send paid Marketing message (meta.messenger_marketing_send)
[HIGH RISK · ADMIN ONLY] SENDS A REAL PAID FACEBOOK MESSENGER MARKETING MESSAGE immediately to one explicitly opted-in subscriber using an active direct campaign. Meta bills the selected ad account for billable delivery. Chirply re-reads live token eligibility, enforces the 12-hour cooldown and 10-minute activation delay, validates current rich-message formats, requires geography/opt-in/payment attestations, and writes a fenced durable receipt before calling Meta so a crash cannot silently duplicate the send.
View Marketing performance (meta.messenger_marketing_insights)
[READ] Read Meta's live paid Messenger Marketing delivered count, reads, link clicks, spend, cost per delivery/click, and attributed Pixel or Conversions API actions, values, and purchase ROAS for one Page-owned campaign. Metrics may be estimated or region-excluded exactly as Meta documents; this sends nothing and spends nothing.
Ask for marketing opt-in (meta.messenger_marketing_optin_request)
[HIGH RISK · ADMIN ONLY] SEND A REAL IN-THREAD FACEBOOK MESSENGER OPT-IN REQUEST to a person who recently started a Page conversation. The notification_messages template asks for explicit Marketing Messages consent; it does not itself grant consent, spend paid-delivery budget, or authorize a later send until Meta returns a subscription token. Chirply enforces the current 24-hour thread window and writes a durable receipt first.
Send NPI news message (meta.messenger_news_send)
[HIGH RISK · ADMIN ONLY] SENDS A REAL FACEBOOK MESSENGER NEWS MESSAGE outside the 24-hour window using Meta's NON_PROMOTIONAL_SUBSCRIPTION tag. Only a Page currently registered in Meta's News Page Index may use it, and the content must be strictly non-promotional news—no subscription offer, deal, coupon, discount, branded content, affiliate promotion, or third-party promotion. Chirply requires both attestations and writes a fenced durable receipt before sending.

Actions — mobile

3 operations.

Mobile apps (mobile.status)
[READ] Report where each Chirply mobile app is up to — Android on Google Play and the iPhone app on the App Store — and every request this account has made to be let into one. An app in 'closed_test' is not publicly installable: it only appears for store accounts a person has added to the tester list, so an install link is useless until a request comes back 'added'. Reads only; changes nothing and sends nothing.
Request mobile app access (mobile.request_test_access)
[HIGH RISK] Ask for an email address to be added to a Chirply mobile app's store tester list, and alert the Chirply team that it is waiting. This does NOT install anything or grant access: a person has to type the address into Google Play Console (or App Store Connect) by hand, usually within a day, and the requester is emailed once that happens. The address must be the one the device's store account uses — a Google account for Android, an Apple ID for iPhone — which is often not the address they sign in to Chirply with; the app will not appear for any other account. Submitting the same address again bumps the existing request rather than queueing it twice. Costs nothing.
Withdraw mobile app request (mobile.withdraw_test_access)
Take one of this account's tester requests back off the queue, so nobody adds that address to the store's tester list. The record is kept (marked withdrawn) rather than deleted, and the same address can be requested again later. It does not remove anyone the store has ALREADY added — that has to be undone in Play Console or App Store Connect.

Actions — notifications

5 operations.

Browsers you're notified on (notifications.list_devices)
[READ] List the browsers registered to receive desktop notifications. A signed-in caller sees only their OWN browsers, since notification permission is granted per browser profile; an API key acts for the account and sees every registration in it. Each entry reports which topics it wants, whether it is still reachable, and when it was last seen. The push endpoint itself is never returned.
Choose what a browser tells you about (notifications.set_topics)
Replace the list of notification topics one browser receives. This is the whole list, not a patch — topics left out are switched off, and an empty list silences that browser without removing it. Valid topics: "message" (new messages and leads), "call" (calls you missed), "approval" (ai employees waiting on you), "payment" (payments), "reminder" (reminders).
Remove a browser (notifications.remove_device)
[HIGH RISK] Stop notifying one browser and forget its registration. The browser keeps its operating-system permission, so it will re-register the next time somebody signs in on it and turns notifications on again — this is not a permanent block.
Send a test (notifications.send_test)
Fire a single test notification at one registered browser and report whether the push service accepted it. Nothing is charged and nobody outside the account sees it. This is the way to tell 'notifications are misconfigured' apart from 'nothing has happened yet'.
Notify the team (notifications.send)
Show a desktop notification on every browser in this workspace that has opted into the given topic. This reaches STAFF ONLY — it is not a way to message a contact or a customer, it sends no SMS or email, and it costs nothing. Anyone at a desk sees it immediately, so use it for things that genuinely warrant interrupting someone. Topics: "message" (new messages and leads), "call" (calls you missed), "approval" (ai employees waiting on you), "payment" (payments), "reminder" (reminders).

Actions — partnerships

5 operations.

Partnerships available to you (partnerships.list_offers)
[READ] List the partnerships this workspace can buy right now, with the monthly price of each, what it includes, and who bills it. These appear only in a workspace created by a white-label agency that has switched them on — the agency's client is buying a partnership with Chirply, the software company behind the platform, not with the agency: Chirply takes the payment on its own checkout and the agency is paid a referral commission. Returns an empty list, and no error, wherever there is nothing on offer. Reads only: charges nothing and changes nothing.
Start a partnership purchase (partnerships.start_purchase)
[HIGH RISK · ADMIN ONLY] Open a purchase of one of the partnerships from 'partnerships.list_offers' and get back the amount and the Stripe publishable key the card form needs. NOTHING IS CHARGED AND NOTHING IS CREATED IN STRIPE by this call - it records the intent and reserves the price, which the server computes itself. The price is NOT an argument: White-Label is $497 per month and Reseller is $297 per month, billed by Chirply on Chirply's own account, recurring until cancelled. Note what completing it does to this account: it is promoted out of the agency's client list into an independent agency of its own, keeping all of its data, and the agency that used to run it loses access. Only an owner or admin of the workspace who is NOT one of the agency's own people may do this. Pair it with 'partnerships.complete_purchase', which is the call that actually takes the money.
Pay for the partnership (partnerships.complete_purchase)
[HIGH RISK · ADMIN ONLY] CHARGES THE CARD and, when it succeeds, makes the buyer a partner: a real recurring monthly subscription on Chirply's Stripe at the price reserved by 'partnerships.start_purchase', the paid entitlement applied, and THIS WORKSPACE PROMOTED out of its agency's client list into an independent agency of its own - it keeps every contact, funnel and campaign in it, gains the ability to brand itself and open client workspaces, and the agency that used to run it loses its access and is emailed to say so. Pass the Stripe ConfirmationToken the card form produced. If the bank asks for 3-D Secure the call returns 'requires_action' with a client secret, and the same capability is called again with no token once the browser has cleared it. Safe to call more than once — every step after the charge is idempotent.
Partnerships you offer your clients (partnerships.get_selling_settings)
[READ · ADMIN ONLY] Report whether this white-label agency offers its client workspaces a Reseller or a White-Label partnership, what each costs the client, and the deal the agency earns on one — the commission percentage, whether it pays on every renewal or only the first payment, and how many months it runs for (0 meaning it never stops). All of it is read from the live rate table rather than fixed numbers. Both offers are off until an agency deliberately turns them on. Reads only: changes nothing and shows nothing to anybody.
Save partnerships you offer (partnerships.set_selling_settings)
[HIGH RISK · ADMIN ONLY] Decide whether this white-label agency's CLIENT accounts are shown the option to buy a Reseller or a White-Label partnership. THIS IS OUTWARD-FACING: switching one on puts an offer in front of the agency's own clients and tells those clients that Chirply exists and that they would be paying Chirply rather than the agency. It charges the agency nothing and earns them affiliate commission on every purchase. A client who buys is permanently credited to this agency — the attribution cannot be moved afterwards, and the commission is paid on every renewal for as long as that client keeps paying, whether or not they still use anything the agency sells them. It also MOVES THAT CLIENT OUT OF THE AGENCY: their workspace is promoted to an agency of its own, keeps all of its data, stops counting against the agency's client account limit, and the agency's access to it ends. The agency is emailed when that happens, and any subscription they were running for that client on their own Stripe is left untouched for them to cancel. Switching an offer back off hides it everywhere but never cancels, downgrades, or refunds a partnership somebody already bought, and commission already earned keeps paying.

Actions — pipelines

11 operations.

List pipelines (pipelines.list)
[READ] List the organization's deal pipelines in board order, with the default one flagged. Call this first when you need a pipeline_id.
Open a pipeline (pipelines.get)
[READ] Fetch one pipeline together with its stages, in board order. Omit the id to get the org's default pipeline.
View the pipeline board (pipelines.board)
[READ] Summarize a pipeline board the way the Pipeline page and the dashboard's Pipeline widget do: every stage with its deal count and total value, plus the board's split into in-progress (open), won, and lost deals with the money in each. 'Lost' counts both lost and abandoned deals — closed without a win. All values are integer cents. Read-only.
Create a pipeline (pipelines.create)
[ADMIN ONLY] Create a new deal pipeline and seed it with the starter stages (New → Qualified → Proposal → Won → Lost) so its board is usable immediately. It is added after the existing pipelines and does not become the default.
Create the default pipeline (pipelines.seed_default)
[ADMIN ONLY] Set up the starter 'Sales' pipeline (New → Qualified → Proposal → Won → Lost) for an org that has no pipeline yet, and mark it default. Does nothing if the org already has at least one pipeline.
Rename a pipeline (pipelines.rename)
[ADMIN ONLY] Change a pipeline's name. Stages and deals are untouched — this is the name field in the pipeline settings dialog.
Make a pipeline the default (pipelines.set_default)
[ADMIN ONLY] Mark one pipeline as the org's default. The default is what the Pipeline page opens on and what a deal created without a pipeline_id lands in; any other pipeline loses the flag.
Money or a process (pipelines.set_value_tracking)
[ADMIN ONLY] Switch a board between a sales pipeline and a process board. With tracks_value true each card carries a value and the columns total it; false hides the value field and the totals, which is what you want for onboarding, fulfilment, hiring or any board where the cards aren't sales. This is a display decision only — values already saved on the deals are kept, so switching back restores them.
Reorder pipelines (pipelines.reorder)
[ADMIN ONLY] Set the left-to-right order of the pipelines in the switcher. Pass every pipeline id in the order you want; any pipeline you leave out keeps its current position.
Delete a pipeline (pipelines.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete a pipeline. DESTRUCTIVE: the database cascades, so every stage in the pipeline AND every deal on its board is deleted with it — deals are not moved anywhere. Cannot be undone.
Relabel deal currency (pipelines.relabel_deal_currency)
[HIGH RISK · ADMIN ONLY] Relabel the currency stored on this account's deals — for example correcting deals that were stamped usd by the old default when the business trades in gbp. This changes the LABEL only: it does not convert amounts, does not touch the numbers, and does not move money. A deal worth 1000 (ten pounds or ten dollars) is still worth 1000 afterwards, it is simply denominated differently. Use it once after setting the account's currency in Settings > Business; it is not part of normal day-to-day work. Returns how many deals were changed.

Actions — plans

2 operations.

My plan & limits (plans.get)
[READ] The plan this account is on and every limit it carries — caps like phone numbers and seats, and on/off features like ringless voicemail or the MCP server — with where the plan came from (bought by the owner, pinned by a platform admin, or inherited from a parent agency) and any limit bent for this account specifically. Read-only; nothing is charged.
Plan usage (plans.usage)
[READ] How much of each countable limit this account has used — phone numbers, seats, funnels, workflows, AI agents and so on — with the cap beside it and whether there's room for another. Use this before creating something to know whether it will be refused. Read-only.

Actions — predictive_dialer

10 operations.

Start the predictive dialer (predictive_dialer.start)
[HIGH RISK] Open a predictive dialing session on a call queue. Once a rep takes a seat in the console, the server begins placing REAL outbound calls — several per free rep — from the account's own Twilio number and billed to its own Twilio account. It rings people it screens and drops (a small share hear a recorded apology and nothing else), so it is a live outbound campaign, not a draft. A session with nobody seated dials nobody, so this is safe to call ahead of a shift. One session per queue: called again on a queue that already has one, it returns the existing session rather than starting a second. Settings default to the queue's own saved dialer settings; anything passed here overrides them for this session only.
Predictive session status (predictive_dialer.get)
[READ] Read one predictive dialing session: how many lines are up, how many people have been dialed, picked up, been connected to a rep or been dropped, the live dropped-call rate, and who is seated.
Predictive session on a queue (predictive_dialer.find_for_queue)
[READ] Find the predictive dialing session currently open on a call queue, if there is one. A queue can only have one at a time, so this is how to tell whether dialing is already under way before starting it.
List predictive sessions (predictive_dialer.list)
[READ] List this account's predictive dialing sessions, newest first — the open ones and, optionally, the finished ones with their final numbers.
Pause dialing (predictive_dialer.pause)
Stop a predictive session from placing any NEW calls. Calls already up are left alone — nobody mid-conversation is cut off, and phones already ringing keep ringing. Seats stay open, so resuming picks straight back up.
Resume dialing (predictive_dialer.resume)
[HIGH RISK] Put a paused predictive session back to work. Real outbound calls start again within seconds for every rep who is free, billed to its own Twilio account.
Stop dialing (predictive_dialer.stop)
[HIGH RISK] End a predictive session for good. Every phone still ringing is HUNG UP mid-ring, every seat is closed, and the people who were being dialed go back to waiting on the queue. Conversations already in progress are not interrupted. This cannot be undone — a new session has to be started to carry on.
Change how hard it dials (predictive_dialer.set_pacing)
Change a running session's pacing. Raising lines_per_agent reaches more people per hour and drops more calls; lowering it does the reverse. Takes effect on the next pass, within a couple of seconds. Setting lines_per_agent by hand also switches pacing to 'fixed', so the automatic throttle stops overriding the number you chose — pass pacing_mode 'adaptive' to hand it back.
Calls from a predictive session (predictive_dialer.list_calls)
[READ] List the individual call attempts a predictive session has made, newest first, with how each one ended — connected to a rep, answering machine, no answer, dropped because no rep was free, or blocked because the number is on the do-not-contact list.
Save how a predictive call went (predictive_dialer.record_outcome)
Record the outcome of one predictive call: its disposition and a note. Writes the call log, stamps the person's queue entry as called, runs whatever actions the disposition is wired to, and puts the rep who took it back in rotation. This is what the console's wrap-up form does — use it when something else took the notes.

Actions — presence

7 operations.

See who is around (presence.list)
[READ] List every teammate in this workspace with their current state — online, away or offline — plus any status they set and whether they have do-not-disturb on. Use it before routing something to a person, or to answer "who is around right now?". States are derived from heartbeats the person's browser sent, so they say whether somebody is at a screen — never whether they have read anything. Sends nothing and costs nothing.
Check one person (presence.get)
[READ] Fetch one teammate's current state, status line and do-not-disturb window. Answers "is Sam free?" with what was measured rather than with a guess. States are derived from heartbeats the person's browser sent, so they say whether somebody is at a screen — never whether they have read anything. Sends nothing and costs nothing.
Set a status (presence.set_status)
Set YOUR OWN status — the emoji and line teammates see beside your name in Team Chat — with an optional expiry. Changes nothing about what reaches you; to pause notifications use presence.start_do_not_disturb. Acts as the signed-in person, so an API key cannot use it. Sends nothing and costs nothing.
Clear your status (presence.clear_status)
Remove YOUR OWN status line, so your name shows with no status beside it. Acts as the signed-in person, so an API key cannot use it. Sends nothing and costs nothing.
Pause your notifications (presence.start_do_not_disturb)
Turn on do not disturb for YOURSELF until a moment you choose. While it is on, Chirply stops sending you desktop and phone notifications — a live incoming call still rings, because it cannot be caught up on later. Nothing is deleted: every message, mention and alert is waiting when you come back. Acts as the signed-in person, so an API key cannot use it.
Resume your notifications (presence.end_do_not_disturb)
Turn do not disturb off for YOURSELF, so desktop and phone notifications reach you again immediately. Acts as the signed-in person, so an API key cannot use it.
Show yourself as away (presence.set_availability)
Mark YOURSELF as away, or hand availability back to the automatic reading of your browser activity. Being away changes what colleagues see, not what reaches you — notifications keep arriving. Acts as the signed-in person, so an API key cannot use it.

Actions — preview

6 operations.

Design packs (preview.list_packs)
[READ] List the design packs available for previews — one per trade — with the choices, stackable layers and product styles each offers. Call this first: the ids returned here are what preview.render expects, and they differ per pack. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Generate preview (preview.render)
[HIGH RISK] Edit a photo of a customer's property to show the finished work on THAT building — the point being that it is their house, not a stock example. SPENDS REAL MONEY: every call runs an image model on this account's own OpenRouter key and is billed to them directly, with no caching, and requesting several product styles bills once per style. Takes 20-60 seconds. The photo goes in as a base64 data URL; the result is archived to the media library and returned as a permanent URL. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Preview history (preview.list_renders)
[READ] List previews already generated, newest first, with the permanent image URLs. Every render is kept — they cost money to produce — so this is the archive to pull from when attaching a before/after to a proposal or a follow-up message. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Delete preview (preview.delete_render)
[HIGH RISK] Permanently remove one preview from the archive. The image itself stays in the media library, so anything already attached to a proposal or sent to a customer keeps working — this removes the archive entry only. Previews cost money to generate and cannot be recreated identically, so deleting is rarely the right move. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Preview settings (preview.get_settings)
[READ] The account's preview configuration: which design packs are switched on, and whether the public lead-capture page is live — its address, its wording, and the monthly render cap that limits what the public can spend. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Save preview settings (preview.save_settings)
[HIGH RISK · ADMIN ONLY] Update which design packs are offered and configure the public lead-capture page. TURNING THE PUBLIC PAGE ON PUBLISHES A URL ANYONE CAN USE, and every submission spends this account's own AI credit — which is what the monthly cap is for. Set the cap to what you are willing to spend on strangers in a month, because that is exactly what it controls. Requires the AI Project Preview app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.

Actions — privacy

6 operations.

Privacy mode (privacy.get_settings)
[READ] Read the user's screen-share privacy settings: whether privacy mode is on, which classes of information it is hiding, and whether redaction is `partial` (a short readable prefix survives on names, phone numbers and emails) or `full` (nothing survives). Also returns the full catalog of categories, marking the three that are always hidden (contact details, conversations, and keys) and the six the user can choose.
Turn on privacy mode (privacy.enable)
Turn on privacy mode so the user can share their screen, demo, or record a walkthrough safely. Sensitive values are blurred on screen immediately: contact names and details, conversation and call content, and API keys are ALWAYS hidden, plus whichever optional categories the user has chosen. Nothing is deleted and no permissions change — this only affects what is legible on screen. Optionally pass `also_hide` to switch extra categories on at the same time.
Turn off privacy mode (privacy.disable)
[HIGH RISK] Turn privacy mode off, making every hidden value readable again across the whole app — contact names, phone numbers, email addresses, message content and API keys included. Only do this when the user has confirmed they are no longer sharing their screen or recording; if they are, this puts their customers' personal information straight back on the stream.
How much to hide (privacy.set_strength)
[HIGH RISK] Choose how much of a redacted identity stays readable. `partial` (the default) leaves the first few characters of names, phone numbers, emails and addresses legible — 'Sar…', '+1 (415) …' — so the user can still tell rows apart and talk about one while demoing, without anyone being identifiable. `full` blurs them completely, for a recording that will be published. Either way this only affects IDENTITIES: money and counts are always hidden whole, because the leading digits of a figure give the figure away.
Hide more in privacy mode (privacy.hide)
Switch additional optional categories on, so privacy mode also hides them. Use this for the user's own commercially sensitive figures — their revenue, what individual customers have paid, their subscription, their teammates' names, their volumes, or their own name and account. Takes effect immediately if privacy mode is on, and is remembered for next time if it isn't. Contact details, conversations and keys don't need to be listed here: they are always hidden.
Stop hiding a category (privacy.reveal)
[HIGH RISK] Stop hiding one or more optional categories, making those values readable again even while privacy mode stays on — for example to show revenue during a sales demo. This exposes real figures on screen, so confirm the user actually wants them visible. It cannot unhide contact details, conversation content or API keys: those stay hidden whenever privacy mode is on.

Actions — profile

4 operations.

View profile (profile.get)
[READ] Read the acting person's profile. For an account API key, reads the account owner's profile. Founder-only fields are included when that person is a founder.
Save profile (profile.update)
Update the acting person's real name, chat handle, and photo across the app. If the person is a founder, also updates their founder-wall biography, links, and public-or-anonymous visibility. For an account API key, updates the account owner's profile. This sends no messages and costs nothing.
Sign-in & security (profile.security_status)
[READ] Read how the acting person's sign-in is protected: whether they use an authenticator app, how many passkeys they have registered, how many single-use recovery codes are left in case they lose the authenticator, and how many browsers are set to skip the second step. For an account API key, reads the account owner's status. Read-only, and it never returns a passkey or a recovery code — only whether they exist. Enrolling an authenticator, adding a passkey, generating recovery codes and spending one to get back in can only be done by the person themselves, because each needs a live code, a live browser ceremony, or a sign-in session; see the note at the foot of this module.
Forget all browsers (profile.forget_trusted_browsers)
[HIGH RISK] Remove every browser that was set to skip the two-factor step for this account, so the next sign-in on each one asks for a second factor again. Use this when a laptop or phone is lost or stolen. It signs nobody out and removes no sign-in method — it only withdraws the ‘don’t ask again on this browser’ permission. It cannot be undone except by ticking that box again on each device.

Actions — projects

17 operations.

Project summary (projects.dashboard)
[READ] Read full-project task totals and assignment counts, including subtasks. Applies project membership, private-list and private-task restrictions. Reads only and sends no notifications.
All projects (projects.directory)
[READ] Read the project directory and whether the caller can create projects. Members see only their projects; account admins see all. Sends no notifications.
Create project (projects.create)
[ADMIN ONLY] Create a project with a General task list and To do, In progress and Done board stages. Adds the creating admin as a project member; other members are selected explicitly later. Requires an account admin. Sends no notifications and does not update Teamwork.
Create task list (projects.create_list)
Create a task list inside a project you belong to. The list is visible to existing project members. Does not add members, send notifications or update Teamwork.
Star project (projects.set_star)
Star or unstar a project for the signed-in person, which floats it to the top of their own projects list. The star is PRIVATE: it changes nobody else's ordering and nobody else can see it. Acts as the signed-in person, so an API key cannot use it. Sends no notifications and does not write to Teamwork.
Projects (projects.list)
[READ] List projects this caller belongs to. Account administrators can view all projects. Reads only; sends no notifications.
Open project (projects.overview)
[READ] Read a project, its visible task lists, board stages and existing project members. Membership and private list restrictions apply.
Tasks and notebooks (projects.list_items)
[READ] Read a paginated project task or notebook list. Preserves project membership, private task lists and individual item restrictions.
Open task or notebook (projects.get_item)
[READ] Read the full content of one project task or notebook after checking membership and item privacy.
Save task (projects.save_task)
Create or edit a task in a project you can access. Updates title, notes, assignment, dates, list, stage or completion in Chirply; sends no messages and does not write to Teamwork.
Save notebook (projects.save_notebook)
Create or edit a project notebook you can access. Preserves existing privacy. Saves content inside Chirply without notifying people or updating Teamwork.
Project files (projects.list_files)
[READ] List private project files, 50 at a time. Requires project access and sends no messages.
Upload file (projects.upload_file)
[HIGH RISK] Upload a private project file up to 10 MB. Accepts images, PDF, audio and video; consumes file storage. Project members can download it. Sends no messages.
Download file (projects.download_file)
[READ] Read a private project file after checking current project access. Returns file metadata and base64 bytes for API/MCP clients; the URL requires a signed-in browser session.
Remove file (projects.remove_file)
[HIGH RISK] Remove a file from its project and stop downloads. Only its uploader or an account admin can do this. The stored bytes are retained for recovery; sends no messages.
Change project member (projects.set_member)
[HIGH RISK · ADMIN ONLY] Account admins add an existing account member to a project or remove them. Adding grants Projects alongside their existing feature access. Removing also removes their seats in linked project chats. Sends no invitations or messages; other account access is preserved.
Project chats (projects.chats)
[READ] List linked project chats you already belong to and your notification preference for each. Does not grant access to private chats or change their existing participants.

Actions — proposals

15 operations.

Price book (proposals.list_price_book)
[READ] List the account's reusable services and materials with their unit prices — the catalog the proposal builder's pickers draw from and the AI drafter is grounded in. Prices are returned in integer cents. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Save price book item (proposals.save_price_book_item)
Create or update one reusable service or material in the price book. Pass an id to update an existing item, omit it to create a new one. Item names are unique within the account, so saving under an existing name is rejected rather than silently creating a duplicate the builder's picker would show twice. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Delete price book item (proposals.delete_price_book_item)
[HIGH RISK] Permanently remove one item from the price book. Proposals that already used it keep their lines — a proposal's lines are copies, not references — so this affects only what appears in the builder's pickers from now on. Prefer setting is_active to false if you may want it back. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Financing products (proposals.list_financing)
[READ] List the financing products this account offers, with their APR, term and qualifying amount range. Chirply only DISPLAYS the monthly payment on a proposal — it does not originate, underwrite or service any loan; the lender's own approval happens off-platform. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Save financing product (proposals.save_financing)
Create or update a financing product customers can be offered on a proposal. The monthly payment Chirply shows is a standard amortized calculation from the APR and term you set here — set them to match what your lender actually approves, because the number a customer sees on the proposal is the number they will expect. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Proposals (proposals.list)
[READ] List proposals with their status, customer and price. Each returns a `from` price — the cheapest option — because a proposal offers several, and its accepted total once the customer has chosen. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Open proposal (proposals.get)
[READ] Fetch one proposal in full — every option with all its lines and add-ons, the attachments, the customer-facing link, and the activity trail showing when it was sent, opened, and decided. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Save proposal (proposals.save)
Create or update a proposal and its options. Pass an id to update an existing one, omit it to create a draft. Every option total is recalculated from its lines here — subtotal minus discount plus surcharge, then tax — so a total you send is ignored. This only writes the document; it does not notify the customer (use proposals.send). Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Draft with AI (proposals.draft_with_ai)
Describe a job in plain language and get back a priced Good/Better/Best draft, grounded in this account's own price book. The AI asks a clarifying question instead of guessing whenever a quantity that drives the price is missing — footage, fixture count, storeys — so a reply may be a question rather than a draft. Nothing is saved or sent: the returned draft is a suggestion to review, edit and then save with proposals.save. Uses this account's own OpenRouter key and is billed to it. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Send proposal (proposals.send)
[HIGH RISK] Mark a proposal as sent and return the customer-facing link. Sending is what makes the link acceptable — until then it renders as a preview the customer cannot act on. This does not itself deliver an email or text; pass the returned url to communications.send_email or communications.send_sms, or copy it to the customer yourself. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Record decision (proposals.record_decision)
[HIGH RISK] Record that the customer accepted or declined, for the times they tell you over the phone or in person instead of clicking the link. Accepting freezes the chosen option and its add-ons at today's prices, exactly as the customer-facing page does. Only use this for a decision a real customer actually gave you. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Proposal activity (proposals.activity)
[READ] The trail of what happened to a proposal and when — created, sent, first opened by the customer, accepted or declined. This answers the question every contractor asks before following up: have they even looked at it yet? Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Delete proposal (proposals.delete)
[HIGH RISK] Permanently delete a proposal and its activity trail. The customer-facing link stops working immediately, so anyone still holding it sees a not-found page. An accepted proposal is the record of what somebody agreed to buy and cannot be deleted. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Proposal settings (proposals.get_settings)
[READ] The account's proposal defaults: sales-tax rate applied to new options, how many days a proposal stays valid, the terms shown under the total, the wording above the accept button, and whether accepting creates an invoice automatically. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.
Save proposal settings (proposals.save_settings)
[ADMIN ONLY] Update the account's proposal defaults. Changing the default tax rate affects new options only — proposals already built keep the rate they were priced at, so an already-sent quote never changes underneath the customer looking at it. Requires the AI Quotes & Proposals app (a purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required.

Actions — providers

4 operations.

Connectable API catalog (providers.catalog)
[READ · ADMIN ONLY] List every third-party API this account's own agents can reach through Chirply once the account is connected — each provider's id, the exact hosts it may be called on, a link to its API reference, and how to build a correct path. Also names the providers that are connectable but NOT reachable by passthrough, with the reason. Read this before calling providers.request so you use the right provider id and path shape. Prefer a curated capability (meta.*, telephony.*, campaigns.*) whenever one exists: those validate input, respect plan limits, and write results back into the CRM, which passthrough does not. Read-only and costs nothing.
Connected provider APIs (providers.connected)
[READ · ADMIN ONLY] Report which third-party accounts THIS account has actually connected, and for each one whether its API can be reached through passthrough right now — including why not, when it cannot (the provider isn't wired for passthrough, or its credentials come from the parent agency's pooled account rather than this account's own). Never returns any credential, only which ones exist. Use it to find out what an agent can do here before trying a call. Read-only and costs nothing.
Read from a connected API (providers.read)
[READ · ADMIN ONLY] Make a read-only (GET or HEAD) call to a third-party API using the credentials this account already connected to Chirply — Meta Graph, Twilio, Stripe, Supabase, Mailgun, Klaviyo, Cloudflare and the rest. The credential is attached server-side and is never returned. Use this to pull data an agent needs: ad account performance, a Stripe customer, Twilio call logs, a Supabase project list. Nothing is written and nothing is charged beyond whatever the provider bills for a read (most bill nothing; Outscraper, fal.ai, Replicate and OpenRouter charge per request even for reads). Only hosts on the provider's allowlist can be reached, and redirects are never followed.
Call a connected API (providers.request)
[HIGH RISK · ADMIN ONLY] Make any HTTP call — including POST, PUT, PATCH and DELETE — to a third-party API using the credentials this account already connected to Chirply. This acts AS the account on its own accounts, so it can do anything those credentials can: publish a Facebook ad and start it spending, send an SMS billed to the org's Twilio account, charge a card on its Stripe account, or delete records in its Supabase project. There is no undo, no confirmation from the provider, and no Chirply-side spend limit — the cost lands on the account's own provider bills. Prefer a curated capability (meta.*, telephony.*, campaigns.*) when one exists; those validate input, respect plan limits, and write results back into the CRM. Only hosts on the provider's allowlist can be reached, credentials are attached server-side and never returned, and redirects are never followed. Every call is written to the account's audit log.

Actions — rcs

10 operations.

List RCS senders (rcs.list_senders)
[READ] List the RCS senders (branded agents) registered for this organization, with the review status of each and which carriers have approved it. Read-only and free. An empty list is the normal state until someone registers a sender on the organization's own Twilio account.
Register an RCS sender (rcs.register_sender)
[ADMIN ONLY] Record an RCS sender that already exists on the organization's own Twilio account, so Chirply routes that Messaging Service's traffic over RCS once it is approved. THIS DOES NOT CREATE THE SENDER — Twilio only onboards RCS senders through its Console, after which Google and each US carrier verify the brand separately, which Twilio says takes four to six weeks. Register it here as 'submitted', then set the status to 'approved' when Twilio's console shows a carrier has approved it. Nothing routes over RCS until the status is 'approved'.
Update an RCS sender (rcs.update_sender)
[ADMIN ONLY] Update a registered RCS sender — most often to move its status along as Twilio's console reports carrier approvals, or to record per-carrier verdicts. Setting status to 'approved' is what makes Chirply start routing that Messaging Service's messages over RCS; setting it to anything else stops that immediately and sends fall back to plain SMS.
Remove an RCS sender (rcs.delete_sender)
[HIGH RISK · ADMIN ONLY] Remove a registered RCS sender from Chirply. Messages on that Messaging Service immediately go back to plain SMS. This does NOT delete anything on Twilio — the sender and its carrier approvals stay on the organization's Twilio account, and re-registering it here restores RCS routing without any new review.
List rich message templates (rcs.list_templates)
[READ · ADMIN ONLY] List the organization's rich RCS message templates — cards, carousels, media and text — with each one's sync state and its Twilio Content SID once synced. Read-only and free.
Create a rich message template (rcs.create_template)
[ADMIN ONLY] Create a rich RCS message — a card with buttons, a carousel, an image, or plain text. Creating it here does not put it on Twilio; run rcs.sync_template to do that, which is what gives it the Content SID needed to send it. The `body` field is the plain-text fallback delivered as an SMS to any handset that can't take RCS, so write it to stand on its own.
Edit a rich message template (rcs.update_template)
[ADMIN ONLY] Edit a rich RCS template. Any change puts it back into 'draft' — Twilio's Content Templates are immutable, so an edited template has to be pushed again before the new version can be sent. Messages already sent are unaffected.
Push a template to Twilio (rcs.sync_template)
[HIGH RISK · ADMIN ONLY] Push a rich template to the organization's own Twilio account as a Content Template and store the resulting Content SID, which is what lets it be sent. Twilio's Content Templates are immutable, so syncing an edited template creates a new one on Twilio and the old one is left behind unreferenced. Uses the organization's own Twilio credentials.
Delete a rich message template (rcs.delete_template)
[HIGH RISK · ADMIN ONLY] Delete a rich RCS template from Chirply and, if it was synced, remove the matching Content Template from the organization's Twilio account. Messages already sent from it are unaffected. This cannot be undone.
Send a rich message (rcs.send_template)
[HIGH RISK] Send a synced rich template into an existing conversation. THIS SENDS A REAL MESSAGE TO A REAL PERSON, billed to the organization's own Twilio account. It goes out over RCS — branded, with the card or carousel rendered — only when the sending number's Messaging Service has an approved RCS sender AND the recipient's handset supports RCS; otherwise Twilio automatically falls back to SMS carrying the template's plain-text body, which the recipient receives instead. The thread records which of the two actually happened.

Actions — readiness

3 operations.

Feature setup checklist (readiness.list)
[READ] List every feature that needs setup before it will work (AI calling, business texting, custom domains, email, Facebook/Instagram), with each prerequisite and whether this account satisfies it yet — including the external steps only the user can do (accepting Twilio's AI addendum, verifying DNS, registering A2P, granting Meta permissions). Read-only.
Feature setup status (readiness.status)
[READ] Show the setup prerequisites and their satisfied/outstanding state for one feature. "feature" is one of: ai_calling, sms_texting, custom_domains, email_sending, meta_social, ai_studio, affiliate_payouts, restaurant, review_ingestion, contact_enrichment, tenant_subscriptions, white_label, directories. Read-only.
Confirm a setup step (readiness.acknowledge)
Mark an external setup step that can't be verified automatically (e.g. accepting Twilio's AI addendum, verifying DNS, registering A2P) as done for this account, or clear it with done=false. This only updates the advisory checklist — it does NOT perform the step itself. Steps that are detected automatically (a provider being connected) cannot be set here.

Actions — reddit_ads

13 operations.

Open Reddit Ads connection (reddit_ads.get_connection)
[READ · ADMIN ONLY] Read whether this account has connected Reddit Ads, which Reddit ad account and posting profile it works in, and whether the grant is held by a person or a durable System User. Returns identifiers and flags only; never returns tokens.
List Reddit ad accounts (reddit_ads.list_accounts)
[READ · ADMIN ONLY] List the Reddit businesses and ad accounts the connected Reddit identity can reach, including whether Reddit currently allows each one to run ads. Read-only; spends nothing.
Choose Reddit ad account (reddit_ads.select_account)
[ADMIN ONLY] Choose which Reddit ad account this Chirply account works in and which Reddit profile publishes its ads. This decides whose budget later campaigns spend, but by itself changes nothing on Reddit and spends no money.
List Reddit campaigns (reddit_ads.list_campaigns)
[READ · ADMIN ONLY] List this account's Reddit campaigns with their ad groups and ads, including each one's live delivery status and any rejection reason from Reddit. Read-only.
Create Reddit campaign (reddit_ads.create_campaign)
[HIGH RISK · ADMIN ONLY] Create a campaign in the connected Reddit ad account, with its budget and objective. The campaign is created PAUSED and spends nothing until it is started separately, but the budget set here is real money on the advertiser's own Reddit payment method once it runs.
Create Reddit ad group (reddit_ads.create_ad_group)
[HIGH RISK · ADMIN ONLY] Create an ad group inside a Reddit campaign, holding the targeting: which subreddits, interests, keywords, locations and custom audiences the ads reach. Created PAUSED; it spends nothing until started.
Create Reddit ad (reddit_ads.create_ad)
[HIGH RISK · ADMIN ONLY] Create an ad in a Reddit ad group. A Reddit ad is a REAL POST published by the account's chosen Reddit profile — it carries that identity publicly and redditors can comment on it. Created PAUSED, so it is not shown to anyone until started.
Start or pause Reddit ads (reddit_ads.set_status)
[HIGH RISK · ADMIN ONLY] Start, pause or archive a Reddit campaign, ad group or ad. Setting it ACTIVE BEGINS SPENDING the advertiser's real budget on their own Reddit payment method and shows the ad publicly; archiving cannot be undone from here.
Report on Reddit ads (reddit_ads.get_report)
[READ · ADMIN ONLY] Read delivery figures for this account's Reddit ads over a date range — impressions, clicks, spend, CTR, CPC and conversions — grouped by campaign, date, subreddit, country, placement, keyword or interest. Read-only. Reddit's numbers take up to six hours to settle and late conversions can revise earlier days.
Find subreddits to target (reddit_ads.suggest_communities)
[READ · ADMIN ONLY] Ask Reddit which communities (subreddits) to advertise in, seeded from topic words or a website address. This is Reddit's own suggestion engine and returns each community's subscriber count. Read-only and spends nothing, so it is safe to use as research before any campaign exists.
Find Reddit keywords (reddit_ads.suggest_keywords)
[READ · ADMIN ONLY] Ask Reddit for keyword ideas seeded from terms you supply, each with Reddit's own monthly view count, and flag any term Reddit does not consider brand safe. Read-only and spends nothing.
List Reddit payment methods (reddit_ads.list_funding)
[READ · ADMIN ONLY] List the payment methods on the connected Reddit ad account and whether Reddit will currently bill each one, with the reason when it will not. Read-only; returns Reddit's own identifiers and limits, never card details.
Disconnect Reddit Ads (reddit_ads.disconnect)
[HIGH RISK · ADMIN ONLY] Remove this account's Reddit authorization. Campaigns already built keep running on Reddit — nothing is paused or deleted there — but Chirply stops reporting on them and can no longer create or change anything until Reddit is reconnected.

Actions — releases

1 operation.

View release notes (releases.list)
[READ] List every successful production deployment newest first, including its exact build identifier, live time, and only the commits included since the previous deployed version.

Actions — reports

8 operations.

Browse report options (reports.describe_catalog)
[READ] List the report catalog: every dataset the report builder can query, with its available dimensions, metrics, and filters. Read this first to build a valid reports.run call.
Run report (reports.run)
[READ] Run a custom report over one of the curated datasets — contacts (Contacts), deals (Deals), calls (Calls), messages (Messages), appointments (Appointments), revenue (Revenue) — bucketed by day/week/month or as totals, optionally split by one dimension, with 1–3 metrics and the dataset's filters. Returns table rows and a chart-ready series. Read-only; money figures are integer cents.
Saved reports (reports.list_saved)
[READ] List the saved report definitions this caller can see: reports shared with the account plus their own. Account admins (and API keys) see every saved report in the organization.
Save report (reports.save)
Save a report definition so it can be re-run later, or update an existing saved report when an id is given. Setting shared=true makes it visible to every member of the account. The definition is validated against the report catalog before it is stored. Only the report's creator or an account admin can update one.
Delete saved report (reports.delete_saved)
[HIGH RISK] Permanently delete a saved report definition. If it was shared, it disappears for the whole account. The underlying data is untouched — only the saved definition is removed — but this cannot be undone. Only the report's creator or an account admin can delete one.
Report email schedules (reports.list_schedules)
[READ] List the standing email schedules for saved reports: which saved report, its daily/weekly/monthly cadence, the recipient emails, whether it's on, when it last sent, and any delivery error. Members see the schedules they created; account admins (and API keys) see every schedule. Read-only.
Email this report on a schedule (reports.set_schedule)
Create or update the ONE standing email schedule for a saved report: cadence ('daily' sends every day (UTC); 'weekly' sends every Monday (UTC); 'monthly' sends on the 1st of each month (UTC) — all UTC), the addresses it goes to, and whether it's on. Enabling it means the report's CURRENT results are emailed to those addresses automatically — real email through the workspace's own connected email account (Mailgun/Resend, on the org's bill) — until it is paused. No email is sent by this call itself. Only the schedule's creator or a workspace admin can change an existing one.
Email report now (reports.send_scheduled_now)
[HIGH RISK] Immediately runs one saved report and emails its current results — a REAL email to the given addresses, sent through the workspace's own connected email account (Mailgun/Resend, on the org's bill). Up to 20 addresses per send. Only works on a saved report the caller can see: one shared with the workspace, one they saved themselves, or any of them for a workspace admin. Omit recipients to use the ones saved on the report's email schedule. Does not move the schedule's clock: the next scheduled send still happens on time.

Actions — reputation

21 operations.

List reputation locations (reputation.list_locations)
[READ] List the account's business locations and their Google review-link readiness. This only reads data and does not call Google.
Add location (reputation.create_location)
Add a private business location for reputation tracking. This does not create or modify a Google Business Profile and costs nothing.
Save location (reputation.update_location)
Update a reputation location's name, address, Google review link, or active state. This only changes local records and does not modify Google.
List reviews (reputation.list_reviews)
[READ] List imported and manually recorded reviews with ratings and response workflow state. This only reads local records and does not call Google.
Add review (reputation.add_review)
Record a review manually for monitoring and response preparation. This does not publish anything or claim the review exists on Google.
Save response draft (reputation.save_response_draft)
Save a private response draft for a review. Nothing is posted to Google or shown to the reviewer.
List review requests (reputation.list_requests)
[READ] List trackable review-request links and their lifecycle status. A completed request can mean private feedback was submitted; it does not prove a public review was posted or grant testimonial publication permission. This only reads data and sends no messages.
Create review link (reputation.create_request)
Create a private trackable review-request link for one location. This does not email or text anyone and costs nothing; use reputation.send_request to actually deliver one by SMS or email.
Send review request (reputation.send_request)
[HIGH RISK] Create a trackable review link for a contact and immediately deliver it as a real SMS or email — sent through and billed to the org's own Twilio or Mailgun/Resend account, and logged in the contact's conversation thread. Opted-out addresses are refused. The recipient can submit private feedback, after which configured public review options are available regardless of rating. Completing private feedback does not prove a public review was posted or grant testimonial publication permission.
List review sites (reputation.list_destinations)
[READ] List the public Google, Facebook, Yelp, Trustpilot, BBB, Tripadvisor, and custom review destinations attached to account locations. This only reads data.
Attach review site (reputation.add_destination)
Attach a public review destination to a reputation location. It becomes an optional choice shown to every customer after private feedback, regardless of rating; this sends nothing and costs nothing.
List private feedback (reputation.list_feedback)
[READ] List private first-party experience feedback, customer contact requests, and service-recovery status. This data is not published to review sites.
Find your business on Google (reputation.find_google_place)
[HIGH RISK] Search Google Maps for a business so a reputation location can be connected to its Google listing, via the organization's OWN Outscraper account. THIS SPENDS THE TENANT'S MONEY: Outscraper bills per place returned (a few records per search, roughly $3 per 1,000 Maps records on standard tiers). Returns candidate listings with their Google place ids; pass the right one to reputation.set_location_place. Nothing is stored by this call.
Connect Google listing (reputation.set_location_place)
Attach a Google Maps place id to a reputation location so review syncs know which business to pull. Also fills the location's public 'write a review' link from the place id when one isn't set yet. This only updates local records — it costs nothing and does not modify anything on Google.
Sync Google reviews (reputation.sync_reviews)
[HIGH RISK] Pull the newest Google reviews for one location (which must be connected to its Google listing first) and store them in the review inbox, via the organization's OWN Outscraper account. THIS SPENDS THE TENANT'S MONEY: Outscraper bills per review record returned, capped at 100 per sync (roughly $3 per 1,000 records on standard tiers). Re-syncing never duplicates — reviews are matched on Google's own review id and refreshed in place, and saved reply drafts are preserved. If Outscraper queues the job, this returns pending:true; call it again shortly to collect the finished results at no extra cost.
Draft a review reply (reputation.draft_reply)
Write an owner's reply to one review with AI, grounded on the chosen slice of the account's Knowledge Brain, and save it as a private response draft on the review. Runs on the organization's own OpenRouter key (a small AI charge billed to their OpenRouter account). NOTHING IS POSTED ANYWHERE — Google publishing isn't available yet, so a human copies the draft and posts it on Google themselves.
List review widgets (reputation.list_widgets)
[READ] List the account's embeddable review-display widgets with their keys, star-rating thresholds, and status. This only reads data; the key in each row is what the public embed snippet uses.
Create review widget (reputation.create_widget)
Create an embeddable public widget that shows one location's best reviews (star display, newest first) on any website via a one-line script tag. Only reviews at or above the star threshold are shown — the default is 4 stars and up. Creating a widget costs nothing and publishes nothing until the tenant pastes the returned snippet onto their site.
Save review widget (reputation.update_widget)
Change a review widget's name, star threshold, layout, colors, or status. Setting status to 'disabled' makes every copy of the embed on the tenant's websites render nothing until re-published; the embed snippet itself never changes.
Delete review widget (reputation.delete_widget)
[HIGH RISK] Permanently delete a review widget. Every copy of its embed snippet on the tenant's websites immediately renders nothing, and the widget key cannot be restored — a replacement widget gets a new key that has to be re-pasted onto the site. The reviews themselves are not touched.
Save recovery status (reputation.update_recovery)
Update the internal service-recovery status, assignee, and private notes for customer feedback. This does not contact the customer or publish anything.

Actions — reseller

49 operations.

Account domain (reseller.list_client_domains)
[READ] List agency-owned domains, their DNS and HTTPS status, and assigned client account IDs. Read-only; changes no routing and costs nothing. An app_org_id matching the client is its dedicated account address; null means unassigned.
Connect account domain (reseller.connect_client_domain)
[HIGH RISK · ADMIN ONLY] Connect a hostname the agency already owns and assign it to this client account. Requests a public HTTPS certificate, consumes an agency domain slot, and changes where the app opens once DNS is verified. Does not buy a domain or edit DNS; the owner adds the returned CNAME at their provider. Requires White-Label. Existing published content and assignments to other clients are protected.
Assign account domain (reseller.assign_client_domain)
[HIGH RISK · ADMIN ONLY] Assign an agency-owned domain to this client account. Once active, visitors sign in to the assigned account with the agency's branding. Changes live application routing, costs nothing, and preserves domain ownership. Requires White-Label; a domain assigned to another client must be unassigned first.
Remove assignment (reseller.remove_client_domain)
[HIGH RISK · ADMIN ONLY] Remove this client's dedicated account assignment from one agency-owned domain. Immediately restores shared agency sign-in at that hostname. Keeps the domain connection, HTTPS certificate and agency ownership; costs nothing. Requires White-Label.
Check account domain (reseller.verify_client_domain)
[ADMIN ONLY] Re-check DNS and HTTPS certificate status for a domain assigned to this client account and save its connection status. Changes only the stored verification state, edits no DNS and costs nothing. Requires White-Label.
Your plans (reseller.list_plans)
[READ] List the plans this agency sells to its clients — the reseller's own packages, with the price the reseller charges and which underlying platform tier each one unlocks. These are NOT the platform's own retail plans; they're what this agency resells under its own brand.
Create plan (reseller.create_plan)
[ADMIN ONLY] Create a plan this agency sells to its clients: a name the client sees on their invoice, the price the agency charges, which underlying platform tier it unlocks, and optional per-limit tweaks on top of that tier. Creating a plan costs nothing and charges nobody — it only defines a package. Clients are put on it separately with reseller.assign_plan.
Edit plan (reseller.update_plan)
[HIGH RISK · ADMIN ONLY] Change a plan's name, price, billing interval, which underlying platform tier it unlocks, or its per-limit tweaks. This edits a package the agency SELLS: every client already on the plan immediately follows its new tier and limits, so lowering a tier or a limit can take a working feature away from a paying customer, and the new price is what the next client to sign up pays. Their existing Stripe subscription is NOT re-priced — changing what a live customer pays has to be done deliberately by cancelling and re-starting their billing.
Retire plan (reseller.archive_plan)
[HIGH RISK · ADMIN ONLY] Retire a plan so it can no longer be assigned or sold. Clients already on it keep it and keep working — nothing is deleted and nobody's billing changes — but the plan disappears from the pickers. There is no un-retire; recreate it if needed.
Clients (reseller.list_clients)
[READ] List every client account (client account) under this agency, with the included client-account allowance, used and remaining capacity, the plan each one is on, how many people are in it, and whether the agency is billing them. Includes soft-deleted clients — those have status 'canceled' and can be brought back with reseller.restore_client. Read-only.
Open a client (reseller.get_client)
[READ] Everything about one client account: its plan, the people in it, outstanding invitations, and its billing state on the agency's own Stripe. Read-only.
New client account (reseller.create_client)
[ADMIN ONLY] Create a new client account under this agency, optionally putting it straight onto one of the agency's plans. Counts against the agency's paid client account allowance and fails once that's used up. The account starts empty with nobody in it — invite the client with reseller.invite_client_user. Assigning a plan here pins their tier and limits immediately but charges nobody; billing is started separately.
Rename client (reseller.rename_client)
[ADMIN ONLY] Rename a client account. Cosmetic — the URL slug and everything inside it are untouched.
Suspend or reactivate client (reseller.set_client_status)
[HIGH RISK · ADMIN ONLY] Suspend a client account so nobody in it can sign in — how an agency handles a client who has stopped paying — or reactivate a suspended one. Nothing is deleted and it is fully reversible, but suspending locks real people out of their account immediately.
Delete client (reseller.delete_client)
[HIGH RISK · ADMIN ONLY] Delete a client account. This is a soft delete: the account is closed and everyone in it is locked out immediately, but nothing is destroyed — it can be restored later with reseller.restore_client. It stops counting against your paid client account allowance, so deleting a client frees a slot to create another. It does NOT cancel any billing you have running for them on your Stripe — stop that separately with reseller.cancel_client_billing.
Restore client (reseller.restore_client)
[ADMIN ONLY] Bring a deleted (cancelled) client account back to active, with all its data intact. Fails if you're already at your paid client account allowance — free a slot or upgrade first, since a restored client counts again.
Assign plan (reseller.assign_plan)
[HIGH RISK · ADMIN ONLY] Put a client account on one of the agency's plans, or clear it. This changes what a paying third-party business can actually do straight away, because the plan pins their underlying platform tier and limits — moving them down a tier removes features and can push them over a limit they are currently using. It does NOT charge them or change an existing subscription — billing is started separately with reseller.start_client_billing — so the money and the entitlements can end up out of step until someone reconciles them.
Client's people (reseller.list_client_users)
[READ] List who can sign in to a client account, plus any invitations that haven't been accepted yet. Read-only.
Invite to client account (reseller.invite_client_user)
[HIGH RISK · ADMIN ONLY] Invite someone into a client's account — normally the client themselves, so they can log in and use the platform. Creates a pending invitation they accept to join; it grants them access to that one account only, never to the agency. Sends a real invitation to a real email address.
Withdraw invitation (reseller.revoke_client_invite)
[ADMIN ONLY] Withdraw a pending invitation into a client account. Their invite link stops working. Anyone who already accepted is unaffected.
Billing setup (reseller.get_billing_status)
[READ · ADMIN ONLY] Whether this agency has connected its own Stripe account, which is required before it can charge any client. Read-only.
Start billing a client (reseller.start_client_billing)
[HIGH RISK · ADMIN ONLY] SPENDS THE CLIENT'S MONEY. Subscribes a client to one of the agency's plans on the AGENCY'S OWN Stripe account and has Stripe email them an invoice immediately, due in 7 days, recurring at the plan's price and interval. The money goes to the agency; the platform neither holds it nor takes a cut. Requires the agency to have connected Stripe. Fails if the client already has a live subscription.
Stop billing a client (reseller.cancel_client_billing)
[HIGH RISK · ADMIN ONLY] Cancel a client's subscription on the agency's Stripe. By default it ends when the period they've already paid for runs out; `immediately` cuts it off now, which forfeits the rest of a period they have already been charged for and is not reversible. Does not suspend or delete their account.
Refresh billing from Stripe (reseller.sync_client_billing)
[ADMIN ONLY] Re-read a client's subscription from the agency's Stripe account and update the status shown here. This platform receives no webhooks from a tenant's own Stripe, so a payment that failed over there is only noticed when this runs. Read-only as far as Stripe is concerned — it charges nothing.
Client performance rollup (client_reports.rollup)
[READ] Read each active client's new contacts, calls, connect rate, messages, appointments, reviews, and collected net revenue for a UTC period. Failed sources return null metrics and unavailable section names, never zero. Revenue totals disclose client coverage. Read-only; sends no messages.
List client report schedules (client_reports.list_schedules)
[READ · ADMIN ONLY] List every scheduled client report this agency has configured: which client, weekly or monthly, the recipient emails, whether it's enabled, when it last sent, and any delivery error. Read-only.
Set a client's report schedule (client_reports.set_schedule)
[ADMIN ONLY] Create or update the standing report for one client account: weekly or monthly cadence, the client emails it goes to, and whether it's on. Enabling it means a real branded report email is sent to those addresses automatically after each period ends, through this agency's own connected email account. No email is sent by this call itself.
Preview a client report (client_reports.preview)
[READ] Build a branded client report for the latest completed UTC week or month, returning subject, numbers, fetch time, and HTML without sending email. Unavailable source sections are null and visibly labeled; incomplete reports cannot be sent.
Send a client report now (client_reports.send_now)
[HIGH RISK · ADMIN ONLY] Assemble and email a client's branded performance report for the latest completed UTC week or month — a REAL email through the agency's connected Mailgun/Resend account, billed to the agency. Delivery is held if any source section is unavailable. Use preview to inspect without sending.
Pooled credentials (reseller.list_pooled_credentials)
[READ] For one client account, show which providers it's using YOUR pooled credentials for versus its own. Each row reports the provider, whether pooling is on, its status (off / provisioning / active / error), and any isolation detail (the Twilio subaccount SID, the Mailgun subdomain and its DNS state). Read-only.
Pool a credential to a client (reseller.enable_pooled_credential)
[HIGH RISK · ADMIN ONLY] Let a client account use YOUR provider account instead of connecting its own. For Twilio this creates an isolated Twilio subaccount under your master account — the client's calls and texts run on it and Twilio bills YOU for them. For Mailgun it provisions an isolated sending subdomain (which needs its DNS verified before it goes live). For ElevenLabs / OpenRouter / Outscraper / Firecrawl it uses your API key directly, effective immediately. The client's usage becomes your real cost — meter and rebill it with the credit system. Reversible at any time.
Stop pooling a credential (reseller.disable_pooled_credential)
[HIGH RISK · ADMIN ONLY] Turn off a pooled provider for a client. By default this is a reversible soft off — the client goes back to using its own connection and the isolation artifacts are kept, so re-enabling is instant. Set teardown to also SUSPEND the Twilio subaccount (reversible, keeps the client's numbers) or DELETE the Mailgun subdomain.
Verify pooled Mailgun DNS (reseller.verify_pooled_credential)
[ADMIN ONLY] Re-check a pooled Mailgun subdomain's DNS with Mailgun and flip it live once the records verify. Only applies to Mailgun; the other providers need no verification. Charges nothing.
Client payment setup (Stripe Connect) (reseller.get_stripe_connect)
[READ] For one client account, show whether it accepts payments through YOUR Stripe (a connected account under your platform) or its own. Reports the status (own Stripe / onboarding / restricted / live), whether charges and payouts are enabled, and the application fee you take on its transactions (the per-client override or the plan default). Read-only.
Let a client take payments through you (reseller.enable_stripe_connect)
[HIGH RISK · ADMIN ONLY] Turn on Stripe Connect for a client: create (or reuse) an Express connected account under YOUR Stripe platform so the client can accept card payments through you. Money settles to the client and they stay merchant of record; you take an application fee on each transaction (set separately). This does NOT finish setup — the client must still complete Stripe's identity + bank verification (a link, from get_stripe_connect_link) before they can accept a payment. Requires your own Stripe to be connected and have Connect enabled. Reversible.
Get a client's payment-setup link (reseller.get_stripe_connect_link)
[ADMIN ONLY] Mint a fresh Stripe onboarding link for a client's connected account — the URL the client opens to complete identity + bank verification. The link is single-use and expires within minutes, so generate it when you're about to send it. Connect must already be enabled for the client.
Refresh a client's payment status (reseller.refresh_stripe_connect)
[ADMIN ONLY] Re-check a client's connected account with Stripe and update whether it can accept charges and receive payouts. Use after the client finishes onboarding to confirm they're live. Charges nothing.
Set a client's payment fee (reseller.set_stripe_connect_fee)
[HIGH RISK · ADMIN ONLY] Set the application fee you take on this client's transactions, in basis points (100 = 1%, max 10000 = 100%). This is money taken off the top of another business's card revenue, and at 10000 it takes all of it — so confirm the number with a human before saving. It is a per-client override; pass null to clear it and inherit the client's plan default instead. Applies to future charges once Connect charge routing is live.
Stop a client taking payments through you (reseller.disable_stripe_connect)
[HIGH RISK · ADMIN ONLY] Turn off Stripe Connect for a client. Reversible: the client goes back to selling on its own Stripe, and the connected account is kept so you can switch it back on instantly. Does not move or refund any money already collected.
Rate card (reseller.get_rate_card)
[READ] Read the per-item prices a reseller charges. With a client_id, returns that client's effective prices (override → plan default → agency default) plus its own overrides. Otherwise returns the default prices for a plan (or the agency-wide default when no plan_id is given). Each price also reports `markup_percent`: the percentage on cost it was written as, or null when it is a fixed dollar amount. Read-only, costs the caller nothing.
Set prices (reseller.set_rate_card)
[ADMIN ONLY] Set what a reseller charges per metered unit, as a fixed price or as a percentage mark-up on what the unit costs them. With a client_id, sets that client's overrides; with a plan_id, the plan's defaults; with neither, the agency-wide defaults. A mark-up price is recomputed from the cost basis (see reseller.get_unit_costs) every time it is charged, so correcting a cost re-prices every unit priced that way. Setting a price changes what the client is billed for future usage on your pooled credentials — it moves no money by itself and bills nobody retroactively. Unknown units are ignored with a warning.
What it costs you (reseller.get_unit_costs)
[READ · ADMIN ONLY] Read what each metered unit costs the RESELLER at their own provider — the base every percentage mark-up price is worked out from. Units the reseller has not given a figure for report Chirply's published list price for that provider, flagged with is_custom false. This is the agency's margin data and is never visible to a client. Read-only.
Set your provider costs (reseller.set_unit_costs)
[HIGH RISK · ADMIN ONLY] Record what metered units actually cost the reseller at their provider, in dollars per unit (e.g. {"sms": 0.0079}). This is agency-wide and is the base for every price written as a percentage mark-up, so changing a cost immediately changes what EVERY client on a mark-up for that unit is charged for future usage — it moves no money by itself and never re-bills past usage. Units listed in `reset` fall back to Chirply's published list price. Unknown units are ignored with a warning.
Client credits (reseller.get_client_credits)
[READ] A client's prepaid credit standing on the reseller's pooled providers: balance (cycle allowance + purchased), whether it's paused for being out of credits, its effective per-unit prices, and its recent credit ledger. Read-only.
Adjust credits (reseller.adjust_client_credits)
[HIGH RISK · ADMIN ONLY] Manually add or remove credits from a client's balance (a comp, a correction). A positive amount grants credits; a negative amount deducts them. Adding credits lifts a paused client back into service. This changes a real balance the reseller is liable for, so it's confirm-gated.
Start card setup (reseller.start_client_card_setup)
[ADMIN ONLY] Begin saving a payment card for a client's credit top-ups. Creates (or reuses) a customer on the RESELLER'S OWN Stripe account and returns a SetupIntent client_secret plus the reseller's publishable key, for a Stripe Payment Element the CLIENT completes in a browser. No money moves and no card data passes through this call — the card is entered directly into Stripe's form. Finish with reseller.complete_client_card_setup.
Finish card setup (reseller.complete_client_card_setup)
[ADMIN ONLY] Verify a confirmed SetupIntent with the reseller's Stripe and record the resulting payment method as the client's saved card for credit top-ups and auto-recharge. Refuses unless Stripe itself reports the setup succeeded for this client's customer. Moves no money.
Charge card (reseller.top_up_client_credits)
[HIGH RISK · ADMIN ONLY] Immediately charges the client's SAVED card on the RESELLER'S OWN Stripe account for a credit top-up — real money, billed to the client by the reseller — and adds the amount to the client's credit balance once Stripe confirms the charge settled (which also resumes paused pooled sends). Between $5 and $2,000. Refuses when no card is saved (see reseller.start_client_card_setup).
Auto-recharge (reseller.set_client_auto_recharge)
[HIGH RISK · ADMIN ONLY] Turn a client's credit auto-recharge on or off and set its rules. While on, whenever a pooled-usage debit drops the client's balance under the threshold, their SAVED card is automatically charged the recharge amount on the RESELLER'S OWN Stripe — unattended, real-money charges, at most one attempt per 15 minutes. Confirm-gated because saving these settings arms future charges nobody clicks on.

Actions — restaurant

71 operations.

Restaurant settings (restaurant.list_locations)
[READ] List the account's restaurant locations with all of their settings — public web address (/eat/<slug>), contact details, opening hours, timezone, currency, sales tax rate, online-ordering/pickup/delivery/reservation toggles, delivery fee and minimum, prep time, tip presets, and public-page branding.
Set up a restaurant (restaurant.create_location)
[ADMIN ONLY] Create a restaurant location — the same thing the Settings first-run wizard does. Claims a globally unique public web address (/eat/<slug>) where diners can immediately see the menu and, when enabled, order and reserve. Only the name is required; everything else has sensible defaults (open toggles, 20-minute prep, no tax).
Save restaurant settings (restaurant.update_location)
[HIGH RISK · ADMIN ONLY] Update a restaurant location's settings. CHANGES WHAT DINERS SEE AND WHAT THEY ARE CHARGED: the tax rate and delivery fee alter real checkout totals, the toggles turn public ordering/reservations on or off, hours change when orders are accepted, and changing the slug MOVES the public pages (old /eat/<slug> links stop working). Omitted fields are left alone.
Kitchen stations (restaurant.list_stations)
[READ] List the kitchen stations (Grill, Fry, Bar…) tickets are sorted onto. Menu items and categories point at a station, and the kitchen display filters by it.
Add station (restaurant.create_station)
[ADMIN ONLY] Add a kitchen station to a location — a named screen/printer tickets route to, like Grill or Bar. Station names are unique within a location.
Delete station (restaurant.delete_station)
[HIGH RISK · ADMIN ONLY] Permanently delete a kitchen station. Menu items and categories routed to it fall back to 'no station' — their tickets keep printing but stop being sorted onto this screen. Cannot be undone.
Reservation services (restaurant.list_service_periods)
[READ] List a location's service periods — the bookable sittings on the public reservation page (e.g. Dinner: Tue–Sun 5–10pm, 30-minute slots, tables turn in 90 minutes). Days use 0=Sunday…6=Saturday; times are 24-hour local to the location.
Save reservation services (restaurant.set_service_periods)
[ADMIN ONLY] REPLACE a location's entire reservation schedule with the given service periods. This immediately changes which dates and times diners can book on the public page — services not in the list are removed (existing reservations are kept). Pass the full schedule, not a delta.
List menus (restaurant.list_menus)
[READ] List the restaurant's menus (Dinner, Brunch, Drinks…) in display order, optionally for one location only. Each menu row includes whether it is live — an inactive menu is hidden from the POS, tablets, online ordering, and the website.
Open a menu (restaurant.get_menu)
[READ] Fetch one menu with its full contents: categories in service order, every dish in each category (including 86'd ones, flagged by available=false), and the ids of the modifier groups attached to each dish.
New menu (restaurant.create_menu)
Create a menu (e.g. Dinner, Brunch, Drinks) at one of the restaurant's locations. A live menu appears on the POS, table tablets, online ordering, and the website menu block as soon as it has dishes.
Edit a menu (restaurant.update_menu)
[HIGH RISK] Rename a menu, change its display position, or toggle it live/hidden. Setting active=false immediately pulls the ENTIRE menu — every category and every dish on it — off the POS, table tablets, online ordering, and the website, mid-service if that is when you run it; real diners stop being able to order any of it within seconds. Nothing is deleted, and active=true puts it all back.
Delete a menu (restaurant.delete_menu)
[HIGH RISK] Permanently delete a menu with all of its categories and dishes, removing it from the POS, tablets, online ordering, and the website. This cannot be undone — to take a menu offline temporarily, set active=false instead.
New category (restaurant.create_menu_category)
Add a category (Starters, Mains, Desserts…) to a menu. Optionally route its dishes to a kitchen station, so they print on that station's kitchen screen.
Edit a category (restaurant.update_menu_category)
Rename a category, change its description or display position, or point it at a different kitchen station. Pass station_id: null to clear the station.
Delete a category (restaurant.delete_menu_category)
[HIGH RISK] Permanently delete a category and every dish in it, removing them from all ordering surfaces. This cannot be undone.
List dishes (restaurant.list_menu_items)
[READ] List the dishes on the menu, in display order. Filter by category or by menu, restrict to available (or 86'd) dishes only, and search names and descriptions. available=false rows are 86'd — hidden from diners but still on the books.
Add a dish (restaurant.create_menu_item)
Add a dish to a menu category with its price, description, photo, and dietary tags. It becomes orderable on every surface (POS, tablets, online ordering, website menu) immediately unless available=false.
Edit a dish (restaurant.update_menu_item)
[HIGH RISK] Update a dish — name, price, description, photo, dietary tags, kitchen station, SKU, or which category it sits in. Omitted fields are left alone. Every change is outward-facing: this edits a dish real diners are looking at, and a new price_cents is what the next order charges on the POS, the tablets, online ordering, and the website, within seconds and with no review step. A wrong dietary tag reaches someone with an allergy. To 86 a dish use restaurant.set_item_availability instead.
Delete a dish (restaurant.delete_menu_item)
[HIGH RISK] Permanently delete a dish from the menu. Past order lines keep their snapshot of it, but it disappears from every ordering surface and cannot be restored. To take it off temporarily, 86 it instead.
86 a dish / bring it back (restaurant.set_item_availability)
[HIGH RISK] Flip a dish's availability. available=false 86's it: the dish disappears from the POS, table tablets, online ordering, and the website menu immediately, so real diners can no longer order it. available=true puts it back on sale everywhere. Nothing is deleted either way.
List modifier groups (restaurant.list_modifier_groups)
[READ] List the restaurant's reusable option sets ("Choose a side", "Add-ons"…), each with its options and their price bumps. available=false options are hidden from diners.
New modifier group (restaurant.create_modifier_group)
Create a reusable option set diners pick from when ordering a dish — e.g. "Choose a side" (required, exactly one) or "Add-ons" (optional, any number). Attach it to dishes with restaurant.attach_modifier_group.
Edit a modifier group (restaurant.update_modifier_group)
Rename a modifier group or change its pick rules (min/max/required). The change applies at once to every dish the group is attached to.
Delete a modifier group (restaurant.delete_modifier_group)
[HIGH RISK] Permanently delete a modifier group and all of its options, detaching it from every dish that offered it. Diners lose those choices immediately. This cannot be undone.
Add an option (restaurant.create_modifier)
Add one option to a modifier group — e.g. "Fries" or "Extra shot (+$1.50)". Its price is added on top of the dish's own price whenever a diner picks it.
Edit an option (restaurant.update_modifier)
Update one option in a modifier group — rename it, change its extra cost, its display position, or hide/show it (available). Price changes reach diners immediately on every dish offering the group.
Delete an option (restaurant.delete_modifier)
[HIGH RISK] Permanently delete one option from a modifier group. Diners can no longer pick it on any dish. This cannot be undone — to pull it temporarily, set available=false instead.
Attach a modifier group to a dish (restaurant.attach_modifier_group)
Offer a modifier group's options on one dish. Diners ordering that dish are shown the group (and must pick from it if the group is required) on every ordering surface. Attaching an already-attached group just updates its display position.
Detach a modifier group from a dish (restaurant.detach_modifier_group)
[HIGH RISK] Stop offering a modifier group on one dish. Diners immediately lose those options when ordering it (a required group's detachment means the dish orders as-is). The group itself and its other attachments are untouched.
List orders (restaurant.list_orders)
[READ] List the restaurant's orders (POS, tablet and online), newest first. Filter by status, order type, source channel, location, or an opened-at date range.
Open an order (restaurant.get_order)
[READ] Fetch one order in full: its line items (with modifiers and kitchen status), its checks with computed totals, and every payment taken against them.
New order (restaurant.create_order)
Open a new restaurant order with its first check. Nothing is cooked or charged yet — add items with restaurant.add_order_items, then fire them to the kitchen with restaurant.fire_order.
Add items to order (restaurant.add_order_items)
Add menu items to an open order. Prices, names and station routing are ALWAYS re-read from the menu on the server — pass menu item and modifier ids only. Items land as 'pending' and are not cooked until restaurant.fire_order sends them.
Send to kitchen (restaurant.fire_order)
[HIGH RISK] Fire an order's pending items to the kitchen — they appear on the kitchen display for REAL cooks to start making, and each item's recipe depletes inventory. Optionally fire only specific item ids (a course). Fired food can't be un-fired, only voided.
Split a check (restaurant.split_check)
Split a check two ways: mode 'items' moves the listed item groups onto new checks on the same order (groups[0] stays on the original), each paying independently; mode 'even' creates NO new checks — it returns the per-payer share amounts, each of which is then taken as a partial payment (restaurant.record_cash_payment, or a card payment in the app).
Record cash payment (restaurant.record_cash_payment)
[HIGH RISK] Record REAL MONEY taken in cash against a check. The amount (plus any tip) counts toward the check's total, and the check marks itself paid once its payments cover it. An amount below the total is a partial payment — how an even split settles. This is a financial record; get it wrong and the till won't balance.
Complete order (restaurant.complete_order)
[HIGH RISK] Close an open order out as completed. One-way and irreversible: completed orders can NOT be reopened — anything else the table wants has to go on a new order, and any check still unpaid stays unpaid on a closed order. Normally done only after every check is paid.
Cancel order (restaurant.cancel_order)
[HIGH RISK] Cancel an open order. One-way: the order closes as canceled and can't be reopened; its checks and any payments already taken stay on record as the audit trail. Food already fired to the kitchen is NOT recalled automatically.
Send receipt (restaurant.send_receipt)
[HIGH RISK] Email and/or text a REAL diner the itemized receipt for a check, on the org's own connected email sender and Twilio number. NOT SAFE TO RE-SEND: there is no de-duplication, so every call delivers another message to that person's phone and inbox, and every SMS is another Twilio message billed to the org. Send it once. It does not charge the diner's card or change the check — the cost is the messaging, and the harm is texting a customer repeatedly. Optionally captures the guest's email/phone onto the order first.
Kitchen display (restaurant.kitchen_queue)
[READ] Read the live kitchen display: every fired order item that is queued, cooking, or ready, grouped into per-order tickets (oldest fire first) with table/guest, order type, modifiers, notes, seats and courses — plus the 'all day' totals per item name still being cooked. Optionally filter to one location or one kitchen station. Read-only; changes nothing.
Bump an item (restaurant.bump_item)
Advance one fired order item through the kitchen: queued → 'in_progress' (start cooking), → 'ready' (up in the window), ready → 'served' (drops off the display). Sending 'in_progress' to an item that is currently 'ready' un-bumps it back to cooking — the fix for a mis-tap. Only legal moves are accepted; the kitchen display updates in real time.
Bump a whole ticket (restaurant.bump_order)
Advance every fired item on one order in a single move — the ticket-level bump-all. Only items a step can legally reach are moved: 'in_progress' starts the queued items, 'ready' moves queued and cooking items up, 'served' clears the ready ones off the display. Items already past the target (and pending/voided items) are left alone. Returns how many items moved.
Tables (restaurant.list_tables)
[READ] List the restaurant's dining tables and their floor-plan geometry: name, seat count, room, shape, position, size, rotation, server section, service state, and QR/tablet token. Filter by location, room, section, or active state, or search by name.
Add table (restaurant.create_table)
Add a dining table to the restaurant's floor plan. It appears on the Tables screen immediately and gets its own tablet ordering screen (/restaurant/tablet/<id>) that staff can hand to guests. Nothing is sent to anyone.
Edit table (restaurant.update_table)
Update a dining table: rename it, change its seats, shape, floor position, size, rotation, room, server section, location, display order, or service state. Omitted fields are left alone, except moving a table to another location without naming a destination section clears its old section. Taking a table out of service makes its tablet screen refuse new orders.
Server sections (restaurant.list_floor_sections)
[READ] List the restaurant's floor sections, including each section's display color, assigned server, location, and the number of tables currently in the section. This reads scheduling state only and sends nothing.
Create section (restaurant.create_floor_section)
Create a color-coded floor section at one restaurant location and optionally assign an account teammate as its server. No tables move until they are explicitly assigned, and nothing is sent to the teammate.
Save section (restaurant.update_floor_section)
Update a floor section's name, color, display order, or assigned server. Changing the server reassigns responsibility for every table already in that section; it does not send a notification or message.
Assign selected (restaurant.assign_tables_to_section)
Assign one or many dining tables at the same restaurant location to a server section, or clear their section. The section's assigned teammate becomes responsible for the whole selected group; no guest or teammate is messaged.
Delete section (restaurant.delete_floor_section)
[HIGH RISK] Permanently delete a server section. Its dining tables remain on the floor plan but immediately become unassigned; the lost section name, color, and server assignment cannot be restored automatically. No messages are sent.
Physical floor plan (restaurant.get_physical_floor_plan)
[READ] Read one restaurant location's measured building plan, uploaded-image reference, rooms, walls, doors, fixed service areas, and exact seat markers. This returns layout data only and sends nothing.
Save building plan (restaurant.save_physical_floor_plan)
Create or update the real-world width, depth, measurement unit, and uploaded-plan visibility for one restaurant location. Existing uploaded images, rooms, fixtures, seats, tables, orders, and reservations stay in place.
Remove plan image (restaurant.remove_floor_plan_image)
[HIGH RISK] Permanently delete the private uploaded architectural-plan image from one restaurant location. Every traced room, wall, fixture, seat, operational table, order, reservation, and server section stays in place, but the image itself cannot be restored automatically.
Upload plan image (restaurant.upload_floor_plan_image)
[HIGH RISK] Upload or replace the private architectural-plan image underneath one restaurant floor. The image is stored permanently in the account's Supabase Storage (up to 10 MB, which can incur storage and egress cost); traced rooms, fixtures, seats, and tables remain unchanged.
Add floor feature (restaurant.create_floor_feature)
Add one measured physical feature—room, wall, door, bar, kitchen, checkout, restroom, patio, fixture, or exact seat—to a restaurant building plan. A seat can be linked to its operational dining table; nothing is sent or charged.
Save floor feature (restaurant.update_floor_feature)
Update a traced room, wall, door, fixed service area, fixture, or exact seat on the physical restaurant plan. This changes only the drawing; linked tables, orders, reservations, and server assignments remain intact.
Delete floor feature (restaurant.delete_floor_feature)
[HIGH RISK] Permanently delete one traced room, wall, door, service area, fixture, or exact seat marker from the physical restaurant plan. Linked operational tables, orders, reservations, and server sections stay intact, but the deleted drawing cannot be restored automatically.
Delete table (restaurant.delete_table)
[HIGH RISK] Permanently delete a dining table from the floor plan. Past orders keep their history (they just lose the table link), but the table's tablet ordering screen and QR token stop working immediately. This cannot be undone — prefer taking the table out of service (restaurant.update_table with active=false) if it might come back.
Table status (restaurant.table_status)
[READ] The live floor view: for each table, whether it currently has an open order (with order number, when it opened, and covers) and its next upcoming reservation inside the look-ahead window. This is exactly what the Tables screen shows staff.
Inventory (restaurant.list_inventory)
[READ] List the restaurant's inventory items with what's on hand, the unit each is counted in, its par (reorder) level, unit cost in cents, and SKU. Optionally filter to one location or search by name/SKU. Costs nothing to run. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
New item (restaurant.create_inventory_item)
Create an inventory item — something the restaurant keeps on the shelf and wants tracked (an ingredient, a bottle, packaging). An opening on-hand amount, when given, is recorded as a 'count' movement so the ledger starts complete. Link the item to menu items with restaurant.set_recipe to have sales deplete it automatically. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Edit item (restaurant.update_inventory_item)
Edit an inventory item's name, unit, par level, unit cost, SKU, or location. Omitted fields are left alone. The on-hand amount is deliberately NOT editable here — change it with restaurant.adjust_stock so the ledger records why. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Adjust (restaurant.adjust_stock)
[HIGH RISK] Change an inventory item's on-hand amount by a signed delta and write the matching row in the stock-movement ledger. This rewrites what the shelf says the restaurant owns — deliveries, waste, corrections, and physical counts all go through here — so the number feeds the low-stock report and everything downstream that trusts it. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Movements (restaurant.list_stock_movements)
[READ] Read the stock-movement ledger, newest first: every change to every on-hand count, with its signed delta, reason ('purchase', 'waste', 'adjustment', 'count', or the automatic 'sale' written when the kitchen fires an order), note, the order that consumed the stock for sale rows, and who made it. Optionally filter by item or reason. Costs nothing to run. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Save recipe (restaurant.set_recipe)
Replace a menu item's ingredient lines — how much of which inventory items selling ONE of that dish consumes. This is what makes sales deplete stock automatically: when the kitchen fires the dish, each line writes a 'sale' movement. An empty ingredient list clears the recipe, and the dish stops touching inventory. Quantities are per single sale, in each ingredient's own unit. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Reorder list (restaurant.low_stock)
[READ] The reorder report: every inventory item at or below its par level, with what's on hand, the par line, unit and unit cost — i.e. what to order before service runs out. Items without a par level never appear. Costs nothing to run. Requires the Restaurant app (a one-time purchase from the Chirply App Marketplace) to be installed in this account; without it the call returns 403 app_required and no data.
Reservations (restaurant.list_reservations)
[READ] List the restaurant's reservations — the same book the host stand shows. Filter to one local calendar day (the 'tonight's book' view), a status, or a location. Rows include guest name/phone/email, party size, start time (UTC instant), assigned table, status, and how the booking came in (online, phone, walk-in, or API).
Check available times (restaurant.reservation_availability)
[READ] The bookable reservation times for one local calendar day and party size, computed from the location's service periods minus what existing reservations and table capacity already consume. Read-only and free. Each slot is a UTC instant with an 'available' flag; offer only available ones to a guest, and know the time is re-validated again at booking.
Add reservation (restaurant.create_reservation)
[HIGH RISK] Book a real table: creates a reservation exactly like the host stand's Add-reservation form, after re-validating the requested time against live availability (an unavailable time is refused). Matches or creates a CRM contact for the guest and immediately sends them a confirmation by email and/or SMS through the org's own connected sender and Twilio number — a real message to a real person.
Update reservation status (restaurant.set_reservation_status)
[HIGH RISK] Move a reservation through its lifecycle, the same buttons the host stand shows: confirm a pending one, seat the party, complete the visit, mark a no-show, or cancel. Canceling or no-showing releases the table, and another guest may book the freed slot immediately — treat those as irreversible in practice. No message is sent to the guest.

Actions — revenue

1 operation.

Revenue (revenue.summary)
[READ] Gross revenue collected by the account across native invoices, sales funnels, and every connected Stripe account for an optional date range, with refunds, transaction counts, and true Stripe MRR from active subscriptions billed every month. Trials, past-due subscriptions, and plans billed quarterly or annually are excluded from MRR. Invoice and funnel charges are removed from the general Stripe bucket so the all-sources total never double-counts them. The connected-Stripe figure is also broken out per connected Stripe account — name, collected, refunded, transactions and MRR each — so a workspace with several Stripe accounts can see which business earned what and reconcile against each Stripe dashboard separately. Also returns what was collected today and yesterday in the account's own timezone, independent of the requested date range. Read-only; changes nothing and charges nobody.

Actions — revenue_operator

7 operations.

View observed recovery outcomes (revenue_operator.get_recovery_outcomes)
[READ] Read subsequent inbound contact messages, inbound calls, noncanceled bookings and linked live-mode invoice/funnel/Stripe payments after one confirmed recovery send. The observation window ends at 30 days, the next confirmed recovery for that contact, or now, whichever comes first. Currencies stay separate; invoices use refund date while funnel/Stripe refunds adjust the collection window. These are contact-level observations and current deal status, not causal lift, guaranteed replies to this email or recovered revenue attribution. Makes no provider or AI calls, changes nothing, sends nothing and spends no money.
Open Revenue Operator (revenue_operator.get_recovery_board)
[READ] Read the Revenue Operator's shadow-mode recovery board. It separately examines up to 2,000 recently updated open risks and 2,000 resolved risks with stored deal intelligence, then derives prioritized recovery proposals, coverage KPIs, and a flagged-to-won-or-lost outcome proxy. Partial populations are explicitly marked in the result. It makes no AI model or provider calls, sends nothing, starts nothing, spends nothing, and changes nothing.
Review recovery email (revenue_operator.get_recovery_workspace)
[READ] Read one deal's current status, linked email contact, and latest twenty recovery drafts and delivery receipts. The deal's current won/lost status is an outcome observation, not evidence the email caused a sale. Read-only; sends nothing.
Save recovery draft (revenue_operator.prepare_email)
Save immutable subject, body, recipient and deal/contact versions for one reviewed recovery email. Requires an open at-risk or stalled deal with an unblocked email contact. Sends nothing and makes no AI calls. Only one pending recovery per contact is allowed; drafts expire after 24 hours. A separate explicit approval sends it.
Approve and send recovery email (revenue_operator.send_email)
[HIGH RISK] Send the saved recovery message to its real recipient through the account's connected email provider, at the account's provider cost, with normal configured signatures, unsubscribe links and tracking. Consumes approval once, rechecks open deal/risk/contact versions, refuses newer messages, calls, bookings or linked collected payments, honors opt-outs and enforces seven days between recovery emails per contact. An uncertain delivery is held for review and is never automatically resent.
Discard recovery draft (revenue_operator.cancel_email)
Cancel an unsent recovery draft so a revised message can be prepared. Cannot cancel or reset a send already in progress. Sends nothing and retains the canceled draft in history.
Check recovery delivery receipt (revenue_operator.check_delivery)
Reconcile an uncertain recovery send against its exact stored message receipt. Marks it sent only when the matching message records provider acceptance or delivery. Missing, failed or merely queued rows remain held because a local failure may follow a provider timeout. Never resets a send claim, sends or retries an email, or spends money.

Actions — rvm

10 operations.

List voicemail recordings (rvm.list_recordings)
[READ] List the saved voicemail recordings this account can drop — uploaded audio, in-app recordings, ElevenLabs-synthesized clips, and Twilio text-to-speech scripts. Newest first.
Open a voicemail recording (rvm.get_recording)
[READ] Fetch one saved voicemail recording by id, including its duration and (for text-to-speech recordings) the script and voice it speaks.
Add a voicemail recording from a URL (rvm.add_recording_from_url)
[HIGH RISK] Save an existing audio file as a reusable voicemail recording by fetching it from a public URL (the machine-surface equivalent of the app's upload button — binary uploads can't ride a tool call). TWILIO FORMAT RULE: the file must be MP3, WAV, GSM, µ-law or AIFF; m4a/aac/webm fail the drop with Twilio error 12300, so they're refused here. Voicemails must be 55 seconds or shorter. THIS MAKES AN OUTBOUND REQUEST FROM CHIRPLY'S SERVERS to whatever address is given, so everything in the URL — host, path, query string — is disclosed to whoever operates it. That is why it asks for confirmation.
Generate a voicemail with text-to-speech (rvm.generate_recording)
[HIGH RISK] Turn a script into a reusable voicemail recording. Engine 'elevenlabs' synthesizes an MP3 right now through its OWN ElevenLabs account and SPENDS ITS TTS CREDITS; engine 'twilio' stores only the script and has Twilio speak it live at drop time (no synthesis charge, billed as part of the call). Scripts longer than about 55 spoken seconds are refused.
List voicemail campaigns (rvm.list_campaigns)
[READ] List ringless-voicemail campaigns with their status and per-recipient tallies (dropped, failed, skipped), newest first.
Open a voicemail campaign (rvm.get_campaign)
[READ] Fetch one voicemail campaign with live per-status drop counts — how many are pending, in flight, dropped, failed or skipped.
List voicemail drops (rvm.list_drops)
[READ] List the individual recipients of a voicemail campaign and what happened to each one — pending, filtering, dropping, dropped, failed (with the error) or skipped (e.g. do-not-contact).
Send a ringless voicemail campaign (rvm.create_campaign)
[HIGH RISK] Create and send a ringless-voicemail campaign to contacts and/or saved lists. THIS DROPS REAL VOICEMAILS: each recipient costs two outbound Twilio calls (a filter call plus the voicemail leg) billed to the account, and 'now' fans out immediately. Needs a saved recording (rvm.generate_recording or rvm.add_recording_from_url) and TWO DIFFERENT active numbers — a filter number and a from number. Do-not-contact is always enforced; quiet hours only when scheduled and explicitly asked for.
Drop a voicemail to one contact (rvm.drop_to_contact)
[HIGH RISK] Drop a ringless voicemail to a single contact right now — the same one-click action as the contact page's 'Drop voicemail' dialog. THIS PLACES REAL CALLS and bills the account two Twilio legs. Needs a saved recording and two different active numbers. Do-not-contact is enforced before dialing.
Cancel a voicemail campaign (rvm.cancel_campaign)
[HIGH RISK] Stop a voicemail campaign: any drop that hasn't gone out yet is skipped and the campaign is marked canceled. Voicemails already delivered can't be recalled, and a canceled campaign can't be resumed.

Actions — security

2 operations.

Account security (security.get)
[READ · ADMIN ONLY] Read this account's security posture: whether two-factor authentication is required for every member. Changes nothing.
Require two-factor for everyone (security.set_require_mfa)
[HIGH RISK · ADMIN ONLY] Turn the account-wide two-factor requirement on or off. Turning it ON locks every teammate without a verified authenticator app out of the account until they enroll — on their next navigation they are taken to a mandatory set-up screen and can do nothing else there but enroll or sign out. It is refused unless the acting person (for an API key, the account owner) already has a verified authenticator, so the requirement can never lock out the person who could undo it. Turning it OFF simply stops requiring enrollment; existing authenticators are untouched.

Actions — segments

9 operations.

List Smart Segment fields (segments.fields)
[READ] List every Smart Segment scalar field and correlated relationship, its supported operators and filters, the account's custom contact fields, and current tenant-scoped choices such as tags, lists, pipelines, team members, forms, Stripe accounts, and Stripe products. Read-only and performs no provider calls.
List Smart Segments (segments.list)
[READ] List the organization's saved Smart Segments, including their complete validated rule definitions and last successful display-only count metadata. This does not evaluate membership.
View Smart Segment (segments.get)
[READ] Get one saved Smart Segment and its complete rule definition. This reads the saved configuration and does not evaluate contacts.
Preview audience (segments.preview)
[READ] Validate unsaved Smart Segment conditions and start a tenant-scoped, exact background evaluation. Large accounts return a preparing status and durable evaluation id for segments.get_evaluation; a final count and up to five sample contact ids appear only after concurrent CRM changes are reconciled. Reads only and sends nothing.
Check audience preview (segments.get_evaluation)
[READ] Read the durable progress or exact final result of a Smart Segment evaluation started by segments.preview or segments.refresh. Preparing results never expose a partial count as final; ready results return the exact count and at most five deterministic sample contact ids. Reads only and sends nothing.
Refresh Smart Segment count (segments.refresh)
[READ] Start or deduplicate an exact background evaluation of one saved Smart Segment's current definition. The saved display count is published only if the definition and tenant configuration remain unchanged through final reconciliation. Sends nothing and does not alter contacts.
Create Smart Segment (segments.create)
Save a reusable dynamic audience definition. Exact previews are timestamped background snapshots, while an outbound campaign resolves its own guarded audience from the then-current definition. Saving sends nothing and does not copy contacts.
Save changes (segments.update)
Replace a Smart Segment's name, description, matching mode, and complete validated rule set. Prior preview counts become historical, future evaluations use the new definition, and already-enrolled campaign recipients do not change.
Delete Smart Segment (segments.delete)
[HIGH RISK] Permanently delete a saved Smart Segment. Contacts are never deleted. The database refuses deletion while any campaign still includes or excludes the segment so a draft audience cannot silently expand.

Actions — settings

22 operations.

Zapier business recipes (zapier.list_recipes)
[READ] Read three practical Zapier build guides: assigning new inquiries, maintaining a booking ledger and handing won deals to delivery. Each includes field mapping, deduplication and a test-before-enable checklist. These are instructions, not installed Zaps. Reading them creates nothing, enables nothing, sends nothing and costs nothing; executing configured actions later may trigger account workflows or send data to other apps.
Zapier for your clients (zapier.get_client_setting)
[READ] Read the one Zapier decision an agency makes for the client accounts it creates, and what it currently resolves to: off (no Zapier link on their screens), Chirply's own invite link, or the agency's white-labelled integration on the $50/month self-serve tier or the $100/month plus one-time $999 done-for-you tier. Also reports whether Chirply still owes a done-for-you setup and what the agency's own invite URL is. Reads configuration only — it changes nothing, charges nothing, and does not affect any Zap that is already running.
Save Zapier choice (zapier.set_client_mode)
[HIGH RISK · OWNER ONLY] Set the single Zapier choice an agency makes for the client accounts it creates. THIS SPENDS REAL MONEY on two of the three values. 'off' is free and shows no Zapier link on any client account's screens — it hides a link and nothing more: it does not revoke anything, does not disconnect existing Zaps, and anyone who already has the invite link can still use the integration. 'self_serve' COMMITS THE AGENCY TO $50 PER MONTH to white-label the integration and do all of the setup themselves in their own Zapier developer account, with Chirply providing instructions and no other help. 'done_for_you' COMMITS THEM TO $100 PER MONTH PLUS A ONE-TIME $999 SETUP FEE — $1,099 on the first charge — for Chirply to build the integration in their Zapier developer account and maintain it. The Stripe products for both tiers are not created yet, so this records the decision, marks it awaiting billing, and files a support ticket for a human to complete the sale; it does not charge a card by itself.
Save your Zapier invite link (zapier.set_branded_app)
[ADMIN ONLY] Record the agency's OWN Zapier integration — its name and the public-invite URL from their own Zapier developer account — so their client accounts are shown that link instead of Chirply's. Only accepted on a paid Zapier white-label tier, because on the free modes there is no integration of the agency's for the link to point at. Costs nothing and sends nothing; it changes which URL Chirply prints on a screen. The URL must be a zapier.com public-invite link, which is what Zapier's own Sharing screen gives you.
Zapier setup instructions (zapier.setup_guide)
[READ] Return the step-by-step instructions for building a white-labelled Zapier integration in the agency's OWN Zapier developer account: the account to create, the OAuth endpoints and scopes to configure against Chirply, where the catalog of triggers, actions and searches comes from, the branding steps, and where to paste the resulting invite link back. This is what the $50/month self-serve tier buys — Chirply supplies the information and does none of the work, does not submit the integration for review, does not maintain it, and does not support it. Reading it costs nothing and changes nothing.
Account settings (org.get)
[READ] Read this account's profile: its name, URL slug, status, what kind of account it is (a plain Account, or a White-Label / Reseller / Agency Partner once those upgrades are bought), its entitlements, its branding, and its seat usage — members, owners, and pending invites.
Workspaces (org.list)
[READ] List every account the signed-in person can switch into — what the account picker in the sidebar shows — with each one's name, kind (a top-level account or a client account under one), the caller's role in it, and which one is currently active. org.get only ever describes the ACTIVE account, so this is the only way to find out what else exists. Soft-deleted (cancelled) accounts are left out, exactly as the picker leaves them out. Read-only.
Switch account (org.switch)
Move the signed-in person into a different account, the way picking one from the sidebar's account switcher does. Everything afterwards — records, settings, billing, every later action — belongs to the new account, so this changes what all subsequent work operates on. Only accounts the person is actually a member of are accepted, and a superadmin who was viewing a tenant stops doing so. THE APP MUST BE RELOADED for the change to show: the switch is stored in a cookie, but pages already open still hold the previous account's data in memory. Changes no records in either account.
List call dispositions (dispositions.list)
[READ] List the call outcomes agents pick after a call — “Connected”, “Left voicemail”, “Not interested”, and any custom ones — in display order, with the actions each one fires.
Add a disposition (dispositions.create)
[ADMIN ONLY] Add a call outcome to the end of the list. Attach actions from the shared Actions registry to have picking it fire them automatically — sending an SMS, tagging the contact, dropping a voicemail, enrolling in a campaign, and so on. Those actions send real messages and spend the account's own Twilio/Mailgun credit every time an agent picks the outcome, so an outcome with a send attached is a recurring cost, not a label. Created switched on unless is_active is false.
Edit a disposition (dispositions.update)
[ADMIN ONLY] Rename a disposition, recolor it, switch it on or off for the dialer, or replace the actions it fires. Omitted fields are left alone; supplying `actions` REPLACES the whole list.
Delete a disposition (dispositions.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete a call outcome and the actions attached to it. Calls already logged against it keep their record; the outcome just stops being offered.
List integrations (integrations.list)
[READ] List every provider this account can connect — telephony (Twilio), email (Mailgun, Resend), AI (OpenRouter, ElevenLabs, fal.ai, Replicate, Firecrawl), commerce and marketing (the tenant's own Stripe, Shopify, Klaviyo, BookFunnel, GoHighLevel, Outscraper, PayPal, Facebook & Instagram), and infrastructure (Cloudflare for automatic DNS, Supabase app backends) — with whether it's connected, whether it's fully configured, its last status, and the callback URLs it needs. Stored credentials are NEVER returned — secrets are reported only as set/not set.
Open an integration (integrations.get)
[READ] Fetch one provider's connection status plus the exact fields its connect form takes — use this before integrations.connect so you know which keys to send. Never returns a stored credential, only whether each secret is set. When manageOnly is set, integrations.connect will refuse this provider and manageHref names the screen that owns its credentials: agency-supplied connections, providers with named or multiple connections, and providers whose keys are verified with the provider before they are stored (the tenant's own Stripe).
Get the Zapier invite (integrations.get_zapier_invite)
[READ] Return the Zapier invite link this account is offered — Chirply's own, or the agency's white-labelled integration where one has been set up — plus how many triggers, actions and searches it exposes. Some accounts are offered no link at all: an agency decides whether the client accounts it creates are shown Zapier, and when that decision is off this reports so instead of returning a URL. That is a decision about what Chirply displays, NOT an access control — it revokes nothing and disconnects nothing, and anyone already holding the link keeps using the integration normally. Reading this costs nothing, connects nothing and grants nobody access on its own: after accepting an invite, an owner or admin still has to approve the connection to a specific account from inside Zapier, and Zaps then run against the REST API, which is plan-gated.
Request access (integrations.request_access)
[HIGH RISK] Ask the Chirply team to switch on an integration that isn't open to everyone yet — the “Request access” button on a limited-availability tile. Meta (Facebook / Instagram) is the case this exists for: until Facebook finishes reviewing Chirply it only works for accounts we have added to our developer list, so connecting it first requires a human at Chirply to add you. This FILES A REAL SUPPORT TICKET on behalf of the signed-in user AND EMAILS THE CHIRPLY TEAM, then answers back through Support. Asking twice is harmless: while a ticket for the same provider is still open it reports that and files nothing new — which is exactly why this exists rather than support.file_bug, whose free-text title would defeat that de-duplication and leave the team with a pile of identical requests.
Connect an integration (integrations.connect)
[ADMIN ONLY] Save this account's own credentials for a provider's single canonical connection, creating the connection or updating it. Named, multi-account, agency-managed, and verify-before-store providers (the tenant's own Stripe) are rejected here and must use their dedicated manager, so the exact connection is explicit and its keys are checked with the provider before anything is written. Secret fields are encrypted with AES-256-GCM before storage and can never be read back; OMIT a secret to keep the one already stored. Connecting Twilio also auto-creates the API Key + Voice app the softphone needs, connecting Mailgun reconciles the inbound route and delivery webhooks in the tenant's Mailgun account, and connecting Cloudflare verifies the token and turns on automatic DNS for custom domains. Charges from these providers bill to the tenant's own account.
Test an integration (integrations.test)
[ADMIN ONLY] Verify this account's single canonical stored connection against the provider with a FREE, read-only call (account metadata, a domain list, a token check — it never sends a message, generates content, or spends the account's balance), then record the outcome on that connection (connected / error). Named, multi-account, agency-managed, and verify-before-store providers (the tenant's own Stripe) are rejected here and must be tested in their dedicated manager. Testing Mailgun also REPAIRS inbound email — it re-creates the missing route or webhook and re-checks the domain's MX. A dead Facebook grant is stamped 'needs_reauth' so the UI offers Reconnect. BookFunnel is webhook-only with no credential to check, so its result reports when the last reader event arrived rather than claiming verification.
Diagnose incoming email (integrations.diagnose_email)
[READ · ADMIN ONLY] Check, end to end, why replies to this account's email are or aren't arriving in Conversations, and report each link in the chain: the Mailgun connection, whether receiving is switched on, whether the domain's MX actually delivers to Mailgun, whether the inbound route exists, whether another route in the Mailgun account outranks it and calls stop() (which silently swallows every reply), whether the webhook signing key is stored, and whether mail Mailgun recently accepted for the domain actually matched that inbound route. Read-only — it inspects the Mailgun account and changes nothing. Costs nothing and sends nothing. Run integrations.test on Mailgun afterwards to repair whatever this finds.
Disconnect an integration (integrations.disconnect)
[HIGH RISK · ADMIN ONLY] Delete this account's single canonical connection to a provider, including its stored credentials. Named, multi-account, and agency-managed providers are rejected here and must be disconnected in their dedicated manager so the target is explicit. Everything that runs on a removed connection stops immediately — disconnecting Twilio kills calling and SMS, Mailgun kills email, OpenRouter kills the AI features.
Provider connection methods (integrations.connection_methods)
[READ · ADMIN ONLY] Read the first-party connection audit: OAuth availability, API-key alternatives, setup links and provider restrictions. Reports registered Cloudflare/Resend apps separately from customer consent. Makes no provider changes and reveals no credentials.
Authorize a provider connection (integrations.authorize)
[READ · ADMIN ONLY] Get an account-bound browser link for OpenRouter, Google Cloud, DigitalOcean, Cloudflare or Resend authorization. A signed-in account manager must review and consent at the provider. Approval replaces the previous connection; future AI, email and cloud operations bill the connected provider account. This call grants no access and incurs no provider charges.

Actions — setup

14 operations.

Save launch follow-up (setup.save_launch_followthrough)
[ADMIN ONLY] Assign an existing agency teammate, record an internal next action and due date, or snooze a client setup task for up to 30 days. Rejects stale revisions and records each change in history. Completion always comes from live setup evidence; this never marks a client ready, grants access, notifies anyone, sends a message, or spends money.
View launch follow-up history (setup.launch_followthrough_history)
[READ · ADMIN ONLY] Read the latest twenty recorded owner, next-action, due-date and snooze changes for one client setup task, with the total change count. Restricted to managers of its current parent agency. Internal read only; sends nothing, changes nothing and spends no money.
Get getting-started banner preference (setup.get_start_banner)
[READ] Read whether the calling person dismissed the optional getting-started banner in this account. This personal preference is independent of the shared first-win goal and welcome tour; a saved goal can also hide the banner. The setup guide stays available through Help & setup. Read-only: changes nothing, sends nothing, and spends no money. Requires a calling user and cannot read another person's preference.
Dismiss getting started (setup.set_start_banner)
Hide or restore the optional getting-started banner for the calling person in this account, across their devices. Set dismissed to true to hide it or false to restore it when no first-win goal is saved. Changes no teammate's preference, account goal, welcome-tour progress, or setup evidence; the guide stays available through Help & setup. Sends nothing and spends no money. Requires a calling user and cannot change another person's preference.
Choose my first win (setup.set_goal)
[ADMIN ONLY] Save the account's first-win focus: organize contacts, capture leads, book appointments, set up follow-up, or launch agency clients. Changes guidance only; creates no customer records, sends no messages, activates no workflows, and spends no money. The choice is shared across this account and can be changed later.
Build my lead form (setup.create_lead_form)
Create one reusable contact-form starter in this account, with lead fields and a thank-you message ready to edit. It stays a private draft until you publish it separately. Repeating this action opens the same form and preserves its edits and current publication state. Existing form plan limits apply. Sends no messages, starts no workflows, publishes nothing, and spends no money.
Client launch queue (setup.client_launch_queue)
[READ · ADMIN ONLY] Inspect ten active client accounts under this agency, with live setup progress, missing requirements, first-outcome evidence, assigned owners, due dates, next actions and snoozes. Includes up to 500 current agency teammates for assignment; larger team inventories are reported unavailable. Completion comes from evidence and regressions reopen attention. Exceptions sort first within the inspected page. Failed checks stay unavailable. Read-only; sends no messages or provider requests that incur charges.
Save client launch path (setup.set_client_profile)
[ADMIN ONLY] Choose a local-business or sales-team setup checklist for one client belonging to this agency. Changes checklist priorities only; installs no assets, enables no workflows, sends no messages, and spends no money.
Get setup overview (setup.get_overview)
[READ] Read the account's available first-win goals, saved focus, practical steps, personalized setup path, required progress, next best action, and feature prerequisites. This is read-only and recomputes provider health, published content, and customer-activity evidence live; it never changes setup or starts customer work.
Save setup path (setup.set_profile)
[ADMIN ONLY] Set whether this account is launching as an agency, local business, or sales team. This changes setup-checklist prioritization only; it sends nothing, starts no workflow or customer action, and spends no money.
Get first-run tour status (onboarding.get_status)
[READ] Read whether a person has been through the first-run product tour — the short welcome sequence covering the AI key, the assistant, the setup guide and the community — how far they got, and which step they are on. Read-only: it changes nothing, shows nobody anything, and touches no customer data.
Save first-run tour progress (onboarding.set_step)
Move a person's bookmark in the first-run tour so their next visit resumes at that step. The step index only ever moves FORWARD — to send someone back to the beginning use onboarding.restart. Affects nothing but which screen of a five-screen overlay they next see; it sends nothing and spends nothing.
Finish the first-run tour (onboarding.complete)
Mark the first-run tour as done for a person, so the welcome overlay stops appearing when they sign in. Use this to stop showing it to someone who already knows the product. It is fully reversible with onboarding.restart, and it changes nothing else — no setup-guide item is ticked off, because that guide reads live evidence from the account rather than anyone's say-so.
Restart the first-run tour (onboarding.restart)
Show the first-run tour again from the beginning next time this person opens the app — the usual reason being a new teammate on an existing seat, or someone who skipped it and wants it back. It is an overlay they can close at any time, so the worst case is one extra click; nothing is sent, spent, or reset in the account itself.

Actions — shared_sections

5 operations.

List shared sections (shared_sections.list)
[READ] List the website's native shared section library and this page's linked instances. Reads saved drafts and binding revisions; it changes nothing.
Share selected section (shared_sections.share)
Save a selected native top-level section to this website's shared library and link its source instance. It stays a fully editable native subtree; no live page changes until publish.
Add linked section (shared_sections.add)
Append a linked copy of a shared native section to a website page's saved draft, preserving existing content and undo history. No public page changes until publish.
Update linked pages (shared_sections.sync)
Copy the selected linked section into every linked draft page in one transaction. Reject the entire update when another linked instance has local edits or a page changed. Published snapshots stay unchanged until publish.
Detach shared section (shared_sections.detach)
Remove the link from one shared section instance while preserving its native page content exactly. Future shared updates leave that independent instance alone; published pages are unchanged.

Actions — shopify

9 operations.

Sync Shopify store (shopify.sync_store)
[HIGH RISK · ADMIN ONLY] Fetch the next resumable batch of customers, products, orders, and abandoned checkouts from one connected Shopify store into this account. It reads from Shopify and changes nothing in the store, but IT WRITES TO THIS CRM AND CAN TEXT OR EMAIL REAL SHOPPERS. Every Shopify customer it sees is created as a CRM contact, or, when one already matches by email or phone, that existing contact's name, email, phone and lifecycle are OVERWRITTEN with Shopify's values. Once the first full pass has finished, every subsequent call reconciles recently abandoned checkouts and runs this account's 'Shopify checkout abandoned' automations for each newly abandoned cart — so any cart-recovery workflow sends real SMS/email to real shoppers, billed to its own Twilio/Mailgun account. Check those automations before running this on a store you have not synced before.
List Shopify stores (shopify.list_stores)
[READ · ADMIN ONLY] List Shopify stores connected to this account, including connection, import, and webhook health. This only reads stored connection metadata and does not call Shopify or spend money.
List Shopify customers (shopify.list_customers)
[READ] List Shopify customer commerce profiles synchronized into this account, including CRM contact linkage, order count, spend, tags, and marketing-consent states. This reads protected customer data but does not contact anyone.
List Shopify products (shopify.list_products)
[READ] List products synchronized from connected Shopify stores with their status, vendor, type, tags, and storefront URL. This does not change Shopify inventory or product listings.
List Shopify collections (shopify.list_collections)
[READ] List Shopify collections synchronized into this account for catalog segmentation and automation filtering. This is read-only and does not change collection membership in Shopify.
List Shopify orders (shopify.list_orders)
[READ] List orders synchronized from connected Shopify stores, including customer linkage, totals, refunds, payment state, fulfillment state, and attribution fields. This does not modify, fulfill, cancel, or refund any order.
List abandoned Shopify checkouts (shopify.list_abandoned_checkouts)
[READ] List synchronized Shopify checkouts that were abandoned or later recovered, including customer linkage, cart value, recovery URL, and timestamps. This reads protected customer commerce data and does not send recovery messages.
List Shopify refunds (shopify.list_refunds)
[READ] List full and partial Shopify refunds synchronized into this account, including order and contact linkage and refunded value. This is read-only and never issues or changes a refund.
List Shopify privacy requests (shopify.list_privacy_requests)
[READ · ADMIN ONLY] List mandatory Shopify customer data access and erasure requests with their due dates and completion states. Protected payloads are not returned. This is read-only and restricted to account administrators.

Actions — signage

3 operations.

View Signage plan (signage.get_account)
[READ · OWNER ONLY] Show this account's Signage trial, renewal date, private Scale-offer status, and installed Signage app. This is read-only and charges nothing.
Unlock Scale for $47/month (signage.accept_scale_offer)
[HIGH RISK · OWNER ONLY] Immediately charges the saved card $47, starts the complete Scale subscription at $47/month, includes the installed $9.99/month Signage app free, and cancels the separate Signage trial subscription so it will not renew. This private offer can only be accepted before its deadline.
Keep my Signage trial (signage.decline_scale_offer)
[HIGH RISK · OWNER ONLY] Permanently declines the one-time $47/month Scale bundle. The existing Signage trial remains unchanged and will renew at $9.99/month after day 30 unless canceled. No money is charged by this action.

Actions — snapshots

20 operations.

Snapshots (snapshots.list)
[READ] Lists the configuration snapshots this account owns, with their status and how many times each has been installed.
Snapshot details (snapshots.get)
[READ] One snapshot with every published version, including what each version contains and which outside servers its configuration would contact.
What can go in a snapshot (snapshots.inventory)
[READ · ADMIN ONLY] Everything in this account that can be packaged into a snapshot, grouped by type. Reads configuration only — it never touches contacts, conversations, calls or any other customer data, because none of that can be put in a snapshot.
New snapshot (snapshots.create)
[ADMIN ONLY] Creates a draft snapshot from a selection of this account's configuration. A draft is private and cannot be installed or shared until it is published.
Edit snapshot (snapshots.update)
[ADMIN ONLY] Renames a snapshot or changes what its next version will contain. Versions already published are frozen and are not affected.
Publish version (snapshots.publish_version)
[HIGH RISK · ADMIN ONLY] Freezes the current selection as a new, permanent version and copies every recording and image it uses into the snapshot. From now on anyone holding a share link or licence installs this version. Published versions can never be edited — publish again to ship a change.
Preview install (snapshots.preview_install)
[READ · ADMIN ONLY] Dry-runs an install and reports exactly what would be created, what would be reused because a name already matches, which outside servers the configuration would contact, and what setup it still needs. Changes absolutely nothing.
Install snapshot (snapshots.install)
[HIGH RISK · ADMIN ONLY] Writes a snapshot's configuration into an account — funnels, automations, templates, phone menus and settings. Everything arrives switched OFF: no automation runs, no message is sent, no page is published until a human turns it on. Nothing existing is overwritten or deleted. Reversible for 14 days.
Push to client accounts (snapshots.push_to_subaccounts)
[HIGH RISK · OWNER ONLY] Installs a snapshot into several client accounts at once. Each account is installed independently, so one failing does not stop the others. As with any install, everything arrives switched off and nothing existing is overwritten.
Install history (snapshots.list_installs)
[READ · ADMIN ONLY] Every snapshot install into this account, with what it created, its status, and any setup steps still outstanding.
Delete snapshot (snapshots.delete)
[HIGH RISK · OWNER ONLY] Permanently deletes a snapshot, every published version of it, and the frozen copies of its recordings and images. Anything anyone already installed from it stays exactly where it is — an install is a copy, so this does not un-install anything.
Create install link (snapshots.create_link)
[HIGH RISK · ADMIN ONLY] Mints a public URL for a published snapshot. ANYONE HOLDING THE LINK can install this configuration into an account they manage, until it is revoked or expires. Optionally cap the number of uses or lock it to one recipient's email address.
Install links (snapshots.list_links)
[READ · ADMIN ONLY] Every share link for a snapshot, with how many times each has been used, when it expires, and whether it has been revoked.
Revoke install link (snapshots.revoke_link)
[HIGH RISK · ADMIN ONLY] Kills a share link immediately, so it can no longer be used to install. Installs already completed from it are unaffected — an install is a copy, so this does not un-install anything.
Finish setup (snapshots.checklist)
[READ · ADMIN ONLY] The outstanding setup steps for an install — the phone numbers, domains and teammates a snapshot could not carry, plus anything that needs a look. Also reports what the install actually wrote: items created, items matched to what the account already had, and the number of detail rows written inside those items (pages, automation steps, knowledge items, invoice lines), broken down by kind so the figures can be checked against the snapshot.
Fill a setup step (snapshots.resolve_slot)
[HIGH RISK · ADMIN ONLY] Supplies one of the things a snapshot could not carry — typically a phone number id. The value is written everywhere the snapshot used it, including inside phone menus and automation steps, and anything that was held back waiting on it is created at that point.
Undo install (snapshots.undo_install)
[HIGH RISK · OWNER ONLY] DELETES everything a snapshot install created in this account and restores anything it replaced. Items you have since attached real data to — a funnel that has taken orders, an invoice that has been paid — are kept rather than deleted. Only available for 14 days after the install.
Who can install this (snapshots.list_grants)
[READ · ADMIN ONLY] Every account that has been granted or has bought the right to install a snapshot, and whether that access is still active.
Revoke access (snapshots.revoke_grant)
[HIGH RISK · OWNER ONLY] Stops an account installing this snapshot again. It does NOT remove anything they have already installed — that is their own configuration now, and there is no remote kill switch.
Snapshot item types (snapshots.types)
[READ] The kinds of configuration a snapshot can carry, with the label and category of each. Useful for building a selection before calling snapshots.create.

Actions — social

13 operations.

View content calendar (social.list_calendar)
[READ] List the account's drafted, scheduled, published, failed, and manual-handoff social posts with the result for every destination.
Open a social post (social.get_post)
[READ] Fetch one content-calendar post and every Page or Group delivery result.
List publishing destinations (social.list_destinations)
[READ] List every place this account can put a social post: connected Facebook Pages and Instagram Professional accounts that publish automatically, and saved Facebook Groups that require a manual handoff. Each destination reports its kind (page, instagram, group) and whether it can currently publish.
Generate posts (social.generate_bulk)
[HIGH RISK] Use its own OpenRouter account to write a reviewable batch of social posts. This consumes paid AI tokens but does not save or publish anything.
Save content batch (social.save_bulk)
[HIGH RISK] Save 2–12 social posts as drafts, or schedule the series across the selected destinations. Scheduled posts create real public posts at their publishing times. Every post in a series shares one set of destinations and none of them carry an image, so an Instagram destination is rejected outright here — schedule Instagram posts one at a time with social.schedule.
Save draft (social.save_draft)
Save social content and its destinations without publishing or scheduling anything. Content is still validated against every selected network, so an Instagram destination without an image is rejected now rather than at publishing time. Facebook Groups remain manual handoffs.
Schedule post (social.schedule)
[HIGH RISK] Schedule this content to publish to every selected Facebook Page and Instagram account at the specified time. Real public posts will be created automatically on the org's own connected Meta assets. Selected Groups become manual handoffs because Meta removed Group publishing from its API.
Publish now (social.publish_now)
[HIGH RISK] Immediately creates REAL public posts on every selected Facebook Page and Instagram account. There is no undo on Facebook or Instagram. Group destinations become ready-to-copy manual handoffs and are not posted automatically.
Retry failed destinations (social.retry)
[HIGH RISK] Retries every failed destination immediately, creating REAL public Facebook or Instagram posts where the retry succeeds. Destinations already published are not duplicated.
Cancel post (social.cancel)
Cancel a draft or scheduled social post before any remaining destinations publish. Public Page posts that already succeeded are not deleted.
Mark Group posted (social.mark_group_posted)
Record that a person copied this scheduled content into its Facebook Group. This does not call Facebook or create a post itself.
Add Group handoff (social.add_group)
Save a Facebook Group as a manual content-calendar destination. Meta no longer permits apps to publish to Groups, so scheduled content is prepared for a person to copy and post.
Remove Group handoff (social.remove_group)
Remove a saved Group from future destination pickers. Existing scheduled posts keep their destination snapshot.

Actions — stages

5 operations.

List pipeline stages (stages.list)
[READ] List a pipeline's stages in board order, with each stage's win probability and whether it counts as won or lost. Omit pipeline_id for the default pipeline.
Add a stage (stages.create)
[ADMIN ONLY] Add a stage to the end of a pipeline. A stage with outcome 'won' or 'lost' closes any deal moved into it (stamping closed_at); 'in_progress' keeps deals open.
Edit a stage (stages.update)
[ADMIN ONLY] Rename a stage or change its win probability or outcome. Omitted fields are left alone. Changing the outcome does NOT restate deals already sitting in the stage — it applies the next time a deal moves in.
Reorder stages (stages.reorder)
[ADMIN ONLY] Set the left-to-right column order of a pipeline's stages. Pass the stage ids in the order you want them; every id must belong to the given pipeline. Deals stay in their stages.
Delete a stage (stages.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete a stage from its pipeline. Deals in that column are NOT deleted — their stage is cleared, so they drop off the board until they're moved into another stage. Cannot be undone.

Actions — stripe

24 operations.

Import progress (stripe.sync_progress)
[READ · ADMIN ONLY] Read each connected Stripe account's import stage, running/queued/completed state, delayed-batch warning, saved customer/payment/subscription counts, last completed sync and tracked webhook activity. Financials separate currencies and live/test connections: successful collected amounts, net after refunds, net attributed to CRM contacts, refunded-payment counts/amounts and disputed-charge counts/full charge amounts. Counts describe charges, not individual refund events; disputed value is not confirmed losses. Totals remain partial during import. Read-only; sends no messages and charges no money.
Connect with Stripe (stripe.connect_oauth)
[HIGH RISK · ADMIN ONLY] Get a browser link to connect a Stripe business by signing in to Stripe and approving Chirply. An owner or admin must complete consent in their browser. Grants access to payments, invoices, subscriptions and CRM data; this action itself charges no money and sends no messages. Existing agency-managed Connect setups remain key-based.
Stripe accounts (stripe.list_accounts)
[READ · ADMIN ONLY] List every Stripe account this account has connected, with how many customers, payments and subscriptions have been imported from each, when it last synced, and which one collects money for invoices and funnels. Read-only; returns no keys.
Choose a Stripe account (stripe.payment_accounts)
[READ] List the connected Stripe accounts that an account member can select when taking a mobile payment. Returns display and availability fields only; no secret or publishable keys are exposed.
Search payment contacts (stripe.search_payment_recipients)
[READ] Search every CRM contact by first name, last name, combined full name, business, email, or phone for the mobile point of sale, with matching imported Stripe customers included when available. Read-only; returns safe identifiers scoped to the selected account and Stripe account.
Enter card securely (stripe.create_mobile_payment)
[HIGH RISK] Create a Stripe PaymentIntent in the selected connected account for secure in-person card entry. Confirming the Stripe payment form can charge the customer's real card in live mode and incurs that account's Stripe processing fees; the card number and security code are never received or stored here. Also CREATES A STRIPE CUSTOMER in that connected account when the payer has no Stripe customer record yet — a permanent record carrying their name, email and phone — and links it to the CRM contact for reuse on later payments.
Open secure card form (stripe.prepare_mobile_card_entry)
[READ] Return the selected connected Stripe account's publishable configuration so the mobile app can display Stripe's encrypted card form. This does not create a PaymentIntent, charge anyone, or leave an incomplete transaction; the intent is created only after the customer enters a payment method and confirms Pay.
Create payment link (stripe.create_mobile_payment_link)
[HIGH RISK] Create a one-time Stripe-hosted checkout link in the selected connected account. Anyone with the link can complete the payment; a successful live checkout charges real money and incurs that account's Stripe processing fees.
Recent payment links (stripe.list_mobile_payment_links)
[READ] List durable one-time Stripe Checkout links created from the mobile POS, newest first, including their amount, selected Stripe account, optional CRM customer, mode and current saved status. Read-only and does not charge anyone.
Prepare Tap to Pay payment (stripe.prepare_mobile_terminal_payment)
[HIGH RISK] Create a Stripe Customer for the selected CRM contact when needed — a permanent record in that connected account carrying their name, email and phone — then create the card-present PaymentIntent that the authenticated mobile app will collect. The later native confirmation can charge the customer's real card in live mode and incurs the connected account's Stripe Terminal fees; this preparation call alone does not collect a card.
Verify mobile payment (stripe.verify_mobile_payment)
[READ] Retrieve one mobile PaymentIntent directly from its connected Stripe account and return Stripe's authoritative current status, amount, customer and receipt details. This is read-only and does not create, capture, cancel, refund or otherwise change the payment.
Start Tap to Pay (stripe.prepare_tap_to_pay)
[HIGH RISK] Create a short-lived Stripe Terminal connection token for the selected connected account and list that account's reader locations. If that account has no Terminal location yet, this also CREATES ONE in Stripe from the account's saved business address — a permanent Terminal Location record on the connected account, named after the account — or, when the address is incomplete, returns setup_required instead of creating anything. A later confirmation on a supported NFC phone can collect real money in live mode and incurs Stripe Terminal fees; this call alone does not charge anything.
Cancel failed Tap to Pay attempt (stripe.cancel_mobile_terminal_payment)
[HIGH RISK] Cancel a failed or abandoned Tap to Pay PaymentIntent in the selected connected Stripe account. If the card was authorized, cancellation releases the authorization instead of collecting money; succeeded payments are never canceled by this action.
Connect a Stripe account (stripe.connect_account)
[HIGH RISK · ADMIN ONLY] Connect another Stripe account by its secret key. The key is verified against Stripe and stored encrypted, and an import of that account's customers, charges and subscriptions starts immediately — a large account continues in the background. Customers are matched to existing contacts by email address; new ones are added as contacts but are NOT subscribed to marketing unless subscribe_to_marketing is set. Handles credentials that can charge money.
Change a Stripe account's settings (stripe.update_account)
[HIGH RISK · ADMIN ONLY] Rename a connected Stripe account, turn its import on or off, change whether it creates contacts or lets them receive marketing email, or replace or REMOVE its live/test keys. Every account remains available on invoices, products, funnels, and websites. Replacement keys are verified before they overwrite working ones. Removing a publishable key (send an empty string) stops card payments on that account until one is added back, and changes nothing else — the secret key, webhook and the other mode's credentials are untouched and importing carries on. Omitted fields are never touched.
Disconnect a Stripe account (stripe.disconnect_account)
[HIGH RISK · ADMIN ONLY] Delete a connected Stripe account's stored keys and remove every customer, payment and subscription imported from it. Contacts are KEPT — they just lose the revenue that came from this account. Nothing changes inside Stripe itself. Irreversible short of reconnecting and re-importing.
Sync a Stripe account (stripe.sync_account)
[ADMIN ONLY] Import one connected Stripe account again, picking up where the last run left off. Reads only — nothing is created or charged in Stripe. May create CRM contacts for payers who aren't contacts yet (subject to the account's settings), and those contacts are excluded from marketing unless the account allows it. A large account may not finish in one call; check `done` in the result and call again.
Turn on real-time sync (stripe.enable_realtime_sync)
[HIGH RISK · ADMIN ONLY] Register the platform's webhook inside this connected Stripe account so payments, refunds and subscription changes land on the contact the instant they happen, instead of waiting up to an hour for the next scheduled import. Uses the account's stored secret key to create the endpoint — no dashboard steps for the user. If that key is a restricted one that can't manage webhooks, this reports why and the account stays on the hourly import (paste a signing secret by hand as the fallback). Safe to run repeatedly; it re-registers rather than duplicating.
Sync all Stripe accounts (stripe.sync_all_accounts)
[ADMIN ONLY] Import every connected Stripe account that has syncing switched on. Same read-only behaviour as stripe.sync_account, run across all of them with the time budget shared between accounts.
Stripe customers (stripe.list_customers)
[READ] List the Stripe customer records imported into this account, newest first. One human can own several of these — one per Stripe account they've bought from — and `contact_id` is the single CRM contact they were all matched onto. Filter by contact to see every Stripe identity behind one person.
Stripe payments (stripe.list_payments)
[READ] List charges imported from the connected Stripe accounts, newest first. Amounts are in minor units (cents) in the charge's own currency. `status` is the outcome of the ATTEMPT — a succeeded payment that was later refunded is still `succeeded`, with `amount_refunded_cents` set — so never total money without filtering to succeeded.
Stripe subscriptions (stripe.list_subscriptions)
[READ] List subscriptions imported from the connected Stripe accounts, in every status so cancelled plans are still visible as history. Amounts are per interval, in minor units.
What this contact has paid (stripe.contact_revenue)
[READ] One contact's saved Stripe history across connected accounts: financials separated by currency and live/test connection, collected money, net after refunds, successful-payment counts, refunded-payment counts and amounts, disputed-charge counts and full charge values, subscriptions and recent charges. historyPending means an initial import is incomplete; totals can increase as older payments arrive. financialsError means currency totals could not be loaded. Amounts are minor units. Refund counts count charges with refunds, not individual refund events; disputed amounts are not confirmed losses. Legacy scalar totals may mix currencies; use financials for money. Read-only; sends no messages and charges no money.
Stripe import history (stripe.list_sync_runs)
[READ · ADMIN ONLY] Every import attempt against the connected Stripe accounts, newest first, with what it pulled, how many contacts it matched versus created, and the error if it failed. This is what answers “why isn't this customer here?”.

Actions — subaccounts

3 operations.

List client accounts (subaccounts.list)
[READ] List the client accounts under this agency, with how many of the plan's client account allowance are used.
Create a client account (subaccounts.create)
[ADMIN ONLY] Create a client account under this agency. The URL slug is derived from the name and de-duplicated automatically. Fails once the reseller plan's client account allowance is used up.
Edit a client account (subaccounts.update)
[ADMIN ONLY] Rename one of this agency's client accounts, or suspend/reactivate it. Suspending locks the account for everyone in it.

Actions — supabase

12 operations.

Check Supabase connection (supabase.get_connection)
[READ · ADMIN ONLY] Checks whether this account has connected its own Supabase account (pasted personal access token or OAuth grant) and, when connected, verifies it live and lists the Supabase organizations the credential can see — the organization ids create_project needs. Never returns the credential itself.
List Supabase projects (supabase.list_projects)
[READ · ADMIN ONLY] Lists the Supabase projects this account knows about — provisioned from here or imported from the connected account — with status, region, API URL, the public (anon) key, and what each one is linked to as a backend. Reads the local mirror; run supabase.sync_projects first for a fresh pull from the account.
Sync projects from Supabase (supabase.sync_projects)
[ADMIN ONLY] Pulls the live project list from the connected Supabase account and mirrors it here: refreshes names/regions/statuses, imports projects that already existed in the account, and marks projects deleted upstream. Changes nothing in the Supabase account itself.
Create Supabase project (supabase.create_project)
[HIGH RISK · ADMIN ONLY] Creates a REAL Supabase project (Postgres database + user auth + file storage) in its own Supabase account. Supabase bills that account's organization directly for the project's compute — real money on the tenant's own Supabase invoice, starting immediately (their free tier covers two small projects). The project comes up asynchronously over one to three minutes; poll supabase.get_project until status is ACTIVE_HEALTHY.
View project (supabase.get_project)
[READ · ADMIN ONLY] One Supabase project's current state: refreshes status from the live account, fetches its API keys once available, and returns the project with its links. Safe to poll after create_project.
Reveal project credentials (supabase.get_project_keys)
[READ · HIGH RISK · ADMIN ONLY] Returns a project's connection credentials: API URL and publishable (anon) key always, plus — only when include_service_role is true — the service-role key, which bypasses every row-level security rule on the tenant's project, and the generated database password for Chirply-provisioned projects. Handing out the service-role key is equivalent to handing out the whole database, which is why this call requires confirmation.
Run SQL on project (supabase.run_sql)
[HIGH RISK · ADMIN ONLY] Executes arbitrary SQL against one of the account's own Supabase projects with full database privileges — creating tables, migrating schemas, reading or DELETING any data in that project. This is the tool for setting up a linked backend's schema. It runs on the tenant's project, not on Chirply, but a destructive statement is still irreversible.
Link project as backend (supabase.link_project)
[ADMIN ONLY] Points a Chirply-built thing at a Supabase project as its backend: one site/funnel, one installed app, or the account-wide default. The target then boots with that project's API URL and publishable key. A target's existing backend link is replaced, not duplicated.
Unlink backend (supabase.unlink_project)
[ADMIN ONLY] Removes one backend link (from supabase.list_projects). The Supabase project itself is untouched; whatever it backed simply no longer has a backend (or falls back to the account default).
Delete project (supabase.delete_project)
[HIGH RISK · ADMIN ONLY] PERMANENTLY deletes a Supabase project from its own Supabase account — the database and every row, user, and file in it are destroyed with no undo, and anything using it as a backend stops working. Supabase stops billing for it. Use supabase.forget_project to merely remove a project from this account without touching the real project.
Remove project from account (supabase.forget_project)
[ADMIN ONLY] Forgets a project locally — removes its row and backend links from this account only. The real Supabase project keeps running, untouched, in the tenant's account; supabase.sync_projects would re-import it.
Disconnect Supabase (supabase.disconnect)
[HIGH RISK · ADMIN ONLY] Removes its own Supabase account connection (the stored token or OAuth grant). Refuses while any backend link still exists, so live sites and apps aren't silently stranded — unlink them first. Project mirror rows are kept; the real projects in the Supabase account are untouched.

Actions — support

19 operations.

List bug reports (support.list_bug_reports)
[READ] List bug reports newest first, with reply and attachment counts. Account owners and admins see every report filed by their team; members see only reports they filed. Optionally filter by status, keep only tickets awaiting a reply from the platform team, or search titles and descriptions.
Open a bug report (support.get_bug_report)
[READ] Fetch one bug report with its full reply thread. Account owners and admins may open any report filed by their team; members may open only their own. Internal platform-team notes are included only for platform admins.
Report a bug (support.file_bug)
File a bug report with the platform team. Emails the team immediately and starts a thread the reporter can be replied to on. Filed on behalf of the signed-in user — or, for an API key, OAuth connection, or installed app, the person who created that credential, who is who replies go to. If you are an agent and something in this workspace errors or misbehaves, this is the right way to tell the team. Screenshots and screen recordings can only be attached from the app.
Reply on a bug report (support.reply_to_bug)
Post a reply on a bug report's thread. Account owners and admins may reply to any report filed by their team; members may reply only to their own. A platform admin's public reply emails the reporter; a reporter's reply emails the platform team and, if the ticket was resolved or closed, automatically reopens it. Set internal=true (platform admins only) to leave a note the reporter never sees.
Delete a bug report (support.delete_bug_report)
[HIGH RISK] Permanently delete a bug report, its whole thread, and its uploaded screenshots. Only the person who filed it, or the platform team, can do this.
List feature requests (support.list_feature_requests)
[READ] List the feature-request board this account is on, with vote and comment counts. Which board that is depends on the account: a client of a white-label agency is on that agency's own private board, and everyone else is on the platform-wide public board, which is shared by every account on purpose and carries no customer data — only a poster's display name. A white-label agency can additionally pass board=clients to read the board its own clients post to. Never returns another agency's board.
Open a feature request (support.get_feature_request)
[READ] Fetch one feature request with its vote count and its comment thread. Only requests on a board this account is on are readable — its own public-board posts, or the private board of the white-label agency it belongs to; anything else reports as not found. Internal platform-team comments are included only for platform admins.
Request a feature (support.request_feature)
Post a feature request, and upvote it for its author. Posted on behalf of the signed-in user — or, for an API key, OAuth connection, or installed app, the person who created that credential. If you are an agent and the platform is missing something you need, this is the right way to ask for it — but search support.list_feature_requests first and upvote an existing request instead of posting a duplicate. It lands on whichever board this account posts to — the platform-wide public board, where every user on the platform can see and vote on it, or, for a client of a white-label agency, that agency's own private board. The team that answers that board is emailed.
Comment on a feature request (support.comment_on_feature)
Add a public comment to a feature request and email its author. Only requests on a board this account is on can be commented on; anything else reports as not found. Set internal=true (platform admins only) for a note nobody else sees.
Upvote a feature request (support.vote_feature)
Upvote a feature request, or take your vote back. Only requests on a board this account is on can be voted on; anything else reports as not found. Votes are one per person and drive that board's “most wanted” ranking, which is how the team behind it decides what to build next.
Delete a feature request (support.delete_feature_request)
[HIGH RISK] Permanently delete a feature request, its comments, its votes, and its attachments. Only the person who posted it, or the platform team, can do this.
Delete a feature comment (support.delete_feature_comment)
[HIGH RISK] Permanently delete one comment from a feature request, along with anything attached to it. Only its author, or the platform team, can do this.
Client reports (support.list_client_reports)
[READ] List the bug reports filed by this agency's client accounts — the tickets the agency answers itself, because its clients bought a white-labelled product and have never heard of Chirply. Shows each ticket's title, status, severity, which client account it came from, who is waiting on whom, and whether it has already been raised with Chirply. Reads only. This is the agency's own desk; it never returns tickets belonging to another agency, or the agency's own tickets with Chirply.
Read a client report (support.get_client_report)
[READ] Read one bug report filed by a client of this agency, in full, with every reply on the thread. Internal notes the agency's own staff left are included; the client cannot see those. Reads only. Refuses any ticket that is not on this agency's desk.
Reply to a client report (support.reply_to_client_report)
[HIGH RISK · ADMIN ONLY] Post a reply on a client's bug report. A public reply is SENT TO A REAL PERSON — the client who filed it gets an email, branded as this agency, and sees the message in their own account. An internal note is visible only to this agency's staff and is never shown to the client. Refuses any ticket that is not on this agency's desk.
Update a client report (support.set_client_report_status)
[HIGH RISK · ADMIN ONLY] Change the status and/or severity of a client's bug report on this agency's desk. CHANGING THE STATUS EMAILS THE CLIENT who filed it, branded as this agency — marking something resolved tells a real person their problem is fixed, so do not use it to tidy a queue. Refuses any ticket that is not on this agency's desk.
Raise a client report with Chirply (support.escalate_client_report)
[HIGH RISK · ADMIN ONLY] Raise a client's bug report with Chirply as a genuine platform fault. This opens a SEPARATE ticket between this agency and Chirply, quoting what the client wrote, and Chirply's team answers the agency on it. The client is not told, is never contacted by Chirply, and sees nothing change on their own ticket — the agency stays the only company they deal with. One escalation per client ticket; asking twice is refused. Refuses any ticket that is not on this agency's desk.
Client ideas (support.list_client_ideas)
[READ] List the feature requests this agency's client accounts have posted to the agency's OWN board — what their clients are asking THEM to build, sorted by how many clients voted for it. A white-label agency's clients post here rather than to Chirply's public board, so nobody outside the agency's own accounts can see these. Reads only. Not to be confused with support.list_feature_requests, which is the board this agency posts to as Chirply's customer.
Send a client idea to Chirply (support.promote_client_idea)
[HIGH RISK · ADMIN ONLY] Send one of this agency's client ideas up to Chirply as a request for the platform itself. Opens a SEPARATE request on Chirply's public board, authored by this agency, quoting what the client wrote and carrying the number of client accounts that voted for it — that vote count is the argument, so it travels with the request. The client is not told, is never contacted by Chirply, and their own post is unchanged. One promotion per idea; asking twice is refused. Refuses any request that is not on this agency's board.

Actions — tasks

6 operations.

List tasks (tasks.list)
[READ] List the organization's tasks, newest first. Optionally filter by status, priority, assignee, or the contact/deal a task hangs off, and search titles and descriptions.
Open a task (tasks.get)
[READ] Fetch one task by id, with all of its fields.
Create a task (tasks.create)
Create a task. Only a title is required; link it to a contact or deal to have it show on that record's timeline.
Edit a task (tasks.update)
Update any field on an existing task. Omitted fields are left alone. Setting status to 'done' stamps the completion time automatically.
Mark a task done (tasks.complete)
Mark a task complete (or reopen it with done=false). Same as ticking the checkbox in the app.
Delete a task (tasks.delete)
[HIGH RISK] Permanently delete a task. This cannot be undone.

Actions — team

10 operations.

List team members (team.list_members)
[READ] List everyone with access to this account — name, email, role (owner/admin/member), and when they joined. Optionally narrowed by a name/email search or a single role, and returned a page at a time, exactly as the Team screen does.
List pending invitations (team.list_invites)
[READ · ADMIN ONLY] List invitations to this account that haven't been accepted or revoked yet, including which have passed their 14-day expiry.
Copy link (team.get_invite_link)
[READ · ADMIN ONLY] Get the acceptance link for a pending invitation — the “Copy link” button on the team page. Use it when the invitation email didn't arrive, or to hand someone their link over chat instead. ANYONE HOLDING THIS LINK CAN JOIN THE WORKSPACE at the invitation's role until it is accepted, expires (14 days), or is revoked with team.revoke_invite, so treat it like a password: send it to the invited person and nobody else. Reading it changes nothing and sends no email.
Invite a teammate (team.invite)
[HIGH RISK · ADMIN ONLY] Creates an invitation and sends a real email inviting someone to join this account as a member, an admin, or an EXTERNAL client who only ever reaches Team Chat — a real message to a real person, billed to the account's own email provider. The email contains a 14-day acceptance link; owners can only be made by changing an existing member's role. The invitation is created FIRST and always survives: if the email cannot be sent (the account has no verified sending domain, or the provider failed), the invitation still exists and stays pending, `email_sent` comes back false with the reason in `delivery_status`, and the link can be handed over with team.get_invite_link or the email retried with team.resend_invite.
Resend (team.resend_invite)
[HIGH RISK · ADMIN ONLY] Sends the invitation email again for an invitation that is still pending — a real email to a real person, billed to the account's own email provider. Use it after a mail outage, or once the account has connected a verified sending domain and wants invitations created before that to actually go out. It does NOT create a new invitation and does not change the existing link, its role, or its 14-day expiry, so an invitation that was already emailed will simply be emailed a second time. If the send fails again the invitation is left untouched and still pending.
Change a member's role (team.change_role)
[HIGH RISK · ADMIN ONLY] Change what a teammate can do in this account. Promoting to owner grants full control including billing, so only an owner (or the platform team) can hand the owner role out or take it away — an admin cannot. Nobody can change their own role, and demoting the last remaining owner is refused, since an organization must always keep one.
Remove a teammate (team.remove_member)
[HIGH RISK · ADMIN ONLY] Remove someone's access to this account. They lose the account immediately; their records (contacts, notes, calls) stay. Removing an owner takes an owner (or the platform team) — an admin cannot remove one — though anyone may remove themselves to leave. The last owner can never be removed.
Revoke an invitation (team.revoke_invite)
[ADMIN ONLY] Cancel a pending invitation so its link stops working. The person can be invited again afterwards.
View feature access (team.get_access)
[READ · ADMIN ONLY] Read the feature restrictions for a team member or invitation. Null means all features allowed by their role.
Save feature access (team.set_access)
[HIGH RISK · ADMIN ONLY] Set the features a team member may use, or the restrictions inherited when an invitation is accepted. Restricts data access and available actions; does not send an email or change the person’s role. Owners retain full access.

Actions — team_chat

34 operations.

Attach a saved image (team_chat.prepare_image_attachment)
Prepare a completed AI Studio or media-library image for a team-chat room you belong to. Copies the account-owned PNG/JPEG/GIF/WebP file (up to 6 MB) privately into that room without downloading image bytes into the model. Requires read access to the source library. Returns an attachment to pass unchanged to team_chat.send_message; this step sends no message and incurs no AI generation charge. Generate first with ai_studio.generate_image or assets.generate_image when a new image is needed.
Attach a file (team_chat.upload_attachment)
Upload one file of up to 6 MB to a team-chat room you belong to — an image, video, audio clip, PDF or ZIP archive. Returns an attachment for team_chat.send_message. The 6 MB cap is this JSON surface's base64 transport limit; people using the app itself can attach files up to 25 MB, and team_chat.send_message accepts attachments of either origin. File bytes are validated like web chat uploads and remain private to the room, readable only by its members. ZIP archives are TEMPORARY: they delete themselves 14 days after upload and cannot be recovered, so do not use this as storage for anything that has to last. Uploading alone sends no notification; posting the attachment notifies room members according to their preferences.
List teammates for chat (team_chat.list_people)
[READ] List everyone in this account who can be messaged in team chat — their user id, display name, email, avatar and public GitHub usernames saved in their profile or linked in this account. These are staff, not CRM contacts; use contacts.list for customers. Sends no messages and costs nothing.
List chat channels (team_chat.list_channels)
[READ] List the internal chat rooms available to the caller: channels they have joined, open channels they could join, and their direct messages. Each row carries the room's last message, its member count, and the caller's own unread count. An API key sees open channels only — private rooms and DMs belong to a person.
Read a chat conversation (team_chat.list_messages)
[READ] Read messages from one channel or direct message, oldest first. The room's ENTIRE history is reachable through this action, however old: it is not capped to recent messages. Read the newest with no timestamps; read a date range by passing `after` and `before` together; walk a long room by repeating the call with `before` set to the oldest message you have so far, until `has_more` comes back false. Each page is at most 200 messages, so call team_chat.channel_stats first to find out how far back the room goes and how many messages are in it before paging a large one. Pass `parent_id` to read one thread's replies instead of the channel's main transcript — the two are separate, and the main transcript never contains thread replies. Refuses a room the caller cannot see.
Read chat images (team_chat.inspect_images)
[HIGH RISK] Read pictures and screenshots attached to selected chat messages, including visible text. Inspects up to four PNG, JPEG, WebP or GIF images per request (6 MB each) using the account's vision model; AI usage is billed to its connected OpenRouter account. Returns observations and explicit unreadable/skipped results. Reads only messages and stored attachments in a channel the caller can see; never fetches arbitrary URLs. Use list_messages to find message ids, including older messages and thread replies.
Search team chat (team_chat.search)
[READ] Search the text of team-chat messages. Searches every room the caller can see unless `channel_id` narrows it to one conversation. Deliberately never reaches a private channel the caller is not a member of — naming one in `channel_id` returns nothing rather than searching it.
Send a chat message (team_chat.send_message)
[HIGH RISK] Post a message into a team-chat channel or direct message. It appears immediately for everyone in the room and pushes a notification to each member whose notification setting allows it — on their desktop AND on their phone, so real people are interrupted wherever they are; treat it like speaking in the room. Costs nothing: this is internal staff chat, never an SMS or email to a customer. A message can be edited or deleted afterwards, but not unsent. Messages posted by a signed-in person queue replies from mentioned AI teammates (and AI direct-message recipients); those replies use the account’s AI credits and run under that person’s permissions. Machine callers without a user cannot wake AI teammates. The sent message returns immediately; AI replies arrive separately.
Edit a chat message (team_chat.edit_message)
Rewrite the text of a message you sent. It is marked as edited for everyone in the room. You can only edit your own messages — not a colleague's, whatever your role.
Delete a chat message (team_chat.delete_message)
[HIGH RISK] Remove a message from the conversation. Its text and any attachments stop being readable immediately and cannot be recovered. You can delete your own messages; account owners and admins can delete anyone's.
React to a chat message (team_chat.react)
Add an emoji reaction to a message, or take yours off if it is already there — the same toggle as clicking the emoji in the app. Acts as the signed-in person, so an API key cannot use it.
Star a chat message (team_chat.star_message)
Save a message to your own starred list, or take the star off if it is already there — the same toggle as clicking the star in the app. A star is PRIVATE: unlike a reaction, nobody else in the room can see that you saved it, and it changes nothing about the message for anyone else. Acts as the signed-in person, so an API key cannot use it. Sends no notifications.
Starred messages (team_chat.list_starred)
[READ] Read your own starred messages, newest star first, each with the room it was said in. Returns only the signed-in person's stars — there is no way to read anyone else's. Reads only and sends no notifications.
Create a chat channel (team_chat.create_channel)
Open a new internal chat channel and add teammates to it. A private channel is invisible to everyone outside its member list and cannot be opened up later, so choose deliberately. Channel names are unique within the account.
Update a chat channel (team_chat.update_channel)
Change a channel's name, its one-line description, its standing meeting link, or whether new teammates are added to it automatically. Only the channel's owner, its creator, or a account owner/admin can. Making a public channel private is possible and permanent; the reverse is not, because it would retroactively expose a transcript people wrote in private.
Change channel image (team_chat.set_channel_image)
Upload, replace or remove the picture shown for a channel in its chat list, header and Details. Accepts JPG, PNG or WebP up to 2 MB. Requires channel-management permission; linked project channels require an account admin. Images remain private to people who can view the channel. Does not send a chat message or change membership.
View channel image (team_chat.get_channel_image)
[READ] Read a channel's current picture as base64 bytes and its image MIME type, or null when no picture is set. Applies the same channel visibility rules as chat; an API key can read only open channels. Does not change data or send messages.
Archive a chat channel (team_chat.archive_channel)
[HIGH RISK] Archive a channel so it drops out of everyone's sidebar and takes no new messages. The transcript is kept and the channel can be unarchived with `archived: false`. Only the channel's owner, its creator, or a account owner/admin can.
Delete a chat conversation (team_chat.delete_channel)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete an internal chat conversation — a channel or a direct message — and everything inside it: every message for every member, every reaction, every starred item, and every file that was shared in it, which is deleted from storage too. There is no undo and no export; archiving (team_chat.archive_channel) is the reversible version and is almost always what is wanted instead. Only an account owner or admin can, and only in a room they can already see, so a private room or a DM they are not in stays out of reach. Any AI employee duty that was reporting into this room keeps running but announces nowhere afterwards.
Open a direct message (team_chat.open_direct_message)
Find or start the private conversation between you and one or more teammates, and return its channel id so you can post into it. Calling it twice never creates a second thread. Acts as the signed-in person, so an API key cannot use it.
Message a teammate directly (team_chat.message_person)
[HIGH RISK] Send one direct message to a single teammate, starting the private conversation with them if there isn't one yet — the two steps a person takes by clicking a colleague's name in chat and typing. It appears immediately for them and pushes a notification to their desktop AND their phone, so treat it like tapping a real colleague on the shoulder. Costs nothing: this is internal staff chat, never an SMS or email to a customer. It can be edited or deleted afterwards, but not unsent. Acts as the signed-in person, so an API key — which has no colleagues — cannot use it.
Join a chat channel (team_chat.join_channel)
Join an open channel, so it appears in your sidebar and you start getting its messages. A short 'joined the channel' line is posted. Private channels cannot be joined — someone in them has to add you.
Leave a chat conversation (team_chat.leave_channel)
[HIGH RISK] Leave a channel or a group direct message. It drops out of your sidebar and stops notifying you; the transcript stays for everyone else and you can rejoin an open channel later. Leaving a PRIVATE channel means you can no longer see it at all unless someone adds you back. Leaving a direct message removes only your seat — starting a direct message with the same people again reopens the same thread with its history.
Add people to a chat channel (team_chat.add_members)
[HIGH RISK] Add teammates to a channel and notify the people added. A private channel grants access to its entire past transcript. You must already belong to the channel. Linked project chats require an account admin; other channels allow existing members to add people.
Remove someone from a chat channel (team_chat.remove_member)
[HIGH RISK] Take a teammate out of a channel. In a private channel they immediately lose access to the whole conversation, including its history and files. Only the channel's owner, its creator, or a account owner/admin can.
How much history a channel holds (team_chat.channel_stats)
[READ] How far back one channel or direct message goes and how much is in it: when its oldest surviving message was posted, when the most recent one was, how many messages it holds in total, and how many of those are in the main transcript rather than inside threads. Read this BEFORE paging a room you have not read — it is what turns 'give me everything from 2019' from blind paging into a bounded range read with team_chat.list_messages. Deleted messages and the grey system lines ('Sam joined the channel') are excluded from both counts, since neither is what a person means by a message. Refuses a room the caller cannot see.
List who is in a chat channel (team_chat.list_channel_members)
[READ] List the PEOPLE in one channel or direct message by name, each with when they last posted in that room, how many messages they have posted in it, and when they joined it. This is the answer to 'who is in here' and 'who has gone quiet' — the transcript only shows who happened to speak recently, and team_chat.list_people returns the whole account rather than this room. Quietest first. Humans only: the AI members of a room are silent unless mentioned, so they are listed by team_chat.list_ai instead. Refuses a room the caller cannot see.
List AI available for chat (team_chat.list_ai)
[READ] List every AI in this account that can be put into a team-chat room — AI employees (which can take actions) and AI agents (which answer as themselves). Shows whether each is currently active; a paused employee or a switched-off agent stays silent in chat.
Add AI to a chat channel (team_chat.add_ai)
[HIGH RISK] Put an AI employee or AI agent into a team-chat room so people can @mention it there. It will be able to read everything said in that room from then on — including, in a PRIVATE channel, the whole history. An AI employee added this way acts under the permissions of whichever person asks it something, never its own. Only the channel's owner, its creator, or a account owner/admin can.
Remove AI from a chat channel (team_chat.remove_ai)
[HIGH RISK] Take an AI employee or agent out of a room. It stops answering there and stops seeing what is said. Anything it already did is not undone. Only the channel's owner, its creator, or a account owner/admin can.
Open a direct message with an AI (team_chat.open_ai_direct_message)
Find or start your own private one-to-one conversation with an AI employee or agent, and return its channel id. Nobody else in the account can see it. In a one-to-one the AI answers every message without being @mentioned. Calling it twice never creates a second conversation. Acts as the signed-in person, so an API key cannot use it.
Ask an AI in a chat channel (team_chat.ask_ai)
[HIGH RISK] Post a question into a team-chat room addressed to an AI that is already in it, wait for that AI to answer, and return its reply. Everyone in the room sees both the question and the answer. This SPENDS MODEL CREDITS on the account's own AI key, and an AI employee may take real actions while answering — under the permissions of the person asking, with anything risky stopping in the approvals inbox. Slow by nature: a turn with tool calls can take tens of seconds. Acts as the signed-in person, so an API key cannot use it.
Set a channel's notifications (team_chat.set_notifications)
Choose what one channel sends you — every message, only mentions, or nothing — and whether it is starred to the top of your sidebar. Personal to you and invisible to everyone else in the room. Acts as the signed-in person, so an API key cannot use it.
Mark a conversation read (team_chat.mark_read)
Clear your unread badge for one channel or direct message, exactly as opening it in the app does. Personal to you. Acts as the signed-in person, so an API key cannot use it.

Actions — teamwork

32 operations.

Find active projects (teamwork.discover_projects)
[READ · ADMIN ONLY] List Teamwork projects with activity since a chosen date. Reads the connected Teamwork site without modifying it.
Migration progress (teamwork.project_import_status)
[READ · ADMIN ONLY] Read saved project migration progress and errors. Includes counts, selected content and native project links; does not expose notebook bodies.
Migrate selected projects (teamwork.start_project_import)
[HIGH RISK · ADMIN ONLY] Recreates selected Teamwork projects with their existing project members, task lists, board stages, and selected tasks and notebooks. Grants Projects access to matched existing members and pending invitations while preserving other feature limits. Private items retain restrictions. Background reads resume from saved pages; existing imported records and Chirply edits are preserved on retries. Sends no invitations, changes no Teamwork data and cancels no subscription.
Continue migration (teamwork.run_project_import)
[ADMIN ONLY] Process one saved project migration page for this account. Reads Teamwork and writes native Chirply project data. Safe to retry after an interruption; no source writes or messages.
Retry migration (teamwork.resume_project_import)
[ADMIN ONLY] Resume a failed project import from its saved page. Existing imported items are retained and deduplicated; does not overwrite Chirply edits or send messages.
Connect with Teamwork (teamwork.connect_oauth)
[HIGH RISK · ADMIN ONLY] Creates a ten-minute browser connection link for this account. An authenticated account administrator must approve access in Teamwork; the resulting encrypted token is shared with account admins. Connecting disables automatic sync, imports no records and changes no Teamwork data. Development access is limited to enabled accounts.
Browse all paired tasks (teamwork.list_pairs)
[READ · ADMIN ONLY] Reads 30 paired tasks with source IDs, last shared fields and sync errors. Follow next_page to inspect older pairs and resolve conflicts beyond the recent status view. Makes no Teamwork request or changes.
Review task versions (teamwork.preview_task)
[READ · ADMIN ONLY] Reads the current mapped task fields from Chirply and Teamwork alongside the last shared baseline. Changes no task; consumes one Teamwork read. Review again if either platform changes before resolving a conflict.
Browse extraction jobs (teamwork.list_jobs)
[READ · ADMIN ONLY] Reads 30 extraction jobs with saved cursors, error details and optional status filter. Follow next_page to inspect every resource in a migration, including older failures. Changes no provider data.
Capture Projects and Chat (teamwork.start_migration)
[HIGH RISK · ADMIN ONLY] Queues all supported root resources and discovers project files/messages/boards, task comments, board columns and Chat message history. Saves admin-only original JSON, with per-resource errors and resumable cursors. Does not download file bytes or create native projects/chat; import tasks separately. Consumes Teamwork reads and never cancels a subscription.
Connect Teamwork (teamwork.connect)
[HIGH RISK · ADMIN ONLY] Verifies and encrypts a Teamwork token shared with account administrators. Grants them access within that Teamwork account's permissions. Connecting disables automatic sync and changes no Teamwork data.
Refresh status (teamwork.status)
[READ · ADMIN ONLY] Reads this account's connection, latest 30 extraction jobs and 100 task mappings with durable errors. Returns no credential and changes no provider data.
Test connection (teamwork.test)
[ADMIN ONLY] Checks saved credentials against Teamwork and saves a connection result. Consumes one API read; changes no Teamwork data.
Disconnect Teamwork (teamwork.disconnect)
[HIGH RISK · ADMIN ONLY] Removes the saved credential, disables task sync and pauses extraction. Retains archived records and native tasks. An already-running request can finish; does not cancel your Teamwork subscription.
API coverage (teamwork.catalog)
[READ · ADMIN ONLY] Returns supported reads, write examples, task field mappings and migration limits. Does not contact Teamwork. Examples require replacing sample IDs and may send real messages when executed with teamwork.write.
Browse Teamwork (teamwork.browse)
[READ · ADMIN ONLY] Reads one page of Teamwork Projects or Chat data using the account-shared account. Follow next_page. Chat only includes accessible conversations; no record is imported or edited. Consumes Teamwork read quota.
Search archive (teamwork.archive_list)
[READ · ADMIN ONLY] Reads 25 archived records and their original JSON, including captured source IDs and timestamps. Archives remain available after disconnecting. File metadata does not include downloaded file bytes.
Archive all pages (teamwork.start_archive)
[HIGH RISK · ADMIN ONLY] Queues a resumable extraction of every accessible page for one selected resource and parent. Saves original JSON visible to account admins; does not convert it to native projects or chat, download files, or delete Teamwork data. Consumes API reads in the background.
Pause or resume extraction (teamwork.control_job)
[ADMIN ONLY] Pauses or resumes a saved extraction cursor. Resume consumes provider reads. An in-flight page may finish; repeated source IDs update existing archive records.
Run next batch (teamwork.run_batch)
[HIGH RISK · ADMIN ONLY] Advances a bounded batch of this account's queued extractions and enabled paired-task syncs. Enabled syncs can update real Teamwork tasks and trigger provider automation. Durable cursors retain unfinished work.
Save sync settings (teamwork.configure_sync)
[HIGH RISK · ADMIN ONLY] Chooses coexistence or migration mode. Enabling sync authorizes background changes to explicitly paired tasks on both platforms and may trigger Teamwork automation. Migration mode permits only reads from Teamwork. No deletions are synchronized.
Import task (teamwork.import_task)
[HIGH RISK · ADMIN ONLY] Creates an account-visible native Chirply Task from a Teamwork task, preserving mapped fields and a private original JSON archive. Repeated imports return the same mapping. Does not copy assignees, subtasks or attachments. Enabled coexistence sync can subsequently write changes back.
Pair existing tasks (teamwork.pair_task)
[HIGH RISK · ADMIN ONLY] Pairs a native Chirply task with an existing Teamwork task only when all mapped fields match. Does not create duplicates or change either task now. Enabled sync subsequently transfers edits in either direction; assignees and non-mapped fields stay independent.
Sync task (teamwork.sync_task)
[HIGH RISK · ADMIN ONLY] Reconciles mapped fields of one paired task. Stops if both sides changed unless an explicit resolution selects the winning platform. A push overwrites Teamwork mapped fields and may trigger notifications or automation. Teamwork has no atomic conditional write; avoid concurrent editing during this operation.
Send to Teamwork (teamwork.write)
[HIGH RISK · ADMIN ONLY] Immediately executes one allowlisted Teamwork write in coexistence mode. Can create or update real projects, tasks, boards, comments or send a real Chat message, with provider notifications and automation. Reuse request_id after uncertain outcomes; pending/uncertain requests are held to prevent duplicate delivery. No automatic reverse mapping is created.
Refresh chat import (teamwork.chat_import_status)
[READ · ADMIN ONLY] Reads native Teamwork chat migration cursors, imported message counts and errors for this account. Does not send messages.
Import next chat batch (teamwork.import_chat_batch)
[HIGH RISK · ADMIN ONLY] Copies up to three saved conversations’ next history pages into native Team Chat, preserving source dates and bylines without sending push notifications. Skips conversations marked membership only. Uses Teamwork API reads and stores message data; file bytes are not copied.
Create active chats (teamwork.provision_chats)
[HIGH RISK · ADMIN ONLY] Creates native channels for accessible Teamwork conversations active since the selected date and maps original participants by email. Private conversations remain private channels. Pending members join on verified invitation acceptance. Does not send invitations or messages; subsequent batches import history. Review aliases and existing channel mappings carefully.
Sync new messages (teamwork.sync_chat_messages)
[HIGH RISK · ADMIN ONLY] Reads the newest messages in each connected Teamwork conversation and posts anything said since the last check into its linked Team Chat channel, where it appears under the original author’s name and is badged as coming from Teamwork. New messages raise unread badges and send the usual Team Chat notifications to the people in that channel. Conversations imported without history receive only messages written after they were set up. Reads Teamwork only — nothing is written back to Teamwork. This runs automatically every minute; use this to check immediately.
Preview direct message merge (teamwork.direct_message_plan)
[READ · ADMIN ONLY] Lists the imported Teamwork one-to-one conversations that would become native direct messages, and which rooms would be folded together. Reads only; changes nothing. A pair with several untitled Teamwork conversations merges into one thread, because Chirply keeps exactly one direct message per pair of people.
Merge direct messages (teamwork.merge_direct_messages)
[HIGH RISK · ADMIN ONLY] Turns imported Teamwork one-to-one conversations into native Chirply direct messages, moving their history into a single thread per pair of people and deleting the emptied rooms. Existing direct messages are merged into, never replaced. Titled rooms, group rooms, and one-to-ones with someone who has no Chirply account are left as channels. Rewrites message ownership rows and removes channels, so preview it first; it sends nothing and notifies nobody.
Copy profile images (teamwork.import_profile_images)
[HIGH RISK · ADMIN ONLY] Copies current Teamwork users’ public profile photos to Chirply storage. Matches existing members by email and preserves their chosen Chirply photos. Saves photos for pending invitees to apply on verified acceptance. Uses provider reads and storage; sends no invitations.

Actions — telephony

91 operations.

List phone numbers (numbers.list)
[READ] List the phone numbers this account uses, with each one's inbound destination, recording preferences, missed-call text-back settings and status. Read-only — costs nothing.
Open a phone number (numbers.get)
[READ] Fetch one phone number with every setting on its settings page: label, inbound destination and its target, call recording, transcription, forwarding preferences and missed-call text back.
Search available numbers (numbers.search_available)
[READ · ADMIN ONLY] Search its own Twilio account for local, toll-free, or mobile numbers available to buy. Filter by country, beginning prefix, locality, digit/keypad-letter pattern, and required voice/SMS/MMS capabilities; use the returned cursor to load every matching page. This only searches — nothing is purchased and nothing is billed.
Buy a phone number (numbers.buy)
[HIGH RISK · ADMIN ONLY] PURCHASE a phone number on its own Twilio account. This SPENDS REAL MONEY — Twilio bills the tenant an upfront and a monthly fee for the number immediately, and it can only be undone by releasing it. By default the number is also routed into this account (voice + SMS webhooks) and added to the dialer.
Release a phone number (numbers.release)
[HIGH RISK · ADMIN ONLY] PERMANENTLY release a phone number back to Twilio and remove it from this account. This CANNOT BE UNDONE — the number is gone from the account, anyone who calls it reaches nobody, and it may not be re-purchasable. Billing for it stops. Use numbers.archive instead to simply hide a number you want to keep.
Save a number's settings (numbers.update_settings)
[ADMIN ONLY] Update any setting on one phone number's settings page: its internal label, where incoming calls go (team simulring, direct voicemail, an AI receptionist, an IVR phone menu, a blind forward, or a conference room), how long the team rings and where unanswered team calls go, destination targets, call recording, transcription and recording announcements, transparent-forward caller ID, and whether it is the account's default outbound caller ID. Omitted fields are left alone. Does not touch Twilio's own webhook routing — use numbers.configure_routing for that.
Open a number's call & text schedule (numbers.get_schedule)
[READ · ADMIN ONLY] Fetch the ordered timezone-aware windows that decide how one number handles incoming calls and texts. Read-only; the normal number settings remain the fallback outside every matching window.
Save inbound text routing (numbers.set_sms_routing)
[HIGH RISK · ADMIN ONLY] Choose what one number does with incoming SMS outside scheduled windows. Inbox stores the message without replying; static immediately sends fixed text; autoresponder runs one attached keyword rule (or all active rules when no id is supplied); ai_agent automatically replies from the chosen agent using the thread and its Brain. Static, responder and AI modes SEND REAL SMS from the tenant's own Twilio account and incur carrier charges when a message arrives.
Save missed-call text back (numbers.set_missed_call_text_back)
[HIGH RISK · ADMIN ONLY] Enable, disable, or edit one number's missed-call text back. When enabled, every unanswered inbound call immediately sends one REAL SMS from that same number, billed to its own Twilio account. Callers who opted out of SMS are skipped, and webhook retries never send a duplicate for the same call. Two optional gates narrow when it sends: only outside the account's business hours (from the Business profile), and only to callers who aren't already a contact.
Save call & text schedule (numbers.set_schedule)
[HIGH RISK · ADMIN ONLY] Replace one number's complete ordered schedule, interpreted in the account timezone from Business profile. The first local-time window that matches controls both incoming calls and texts; outside it, the normal number settings apply. Enabling static, responder or AI text behavior causes REAL automatic SMS, billed to the tenant's Twilio account, whenever matching messages arrive. Call destinations take effect on the next inbound call.
Set where a number's calls arrive (numbers.configure_routing)
[ADMIN ONLY] Point one Twilio number's inbound voice and/or SMS webhooks at this account, at a custom https URL, or turn the channel off. This changes configuration on its own Twilio account and takes effect on the next call. Addressed by the Twilio number SID, so it also works for numbers that aren't in the dialer yet.
Use a Twilio number in this account (numbers.use_in_chirply)
[ADMIN ONLY] One click: route a Twilio number's voice AND SMS into this account and add it to the dialer so it can place calls and send messages. Addressed by the Twilio number SID. Does not buy anything.
Stop using a number in this account (numbers.stop_using_in_chirply)
[ADMIN ONLY] Reverse of 'use in this account': clear this account's voice + SMS routing on Twilio and remove the number from the dialer. The number stays on the Twilio account and keeps billing — this does not release it. Clears the default-outbound preference if it pointed here.
Archive a phone number (numbers.archive)
[ADMIN ONLY] Hide a number from the dialer and every from-number picker WITHOUT releasing it on Twilio or changing its routing — for a line you run elsewhere but want out of the way. Billing continues. Clears the default-outbound preference if it pointed here. Reverse it with numbers.restore.
Restore an archived number (numbers.restore)
[ADMIN ONLY] Bring an archived number back into the dialer and the numbers console.
Set the default outbound number (numbers.set_default_outbound)
[ADMIN ONLY] Set (or clear) the account's default outbound caller ID and SMS sender. The number must already be active in this account.
Look up known line types (numbers.get_line_type)
[READ] Read the cached line type (mobile / landline / VoIP / toll-free) and carrier for one or more phone numbers. Reads the platform's shared lookup cache only, so it is instant and costs nothing; numbers nobody has ever paid to look up simply come back unknown. Use numbers.queue_line_type_lookup to pay for the unknown ones.
Look up line types (paid) (numbers.queue_line_type_lookup)
[HIGH RISK] Queue phone numbers for a Twilio Lookup line-type check. This SPENDS REAL MONEY — each number not already in the shared cache is billed to its own Twilio account (roughly $0.008 each). Numbers already known, or already queued, are skipped for free. Nothing is queued at all when the account has switched automatic lookup off (numbers.set_auto_line_type_lookup) or has no Twilio connected. Results land asynchronously; read them back with numbers.get_line_type.
Scan the database for line types (numbers.scan_line_types)
[HIGH RISK · ADMIN ONLY] One-time sweep: queue EVERY not-yet-known phone number across this account's contacts and staged leads for a line-type lookup. This SPENDS REAL MONEY — each unknown number is billed to the account's own Twilio (roughly $0.008 each), and a large database can mean thousands of lookups.
Toggle automatic line-type lookup (numbers.set_auto_line_type_lookup)
[ADMIN ONLY] Turn automatic line-type lookup on or off for this account. When on, every new phone number that enters the CRM is looked up on its own Twilio account (a small per-number charge) unless the platform already knows it. Stored alongside the Twilio credentials it spends.
Check the Twilio connection (telephony.get_connection)
[READ] Report whether this account has connected its own Twilio account, and the connection's current status. Never returns the auth token or API key secret — those are stored encrypted and are not readable.
Save Twilio credentials (telephony.connect_twilio)
[HIGH RISK · ADMIN ONLY] Connect (or update) its own Twilio account. Every call, message and number purchase made here is billed to these credentials, so pointing them at a different account changes who pays. The auth token and API-key secret are encrypted before storage; leaving either blank on an update keeps the stored value.
Test the Twilio connection (telephony.test_connection)
[ADMIN ONLY] Verify the stored Twilio credentials by fetching the account from Twilio, and update the connection's status to reflect the result.
List calls (calls.list)
[READ] List the call log, newest first — inbound and outbound, with duration, disposition, recording state and transcript availability. Filter by direction, status, contact, line, voicemails, or whether a recording was kept.
Open a call (calls.get)
[READ] Fetch one call from the log with its full detail: both numbers, duration, disposition, notes, recording URL (when the audio is still stored) and transcript.
Place a call (calls.place)
[HIGH RISK] PLACE A REAL OUTBOUND PHONE CALL from one of the account's numbers. This DIALS A REAL PERSON immediately and bills its own Twilio account for the minutes. The call is logged, and when a contact is named the call also lands on that contact's timeline. If the from-number has recording switched on, the call is recorded.
Start in-app call (calls.start_softphone)
[HIGH RISK] Prepare a real outbound VoIP call from the signed-in mobile softphone. The mobile app immediately connects the caller to the recipient through its own Twilio account, so the recipient's phone rings and Twilio bills the account for call minutes.
Set a call's outcome (calls.set_disposition)
[HIGH RISK] Record a call's disposition (outcome) and note, the same as picking one in the power dialer or the call log. Setting a disposition FIRES ITS ATTACHED ACTIONS against the call's contact — which can send real SMS or email, enrol them in a campaign, or move a deal — and runs any automation set to fire when a call outcome is recorded. It is not a passive edit.
List calls with no outcome (calls.list_needing_disposition)
[READ] List calls that have ended but still have no outcome recorded — the review queue. This is where calls taken on a desk phone or the mobile app land, since no browser was open to ask at the time. Read-only; it changes nothing.
Calls by outcome (calls.outcomes_report)
[READ] Roll up the call log by recorded outcome for a date window: how many calls landed on each outcome (with percentages), total calls, how many were answered (connect rate), how many have an outcome recorded versus still missing one, and a per-teammate breakdown with each person's connect rate and commonest outcome. Spam and voicemail drops are excluded, matching the Calls page. Read-only — it counts existing calls and changes nothing.
Suggest a call's outcome (calls.suggest_disposition)
[READ] Read a call's transcript and suggest which of the account's own call outcomes fits, with a confidence score and the reason. It only suggests — nothing is saved and no actions fire; pass the answer to calls.set_disposition to apply it. Requires a transcript, so the number must have transcription switched on. Uses and bills its own OpenRouter account.
Delete a recording's audio (calls.delete_recording_audio)
[HIGH RISK] Permanently delete ONLY a call's recorded audio from storage, keeping the call log entry and its transcript. This cannot be undone — the audio is gone.
Delete a call (calls.delete)
[HIGH RISK] Permanently delete a call from the log, along with its recorded audio. This cannot be undone.
Set the voicemail greeting (calls.set_voicemail_greeting)
[HIGH RISK · ADMIN ONLY] Set one phone number's voicemail greeting. Twilio speaks built-in voices live; ElevenLabs generates and stores finished audio immediately using its own OWN account and SPENDS ITS TTS CREDITS. Recording or uploading a clip is available in the app.
Mute (calls.set_mute)
Mute or unmute THIS side of a call that is happening right now — the account's own leg, exactly like the Mute button on the in-call bar. The other party stays connected and keeps talking; they simply stop hearing you. Escalates the call into a conference if it isn't one already (a brief, silent transition), because muting one participant is a conference operation. Trivially reversible by calling again with muted=false.
Hold (calls.set_hold)
Put the other party on hold on a call that is happening right now, or take them off it. On hold they hear hold music instead of this side and cannot hear anything said here. Escalates the call into a conference if it isn't one already (a brief, silent transition). NOTE: the app has no hold button today — this is the same participant-hold the warm-transfer flow uses internally, and for now it is a machine-only control. Trivially reversible by calling again with on_hold=false.
Keypad (calls.send_digits)
[HIGH RISK] Press keypad digits on a call that is happening right now — the in-call keypad. The tones are played down the line TO THE OTHER PARTY, so this is how you drive somebody else's phone menu (“press 2 for accounts”) or enter an extension, an account number or a PIN. IRREVERSIBLE ONCE SENT: a wrong digit can commit the far end's IVR to a selection you cannot take back, and digits are audible to whoever is on the line, so never send anything secret this way. Escalates the call into a conference if it isn't one already, and the other party leaves the room for the moment the tones play, which both sides hear as a short silence.
Decline (calls.decline)
[HIGH RISK] Decline a still-ringing INBOUND call without answering it, so it falls through to whatever the line does next — voicemail, or the number's fallback. The caller is not hung up on and never hears a rejection. Because a machine caller has no browser leg of its own, this declines the ring for the WHOLE account rather than for one person's softphone: everybody's phone stops, and the caller moves on. That cannot be taken back for this call. Refused once somebody has picked up — end an answered call with calls.hangup instead. To choose the destination yourself, use calls.send_to_voicemail or calls.forward_incoming.
Available for calls (calls.set_presence)
Set whether a member is available to take inbound calls on the browser phone — the softphone's Available/Away switch. A line whose inbound routing is set to the team rings everyone currently available, so switching someone off stops inbound calls reaching them, and switching everybody off means nobody's phone rings and callers fall through to voicemail. Availability lapses on its own about a minute after the browser stops heartbeating, so this is a way to take somebody OFF the rota, not a way to keep them on it.
Who's available (calls.list_presence)
[READ] List who in this account is currently able to answer an inbound call, and who is not. Covers both the browser phone and registered mobile apps, with each person's name and email and when they were last seen. This is the answer to “why is nobody picking up the main line?” — a number whose inbound routing is set to the team only rings people who are available here, so an empty list means every caller goes to voicemail. Read-only.
Add someone to a live call (calls.add_party)
[HIGH RISK] DIAL A THIRD PERSON into a call that is happening right now, escalating it to a conference so all three can talk. This RINGS A REAL PHONE and bills the account's own Twilio for the extra leg.
Transfer a live call (calls.transfer)
[HIGH RISK] Blind-transfer a call that is happening right now: DIAL the target and hand the other party straight over, dropping this side. This RINGS A REAL PHONE, bills the account's own Twilio, and cannot be taken back once the transfer lands. Use calls.warm_transfer_start to consult first.
Start a warm transfer (calls.warm_transfer_start)
[HIGH RISK] Step one of a consultative transfer on a live call: DIAL the target, put the other party on hold, and let this side speak to the target privately. RINGS A REAL PHONE and bills the account's own Twilio. Finish with calls.warm_transfer_complete or back out with calls.warm_transfer_cancel.
Complete a warm transfer (calls.warm_transfer_complete)
[HIGH RISK] Finish a consultative transfer: take the caller off hold, connect them to the target, and drop this side out of the call. Cannot be taken back.
Cancel a warm transfer (calls.warm_transfer_cancel)
[HIGH RISK] Back out of a consultative transfer: drop the target's leg and take the caller off hold so this side keeps the call.
End a live call (calls.hangup)
[HIGH RISK] END a call that is happening right now, dropping every remaining party. This disconnects real people mid-conversation and cannot be undone.
Send a ringing call to voicemail (calls.send_to_voicemail)
[HIGH RISK] Send a still-ringing INBOUND call straight to voicemail without answering it. The caller hears the account's greeting and can leave a message.
Forward a ringing call (calls.forward_incoming)
[HIGH RISK] Forward a still-ringing INBOUND call to another number without answering it. This RINGS A REAL PHONE and bills the account's own Twilio for the forwarded leg. When the receiving line opts into transparent forwarding, the original caller's number is presented.
List IVR phone menus (ivr.list)
[READ] List the account's IVR flows (phone menus) built in the visual builder, with whether each is live and which lines it answers.
Open an IVR phone menu (ivr.get)
[READ] Fetch one IVR flow: its full node/edge graph as drawn in the builder, whether it is live, any validation issues that would stop it answering a real line, and every phone number currently pointing at it.
Create an IVR phone menu (ivr.create)
Create a new, empty IVR flow and return its id. Deliberately off air and unattached — pointing a live number at a flow with no steps would answer real callers with silence. Draw it with ivr.update, then publish and attach it.
Save an IVR phone menu (ivr.update)
Rename an IVR flow and/or replace its node/edge graph — the same graph the visual builder saves, and the one the live call runtime walks for both inbound calls and outbound voice campaigns. The flat greeting/options summary is recompiled automatically. A flow that is already LIVE is refused if the new graph would misroute a real caller.
Upload audio (ivr.upload_prompt_audio)
Store a recorded clip for one step of a phone menu to play, and get back the permanent URL to put on that step with ivr.update. Send the bytes base64-encoded, up to 10 MB. IT MUST BE PLAYABLE ON A PHONE CALL: WAV, MP3, AIFF, GSM or u-law only — Twilio rejects anything else outright and the caller hears dead air, so a clip in another format is refused here rather than stored. Best results come from 8 kHz mono WAV, which is what the builder's own recorder produces. Costs nothing and calls nobody; it stores one file.
Generate with AI voice (ivr.generate_prompt_audio)
[HIGH RISK] Speak a line of a phone menu in an ElevenLabs voice and store it, returning the permanent URL to put on that step with ivr.update. SPENDS REAL MONEY: every call renders the text on its OWN ElevenLabs account and consumes its credits, so re-rendering the same line ten times costs ten times — and there is no cached preview to fall back on. Needed because Twilio's built-in <Say> voices cannot speak ElevenLabs: choosing a cloned or premium voice for a menu prompt means rendering it up front and playing the file on the call. Twilio's own voices (Polly, Google) are spoken live and never come through here. Nothing is dialed and no caller hears anything until the URL is saved onto a step and the menu is published.
Publish an IVR phone menu (ivr.publish)
[HIGH RISK] Put an IVR flow LIVE so it can answer real callers, or take it off air. Publishing is refused when the flow has issues that would misroute a caller (a dead hand-off, a missing or paused AI agent, an unconnected key). TAKING IT OFF AIR CHANGES WHERE CALLS GO: an off-air menu cannot answer, so every line pointing at it is sent back to the team simulring and named in the result.
Attach an IVR to a number (ivr.attach_number)
[ADMIN ONLY] Point one of the account's phone numbers at this IVR flow, so incoming calls to that line walk the menu. The flow must be live. A line already answering with an AI receptionist, a forward, a conference room or a different IVR is refused rather than silently repointed.
Detach an IVR from a number (ivr.detach_number)
[ADMIN ONLY] Stop a phone number answering with this IVR flow and send it back to the team simulring. Omit the number to release every line pointing at the flow.
Delete an IVR phone menu (ivr.delete)
[HIGH RISK] Permanently delete an IVR flow. This cannot be undone. Any line answering with it is first sent back to the team simulring and named in the result. A flow that ANOTHER flow hands calls to is refused, because deleting it would leave that other flow hanging up on real callers.
List sales bridges (sales_bridges.list)
[READ] List the account's sales bridges — the press-1 simulring connectors that ring a pool of agents for one hot lead.
Open a sales bridge (sales_bridges.get)
[READ] Fetch one sales bridge with its whisper script, caller-ID line, dial timeout, recording preferences and its full agent pool in ring order.
Create a sales bridge (sales_bridges.create)
[ADMIN ONLY] Create a sales bridge: a name, the line to call from, an optional whisper played to the agent who answers, an optional SMS sent to each agent on dispatch, and the pool of agent phones to ring. Creating it dials nobody — use sales_bridges.start_run for that.
Edit a sales bridge (sales_bridges.update)
[ADMIN ONLY] Update a sales bridge's settings. Omitted fields are left alone. Supplying `agents` REPLACES the whole pool in the order given.
Delete a sales bridge (sales_bridges.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete a sales bridge and its agent pool. This cannot be undone. Past runs are removed with it.
Start a sales bridge (sales_bridges.start_run)
[HIGH RISK] Dispatch a sales bridge for one lead RIGHT NOW: it RINGS EVERY AGENT IN THE POOL simultaneously and, on the first press of 1, bridges that agent to the lead. This places multiple REAL CALLS and bills the account's own Twilio for every leg, plus an SMS per agent when the bridge has one. Numbers on the do-not-contact list are refused.
List sales bridge runs (sales_bridges.list_runs)
[READ] List recent sales-bridge dispatches with their outcome — ringing, claimed, bridged, completed, no answer, failed or canceled — and which agent won each one.
Open a sales bridge run (sales_bridges.get_run)
[READ] Fetch one sales-bridge run with every agent leg it dialed and how each leg ended, plus the call-log row for the bridged conversation.
List voice campaigns (voice_campaigns.list)
[READ] List the account's outbound voice campaigns (call blasts and outbound IVR) with their status, schedule and per-recipient tallies.
Open a voice campaign (voice_campaigns.get)
[READ] Fetch one voice campaign with its content (IVR menu, spoken message, recorded audio or AI agent), schedule, quiet-hours and concurrency settings, and its recipient tallies.
List campaign recipients (voice_campaigns.list_recipients)
[READ] List a voice campaign's recipients with each one's dial status, attempt count, answering-machine verdict and last keypad selection.
Create a voice campaign (voice_campaigns.create)
[HIGH RISK] Create and LAUNCH an outbound voice campaign. This CALLS REAL PEOPLE — every contact in the chosen audience is dialed from its own Twilio account and billed to it, starting immediately unless a future start time is given. Content is either an IVR phone menu (the live runtime walks the same flow the builder draws), a spoken message, or an AI agent. Every answered call also offers a keypad opt-out (“press 9 to be removed”) unless opt_out_enabled is false — that is the only way somebody being dialed can stop the calls, so leave it on. Uploading pre-recorded broadcast audio is only possible in the app.
Save opt-out settings (voice_campaigns.set_opt_out)
[HIGH RISK] Change how somebody being dialed by a running voice campaign can get off the list — whether the “press a key to be removed” offer is made at all, which key, what pressing it stops (calls, voicemail drops, texts, emails), and the exact sentence read to them. This is deliberately editable WHILE the campaign dials, because “I set the wrong key and it's calling people right now” needs fixing in the next thirty seconds. Changes apply to calls placed from now on; anyone already dialed keeps whatever they heard. TURNING IT OFF REMOVES THE ONLY WAY A CALLEE CAN STOP THE CALLS — the campaign itself keeps running. Campaigns that play an IVR menu opt people out through an Unsubscribe action node in the menu instead, and are refused here.
Start, pause or cancel a campaign (voice_campaigns.set_status)
[HIGH RISK] Change a voice campaign's status. Setting it to 'running' STARTS OR RESUMES DIALING REAL PEOPLE and billing the account's own Twilio. 'paused' holds the queue; 'canceled' stops it for good and marks every not-yet-dialed recipient as skipped, which cannot be undone.
Add contacts to a campaign (voice_campaigns.add_recipients)
[HIGH RISK] Enqueue more contacts into an existing voice campaign. On a RUNNING campaign they WILL BE CALLED — real calls billed to the account's own Twilio — as soon as the dispatcher reaches them. Contacts already on the campaign, and contacts without a dialable number, are skipped.
Call one contact with a menu or message (voice_campaigns.call_contact)
[HIGH RISK] Place a single outbound IVR (or spoken-message) call to one contact. This CALLS A REAL PERSON and bills the account's own Twilio. Implemented as a one-recipient campaign so it goes through the same dispatcher — quiet hours, do-not-contact and pacing all apply, and the same IVR runtime walks the flow.
Delete a voice campaign (voice_campaigns.delete)
[HIGH RISK] Permanently delete a voice campaign, its recipient queue and its stored broadcast audio. This cannot be undone. A running campaign stops.
Countries you can call (regions.list_calling)
[READ] Lists every country with whether its own Twilio account is currently allowed to call it. A brand new Twilio account can only call its own country, and calls to anywhere switched off are refused before they are placed — this is what that setting says right now. Reads its own Twilio account and costs nothing. Note this is the CALLING list only; Twilio keeps texting permissions on a separate switch it publishes no API for, so use regions.texting_status for that.
Check calling to a country (regions.get_calling)
[READ] Answers whether its own Twilio account is allowed to call one particular country, named either by ISO code or by giving any phone number in it. Reading is free; when a phone number is given its country is resolved through a Twilio Lookup requested without any billable data packages, so that is free as well.
Turn on calling to this country (regions.enable_calling)
[HIGH RISK · ADMIN ONLY] SWITCHES ON INTERNATIONAL CALLING to one country on its own Twilio account, immediately and for every user in the account. Calls placed after this are billed by Twilio at that country's international rates, which can be many times the domestic rate. Premium-rate and known toll-fraud number ranges stay OFF unless they are asked for by name — those are the ranges that turn a compromised account into a very large bill, so enabling them is a separate, deliberate decision.
Turn off calling to this country (regions.disable_calling)
[HIGH RISK · ADMIN ONLY] SWITCHES OFF calling to one country on its own Twilio account. Every call placed to it after this is refused before it is dialed, for every user in the account — including calls made by dialers, campaigns and AI agents. Use it to close down a destination that is being abused or is not needed; it takes effect immediately.
Why texting this country is blocked (regions.texting_status)
[READ] Explains a blocked international TEXT (Twilio error 21408) and says exactly who can unblock it and where. Unlike calling, Twilio publishes no API for messaging geo-permissions — it states they cannot be changed programmatically, for security reasons — so neither Chirply nor any agent can switch a country on, and there is no endpoint to read the current setting from either. This returns the country the number belongs to, the Twilio console page that owns the setting, and the account SID that page has to be opened against, so a human can finish it in about thirty seconds. Costs nothing.
List call scripts (call_scripts.list)
[READ] List this account's call scripts, with how many steps and objection handlers each one has. Read-only.
Read a call script (call_scripts.get)
[READ] Read one call script in full — its ordered steps and its objection handlers. Read-only.
Open the script for this call (call_scripts.for_call)
[READ] Answer “which script is this live call on?” in one hop: the script the call opens with by default (taken from the call queue it was dialed from, then from the line it is on), every other script a rep could switch to, and the latest AI assist reading already taken on the call. This is exactly what the in-call script panel paints itself from. Read-only — it never speaks to the customer, changes nothing about the call, and unlike call_scripts.assist_reading it takes no NEW reading, so it costs nothing.
Create a call script (call_scripts.create)
[ADMIN ONLY] Create an empty call script. Add its steps afterwards with call_scripts.add_step. Nothing is shown to a rep until the script has at least one step.
Edit a call script (call_scripts.update)
[ADMIN ONLY] Rename a call script, change what it's for, switch it on or off for calls, or turn the AI assist on or off. Turning assist ON means the AI reads the live transcript of every call using this script and spends this account's own OpenRouter credit doing so; it never speaks to the customer. Omitted fields are left alone.
Delete a call script (call_scripts.delete)
[HIGH RISK · ADMIN ONLY] Permanently delete a call script and every step and objection handler in it. This cannot be undone. Any call queue or phone number pointing at it simply stops offering a script.
Add a step or objection handler (call_scripts.add_step)
[ADMIN ONLY] Add one entry to a call script. A 'step' is appended to the end of the ordered path through the call; an 'objection' is a handler and must name which objection it answers.
Edit a step or objection handler (call_scripts.update_step)
[ADMIN ONLY] Rewrite one entry of a call script in place. Supplying a field replaces it; the entry keeps its position.
Delete a step or objection handler (call_scripts.delete_step)
[HIGH RISK · ADMIN ONLY] Permanently delete one entry from a call script. This cannot be undone. The remaining entries keep their order.
Reorder a call script (call_scripts.reorder_steps)
[ADMIN ONLY] Set the order of a script's steps (or of its objection handlers) by giving their ids in the order you want. Pass every id of that kind — any left out keeps a stale position.
Read where a live call is in its script (call_scripts.assist_reading)
[READ] Take one reading of a call in progress: which step of its script the conversation appears to be in, and whether the customer just raised an objection the script has a handler for. Reads the call's transcript only — it never speaks to the customer and changes nothing about the call. Requires the script to have assist switched on and the number to have transcription on. Uses and bills its own OpenRouter account.

Actions — templates

7 operations.

List message templates (templates.list)
[READ] List the organization's reusable message templates — SMS bodies, email subject+body pairs, and ringless-voicemail scripts or recordings. These are what campaigns, automations, dispositions and bulk sends pick from.
Open a message template (templates.get)
[READ] Fetch one message template with its subject, body and — for a recorded voicemail — the audio URL.
Create a message template (templates.create)
Create a reusable SMS, email or ringless-voicemail template. Bodies may contain merge tokens like {{first_name}} or {{company.name}}, resolved per recipient at send time — call templates.list_merge_tokens for the full set. Creating a template sends nothing.
Edit a message template (templates.update)
Update a message template's name, subject, body, voice or recording. Editing a template changes what every campaign, automation and disposition using it will send from now on; messages already sent are unaffected. Omitted fields are left alone.
Delete a message template (templates.delete)
[HIGH RISK] PERMANENTLY DESTROY a message template. This cannot be undone, and any campaign, automation or disposition still pointing at it loses its message content.
List merge tokens (templates.list_merge_tokens)
[READ] List every merge token a template body can use — the built-in contact, company and address fields plus one entry per contact custom field this organization has defined. Use these exact spellings; an unknown {{token}} renders as an empty string.
Preview a template (templates.preview)
[READ] Render a template's subject and body with merge tokens resolved, either for a real contact or with the tokens left empty. Sends nothing — this is the preview shown in the template editor.

Actions — tracking

30 operations.

Traffic & Sources (tracking.traffic_report)
[READ] Read historical website traffic for a date range: exact visitors (tracked browsers), reconstructed visits, page views, daily trend, destination websites and arrival sources, plus a paginated visit list. Includes paid, organic, other and unattributed visit totals, the same visits split by the fine-grained arrival channel behind each bucket (channelKinds, e.g. organic_search / meta_social / direct), source/type breakdowns and per-visit classification evidence. Filter by website, destination hostname, source, traffic channel and bot_filter (all, exclude_bots, bots_only, likely_human). Exclude bots removes entire visits with identified or suspected automation evidence; unknown visits stay included. Every aggregate, source attribution, daily chart and paginated visit follows the bot filter. trafficQuality reports unfiltered totals and per-status counts within the same date/site/source/channel scope, so bot share remains measurable after exclusion; visits expose trafficStatus. The strongest event-time signal in the retained visit before the report end determines its status, including earlier pages before the range start. Legacy evidence stays unknown; likely human is an estimate, not verified identity. Traffic type comes from the same classifier the contact records use, then rolls up into four columns. Paid requires a recognized ad-click ID or a paid medium on a known ad network; a Meta click ID alone does not establish paid status, because Meta stamps one on organic post links too — that visit reads meta_social. Organic covers search and answer engines, unpaid social posts, and direct arrivals that carried no referrer and no campaign tag, since nobody buys a click that arrives carrying nothing; channelKind separates them. Other covers email, SMS, affiliate links and referrals from other websites. Unknown means only that the visit resumed after an inactivity break with no new arrival evidence. A recorded arrival or the site's inactivity threshold begins a visit; source and channel are the visit's original event evidence, never a contact's latest source. Only retained, recorded page views count; unknown sources remain explicit. Read-only: no messages sent and no provider spend. Requires Website Visitors access.
Website tracking (tracking.overview)
[READ] The Website tracking landing screen's headline numbers, for the WHOLE account rather than one site: total visitors ever seen across every tracked website, how many of them are matched to a CRM contact, and how many are on the sites right now. Also lists each tracked website with its own lifetime and live counts, split into the tenant's own installed sites and the system-owned 'Chirply pages' source. These are LIFETIME totals with no date window — tracking.stats answers a single site over the last 1–90 days and cannot reproduce these numbers, and tracking.live_visitors only ever answers 'in the last few minutes'. Read-only.
List tracked websites (tracking.list_sites)
[READ] List the organization's tracking sources, newest first. A source with hosted_pages=true is the system-owned 'Chirply pages' source for platform-hosted websites, funnels, invoices, payment pages, and receipts; it is tracked automatically and never needs an install snippet. Other sources are external websites that require the tracking script. Returns no visitor data.
Open a tracked website (tracking.get_site)
[READ] Fetch one tracking source by id. External websites include their allowed origins and exact install snippet. The system-owned 'Chirply pages' source has hosted_pages=true and covers platform-hosted websites, funnels, invoices, payment pages, and receipts automatically; no snippet or allowed-origin setup is required.
Copy install snippet (tracking.install_snippet)
[READ] For an EXTERNAL website, return the one-line <script> tag shown by the Copy button. Never instruct a user to install this on the system-owned 'Chirply pages' source: platform-hosted websites, funnels, invoices, payment pages, and receipts are tracked automatically and require no snippet.
Add a website (tracking.create_site)
[ADMIN ONLY] Register a website for tracking and mint its public embed key. Collection FAILS CLOSED: until at least one allowed origin is added (pass `origin`, or call tracking.add_origin), the script records nothing. Creating a site costs nothing and sends nothing.
Edit tracking settings (tracking.update_site)
[HIGH RISK · ADMIN ONLY] Rename a tracked website, pause or resume collection, or change how it behaves. Omitted fields are left alone. Setting status to 'paused' stops all collection immediately without the tenant editing their website's HTML. This covers every control on the site's settings screen EXCEPT session replay — screen recording is turned on and off through tracking.set_replay, which requires an explicit human approval.
Record sessions I can watch back (tracking.set_replay)
[HIGH RISK · ADMIN ONLY] TURN SESSION RECORDING ON OR OFF for a tracked website. When on, the script captures what real visitors do on the tenant's pages — mouse movement, clicks, scrolling and DOM changes — and stores it so anyone on the team can replay the visit at tracking.get_replay. Everything a visitor types is masked in their browser before it is ever sent, and pages listed in the site's excluded paths are never recorded, but this is still the most privacy-consequential switch in the product: it is OFF BY DEFAULT and deliberately opt-in, and whoever turns it on is taking on whatever their own privacy policy and local law require them to disclose. Recordings are deleted automatically once they reach retention_days old (default 30). Turning it off stops new recordings immediately; recordings already captured are kept until they age out — delete those with tracking.delete_replay. It is split out of tracking.update_site precisely so it cannot be flipped as a side effect of editing some other setting.
Delete a website (tracking.delete_site)
[HIGH RISK · ADMIN ONLY] Permanently delete a tracked website, along with every visitor and event recorded for it. The embed key stops working, so the script left on the site becomes a no-op. Contacts and their timeline entries are NOT deleted. This cannot be undone.
List allowed websites (tracking.list_origins)
[READ] List the website addresses a tracking site is allowed to report from. An empty list means the script records nothing at all.
Add allowed website (tracking.add_origin)
[HIGH RISK · ADMIN ONLY] Allow a website address to report tracking data against this site. THIS GRANTS THAT DOMAIN WRITE ACCESS TO THIS ORGANIZATION'S CRM: anything served from that origin can create page views and, while 'Match form fills to contacts' and 'Add new people as contacts' are on, create real contact records. Add only hosts the tenant actually controls — a typo'd or attacker-supplied origin is a standing injection route into the CRM, and nothing else re-checks it. Add every host the script legitimately runs on: apex, www, and staging. Removing it again is tracking.remove_origin.
Remove allowed website (tracking.remove_origin)
[HIGH RISK · ADMIN ONLY] Stop accepting tracking data from one website address. Takes effect on the next page view; already-recorded data is kept. Removing the last origin stops collection entirely.
List browsers seen (tracking.list_visitors)
[READ] List individual BROWSERS seen on a tracked website — the rows the app labels "Browsers seen" — most recently active first, with their page-view counts and first-touch attribution (first referrer, landing page, and campaign parameters). One row is one browser, so the same human on a laptop and a phone appears twice; for one row per resolved person use tracking.list_people, which is what the app's own Visitors list shows. Filter to a single contact, to one resolved person, or to only browsers that have been identified. Read-only.
Open a browser seen (tracking.get_visitor)
[READ] Fetch ONE BROWSER with its attribution and, optionally, its 50 most recent events — the 'what did this browser read?' view behind a contact record. This is a single browser, not the whole human: for everything one person has ever done across all their devices, use tracking.get_person, which is what the app's Visitor page shows. When the browser was never identified but FRIENDER reported the recipient of the link it arrived on, and that recipient matches exactly one contact, the match is returned as friender_contact_id with contact_via="friender"; that is an unverified provider claim about who a link was addressed to, not a sign-in, and a forwarded link means the reader may be somebody else. contact_via="identified" means contact_id was stored by a signed token or an identify/form submission. Read-only.
List website activity (tracking.list_events)
[READ] List recorded website activity — page views, form fills, identifications, and custom events — newest first with pagination. Each event includes trafficClassification (status, label, confidence, agent and reason): identified_bot is a self-reported crawler, suspected_bot is an automation signature, likely_human is an estimate, and unknown means insufficient event-time evidence. Browser names are spoofable; provider identity is not verified. Legacy events remain unknown. Includes recorded_url to reopen its safe saved query. FRIENDER identify events expose identity_provider, provider_name, provider_profile and provider_referrer (sender name and fb_profile_url) in props as unverified link-recipient reports. Page views also include props.chirply_url_parameters: filtered URL parameter names mapped to arrays of distinct values, including custom parameters, retained per event rather than overwritten across visits. Sensitive names/values are excluded; capture is bounded to 64 names, 8 values per name, 500 characters per value and 8192 characters aggregate. Each event includes its own utm/referrer and props.chirply_acquisition when captured by the current tracker: v=1 with touch=null marks ordinary navigation; a touch object records that arrival's source, campaign, landing path and time. These are individual recorded arrivals, not changes to the contact's original acquisition source. Legacy rows retain raw UTM/referrer evidence. Filter by site, visitor, contact, kind, or URL path. Read-only; recorded events follow the platform's retention window (395 days by default).
Ad visits and other arrivals (tracking.acquisition_history)
[READ] Read individual recorded website arrivals with their source, channel, campaign and timestamp, newest first. Later retargeting visits remain separate and never replace the contact's original source. Reads page-view acquisition evidence independently of ordinary browsing events; legacy rows use their recorded UTM/referrer when no explicit arrival marker exists. Each arrival carries url: the safe reopenable address for that visit, with its recorded query preserved and sensitive parameters stripped, or null when the stored address cannot be reopened. Filter by contact, resolved person, browser or site. Results follow the event retention window (395 days by default) and collection consent/limits; these are observed website arrivals, not ad impressions or a verified platform engagement report. Use nextOffset to load more; null means no more matching rows. Read-only, sends no messages and incurs no advertising cost.
Website tracking stats (tracking.stats)
[READ] Headline numbers for a tracked website over a recent window: page views, unique visitors seen, how many were identified as contacts, and the busiest pages. Read-only.
Test installation (tracking.check_install)
[READ] Check whether a tracked website's script is actually working, and explain why not if it isn't. Reports whether any beacon has ever arrived, when the last one did, and the specific blocker when one exists (collection paused, or no allowed website addresses so everything is being ignored). Read-only — it inspects what has already been received rather than fetching the site.
Live visitors (tracking.live_visitors)
[READ] Who is on the organization's tracked websites right now, plus the most recent visitors. Each row includes trafficClassification with status, label, confidence, agent and reason: identified_bot (self-reported crawler), suspected_bot (automation signature), likely_human (browser estimate) or unknown. Neither browser identity nor reported engagement proves a human; provider identities are unverified. Includes: the page each person is reading, how long that page and the current session have been open, how many pages are in the current session, when activity last arrived, which visitors are known contacts, and first/latest-source attribution badges with channel and UTM/campaign details even for anonymous visitors. A visitor matched to a contact who has paid also carries that person's money — lifetime value net of refunds and monthly run rate in integer cents, their payment and live-subscription counts, and how many connected Stripe accounts they have paid — so a customer browsing your pricing page is distinguishable from a stranger; the field is absent for anyone who has never paid. Returns everyone with a live open-tab lease followed by the most-recently-seen visitors up to the limit, regardless of how long ago they left. Read-only.
Bot traffic visibility (tracking.get_bot_visibility)
[READ] Report whether this workspace is currently hiding bot traffic from its visitor screens. When hideBots is true, visits whose recorded browser identity is an identified or suspected crawler, unfurler or script are left out of the Live Visitors board, the Activity Log's website visits and every count above them, and the Traffic & Sources report defaults to its Exclude bots filter. Nothing stops being collected and nothing is deleted at any setting — the evidence stays on every row, the report's estimated bot share is still measured before the filter, and turning it off restores every hidden row. Visits with no recorded browser identity are never hidden, because rows that predate user-agent capture carry none and hiding those would remove real history. Read-only: changes nothing and costs nothing.
Bots hidden (tracking.set_bot_visibility)
[ADMIN ONLY] Turn this workspace's bot-traffic filter on or off. It is remembered until it is changed again, and it applies to everyone in the workspace at once: the Live Visitors board and page, the Activity Log's website visits, every visitor count above those lists, and the Traffic & Sources report's default filter. Setting it to true hides visits whose recorded browser identity is an identified or suspected crawler, unfurler or script; setting it to false shows them again, still labelled with what they are. This changes DISPLAY only and is fully reversible — no tracking is switched off, no stored visit, page view or contact is altered or deleted, no message is sent and nothing is charged. Visits with no recorded browser identity stay visible at either setting. Owner or admin only, because it changes what a visitor total means for every teammate reading it.
List visitors (tracking.list_people)
[READ] List website visitors grouped as PEOPLE rather than browsers — one entry per resolved human, folding together every device and anonymous session stitched to them. Newest activity first, with each person's visit count, device count, and a link to their contact. contactVia says how that link was reached: "identified" means it is stored on the person (a signed token or an identify/form submission), while "friender" means it was resolved at read time from the recipient FRIENDER reported for the link they arrived on — an unverified provider claim about who a link was addressed to, not a sign-in, since a forwarded link means the reader may be somebody else. The identified filter matches only the stored kind. Read-only.
Open a visitor (tracking.get_person)
[READ] Fetch one resolved visitor (person) with their whole story across every device: totals, first-touch attribution, the individual browsers folded into them, known IP addresses, and their most recent page views and form fills. This is the 'everything this person has ever done on our sites' view behind a visitor row. contactVia says how contactId was reached: "identified" is stored on the person, "friender" was resolved at read time from the recipient FRIENDER reported for the link they arrived on — an unverified provider claim about who a link was addressed to, not a sign-in. providerReferrer names the FRIENDER account that sent that link, when the provider reported one. Read-only.
Merge visitors (tracking.merge_people)
[HIGH RISK · ADMIN ONLY] Merge two resolved visitors (people) into one, for when they are really the same human seen as two and the automatic stitching missed it. Every browser, page view and form fill from the second is moved onto the first, their counts are recombined, and the second visitor is deleted. Contacts and their timelines are untouched. This cannot be undone.
List heat maps (tracking.list_heatmap_pages)
[READ] List the pages that have a click/scroll heat map, busiest first, with view and click counts, rage-click totals, and how far down the page half of visitors reached. Heat is kept separately per screen size (mobile/tablet/desktop) because a phone and a desktop render different layouts — filter by `device` to compare like with like. Read-only, and free.
Open a heat map (tracking.get_heatmap)
[READ] Fetch one page's heat map: which elements get clicked and how often (keyed by CSS selector, so it stays correct across screen sizes), the scroll-depth curve in 5% bands, and optionally the raw click density grid. Aggregate counts only — a heat map cannot be traced back to an individual visitor. Read-only, and free.
Start a heat map over (tracking.reset_heatmap)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete one page's heat map — every click position, element count and scroll sample for it. There is no per-click history behind these totals, so this cannot be undone and the data cannot be rebuilt. The honest use is after a redesign, when the old clicks describe a layout that no longer exists. Collection continues from zero on the next visit.
List session recordings (tracking.list_replays)
[READ] List session recordings — replayable captures of what a visitor did on a tracked page — newest first, with who it was (when identified), which page, how long, and whether the recording was cut off. Filter to one site, contact, or person. Recording is opt-in per site and off by default. Read-only, and free.
Open a session recording (tracking.get_replay)
[READ] Fetch one session recording's details — who, which page, how long, how big, and when it expires — plus the link to watch it. Does NOT return the recorded events themselves: a recording is megabytes of DOM mutations that only the player can render, and it is not something a model can usefully read. Read-only, and free.
Delete a session recording (tracking.delete_replay)
[HIGH RISK · ADMIN ONLY] PERMANENTLY delete one session recording and the stored video-like event data behind it. Cannot be undone. Use it to honour a visitor's erasure request, or to drop a recording that captured something it shouldn't have.

Actions — white-label

28 operations.

White-label setup checklist (white_label.get_onboarding)
[READ] List every step a white-label agency has to complete before its clients see nothing of Chirply — their own sign-in domain, a verified sending address of their own, the plans they sell their clients, connecting their own Stripe, the Zapier decision, the App Marketplace decision, their brand, and the app-reselling offer — with each step's live done/outstanding state, the wording a person reads on the same screen, and where to go to finish it. Also reports which banner the app shell is showing in this account right now — the setup reminder, the app-reselling offer, or neither; it is never both. Reads only: it changes nothing, costs nothing, and marks nothing done.
App reseller offer (white_label.get_reseller_apps_offer)
[READ] Read the offer that lets a white-label agency resell every app Chirply has published in the App Marketplace — unlimited, to as many client workspaces as they like, under their own brand. It costs $497 per month, or $250 per month for an agency that takes it inside its 7-day introductory window; an agency that took the introductory rate keeps it permanently. Returns the price THIS agency would pay, whether that is the introductory or the list price, how long their window has left, the live list of apps the licence covers today, and whether they have already answered. Reads only — nothing is bought and nothing is charged.
Take the app reseller offer (white_label.buy_reseller_apps)
[HIGH RISK · OWNER ONLY] Take the app-reselling offer for this agency. THIS SPENDS REAL MONEY: it immediately starts a recurring subscription on the card saved to the owner's Chirply billing account at $497 per month, or $250 per month if the agency is still inside its 7-day introductory window — whichever applies is decided by the server, never by the caller, and the price is then locked to this agency permanently so it does not rise when the window closes for everybody else. In return the agency may resell every app Chirply has published in the marketplace, unlimited, to as many client workspaces as it likes, and any app Chirply publishes later is included. If there is no saved card, nothing is charged or activated and the owner can add one in Billing and retry without Chirply staff. Owner only.
Pass on the app reseller offer (white_label.decline_reseller_apps)
[ADMIN ONLY] Record that this agency does not want the app-reselling offer for now. Costs nothing, charges nothing, and is not final — the offer stays available and can be taken later, though the introductory price is only held for the length of the agency's introductory window. Its purpose is to complete the optional 'decide about reselling our apps' step in the white-label setup, so an agency that does not want it stops being asked.
Managed support status (white_label.get_managed_support)
[READ] Report whether Chirply is answering this agency's clients' support tickets, and what that costs. By default a white-label agency answers its own clients' bug reports — they arrive in the agency's 'Client reports' inbox and never reach Chirply. This add-on hands the answering back to Chirply, who reply inside the client's account under the agency's brand. Returns the current status, the monthly price this agency pays (or would pay), whether the introductory rate still applies and when that window closes. Reads only: it changes nothing and charges nothing.
Have Chirply answer client support (white_label.start_managed_support)
[HIGH RISK · OWNER ONLY] Hand this agency's client support over to Chirply. THIS SPENDS REAL MONEY: it starts a recurring subscription charged to the card already on the agency's Chirply account, at $497 per month, or $250 per month inside the 7-day introductory window — the server decides which applies and then locks that price to this agency permanently, so it does not rise when the window closes for everyone else. From then on, bug reports filed by the agency's client accounts go to Chirply's support team instead of the agency's own inbox, and are answered inside the client's workspace under the agency's brand. Any of the agency's client tickets that are still open move across immediately; closed ones stay where they were answered. Owner only.
Stop Chirply-managed support (white_label.stop_managed_support)
[HIGH RISK · OWNER ONLY] Stop paying Chirply to answer this agency's clients, and take the support desk back. Cancels the recurring subscription immediately, so billing stops, and every still-open ticket filed by this agency's client accounts moves back into the agency's own 'Client reports' inbox for them to answer; tickets Chirply already closed stay closed where they are. This is not free to undo: restarting later is a new purchase at whatever the price is on that day, and the introductory rate is NOT held. Owner only.
Your prices (white_label.list_reseller_app_prices)
[READ] List what this agency charges its own client accounts for each Chirply-published app its reselling licence covers. An app with no price is INCLUDED — the licence already paid for it, so the agency's clients install it free. Prices set here are collected on the agency's own Stripe account; Chirply takes no cut of them. Reads only — nothing is charged.
Save (white_label.set_reseller_app_price)
[ADMIN ONLY] Set what this agency's own client accounts pay for one Chirply-published app that its reselling licence covers. The client is billed on the AGENCY's own Stripe account — Chirply neither collects the money nor takes a cut of it. This does not charge anybody by itself: it changes the price the agency's clients see in the marketplace from that moment on, and a client already on a subscription keeps the price they were sold at. Set 0 to list the app as free, or use white_label.clear_reseller_app_price to make it included again. Owners and admins only.
Include it (white_label.clear_reseller_app_price)
[ADMIN ONLY] Stop charging this agency's clients for one Chirply-published app, so it goes back to being included with their account at no cost — which is the reselling licence's default. Does not cancel a subscription a client is already on; it only stops the app being sold to new clients. Owners and admins only.
Install for a client (white_label.give_app_to_client)
[ADMIN ONLY] Install a Chirply-published app into one of this agency's own client accounts at no charge, bypassing whatever price the agency's rate card sets for it. This is the other half of the reselling licence: a covered app may be sold to a client or simply handed to them. Nobody is billed and no Stripe account is touched — the client can use the app immediately. To charge for it instead, use white_label.sell_app_to_client.
Bill a client for an app (white_label.sell_app_to_client)
[HIGH RISK · ADMIN ONLY] Bill one of this agency's own client accounts for a Chirply-published app at the price on the agency's rate card. THIS SPENDS THE CLIENT'S MONEY: Stripe immediately emails them a real invoice from the AGENCY's own Stripe account, and a recurring price starts a real subscription that bills them every period until somebody cancels it. The money goes to the agency and Chirply takes no cut. The amount is read from the agency's rate card and can NOT be set here. The client owns the app once the invoice is paid, not before. To hand the app over free instead, use white_label.give_app_to_client.
How to use your own Google or Microsoft app (oauth_apps.setup_guide)
[READ · ADMIN ONLY] Explain, provider by provider, how a white-label agency registers its OWN Google or Microsoft OAuth application so its clients read the agency's name on the consent screen instead of Chirply's. Returns the ordered setup steps, the scopes the application must be allowed to request, the console to do it in, and — for each of the agency's own sign-in domains — the exact redirect URI to register. Reads only: it changes nothing and costs nothing. Note that the provider's own verification review, which can take days or weeks, is the agency's to complete; Chirply cannot do it for them.
Your own integrations (oauth_apps.list)
[READ · ADMIN ONLY] List the OAuth applications this agency has registered of its own, with the client ID, the callback domain, when the credentials were last checked and whether that check passed. Never returns a client secret. A provider missing from the list is one whose connections still run through Chirply's application, which means the agency's clients see Chirply's name when they connect. Reads only.
Save your own app credentials (oauth_apps.save)
[HIGH RISK · ADMIN ONLY] Register or replace this agency's own OAuth application for a provider. From the moment it is saved, EVERY calendar or mailbox connection made in this agency's account and in all of its client accounts runs through this application — so the agency's clients read the agency's name on the consent screen, and the agency, not Chirply, owns the provider-side setup and verification. Google credentials are checked against Google before the response returns; Microsoft's cannot be checked without a real sign-in, so a Microsoft save reports credentialsChecked false and the first connection is the test. Two consequences worth approving deliberately: every calendar already connected through a DIFFERENT application has to be reconnected by the person who owns it, because a refresh token only works against the client that minted it; and a half-finished application on the provider's side produces a broken consent screen for this agency's clients rather than a working one. The client secret is encrypted at rest and is never shown again.
Check your app credentials (oauth_apps.recheck)
[ADMIN ONLY] Ask the provider whether this agency's stored client ID and secret still authenticate, without sending anyone to a consent screen, and record the result. Works for Google only: Microsoft's token endpoint rejects the probe before it resolves the application, so a made-up Microsoft client ID and secret are indistinguishable from a correct pair and no check is attempted — it returns credentialsChecked false rather than a meaningless pass. Even for Google, a pass confirms the credentials are real and nothing more: the provider's verification review, the enabled APIs and the registered redirect URI are not visible from here. Changes nothing except the recorded check result.
Stop using your own app (oauth_apps.remove)
[HIGH RISK · ADMIN ONLY] Delete this agency's own OAuth application for a provider and fall back to Chirply's. From that moment the agency's clients see Chirply's name on the consent screen again, and every calendar or mailbox connected through the agency's application has to be reconnected. The stored client secret is destroyed and cannot be recovered — it has to be copied from the provider again to undo this.
White-label settings (white_label.get)
[READ · ADMIN ONLY] Read the agency's white-label configuration: brand display name, logo URL, favicon URL, primary/accent colors, every connected custom domain with its SSL and verification state, and the verified default identity used for branded authentication email.
Save brand (white_label.update_branding)
[ADMIN ONLY] Set the agency brand applied across the app for this account and every client account under it — display name, logo, favicon, and primary/accent colors. The logo and favicon are given here as hosted https:// URLs (in the app you can instead upload an image file and it becomes such a URL). Any field left out is cleared; on a custom domain the organization name and a neutral favicon are used instead of exposing the platform brand.
Branded app (white_label.get_app)
[READ · ADMIN ONLY] Read the agency's installable app: its name, home-screen label, icon, splash colors, and whether it is switched on. Clients install it from the agency's own custom domain — it carries the agency's branding and involves no app store, no developer account and no review. This configures the AGENCY's app, which is offered on their custom app domain. Chirply's own host installs separately as Chirply and is not affected by anything here.
Save branded app (white_label.update_app)
[ADMIN ONLY] Configure the installable app the agency's clients add to their home screen or dock from the agency's custom domain. Every field is optional and falls back to the agency's existing brand — the app is named after the white-label display name, and painted in the primary color, unless overridden here. Setting `enabled` to false withdraws the app: existing installs keep working but stop being offered. Fields left out are cleared and fall back to those defaults.
App Marketplace for your clients (white_label.get_app_marketplace)
[READ · ADMIN ONLY] Read whether the client accounts under this agency are offered the App Marketplace. Returns the effective answer, whether it was set deliberately or is still the default, and the default itself. The agency's OWN account always has the marketplace and is not affected by this setting. Read-only; changes nothing.
Let client accounts use the App Marketplace (white_label.set_app_marketplace)
[HIGH RISK · ADMIN ONLY] Decide whether the client accounts under this agency can browse and install apps from the App Marketplace. It is OFF for them by default, because the marketplace is the PLATFORM's storefront rather than the agency's: listings are published by other agencies, some apps carry the platform vendor's name, and the purchase and developer pages use the vendor's wording. TURNING IT ON MAY THEREFORE EXPOSE THE PLATFORM'S BRAND TO THE AGENCY'S OWN CLIENTS — which is the thing a white label exists to prevent — so treat it as a branding decision, not a feature flag. It changes every client account under this agency at once. The agency's own account always keeps the marketplace and is unaffected either way. Switching it OFF hides the storefront only: apps a client already installed keep running, keep their access tokens, and are never uninstalled or refunded.
What your clients call your services (white_label.get_service_labels)
[READ · ADMIN ONLY] Read the names this agency gives the third-party services it supplies and rebills — telephony, email, AI and lead data — as its client accounts see them, plus which of those services it hides from them entirely. Returns one entry per relabelable service with the supplier's real name, the agency's own name for it where one is set, and whether it is hidden. The agency's OWN account always shows the real supplier names and is not affected by any of this. Read-only; changes nothing.
Rename the services your clients see (white_label.set_service_labels)
[HIGH RISK · ADMIN ONLY] Rename — or hide — the third-party services this agency supplies and rebills, as its client accounts see them. A client's Integrations screen otherwise names the agency's own suppliers (Twilio, Mailgun, OpenRouter and so on) right next to a bill from the agency, which invites a price comparison against the wholesale rate. THIS REPLACES THE WHOLE SET: any service left out of the list goes back to showing its supplier's real name, so send every service you want named, not just the one you are changing. It changes every client account under this agency at once and takes effect immediately. Renaming is cosmetic — no connection changes, no credential moves, and nothing stops sending. Hiding removes the service's tile from client accounts, so a client can no longer connect their own account for it; a client who ALREADY connected their own keeps seeing it under the agency's name rather than losing sight of a credential they own. The agency's own account always shows the real supplier names either way. Only the services the agency buys and rebills can be renamed — providers where the client connects their own account (Facebook & Instagram, Shopify, their own Stripe, PayPal, Klaviyo, Supabase) never can, because the client signs in to that company by name and pays it directly. Spends nothing and sends nothing.
List custom domains (white_label.list_domains)
[READ · ADMIN ONLY] List the custom hostnames this agency serves the app from, with Cloudflare provisioning status, SSL state, and the CNAME target their DNS must point at. DEPRECATED: domains.list returns all of the account's domains, including these.
Connect a custom domain (white_label.connect_domain)
[HIGH RISK · ADMIN ONLY] Point a custom hostname at this account. Registers a Cloudflare custom hostname and issues an SSL certificate; the domain stays 'pending'/'verifying' until DNS is CNAMEd at the returned target. This changes where a real, public hostname resolves.
Remove a custom domain (white_label.remove_domain)
[HIGH RISK · ADMIN ONLY] Disconnect a custom hostname and delete its Cloudflare custom hostname. Anyone still visiting that domain stops reaching the app.

Actions — widgets

13 operations.

List click-to-call widgets (widgets.list)
[READ] List the organization's embeddable click-to-call widgets — the floating button that rings agents and bridges a website visitor without exposing anyone's number.
Open a widget (widgets.get)
[READ] Fetch one CLICK-TO-CALL widget with everything its builder shows: behavior and appearance settings, business hours, the agents it rings, the sites it's allowed to appear on, and the embed snippet. Click-to-call only — a live-chat widget's id returns not-found here, because its settings are a different shape entirely; read those with live_chat.get_widget.
Create a widget (widgets.create)
[ADMIN ONLY] Create a draft click-to-call widget with default copy and weekday 9–5 availability, and mint its public embed key. It renders nowhere until you add allowed sites and publish it.
Edit a widget (widgets.update)
[ADMIN ONLY] Update a widget's name, dialing behavior, which devices it shows on, and its appearance/copy settings. If the widget is published these changes are visible on the tenant's live site immediately. Omitted fields are left alone.
Publish a widget (widgets.publish)
[HIGH RISK · ADMIN ONLY] MAKE THIS WIDGET LIVE ON THE TENANT'S WEBSITE. Once published, the embed snippet renders the floating button to real visitors on every allowed origin, and a visitor pressing it will originate real calls or texts to the configured agents. Add allowed sites first — an unpublished or origin-less widget renders nowhere.
Unpublish a widget (widgets.unpublish)
[HIGH RISK · ADMIN ONLY] Take a widget off the tenant's website. The button stops rendering for visitors and the public config API stops responding for it, even where the embed snippet is still installed. Configuration is kept — publish again to restore it.
Delete a widget (widgets.delete)
[HIGH RISK · ADMIN ONLY] PERMANENTLY DESTROY a widget along with its schedule, agent routing, allowed origins and visitor session history. Any embed snippet still installed on the tenant's site stops working. This cannot be undone.
Get the embed snippet (widgets.embed_snippet)
[READ] Get the one-line script tag that installs a CLICK-TO-CALL widget — paste it into the site's HTML just before </body> — plus the widget's standalone iframe URL. The button only appears on origins added with widgets.add_origin. This returns the click-to-call loader (/embed/w.js and /w/<key>); a live-chat widget needs a DIFFERENT loader and would be inert with this one, so a chat widget's id returns not-found here — use live_chat.embed_snippet for those.
Set widget business hours (widgets.save_schedule)
[ADMIN ONLY] Set the timezone and per-day availability window for a widget. Outside these hours the widget offers a scheduled callback instead of ringing agents.
Allow a site (widgets.add_origin)
[ADMIN ONLY] Allow a website to embed a widget. The widget only renders (and its public config API only responds) on origins in this list, so add every host it should appear on — apex, www and staging.
Remove an allowed site (widgets.remove_origin)
[HIGH RISK · ADMIN ONLY] Stop a widget from rendering on a site. THIS BREAKS A WORKING INSTALL: the button vanishes from that website for real visitors on the loader's next refresh — the embed snippet is still in their HTML, so it looks installed and simply does nothing — and its public config API stops answering for that origin. Visitors on that site can no longer request a call or text. Re-adding the origin with widgets.add_origin restores it.
Add a widget agent (widgets.add_agent)
[ADMIN ONLY] Add someone for a widget to ring: either a team member (rung through their browser softphone) or an arbitrary phone number. Agents are rung in the order they were added when the dial strategy is sequential.
Remove a widget agent (widgets.remove_agent)
[ADMIN ONLY] Stop a widget ringing a particular team member or number. Removing the last agent leaves the widget with nobody to connect visitors to.

Actions — wordpress_sites

7 operations.

View WordPress hosting options (wordpress_sites.catalog)
[READ · ADMIN ONLY] Lists live DigitalOcean regions, the WordPress plans with current monthly server prices, and every domain visible through its connected Cloudflare account.
Check WordPress domain (wordpress_sites.check_domain)
[READ · ADMIN ONLY] Checks whether a hostname belongs to its connected Cloudflare account and lists existing A, AAAA, or CNAME records that a WordPress launch would replace. Makes no DNS changes.
List WordPress sites (wordpress_sites.list)
[READ] Lists this account's DigitalOcean WordPress sites, including server, DNS, HTTPS, provisioning, and cost status. Never returns passwords or OAuth tokens.
Open WordPress site (wordpress_sites.get)
[READ] Fetches one DigitalOcean WordPress site's safe operational status and provisioning history. Passwords and provider credentials are never returned.
Launch WordPress site (wordpress_sites.launch)
[HIGH RISK · ADMIN ONLY] CREATES BILLABLE INFRASTRUCTURE in its own DigitalOcean account. Creates a Droplet, paid backups when enabled, a cloud firewall, hardened WordPress, database, Redis, automatic updates, DNS records when authorized, and HTTPS. DigitalOcean bills the connected team until the site is destroyed.
Retry setup (wordpress_sites.retry)
[HIGH RISK · ADMIN ONLY] Resume a stalled or failed WordPress launch. CAN CREATE BILLABLE INFRASTRUCTURE: if the launch never got as far as creating its server, this CREATES THE DIGITALOCEAN DROPLET (plus paid backups when the site was configured with them), which DigitalOcean bills the connected team for until the site is destroyed. Only when the site already has a server does it merely re-run the bootstrap, DNS and HTTPS checks, adding no new charge — and in that case it may still write the site's DNS records at the configured hostname. Check wordpress_sites.get first: a site with no server id is the billable case.
Destroy site (wordpress_sites.destroy)
[HIGH RISK · ADMIN ONLY] PERMANENTLY DELETES the WordPress Droplet and its managed DigitalOcean firewall, stopping future server and backup charges. The website, database, and files on that server cannot be recovered unless an independent snapshot exists.

Actions — workspace

5 operations.

Export account data (workspace.export)
[READ · HIGH RISK · ADMIN ONLY] Produces a downloadable ZIP archive of this account's own business data — contacts, companies, deals, tasks, appointments, conversations and full message bodies, call metadata and transcripts, invoices and orders, forms and their responses, custom objects, the activity log and the unsubscribe/do-not-call lists — as one CSV per dataset plus a manifest.json listing row counts and everything deliberately left out. Returns a signed download URL that expires in 15 minutes, NOT the rows themselves; fetch the URL to get the file. Nothing is changed or deleted. The archive never contains provider credentials, API keys, encrypted columns, customer-facing bearer tokens, or any other account's data.
List exportable datasets (workspace.list_export_datasets)
[READ · ADMIN ONLY] Lists every dataset a workspace export can contain — the key to pass to workspace.export, the file name it lands under, its columns, and a plain-language description — together with the list of things deliberately excluded from any export and why. Reads nothing from the database and changes nothing.
Request deletion of this account (workspace.request_deletion)
[HIGH RISK · OWNER ONLY] Asks Chirply to delete this entire account and everything in it — every contact, conversation, call recording, campaign, funnel and file — after a 90-day waiting period, as described at chirply.io/legal/data-deletion. This does NOT delete anything now: it records the request, starts the clock, and can be withdrawn at any time before the window closes using workspace.cancel_deletion_request. When the window closes the deletion is permanent and there is no recycle bin. Records Chirply must keep to meet a legal, tax or accounting obligation are retained or anonymized rather than deleted — invoices, payments, payouts, signed agreements and do-not-contact entries. Export anything you want to keep first. Owner only.
Check the account deletion request (workspace.deletion_request_status)
[READ · OWNER ONLY] Reports whether this account has an open deletion request, when it was raised, whether Chirply has confirmed it, and the earliest date the account could be deleted. Reads only — it changes nothing and starts no countdown.
Cancel the account deletion request (workspace.cancel_deletion_request)
[HIGH RISK · OWNER ONLY] Withdraws an open request to delete this account, so nothing will be deleted. Safe to call at any point before the deletion actually happens; after that there is nothing to cancel. Any provider integrations that were revoked when the request was raised stay revoked and have to be reconnected — reconnecting is a normal action in Settings → Integrations. Owner only.

Where to go next

Live pricing, including the current founder price, is on the pricing page. The features page is the same catalog with diagrams, and progression is the dated log of what shipped each day.