MCP tool reference

The MCP server exposes 448 tools for Claude Desktop / Code / web. You connect the server with a single command from /settings/mcp in the app. Workspace-level token, or platform access for super-admins. See also the MCP recipes.

Platform (53) Workspace (395)

Platform tools

Cross-workspace operations. Super-admin only.

agent.*

  • agent.provision_client_complete WRITE-safe AGENT

    Provision a complete Freelance OS client workspace: workspace + admin user + Stripe Connect onboarding link + seed data + onboarding email. Returns the new workspace details. Idempotent on slug.

    scope: *
  • agent.archive_workspace DESTRUCTIVE AGENT

    Archive workspace cleanly: dry-run export, cancel Stripe subscription, soft-archive in DB, notify owner. Multi-step with partial-failure surfacing.

    scope: *

platform.*

  • list_workspaces READ

    List all workspaces with billing + member count + last activity. Filter by status (active/archived/past_due/comped/all), plan, or text query on name/slug.

    scope: *
  • get_workspace READ

    Get full workspace detail by slug: owner, billing, Stripe Connect, domains, theme, member count.

    scope: *
  • list_members READ

    List workspace members. If workspace_id is provided, scoped to that workspace; otherwise returns all members across workspaces.

    scope: *
  • get_member READ

    Get a member by user_id + workspace_id, with profile data joined.

    scope: *
  • list_audit READ

    List recent kernel_activity entries across or within a workspace. since: ISO date (default last 24h).

    scope: *
  • get_billing_overview READ

    Aggregate billing metrics across all workspaces: MRR, ARR, active subscriptions count, past_due count, comped count.

    scope: *
  • list_domains READ

    List custom domains across workspaces.

    scope: *
  • list_themes READ

    List active workspace themes.

    scope: *
  • list_integrations READ

    List per-workspace integrations (Stripe Connect, Google, Meta, LinkedIn, TikTok).

    scope: *
  • get_system_health READ

    Aggregate system health: pending Apify, failed studio publish, pending JIT approvals, recent error count.

    scope: *
  • list_plans READ

    List all billing plans (id, name, monthly_price_cents, currency).

    scope: *
  • list_billing_accounts READ

    List Billing Accounts (a user owns N billing accounts, each paying for N workspaces). Each BA owns one Stripe customer + card and may pay for multiple workspaces. Filter by has_card (BAs with a Stripe customer attached) or text query on owner email.

    scope: *
  • get_billing_account READ

    Get a Billing Account by id or by owner_user_id. Returns the BA row + the Stripe payment method (brand/last4/exp) + every workspace billed by this BA with plan + subscription status.

    scope: *
  • list_waitlist READ

    List signups in the waitlist (status, source, created_at).

    scope: *
  • search_global READ

    Cross-workspace text search across workspaces, members, contacts (top 5 of each).

    scope: *
  • create_workspace WRITE-safe

    Create a new workspace via create_workspace_for_owner_v2_with_domains RPC. Requires existing owner user_id.

    scope: *
  • update_workspace_identity WRITE-safe

    Update workspace name, brand_color, icon_url, logo_url.

    scope: *
  • set_workspace_plan WRITE-safe

    Change the billing plan for a workspace (updates workspaces.plan only; Stripe subscription change is separate).

    scope: *
  • add_member WRITE-safe

    Invite an existing user as a member of a workspace.

    scope: *
  • update_member_role WRITE-safe

    Change a member role within a workspace.

    scope: *
  • set_platform_flag WRITE-safe

    Set a global platform feature flag (Hypervisor-scoped). Affects ALL workspaces.

    scope: *
  • connect_integration WRITE-safe

    Mark a workspace integration as connected (stores credentials elsewhere — this only flips status).

    scope: *
  • add_domain WRITE-safe

    Add a custom domain to a workspace (unverified until DNS check passes).

    scope: *
  • archive_workspace DESTRUCTIVE

    Soft-archive a workspace (sets archived_at). Reversible. Stripe subscription stays active until manually cancelled.

    scope: *
  • delete_workspace DESTRUCTIVE

    HARD delete a workspace via cascade. Irreversible. Use archive_workspace first.

    scope: *
  • delete_member DESTRUCTIVE

    Remove a member from a workspace. Their auth.user row is preserved.

    scope: *
  • purge_audit_older_than DESTRUCTIVE

    Hard-delete kernel_activity rows older than the given ISO date. Cannot be undone.

    scope: *
  • force_billing_cancel DESTRUCTIVE

    Force-mark a workspace billing as cancelled (workspace_billing.stripe_subscription_status = canceled). Stripe must be cancelled separately.

    scope: *
  • revoke_token DESTRUCTIVE

    Revoke an MCP token by id. Sets revoked_at. Subsequent calls return 401.

    scope: *
  • replay_webhook DESTRUCTIVE

    Enqueue a webhook replay for a workspace + provider (Stripe/Meta/...).

    scope: *
  • list_partners READ

    List partners of the platform partner program (Freelance OS). Optional status filter (pending/approved/rejected/suspended). Returns name, email, company, referral code, status and tier.

    scope: *
  • list_partner_tiers READ

    List the tiers of the platform partner program with commission type, rate (bps) and model (referral/agency_override).

    scope: *
  • get_partner_referrals READ

    List the referrals attributed to a partner, with status counts (clicked/signed_up/trial/converted/churned).

    scope: *
  • get_partner_commissions READ

    List a partner commission ledger with totals by status (pending/approved/paid/clawed_back). Amounts in cents.

    scope: *
  • get_partner READ

    Get the full admin detail for one partner: profile, application (channels/audience), tier, referrals (with attribution channel), commissions, and summary counts/totals. Mirror of the Hypervisor partner fiche.

    scope: *
  • get_partner_kit READ

    Get the partner kit copy (markdown) shown/downloaded on the partner program Resources page. Returns the markdown and last-updated timestamp.

    scope: *
  • approve_partner WRITE-safe

    Approve a pending partner and assign a tier. Activates referral attribution and commissions for that partner.

    scope: *
  • set_partner_tier WRITE-safe

    Change the tier assigned to a partner (manual override).

    scope: *
  • reject_partner WRITE-safe

    Reject a partner application.

    scope: *
  • suspend_partner WRITE-safe

    Suspend an approved partner (stops new attributions; existing commissions unaffected).

    scope: *
  • set_partner_note WRITE-safe

    Set the internal admin note on a partner (stored in profile JSONB, admin-only, never shown to the partner). Empty string clears it. Capped at 2000 chars.

    scope: *
  • set_partner_kit WRITE-safe

    Replace the partner kit copy (markdown) shown/downloaded on the partner program Resources page. The new content takes effect immediately.

    scope: *
  • reactivate_partner WRITE-safe

    Reactivate a suspended partner (status → approved). The previously assigned tier is preserved.

    scope: *
  • reconsider_partner WRITE-safe

    Move a rejected partner application back to pending so it can be reconsidered.

    scope: *
  • archive_partner WRITE-safe

    Archive a partner (soft-hide from the default list). Reversible. Does not affect referrals or commissions.

    scope: *
  • unarchive_partner WRITE-safe

    Unarchive a partner (restore it to the default list).

    scope: *
  • delete_partner DESTRUCTIVE

    Permanently delete a partner. Refused if the partner has any referral or commission (use archive instead). Intended to purge test/spam applications.

    scope: *
  • platform.media.workspace_stats READ

    Cross-workspace media library usage (count, archived, bytes, AI generated, quota, last upload).

    scope: *
  • platform.media.orphans READ

    List media items with zero recorded usage older than N days. Sorted by size desc.

    scope: *
  • platform.media.set_quota WRITE-safe

    Set storage_quota_bytes on a workspace. Pass null to remove the quota (unlimited).

    scope: *
  • platform.media.purge_workspace DESTRUCTIVE

    Hard-delete all media_items + storage objects archived more than N days ago for a given workspace. Irreversible.

    scope: *

Workspace tools

Scoped to a single workspace through an OAuth token.

ads.*

  • ads.campaigns.list READ

    List Ads campaigns.

    scope: ads:read
  • ads.campaigns.get_perf READ

    Get performance metrics for an Ads campaign (spend, impressions, clicks, leads).

    scope: ads:read
  • ads.lead_funnel READ

    End-to-end lead-quality funnel for the workspace ads over a configurable window. Returns the aggregated counts at each step: leads submitted, calls booked, contacts who paid, and total revenue in cents. Lets an agent answer "what's my ads ROI" without poking at each table.

    scope: ads:read
  • ads.launches.list READ

    List multi-platform launch groups. Each launch fanned a single brief into 2-4 platform campaigns. Returns the launch_group_id, top-level name, abstract objective, platform count, and total daily budget across platforms.

    scope: ads:read
  • ads.launches.get READ

    Get a single multi-platform launch group with its sub-campaigns + 7-day aggregated metrics (impressions, clicks, spend, conversions) across all platforms.

    scope: ads:read
  • ads.campaign.update WRITE-safe

    Update Ads campaign fields.

    scope: ads:write
  • ads.campaign.pause WRITE-safe

    Pause an Ads campaign.

    scope: ads:write
  • ads.campaign.resume WRITE-safe

    Resume a paused Ads campaign.

    scope: ads:write
  • ads.campaign.delete DESTRUCTIVE

    Delete an Ads campaign.

    scope: ads:delete

agent.*

  • agent.weekly_studio_publish WRITE-safe AGENT

    Publish all approved Studio drafts to the requested channels (LinkedIn / TikTok / Instagram / YouTube). Limits per channel. Continues on partial failure and returns per-channel breakdown.

    scope: *
  • agent.process_inbound_lead WRITE-safe AGENT

    Process an inbound lead (LinkedIn URL or email): enrich via Apollo + Apify, upsert contact, create opportunity deal, enroll in welcome sequence. Continues on best-effort failures (e.g., Apify timeout).

    scope: *
  • agent.monthly_invoice_run DESTRUCTIVE AGENT

    Generate + send recurring monthly invoices for all active retainer clients in a workspace. Idempotent on (workspace_id, billing_month). dry_run=true returns the list without creating invoices.

    scope: *
  • agent.seo_autopilot WRITE-safe AGENT

    Run the SEO content autopilot for this workspace: refill the topic pool from Search Console opportunities, queue topics to the weekly cadence, generate the queued articles, and (only if the workspace enabled auto-publish) approve and publish them. Returns the counts. Does nothing if the autopilot is disabled.

    scope: seo:write
  • agent.relance_impayes DESTRUCTIVE AGENT

    For each overdue invoice : classify severity (1=light, 2=medium, 3=collections), pick template, send relance email.

    scope: *
  • agent.bulk_enrich_contacts WRITE-safe AGENT

    Queue LinkedIn profile scrapes (Apify) for contacts in bulk. Filter by lifecycle_stage or list of ids. Idempotent: skips contacts that already have an in-flight scrape.

    scope: *
  • agent.daily_briefing READ AGENT

    Aggregate yesterday : new contacts/deals/publications/payments/inbox. Returns markdown briefing.

    scope: *
  • agent.send_dm_in_voice WRITE-safe AGENT

    Draft a DM in the user's voice profile and deposit it as a suggested reply in the inbox thread (human validates/sends).

    scope: *

agents.*

  • agents.get_run READ

    Get the status and result of a background agent run dispatched in this workspace.

    scope: agents:read
  • agents.dispatch WRITE-safe

    Hand off a task to a background agent in this workspace. Returns a run_id. The agent runs asynchronously with access to workspace data and tools; poll agents.get_run for its status and result. Use mode "suggest" (default, read-only analysis) or "act" (the agent may perform write-safe actions).

    scope: agents:dispatch

ai.*

  • ai.set_instructions WRITE-safe

    Set the workspace's global AI instructions (Cerveau IA — the voice layer prepended to every generation: DMs, posts, pages, emails). language is an optional forced language (empty = adapt to the audience). enabled=false turns the layer off entirely. Saving the platform default unchanged clears the override so the workspace keeps following future default updates.

    scope: settings:write

analytics.*

  • analytics.summary READ

    Cross-channel business summary over a window: ads spend + lead funnel (leads → calls → revenue) + booking outcomes + total revenue. Returns derived ratios (CPL, CAC, close rate, ROAS, blended ROI). The one-call tool to answer 'comment tourne le business ce mois'.

    scope: analytics:read
  • analytics.calls READ

    Voice call analytics over a window (7d/30d/90d/ytd): calls this period vs the previous one (by status) plus bookings generated. Complements analytics.summary with the calling channel.

    scope: analytics:read
  • analytics.conversations READ

    Inbox / conversation analytics over a window: volumes, response times and outcomes per channel. The DM + messaging view of the business.

    scope: analytics:read
  • analytics.links READ

    Tracked-link analytics over a window: clicks per short link (the /r/<code> redirects) so you can see which shared links pull. Useful to answer "which of my links are working".

    scope: analytics:read
  • analytics.traffic READ

    Website traffic KPIs over the last N days: sessions, visitors, conversions and revenue tracked on the workspace site. The audience view (distinct from analytics.summary, which is the ads → leads → cash funnel).

    scope: analytics:read
  • analytics.exec_summary READ

    Executive analytics summary over a window (7d/30d/90d/ytd): the top-line health metrics for the workspace in one call.

    scope: analytics:read
  • analytics.funnel READ

    Conversion funnel stages over a window (7d/30d/90d/ytd): the volume at each step (visitors → leads → calls → customers) so you can see where prospects drop off.

    scope: analytics:read
  • analytics.geo READ

    Geographic distribution of the workspace audience over a window (7d/30d/90d/ytd): sessions/visitors by country. Answers "where is my traffic coming from".

    scope: analytics:read

api_keys.*

  • api_keys.list READ

    List API keys (fos_sk_live_...) for the current workspace. Returns metadata only — plaintext tokens are never readable after creation.

    scope: api_keys:read
  • api_keys.create DESTRUCTIVE

    Create a long-lived API key for the current workspace. The plaintext token is returned ONCE in this response — store it immediately. Scopes default to ["read:*"] and are listed explicitly, e.g. ["read:*", "write:contacts"]; the "*" wildcard is refused. Pass site_id to mint a key that speaks for one site, which is what the /v1/end-user routes require.

    scope: api_keys:write
  • api_keys.revoke DESTRUCTIVE

    Revoke an API key by id. Sets revoked_at = now. Subsequent calls with the revoked token return 401. Idempotent.

    scope: api_keys:write

autonomy.*

  • autonomy.get READ

    Get the copilot's autonomy policy for this workspace: mode (observe/propose/scoped/autonomous), which domains it may act on alone, which always need approval, the daily autonomous spend cap, cadence and report channel. Returns a fail-closed default (propose) if none is configured.

    scope: autonomy:read
  • autonomy.set WRITE-safe

    Set the copilot's autonomy policy — HOW MUCH the copilot may do on its own. mode: observe (never acts), propose (always asks first), scoped (acts alone only on auto_domains), autonomous (acts alone except always_confirm_domains). auto_domains/always_confirm_domains are module prefixes (e.g. 'email','contacts'). daily_spend_cap_cents bounds autonomous spending (0 = none). High-stakes domains (billing, payments, counsel, team) always need approval regardless. Only change this at the user's explicit request.

    scope: autonomy:write

billing.*

  • billing.get_subscription READ

    Get the current Freelance OS subscription state for this workspace: plan, status, trial_end, period end, cancel_at_period_end.

    scope: billing:read
  • billing.get_usage READ

    Get current-period usage summary (service, included quota, used, estimated overage cost) for this workspace.

    scope: billing:read
  • billing.get_account READ

    Get the Billing Account paying for this workspace (a user owns N billing accounts, each paying for N workspaces). Returns owner, Stripe customer, payment method (brand/last4/exp). The cross-workspace list of workspaces billed by the same BA is only returned to the BA owner (viewer_is_owner=true); guests see only the current workspace.

    scope: billing:read
  • billing.list_my_accounts READ

    List the current user's own Billing Accounts (a user owns N accounts, one per paying entity; each pays for N workspaces). Returns id, name, billing_email, whether a card is on file, and the count of workspaces billed by each. Use billing.create_account / rename_account / assign_workspace / delete_account / open_account_portal to manage them.

    scope: billing:read
  • billing.upgrade_checkout WRITE-safe

    Create a Stripe Checkout session to upgrade this workspace to Pro (14-day trial, CB required). Returns the hosted Checkout URL — open it in a browser to complete the payment.

    scope: billing:write
  • billing.open_portal WRITE-safe

    Open a Stripe Customer Portal session for this workspace (update card, change plan, cancel). Returns the portal URL.

    scope: billing:write
  • billing.open_user_portal WRITE-safe

    Open a Stripe Customer Portal session for the current user's Billing Account (cross-workspace : every subscription paid by the same card is manageable from one portal). Use this when the user wants to update their card once for all workspaces they own.

    scope: billing:write
  • billing.create_account WRITE-safe

    Create a new Billing Account for the current user (one per paying entity — e.g. a company). A user owns N billing accounts, each with its own Stripe customer + card, each able to pay for N workspaces. Returns the new account id.

    scope: billing:write
  • billing.rename_account WRITE-safe

    Rename one of the current user's Billing Accounts. Owner-only. Name is 2-80 chars.

    scope: billing:write
  • billing.assign_workspace WRITE-safe

    Assign the CURRENT workspace to one of the user's Billing Accounts (changes which entity pays for it). The user must own both the workspace and the account. To move another workspace, switch to it first. Refused while the workspace has an active subscription — cancel it first (moving a live Stripe subscription across customers is not done here).

    scope: billing:write
  • billing.delete_account WRITE-safe

    Delete one of the current user's Billing Accounts. Owner-only. Refused while any workspace is still billed by it (reassign them first). The Stripe customer is preserved so historical invoices stay reachable.

    scope: billing:write
  • billing.open_account_portal WRITE-safe

    Open a Stripe Customer Portal session for a SPECIFIC Billing Account of the current user (manage/add its card, billing address). Owner-only. Ensures the Stripe customer first, so it works for a brand-new account too. Returns the portal URL.

    scope: billing:write

booking.*

  • booking.revenue_attribution READ

    Returns revenue attribution for bookings over a period: total bookings, completed, cancelled, no-show, attributed revenue from contacts who had a booking + a succeeded transaction in the window. The killer business metric for a freelance dev who lives on calls → sales.

    scope: booking:read
  • booking.closer_performance READ

    Per-rep sales performance (the closer cockpit): leads captured, bookings, show rate, close rate, cash collected and commission earned over a period, plus workspace totals. Answers 'how are my closers doing' / 'who is converting'. Cash is attributed by matching a paid transaction to the rep's assigned prospect.

    scope: booking:read
  • booking.event_types.list READ

    List bookable event types in the workspace.

    scope: booking:read
  • booking.bookings.list READ

    List bookings (filterable by status, since).

    scope: booking:read
  • booking.bookings.list_detailed READ

    Paginated detailed list of bookings with invitee name / email / timezone / linked event type / host. Use this when the simple list does not give enough context.

    scope: booking:read
  • booking.bookings.get READ

    Get a single booking owned by the calling host: status, invitee, the linked event type, the meeting link and the scheduled window. Returns not_found for another host's booking.

    scope: booking:read
  • booking.pages.list READ

    List the workspace's booking pages (the multi-page model): slug, display name, display mode (person/entity), assignment mode (fixed/round_robin/routing), whether it's public, and the site it's attached to. Use to answer 'what booking pages do I have'.

    scope: booking:read
  • booking.pages.get READ

    Get a single booking page by its id, including its attached event type ids (the meeting types offered on that page). Returns not_found for a page owned by another workspace.

    scope: booking:read
  • booking.event_type.update WRITE-safe

    Update a booking event type (name, duration, active state).

    scope: booking:write
  • booking.pages.create WRITE-safe

    Create a booking page (multi-page model) with just a slug + display name; everything else (bio, avatar, display/assignment mode, visibility, attached event types) defaults and is set afterwards with booking.pages.update. New pages default to person / fixed and are NOT public. The slug must be unique in the workspace. Returns the new page id.

    scope: booking:write
  • booking.pages.update WRITE-safe

    Update a booking page's identity (display name, bio, avatar), its display mode (person/entity), assignment mode (fixed/round_robin/routing), whether it's public, and the site it's attached to (site_id, or null for a direct link). The site is verified to belong to this workspace. Returns not_found for a page owned by another workspace. Use booking.page.set_event_types to change the offered meeting types.

    scope: booking:write
  • booking.page.set_event_types WRITE-safe

    Replace the list of meeting (event) types offered on a booking page, in the given order. Any event type id that does not belong to this workspace is silently dropped, never attached. Pass an empty list to clear them all. Returns not_found for a page owned by another workspace.

    scope: booking:write
  • booking.event_type.delete DESTRUCTIVE

    Delete one of the calling host's booking event types. Irreversible.

    scope: booking:delete
  • booking.pages.delete DESTRUCTIVE

    Delete a booking page (multi-page model) by its id. The page is a surface only, never referenced by bookings, so deleting it orphans no appointment. Scoped to the calling workspace: returns not_found for a page owned by another workspace. Irreversible.

    scope: booking:write
  • booking.availability.get READ

    Get the calling user's booking availability: the weekly recurring rules (weekday + start/end + timezone) and any date overrides (closed days / special hours). Scoped to the caller's own calendar.

    scope: booking:read
  • booking.availability.set_rules WRITE-safe

    Replace the calling user's weekly recurring availability with a new set of rules (each: weekday 0-6 where 0=Sunday, start_time and end_time as 'HH:MM'). This OVERWRITES all existing weekly rules. Scoped to the caller's own calendar.

    scope: booking:write
  • booking.availability.add_override WRITE-safe

    Add a date override to the calling user's calendar: either close a specific date (is_closed=true) or set special hours (is_closed=false + start_time/end_time 'HH:MM'). Scoped to the caller's own calendar.

    scope: booking:write
  • booking.availability.delete_override WRITE-safe

    Remove a date override from the calling user's calendar by its id. Scoped to the caller's own calendar.

    scope: booking:write
  • booking.cancel WRITE-safe

    Cancel a confirmed booking by its id (find it via booking.bookings.list first). Runs the full flow: marks it cancelled, removes the calendar event, and emails the invitee the cancellation. Scoped to the caller's own calendar. Provide a short reason when the user gives one. Irreversible.

    scope: booking:write
  • booking.mark_status WRITE-safe

    Mark a past booking as 'no_show' (the invitee didn't show) or 'completed' (the call happened), by its id. Find it via booking.bookings.list. Scoped to the caller's own calendar. No email is sent. Use booking.cancel (not this) to cancel an upcoming booking.

    scope: booking:write

brand.*

  • brand.save_theme_wizard WRITE-safe

    Save the workspace's design system in one call: vibe preset + accent color + typography + radius + density. Compiles the full token bundle (color/font/radius/shadow + layout) and writes it to workspace_theme. Mirrors the accent into workspaces.brand_color.

    scope: settings:write

business.*

  • business.coupons.delete DESTRUCTIVE

    Hard-delete a coupon (workspace-scoped). Refused if the coupon has already been redeemed, to preserve transaction history — pause it instead. Irreversible.

    scope: business:delete
  • business.coupons.list READ

    List discount coupons for the workspace: code, discount type/value, redemption counts, validity window and status. Answers "what promo codes do I have".

    scope: business:read
  • business.referral.overview READ

    Referral program overview: the program config (status, rewards, payout trigger) plus aggregate counts of referral events by status and pending payouts. Answers "how is my referral program doing".

    scope: business:read
  • business.referral.leaderboard READ

    Referral leaderboard: per-referrer visits, signups, conversions, revenue and reward over the program's full history, sorted by reward/conversions/visits/signups/revenue. Answers 'who are my top referrers'.

    scope: business:read
  • business.coupons.create WRITE-safe

    Create a discount coupon for the workspace. code is normalized to UPPERCASE (unique per workspace). discount_type: 'percentage' (discount_value = 0-100), 'fixed_amount' (discount_value = amount in the currency's smallest unit, e.g. 2000 = 20€), or 'free_trial'. Created as 'draft' by default — set status:'active' to make it usable right away. Optional max_redemptions and valid_until (ISO date). Answers 'create a promo code'.

    scope: business:write
  • business.coupons.update WRITE-safe

    Update an existing coupon by id (workspace-scoped). Any provided field is patched; omit a field to leave it unchanged. Use status to activate ('active'), pause ('disabled') or revert to 'draft'. Answers 'change / activate / pause a promo code'.

    scope: business:write
  • business.referral.update_program WRITE-safe

    Update the workspace referral program config: status ('active' / 'paused' / 'archived'), referrer reward (cash cents or percentage), referee reward, payout trigger, cookie window and minimum payout. Creates the program if it doesn't exist yet. Answers 'set up / change my referral program'.

    scope: business:write

calendar.*

  • calendar.agenda READ

    The workspace agenda for a period: every time-anchored item merged and sorted — tasks & deadlines due, scheduled meetings, scheduled or to-review content posts, people to call, follow-ups, invoices due, webinars. USE THIS for 'what's on my calendar / what's coming up this week / what's due'. Returns only the domains the caller can read.

    scope: calendar:read

classes.*

  • classes.create WRITE-safe

    Create a named reusable style class (Webflow-style). Give it a name and an optional BlockStyle (base/hover/focus/active/sm/md/lg). Returns the new class id. Apply it to elements with classes.apply, then classes.update edits it once for every element that references it.

    scope: pages:write
  • classes.list WRITE-safe

    List the workspace style classes (id, name, style, updated_at), newest-edited first.

    scope: pages:write
  • classes.update WRITE-safe

    Edit a style class — THIS is the edit-once-updates-all path. Change its name and/or its BlockStyle; every element that references it follows at the next render. At least one of name/style must be given.

    scope: pages:write
  • classes.delete WRITE-safe

    Delete a style class. It detaches automatically: ids left on elements are ignored at render (no rule emitted) and cleaned at the next page save.

    scope: pages:write
  • classes.apply WRITE-safe

    Apply a class to one element block: appends the class id to that block's classIds (idempotent, order preserved, capped at 20). The block must be an `element` in the same workspace. Mutates the draft; the live page changes on the next publish.

    scope: pages:write

collections.*

  • collections.list READ

    List this workspace's content collections with their id, name, public slug and status.

    scope: collections:read
  • collections.get READ

    Get one collection with its ordered fields (the schema). Resolve by id or slug.

    scope: collections:read
  • collections.records READ

    List records (entries) of a collection with their data payload. Filter by status.

    scope: collections:read
  • collections.plans READ

    List this workspace's end-user subscription plans (name, price, cadence, status, whether synced to Stripe).

    scope: collections:read
  • collections.subscriptions READ

    List this workspace's end-user subscriptions with the client email, plan name and status (who is subscribed to what).

    scope: collections:read
  • collections.revenue READ

    This workspace's end-user recurring revenue: MRR by currency (yearly plans normalized to a monthly amount) plus active, trialing, past-due and ending-soon subscription counts.

    scope: collections:read
  • collections.create WRITE-safe

    Create a DRAFT content collection with its fields (the schema). Never auto-publishes — call collections.set_status to publish. Mark one field is_title for the display name.

    scope: collections:write
  • collections.set_status WRITE-safe

    Publish, unpublish (back to draft) or archive a collection.

    scope: collections:write
  • collections.add_record WRITE-safe

    Add an entry to a collection. `data` is keyed by field key and validated against the schema. Created as a draft unless status is set.

    scope: collections:write
  • collections.set_record_status WRITE-safe

    Publish, unpublish (back to draft) or archive a collection entry.

    scope: collections:write
  • collections.create_plan WRITE-safe

    Create an end-user subscription plan for this workspace's built app. Syncs a recurring Stripe Price on the workspace's connected account when Stripe is connected (otherwise the plan is created but not yet subscribable).

    scope: collections:write
  • collections.set_plan_status WRITE-safe

    Archive or reactivate an end-user subscription plan. Archived plans stay for history but disappear from the app pricing (only active plans are public).

    scope: collections:write
  • collections.update_plan_pricing WRITE-safe

    Change an end-user plan's price, currency or cadence. A Stripe Price is immutable, so this mints a NEW Price and repoints the plan at it: existing subscribers keep their price, new checkouts use the new one. amount_cents is in the smallest currency unit (e.g. 2500 = 25.00 EUR).

    scope: collections:write

contacts.*

  • contacts.list READ

    List contacts in the current workspace, filterable by lifecycle_stage / source / q (free text) / country / city / role (job title or headline) / company / icp_score_min / icp_score_max / has_linkedin / has_email / created_after / created_before (ISO). Returns the matching rows (with company / role / country / icp_score). To answer "how many" use contacts.count instead — do NOT page through this and tally.

    scope: contacts:read
  • contacts.count READ

    Count contacts matching a structured filter (lifecycle_stage / source / q (free text) / country / city / role (job title or headline) / company / icp_score_min / icp_score_max / has_linkedin / has_email / created_after / created_before (ISO).) WITHOUT returning the rows. THE tool for "how many contacts are <criteria>" (e.g. developers in France with icp_score >= 70). One call, exact count — never list + tally in your head.

    scope: contacts:read
  • contacts.get READ

    Get a contact by id (must belong to current workspace). Returns the billing identity invoices are built from (company, SIRET, VAT number, postal address), which the list tools do not carry.

    scope: contacts:read
  • contacts.get_360 READ

    Prospect 360 view: contact (incl. icp_score) + recent conversations + bookings + audits + deals + the AI outreach brief (hook/pain/belief/CTA + facts used).

    scope: contacts:read
  • contacts.search READ

    Search contacts by email/name/linkedin substring.

    scope: contacts:read
  • contacts.hottest READ

    The contacts to act on first, ranked by a composite intent score (replies/bookings/email opens + funnel stage + ICP fit + recency), top N in ONE call. mode 'hot' = engaged contacts to close; 'cold_fit' = high ICP fit not yet engaged, to prospect. USE THIS for 'who should I contact first / most likely to buy' — never loop contacts.get_360. Each contact returns hotness, why_hot, the cached opener (the message to send) + opener_status, the channel + linkedin_url/email, and the score components. To act: present the opener and offer a ui.link_action button to the contact's linkedin_url (assisted send — the user reviews and sends; never claim you sent it).

    scope: contacts:read
  • contacts.paying_customers READ

    Lists contacts who paid in the period, sorted by total amount desc. Joins prospects.email with transactions.email to recover the contact_id when present. Useful for an agent answering 'qui m'a acheté' or for triggering follow-up workflows.

    scope: contacts:read
  • contacts.interactions.list READ

    List the logged interactions (calls, emails, meetings, notes...) for a contact, most recent first. The timeline written by contacts.log_interaction. USE THIS for 'what's the history with X / when did I last talk to Y'.

    scope: contacts:read
  • contacts.log_interaction WRITE-safe

    Log a real interaction with a contact on their timeline (a call, email, meeting, message...). USE THIS for 'note that I called X / log my meeting with Y' — it appends a timestamped entry, it does NOT overwrite the contact's notes. kind defaults to 'note'. occurred_at defaults to now (pass an ISO date for a past interaction). Find the contact id via contacts.search first.

    scope: contacts:write
  • contacts.upsert WRITE-safe

    Create or update a contact (by id, email, or linkedin_url), including the billing identity invoices are built from: company, SIRET, VAT number and postal address.

    scope: contacts:write
  • contacts.enrich WRITE-safe

    Queue a LinkedIn profile scrape for a contact (via Apify). Idempotent: reuses an in-flight job if one already exists.

    scope: contacts:write
  • contacts.tag WRITE-safe

    Add a tag to a contact.

    scope: contacts:write
  • contacts.delete DESTRUCTIVE

    Hard-delete a contact and all related data. Irreversible.

    scope: contacts:delete

conversations.*

  • conversations.transcripts.list READ

    List call recordings for this workspace: Fathom meetings and Twilio voice calls, unified. Each item carries provider, summary, duration, recording URL and recording id.

    scope: conversations:read
  • conversations.transcripts.get READ

    Get a call recording transcript by id (summary + Fathom turns or diarized voice segments). id is the transcript id returned by conversations.transcripts.list.

    scope: conversations:read
  • conversations.note.create WRITE-safe

    Add a note to a conversation transcript.

    scope: conversations:write

copilot.*

  • copilot.briefing READ

    The proactive 'what should I do now' brief: the top prioritized actions across hot contacts to reach, upcoming bookings to prep, open tasks, and unpaid invoices to chase. USE THIS for 'what should I do today / give me the rundown / where are we'. Each item carries a count + the tool to act on it. Returns only what the caller is allowed to see.

    scope: agents:read
  • copilot.plan.preview READ

    Decompose a multi-step plan against the workspace autonomy policy BEFORE executing it. Give the ordered actions you intend to run (tool_name + domain + a short label). Returns, per action, whether it runs automatically, is covered by a single up-front plan approval (bulk), keeps its own dedicated approval (high-stakes: billing/payments/counsel/team), or is blocked by the current policy. Also returns the ready-to-show approval text grouping the bulk actions. USE THIS before running a playbook or any chain of writes, so the user approves ONCE instead of one modal per step. This is a preview only: it changes nothing.

    scope: autonomy:read
  • copilot.ask WRITE-safe

    Ask the workspace copilot a question and get the full reply synchronously. Runs with read-only access to the workspace data + tools. Optionally attach images or PDFs by URL — the copilot reads them (vision / document). For long autonomous work that may write, use agents.dispatch instead.

    scope: agents:dispatch

counsel.*

  • counsel.legal_entity.get READ

    Read the workspace's issuer identity: the legal name, form, SIREN/SIRET, VAT number, registered address, IBAN/BIC and default payment terms that MUST appear on every invoice, quote and contract it emits. Returns `configured` (has the entity ever been filled in) and `missing_for_invoicing` (the required fields still empty). CALL THIS BEFORE creating or sending an invoice, quote or contract: the documents are legally invalid without it, and nothing else in the API will warn you. Also the place to read the IBAN when a client asks how to pay by bank transfer.

    scope: counsel:read
  • counsel.quotes.list READ

    List Counsel quotes (devis).

    scope: counsel:read
  • counsel.invoices.list READ

    List Counsel invoices (factures).

    scope: counsel:read
  • counsel.invoice.einvoicing_status READ

    Get the e-invoicing (Plateforme Agréée) transmission status of a Counsel invoice.

    scope: counsel:read
  • counsel.received.list READ

    List supplier invoices received via the Plateforme Agréée (inbound e-invoicing).

    scope: counsel:read
  • counsel.revenue.summary READ

    Total revenue from succeeded transactions over a window. Breaks down by week and gives the top contributing customers (email + total). Lets an agent answer 'combien j'ai encaissé ce mois' in one call.

    scope: counsel:read
  • counsel.contracts.get READ

    Get one Counsel contract with its body, signers and linked contact.

    scope: counsel:read
  • counsel.contracts.templates_list READ

    List contract templates available to the workspace (own + built-in presets), with their body.

    scope: counsel:read
  • counsel.contracts.preview READ

    Render a contract body with its variables resolved, as the client will read it. Pass a contract id, or raw markdown to test a draft.

    scope: counsel:read
  • counsel.legal_entity.upsert WRITE-safe

    Set or update the workspace's issuer identity used on every invoice, quote and contract: legal name, form, SIREN/SIRET, VAT number, registered address, IBAN/BIC, default payment terms. Partial update: omitted fields keep their current value, so you can fill the IBAN alone without resending the address. `legal_name` is required the first time only. SIREN, SIRET, VAT, IBAN and BIC may be passed with spaces, they are normalized. Use counsel.legal_entity.get first to see what is missing.

    scope: counsel:write
  • counsel.contract.set_payment_schedule WRITE-safe

    Set the contract's payment schedule: the instalments that each become an invoice when the contract is signed. This is how a deposit and a balance are handled, not by creating standalone invoices by hand. Each entry has a label, a kind (acompte, facture or solde), an amount in cents INCLUDING TAX, a currency and a delay in days from signature. At signature the invoices are created automatically and the first one is finalized and sent. At most one entry may have delay_days 0, otherwise two payment requests go out at once. Only on a draft contract: once sent, the client has read those terms. Pass an empty schedule to clear it. mode is the collection method, manual (a payment link per instalment) is the right one for a client paying by bank transfer.

    scope: counsel:write
  • counsel.payment.record_external_refund WRITE-safe

    Record a refund you already made OUTSIDE the payment provider: a bank transfer back to the client, a cheque, cash. No money moves here, the transfer has already left your bank. This writes the refund into the ledger, issues the credit note the client receives, and stops the payment being counted as revenue. Pass reference with the transfer or cheque number, it is what ties the line to your bank statement. Omit amount_cents to record a full refund. USE THIS for 'I refunded him by transfer'. For a card payment you want Kernel to hand back itself, use counsel.payment.refund instead.

    scope: counsel:refund
  • counsel.invoice.repair WRITE-safe

    Complete an invoice that was numbered without going through the finalization path: fills the issuer snapshot (legal name, SIRET, address, IBAN), mints its public page and its payment link, re-renders the PDF. Sends nothing. Use it on an invoice whose client says the PDF has no bank details or no way to pay. Keeps the number, the dates and the status untouched: they are what the client already received.

    scope: counsel:write
  • counsel.invoice.resend WRITE-safe

    Email an already-sent Counsel invoice again, with its PDF attached. Use it when the first send did not reach the client, or when they ask for another copy. `counsel.invoice.send` refuses an invoice that already has its number: this is the tool for that case. Answers whether the provider accepted the email.

    scope: counsel:write
  • counsel.contract.suspend_collection WRITE-safe

    Stop the upcoming automatic charges of a SIGNED contract, reversibly. Nothing is cancelled and no date is lost: the instalments keep their due dates, only the automatic charge is disarmed, and counsel.contract.resume_collection re-arms them from those same dates. This is the move while a discussion with the client is still open, before anything is decided. To end the contract for good, use counsel.contract.terminate instead.

    scope: counsel:write
  • counsel.contract.resume_collection WRITE-safe

    Re-arm the automatic charges of a contract suspended by counsel.contract.suspend_collection. Each instalment is re-armed on the due date the client signed for, never pushed forward: an instalment whose date has already passed is charged on the cron's next pass, exactly as it would have been without the suspension.

    scope: counsel:write
  • counsel.contract.link_quote WRITE-safe

    Attach a quote to a contract, or detach it by passing contract_id null. A contract can carry SEVERAL quotes: the one it was created from, plus every quote agreed later under the same framework agreement. Use this when a returning client signs a second scope under an existing contract instead of creating a new contract. Both the quote and the contract must belong to this workspace; a foreign id is refused rather than silently ignored.

    scope: counsel:write
  • counsel.invoice.record_payment WRITE-safe

    Record a payment received on an invoice OUTSIDE Stripe: a bank transfer, a cheque, cash. Pass amount_cents to record a partial payment (the invoice moves to partially_paid and keeps its balance), or omit it to settle whatever is still owed. Pass paid_at with the transfer's value date, not the day you are typing: that date is what lands in revenue and puts the amount in the right accounting period. reference stores the transfer or cheque number for later bank reconciliation. Refuses an amount larger than the remaining balance, an already-paid invoice and a cancelled one. USE THIS for 'the client paid by transfer', 'mark the deposit as received', 'they paid half'. Not for Stripe payments, which the webhook records on its own.

    scope: counsel:write
  • counsel.quote.create WRITE-safe

    Create a Counsel quote (devis) as a draft. PREFER `lines`: they carry the VAT and the detail the recipient reads. `amount_cents` alone stores the quote as HT = TTC with NO VAT, which a VAT-registered workspace cannot legally send and which will contradict a contract stating a TTC price. `body_md` is the text shown on the public quote page, the only place the client reads what is included. Amend a draft with counsel.quote.update, then send it with counsel.quote.send.

    scope: counsel:write
  • counsel.quote.update WRITE-safe

    Amend a DRAFT quote: title, lines, body, validity, linked contract. Passing `lines` replaces the whole list and recomputes HT, VAT and TTC. A sent quote is immutable, the client has already read it. Omitted fields are left untouched.

    scope: counsel:write
  • counsel.quote.send WRITE-safe

    Send a Counsel quote to the contact (status → sent).

    scope: counsel:write
  • counsel.invoice.create WRITE-safe

    Create a Counsel invoice (facture).

    scope: counsel:write
  • counsel.invoice.send WRITE-safe

    Finalize and SEND a draft Counsel invoice to its recipient: allocates the legal number, renders the PDF and emails it. Answers whether the email was actually accepted by the provider. Only on a draft: an invoice already sent keeps its number, resend it from the invoice screen.

    scope: counsel:write
  • counsel.contracts.create WRITE-safe

    Create a draft contract. Start from a template (template_head_id) or pass body_md. Signers can be added now or later; sending stays a manual step in the app.

    scope: counsel:write
  • counsel.contracts.update WRITE-safe

    Update a DRAFT contract (title, body, client, signers). Sent or signed contracts are immutable. Omitted fields are left untouched; passing signers replaces the whole list. For a one-passage change use body_replace {find, replace} instead of resending the whole body: it refuses when the passage is missing or appears twice, so a stale anchor fails loudly. The stored PDF is re-rendered after any change.

    scope: counsel:write
  • counsel.contracts.save_as_template WRITE-safe

    Save a contract body as a reusable, published contract template. Variables are kept as-is so they re-resolve for the next client.

    scope: counsel:write
  • counsel.invoice.cancel DESTRUCTIVE

    Cancel a Counsel invoice (status → cancelled).

    scope: counsel:delete
  • counsel.payment.refund DESTRUCTIVE

    Refund a paid Counsel invoice through the payment provider. The money actually moves. Omit amount_cents to refund everything still refundable, or pass it for a partial refund. The credit note follows from the provider event, it is not issued here.

    scope: counsel:refund
  • counsel.contract.terminate DESTRUCTIVE

    End a signed contract: cancels every instalment left to collect and stamps the contract with the date and reason. Money already paid is untouched, refunding is a separate act (counsel.payment.refund).

    scope: counsel:delete
  • counsel.contracts.list READ

    List Counsel contracts for the workspace (number, title, status, sent_at, fully_signed_at), filterable by status. Complements counsel.quotes.list / counsel.invoices.list.

    scope: counsel:read

crm.*

  • crm.segments.list READ

    List CRM segments in the current workspace.

    scope: contacts:read
  • crm.segments.get READ

    Get a CRM segment with its member prospects.

    scope: contacts:read
  • crm.segments.create WRITE-safe

    Create a new CRM segment (manual membership).

    scope: contacts:write
  • crm.segments.create_from_query WRITE-safe

    Create a DYNAMIC CRM segment from a structured contact filter and populate it server-side in ONE call — no per-contact loop, no in-context filtering. Filter: lifecycle_stage / source / q (free text) / country / city / role (job title or headline) / company / icp_score_min / icp_score_max / has_linkedin / has_email / created_after / created_before (ISO). The filter is stored on the segment, so call crm.segments.refresh later to re-materialize it. USE THIS for "build/create a segment of <criteria>" (e.g. developers in France with icp_score >= 70). Returns the segment id + member_count.

    scope: contacts:write
  • crm.segments.refresh WRITE-safe

    Re-materialize a DYNAMIC segment from its stored filter: re-resolve matching contacts and replace the membership. Only works on segments created via crm.segments.create_from_query. Returns the new member_count.

    scope: contacts:write
  • crm.segments.add_members WRITE-safe

    Add contacts to a CRM segment (idempotent — duplicates ignored).

    scope: contacts:write
  • crm.segments.remove_members WRITE-safe

    Remove contacts from a CRM segment.

    scope: contacts:write
  • crm.segments.delete WRITE-safe

    Delete a CRM segment (membership rows cascade).

    scope: contacts:write

data.*

  • data.query READ

    Query the workspace's data with GraphQL, read-only. One call answers questions no single tool covers: filter, relate and aggregate. Coverage: contacts, deals and segments, tasks, projects and milestones, bookings and event types, invoices, quotes and revenue, conversations and messages, calls, transcripts and voice campaigns, Studio content and publications, ads, email campaigns, products, orders, purchases and subscriptions, webinars, collections, coupons, forms and submissions, reviews, media, programme and member progress, wiki, pages and sites, usage. Audience is in here too, inside a required date window: `webAudience` for Google Analytics (visits, traffic sources, countries, devices), `webAudienceHourly` for traffic by local hour (this is what answers 'visitors between 8 and 10': read `byHour` and divide by `days` for a per-day average), `searchConsole` for Search Console (clicks, impressions, position, queries), `geoVisibility` for visibility inside AI answers. For 'who should I contact first', hottestContacts ranks contacts by a live composite score (intent, pipeline, ICP fit, recency) that no filter reproduces. What stays on the analytics tools is the consolidated figure no single query rebuilds: the cross-source summary, the funnel, the geo breakdown joined with leads and revenue, source freshness, and the active-member counters. Fetch the `schemaDigest` field once for the complete field map (every root field with its args, every type with its fields, every enum), then ask for exactly the fields you need instead of guessing names. The workspace is implicit and can never be passed in. Money fields come back redacted (amountCents null, redacted true) when you lack finance permission: say so, never read it as zero. Revenue has three distinct meanings here, so revenueTimeseries requires an explicit basis. If a query is refused, the error carries a hint telling you how to rewrite it.

    scope: data:read

deals.*

  • deals.list READ

    List deals in the current workspace, filterable by stage.

    scope: deals:read
  • deals.get READ

    Get a deal by id.

    scope: deals:read
  • deals.create WRITE-safe

    Create a new deal for a contact.

    scope: deals:write
  • deals.update WRITE-safe

    Update a deal (any field).

    scope: deals:write
  • deals.move_stage WRITE-safe

    Move a deal to a new pipeline stage.

    scope: deals:write
  • deals.delete DESTRUCTIVE

    Delete a deal.

    scope: deals:delete

design.*

  • design.list READ

    List the workspace visual designs (Brand Studio / design editor) with their edit URLs. Use design.create to start a new one a user can then edit.

    scope: design:read
  • design.get READ

    Get one workspace design by id, with its edit URL.

    scope: design:read
  • design.get_doc READ

    Get a design's full editable document: its artboards and the layers on each (type, x/y/w/h, rotation, props). This is the read half of a read-modify-write edit loop — fetch it, change the layers, then send them back with design.update_doc. Returns the artboards + the edit URL.

    scope: design:read
  • design.render READ

    Render a design to PNG preview images and return their public URLs — so you can actually see the result, not just the edit link. Rasterizes every artboard server-side (one image per carousel slide / deck page), faithful to the editor's own thumbnail. Pair it after design.create_from_doc / generate / generate_carousel / update_doc to preview what you built. Returns slides[] (index + preview_url + dimensions), preview_url (first) + edit_url.

    scope: design:read
  • design.create WRITE-safe

    Create a new blank visual design in the workspace's design editor, sized for a channel, and return its edit URL. Channels: linkedin_square, linkedin_portrait, story_9x16, ad_square, one_pager_a4, wide_16x9, web_banner. The user (or another tool) then edits it in the design editor.

    scope: design:write
  • design.generate WRITE-safe

    Generate an on-brand visual design from a text intent (uses the workspace BrandContext + AI), sized for a channel, and save it. Returns the design id + edit URL for review. Channels: linkedin_square, linkedin_portrait, story_9x16, ad_square, one_pager_a4, wide_16x9, web_banner. Metered AI: needs a payment method and the design module in the plan.

    scope: design:write
  • design.from_reference WRITE-safe

    Recreate an inspiration image's LAYOUT LANGUAGE as an on-brand, editable design. A vision model studies the reference's structure (grid, hierarchy, type style, colour rhythm, image scale) and rebuilds it with THIS workspace's brand + original content. It does NOT copy logos, wordmarks, brand names or verbatim text from the source — it's an inspiration tool, not a clone. Pass a public image URL. Returns the design id + edit URL. Channels: linkedin_square, linkedin_portrait, story_9x16, ad_square, one_pager_a4, wide_16x9, web_banner. Metered AI: needs a payment method and the design module in the plan.

    scope: design:write
  • design.compare_to_reference WRITE-safe

    Visually compare a design to an inspiration image and get a MEASURED critique to converge on the layout. Renders the design, shows both to a vision model, and returns a similarity score (0-100), ranked issues, and — key for precision — adjustments[]: per element, a target { x, y, w, h } in the canvas' pixel space measured from the reference. Diff each target against the element's current box to get an exact pixel move, apply with design.update_doc, then compare again until similarity stops rising. The render may show placeholder glyphs for un-embedded fonts, so it judges POSITION and SIZE, not glyph shapes. Metered AI: needs a payment method and the design module.

    scope: design:write
  • design.generate_carousel WRITE-safe

    Generate a multi-slide, on-brand carousel from a text intent (workspace BrandContext + AI), sized for a channel, and save it as one design. Returns the design id + edit URL. Channels: linkedin_square, linkedin_portrait, story_9x16, ad_square, one_pager_a4, wide_16x9, web_banner. Metered AI: needs a payment method and the design module in the plan.

    scope: design:write
  • design.create_from_doc WRITE-safe

    Create a design from a precise layer document — the "design it with detail" path (like building in Figma). You place each layer yourself: text, image or shape, positioned with x/y/w/h (pixels, origin top-left) inside the channel's artboard, plus per-type props. No AI, deterministic — what you send is what gets built. Returns the design id + an edit URL to open it. Channels: linkedin_square, linkedin_portrait, story_9x16, ad_square, one_pager_a4, wide_16x9, web_banner. Layer props: - text: { text, fontSize, color (hex), fontWeight (400-800), align (left|center|right), lineHeight } - image: { src (public https URL) } - shape: { fill (hex), radius, stroke, strokeWidth } Needs the design module in the plan (no card — nothing is metered).

    scope: design:write
  • design.update_doc WRITE-safe

    Edit an existing design by replacing its artboards with the ones you provide — the write half of a read-modify-write loop (read with design.get_doc, change the layers, send them back here). Each artboard is a full document (background + layers). Optionally also set the title/status. Deterministic, bumps the version. Returns the edit URL. Needs design write.

    scope: design:write
  • design.delete DESTRUCTIVE

    Hard-delete a design (Brand Studio visual) from the workspace. Irreversible.

    scope: design:delete

domains.*

  • domains.remove DESTRUCTIVE

    Remove a custom domain from the workspace: detach it from the host and take it offline (the site stops serving on that hostname). Clears its primary flag. Reversible by re-adding with domains.add. Needs settings write.

    scope: settings:write
  • domains.list READ

    List the custom domains attached to this workspace (site, members, blog, pages) with their verification + SSL status. Use to answer "is my domain connected / verified".

    scope: settings:read
  • domains.dns_records READ

    Get the DNS records to set at the registrar for a custom domain (the A / CNAME / TXT entries that make it verify and serve). Pair with domains.list to see verification status, and domains.refresh after setting them.

    scope: settings:read
  • domains.add WRITE-safe

    Connect a custom domain to the workspace's public site or members app. Registers it with the host, stores the DNS records to set, and starts verification (status 'verifying' until the records propagate and SSL issues). Returns the domain id + the DNS records. Requires the Pro plan. Outward-facing but reversible with domains.remove.

    scope: settings:write
  • domains.refresh WRITE-safe

    Re-check a custom domain's verification and SSL with the host and update its stored status + DNS records. Call after setting the DNS records (or to poll a 'verifying' domain).

    scope: settings:write
  • domains.sync_auth_redirects WRITE-safe

    Register the workspace's active custom domains in the Supabase auth redirect allow list, so end-user social login (Google) on those domains returns to the site instead of the default Site URL. Idempotent; run once after connecting a domain. Newly verified domains are registered automatically — this backfills existing ones. No-op if the Management API token isn't configured.

    scope: settings:write
  • domains.set_primary WRITE-safe

    Make an active custom domain the workspace's primary domain — the canonical host used for OG tags, the sitemap and outbound email links. Only one primary per workspace; the domain must be verified/active.

    scope: settings:write
  • domains.connect_search_console WRITE-safe

    Connect an active public-site custom domain to Google Search Console in one step: verify ownership (served automatically by the site), register the property and submit the sitemap. Requires the workspace's Google account to be connected with write access. Returns 'connected', 'not_connected' (connect Google first) or 'reconnect_required' (reconnect Google to grant Search Console write access).

    scope: settings:write

email.*

  • email.templates.list READ

    List every system email template (transactional + marketing) merged with this workspace's overrides. Shows key, label, category, whether it is customised, and whether it is enabled.

    scope: email:read
  • email.templates.get READ

    Get one effective email template (subject + HTML body, override or registry default) by key, optionally for a locale (fr/en).

    scope: email:read
  • email.campaigns.list READ

    List the workspace email campaigns with their status and headline stats (enrolled/sent/opened/replied).

    scope: campaigns:read
  • email.campaigns.get READ

    Get one email campaign by id with its full stats and audience rules.

    scope: campaigns:read
  • email.templates.update WRITE-safe

    Create or update this workspace's override of an email template. Subject + bodyHtml may use {{variable}} placeholders (see email.templates.get for the allowed variables). Set enabled=false to stop sending this email entirely.

    scope: email:write
  • email.templates.reset WRITE-safe

    Remove this workspace's override of a template (for a locale), reverting to the registry default.

    scope: email:write
  • email.send_test WRITE-safe

    Render an email template with the provided sample variables and send it to a test address. Uses the workspace verified sender.

    scope: email:write
  • email.campaigns.create WRITE-safe

    Create a DRAFT email campaign (no emails are sent). Pick an existing outbound sequence and optional audience rules. Use email.campaigns.launch to enroll the audience and start sending.

    scope: campaigns:write
  • email.campaigns.pause WRITE-safe

    Pause, resume, or finish a campaign. action='pause' (active→paused), 'resume' (paused→active), 'done' (active|paused→done). The outbound runner checks status before each send.

    scope: campaigns:write
  • email.campaigns.launch DESTRUCTIVE

    Activate a campaign and enroll the matching audience into its outbound sequence. REAL emails will be sent by the outbound runner. Idempotent: re-running enrolls newly matching prospects. Requires approval.

    scope: campaigns:write

entitlements.*

  • entitlements.list READ

    List the resolved entitlements (modules, features, limits) for this workspace based on its current plan + comped state.

    scope: billing:read
  • entitlements.check READ

    Check whether the workspace can access a feature (module.* or feature.*). Returns allowed + reason + required_plan when denied.

    scope: billing:read

forms.*

  • forms.list READ

    List this workspace's lead-capture forms with their id, title, public slug and status (draft / published / archived).

    scope: forms:read
  • forms.get READ

    Get one form by id with its ordered fields (type, label, options, required).

    scope: forms:read
  • forms.submissions READ

    List recent submissions for a form: answer data, the linked contact id (when an email was captured) and the submitted_at timestamp.

    scope: forms:read
  • forms.stats READ

    Funnel for a form: views, submissions (total + last 7 days) and completion rate (%).

    scope: forms:read
  • forms.create WRITE-safe

    Create a DRAFT lead-capture form with its fields. Never auto-publishes — call forms.set_status to publish. Add an email field to link submissions to contacts.

    scope: forms:write
  • forms.set_status WRITE-safe

    Publish, unpublish (back to draft) or archive a form.

    scope: forms:write
  • forms.set_allowed_origins WRITE-safe

    Set the CORS allowlist of external site origins permitted to submit this form (External Site Connect). Replaces the current list. One exact origin per entry, e.g. https://my-site.com. Empty = same-origin only.

    scope: forms:write
  • forms.set_actions WRITE-safe

    Replace this form's on-submit actions (External Site Connect): notify_internal (email the team), confirm_lead (email the contact), webhook (signed POST). Delivered durably in the background with retries.

    scope: forms:write

goals.*

  • goals.get READ

    Get the workspace's current active goal (the numeric target the user is working toward) and its progress. Returns null goal if none is set. This goal is also auto-injected into the copilot context to prioritize suggestions.

    scope: goals:read
  • goals.set WRITE-safe

    Set the workspace's active goal — the numeric target the user is working toward (e.g. title 'Reach 5000€/month', metric 'monthly revenue', target 5000, unit '€', deadline '2026-09-30'). Replaces any existing active goal. Set this whenever the user states where they want to get to, so future suggestions can be prioritized against it.

    scope: goals:write

inbox.*

  • inbox.threads.list READ

    List Inbox conversation threads (DMs / comments).

    scope: inbox:read
  • inbox.get_agent_modes READ

    Get the per-channel DM agent mode (off | suggested | auto) for Instagram, WhatsApp, LinkedIn, Messenger. LinkedIn 'auto' is forbidden (TOS) and always reported as 'suggested' or 'off'. Also returns the framework, voice prompt, and booking config. Scoped to the calling workspace — returns defaults (all 'off') if no settings row exists for this workspace yet.

    scope: inbox:read
  • inbox.send_dm WRITE-safe

    Reply with a DM in an Inbox thread. Sends for real only when the workspace has that channel in auto mode (LinkedIn); otherwise drafts a suggested reply for human approval.

    scope: inbox:write
  • inbox.set_agent_mode WRITE-safe

    Set the DM agent mode for a single channel (instagram_dm | whatsapp | linkedin | messenger). Modes: off | suggested | auto. LinkedIn 'auto' is rejected (TOS Microsoft — risk of account ban) and clamped to 'suggested'. The legacy global dm_agent_mode is kept in sync as max(IG/WA/Messenger). Scoped to the calling workspace — refuses if no settings row exists for this workspace yet.

    scope: inbox:write
  • inbox.set_dm_agent_settings WRITE-safe

    Set the DM agent's positioning: its conversational framework (spin | bant | awareness | custom) and/or its freeform voice prompt (the business context + tone it writes in). Partial update — only the fields you pass are changed; an empty voice prompt clears it. Use this to configure how the agent sounds, not the per-channel on/off mode (see inbox.set_agent_mode).

    scope: inbox:write

integrations.*

  • integrations.connect READ

    Return the in-app page to connect an integration (linkedin, stripe, whatsapp, instagram, messenger, google_calendar, youtube, tiktok, analytics, resend). The copilot CANNOT connect on the user's behalf — pair this with ui.link_action so the user finishes the OAuth/connect flow. Check team.integrations.list first to see what's already connected.

    scope: settings:read

knowledge.*

  • knowledge.list READ

    List knowledge base items (facts, objections, proof points the copilot can reuse to answer prospects), filterable by type. Each has its text, type, category and approval state.

    scope: knowledge:read
  • knowledge.create WRITE-safe

    Add an item to the knowledge base the copilot reuses to answer prospects. type: 'objection', 'pain', 'win_phrase', 'story', 'vocabulary' or 'anti_pattern'. text is the content (e.g. the objection and how to answer it). Optional category + context. Created as MANUAL and approved (the user authored it on purpose). Use this for 'remember this objection / add to my knowledge base'.

    scope: knowledge:write
  • knowledge.set_approved WRITE-safe

    Approve or unapprove a knowledge base item. Approved items are the ones reused to answer prospects.

    scope: knowledge:write

linkedin.*

  • linkedin.list_devices READ

    List paired browser devices for the current workspace: id, label, status, health, observed LinkedIn account, last heartbeat.

    scope: linkedin:read
  • linkedin.list_jobs READ

    List queued LinkedIn actions for the current workspace, newest first. Filter by status, action, or device.

    scope: linkedin:read
  • linkedin.enqueue_action WRITE-safe

    Queue one LinkedIn action for a paired browser to execute (connect, message, comment, react, visit, scrape_profile, post). Pass target_urn or a contact_id. Use dedupe_key to avoid duplicate live jobs. The action runs in the user's real browser under the anti-ban policy — it is not sent immediately.

    scope: linkedin:write
  • linkedin.import_search WRITE-safe

    Import leads from a LinkedIn or Sales Navigator people search into contacts, via a paired browser (Waalaxy-style acquisition). Pass a search_url (the results page) or keywords, and max leads. The browser scrapes the search and the leads are upserted into contacts, deduped by profile URL. Runs under the anti-ban policy.

    scope: linkedin:write
  • linkedin.scrape_engagement WRITE-safe

    Import the people who reacted to or commented on a LinkedIn post as warm-lead contacts, via a paired browser. Pass the post_url (or activity_urn). Replaces the Unipile engagement pipeline; deduped by (post, author, type). Runs under the anti-ban policy.

    scope: linkedin:write
  • linkedin.generate_pairing_code WRITE-safe

    Issue a one-time pairing code to connect a browser extension to this workspace. Returns the code once — paste it into the extension. Expires in 15 minutes.

    scope: linkedin:manage_devices

mcp.*

  • mcp.tools.list READ

    Self-introspection : returns the catalog of all MCP tools this workspace can call, optionally filtered by module prefix or tier. Useful when an agent needs to discover what actions are available before planning a multi-step workflow.

    scope: mcp:read

media.*

  • media.list READ

    List media items in the current workspace with optional filters (kind, collection, tags, source). Paginated by created_at cursor.

    scope: media:read
  • media.search READ

    Full-text search across alt_text, caption, and generation_prompt. Same filters as media.list.

    scope: media:read
  • media.get READ

    Get a single media item with a fresh signed URL (TTL 1h) or public URL for public assets.

    scope: media:read
  • media.lineage READ

    Return parents (refs used to generate this image) and children (images generated from it).

    scope: media:read
  • media.usages READ

    List entities (pages, drafts, ad creatives, etc.) that reference this media item.

    scope: media:read
  • media.upload WRITE-safe

    Upload a media item to the workspace library from base64 data. Auto-dedup on checksum. Returns the persisted row.

    scope: media:write
  • media.tag WRITE-safe

    Add/remove tags, change collection, update alt-text or caption on a media item.

    scope: media:write
  • media.record_usage WRITE-safe

    Record that an entity (page, draft, creative, …) references this media item. Idempotent on (media, entity, field).

    scope: media:write
  • media.archive WRITE-safe

    Soft-archive a media item (sets archived_at). Reversible.

    scope: media:write
  • media.delete DESTRUCTIVE

    Hard-delete a media item (DB row + storage bytes). Irreversible. Requires JIT approval.

    scope: media:delete

members_app.*

  • members_app.overview READ

    Snapshot of the current members-app config for the workspace: active domain (kind=members), count of enabled features, count of menu items.

    scope: members_app:read
  • members_app.features.list READ

    Full list of member-app feature toggles (registry + workspace override). Each entry: key, label, href, default_enabled, enabled.

    scope: members_app:read
  • members_app.menu.list READ

    List the custom menu items configured for the member app navigation (handle="members"). Returns id, label, url, position, target.

    scope: members_app:read
  • members_app.features.toggle WRITE-safe

    Enable or disable a member-app feature for the workspace. Stores an override only when it differs from the registry default (otherwise the row is removed).

    scope: members_app:write
  • members_app.menu.add WRITE-safe

    Append a new menu entry to the member-app navigation. Auto-positions at the end.

    scope: members_app:write
  • members_app.menu.remove WRITE-safe

    Delete a menu item by id (must belong to the current workspace).

    scope: members_app:write
  • members_app.appearance.set_mode WRITE-safe

    Set the theme mode used by the member app: light, dark, or auto.

    scope: members_app:write

memory.*

  • memory.list READ

    List the durable facts the assistant remembers about this workspace (target rate, tone, constraints, preferences), most recent first. These are also auto-injected into the copilot context — use this when the user asks "what do you remember about me / my business".

    scope: memory:read
  • memory.remember WRITE-safe

    Persist a durable fact about this workspace so you recall it in future conversations (e.g. 'target day rate is 600€', 'prefers a direct tone', 'targets fintech startups'). Pass an optional stable `key` (e.g. 'tjm', 'ton', 'icp') to UPDATE an existing fact instead of stacking duplicates. Only remember stable, useful facts the user states about themselves or their business, never transient chit-chat.

    scope: memory:write
  • memory.forget DESTRUCTIVE

    Delete a remembered fact by id (scoped to this workspace). Use after listing memories when the user asks to forget something. Irreversible — the fact is removed.

    scope: memory:write

orders.*

  • orders.list READ

    List store orders in the workspace, optionally filtered by status (pending / paid / cancelled / refunded). Each row carries the customer, totals, status and fulfillment state.

    scope: products:read
  • orders.counts READ

    Order counts broken down by status for the workspace store — a quick pulse of pending vs paid vs cancelled vs refunded.

    scope: products:read
  • orders.get READ

    Get a single order with its line items, customer, shipping address, totals, status and fulfillment (tracking). Returns null if the order is not in this workspace.

    scope: products:read
  • orders.set_status WRITE-safe

    Set a store order's status: pending, paid, cancelled or refunded. Marking paid/refunded is a bookkeeping state change here (it does not itself move money at the payment provider). Workspace-scoped.

    scope: products:write
  • orders.set_fulfillment WRITE-safe

    Update an order's fulfillment: unfulfilled / partial / fulfilled, plus an optional tracking number and URL to share with the customer. Workspace-scoped.

    scope: products:write

outreach.*

  • outreach.strategy.get READ

    Get the workspace's outreach strategy (offer, ICP, beliefs to break, CTA, tone, custom instruction) that drives per-contact brief personalization. Returns nulls if unset.

    scope: contacts:read
  • outreach.strategy.set WRITE-safe

    Update the workspace's outreach strategy (offer, ICP, beliefs to break, CTA, tone, custom instruction) that drives per-contact brief personalization. Only provided fields are changed.

    scope: contacts:write

pages.*

  • pages.list READ

    List CMS pages for this workspace.

    scope: pages:read
  • pages.list_templates READ

    List the curated page templates available for pages.create_from_template (id, name, description, suggested slug/title, block count).

    scope: pages:read
  • pages.list_blocks READ

    List the draft blocks of a page (the working copy the visual editor and MCP edits operate on, NOT the live published snapshot). Returns each block id, type, parent_id, position, visibility and props. Use this before pages.update_block / pages.move_block to see current ids.

    scope: pages:read
  • pages.create_draft WRITE-safe

    Create a new CMS page in draft status.

    scope: pages:write
  • pages.publish WRITE-safe

    Publish a CMS page (status → published, published_at = now).

    scope: pages:write
  • pages.create_from_template WRITE-safe

    Create a new draft page from one of the 5 curated templates (landing-coaching, about, pricing-3-tiers, contact, blog-post). Returns the new page id + blocks_count. Use pages.list_templates first to see available ids.

    scope: pages:write
  • pages.generate_from_prompt WRITE-safe

    Create a new draft page by asking Claude to generate 6-12 blocks from a natural-language prompt. The same generator the editor Mode IA uses. Returns the new page id + blocks_count.

    scope: pages:write
  • pages.insert_block WRITE-safe

    Insert one block into a page draft. Validates the block type + props against the design system and sanitises rawHtml. Optional parent_id (must be an existing block in the page) and position (default: end). Use site.get_design_context for valid block types + default props.

    scope: pages:write
  • pages.update_block WRITE-safe

    Update a single block in a page draft: its props and/or visibility. Validates + sanitises like insert. At least one of props/visible required.

    scope: pages:write
  • pages.move_block WRITE-safe

    Re-parent and/or reposition a block in a page draft. parent_id null = move to root. Rejects moves that would create a cycle.

    scope: pages:write
  • pages.delete_block WRITE-safe

    Delete a block (and its descendants) from a page draft. Cascades the subtree.

    scope: pages:write
  • pages.convert_baked_sections WRITE-safe

    Recompose a page built from frozen marketing sections into editable HTML elements. Defaults to a non-destructive draft duplicate; pass mode="in_place" to convert the page itself.

    scope: pages:write
  • pages.import_from_url WRITE-safe

    Import a public web page from its URL into a NEW draft page as faithful, editable element blocks (Webflow-style). The only client input is the URL (and an optional title); the workspace is always the active one, never supplied by the client. Runs an SSRF check, renders the page in an external headless browser (kept out of the app bundle), and maps the DOM to element blocks with computed styles. Returns { pageId, slug, stats }. Requires a payment method on file (metered render) and SITE_IMPORT_RENDER_URL to be configured.

    scope: pages:write
  • pages.delete DESTRUCTIVE

    Delete a CMS page.

    scope: pages:delete

payments.*

  • payments.create_link WRITE-safe

    Generate a one-off payment link the buyer can pay online, and optionally email it. Sell a catalogue product (pass product_id, uses its price) or an ad-hoc amount (pass label + amount_cents). Needs the buyer's email: it upserts them as a contact and creates a real, reconciled invoice behind the link, so the sale lands in revenue (not an untracked charge). Returns the hosted payment URL — share it, drop it in a DM, or set send_email=true to email the buyer. amount_cents is the smallest currency unit (600000 = 6000€). USE THIS for 'give me a payment link for X' / 'send a pay link to <email>'. Requires the workspace to have a legal entity configured and (for the online page) Stripe connected.

    scope: counsel:write

platform.*

  • sites_list READ

    List the workspace's Sites (public surfaces: domain + pages + audience + plans). The default site is returned first.

    scope: sites:read
  • sites_create WRITE-safe

    Create a secondary Site in the workspace (e.g. a niche SEO/marketing site on its own domain that funnels to the main one). Provide a name; the slug is derived or given.

    scope: sites:write
  • sites_update WRITE-safe

    Rename, re-slug or change the theme mode of a Site. The default site's slug is locked (its bare subdomain never moves).

    scope: sites:write
  • sites_auth_get READ

    Read a Site's end-user authentication settings: whether the site has its own audience at all (owns_end_user_auth, the master switch), and how that audience signs in. A site with no settings row answers the defaults.

    scope: sites:read
  • sites_auth_update WRITE-safe

    Turn a Site's own user accounts on or off, and set how its audience signs in. `owns_end_user_auth` is the master switch: while it is false, signup and sign-in are refused whatever the other flags say. Omitted flags keep their current value.

    scope: sites:write
  • sites_set_default WRITE-safe

    Promote a Site to be the workspace default (the one served on the bare workspace subdomain).

    scope: sites:write
  • sites_delete DESTRUCTIVE

    Delete a Site and everything scoped to it (pages, audience, plans, domains cascade). The default site cannot be deleted.

    scope: sites:delete
  • sites_audience_list READ

    List a site's end-users (the people who signed up on that public site, not workspace members). Returns each one's email, name, whether their email is verified, the role the site assigned them, and how many owner-scoped records they own. Also returns the roles the site defines, so a role id can be read back as a name. Scoped to this one site: an end-user of another site of the same workspace is a different person here.

    scope: sites:read
  • sites_audience_remove DESTRUCTIVE

    Remove one end-user from a site. This deletes their membership of THAT site only: their login still exists, and their memberships of the workspace's other sites are untouched. The database cascade also removes the records they own on this site and their pending reset tokens. Irreversible.

    scope: sites:write
  • reviews_list READ

    List the workspace's reviews. Filter by status (pending/published/rejected), subject (product/program/brand + id), display site or source. Each row carries a resolved `verified` flag (the linked booking was won or the transaction was paid).

    scope: reviews:read
  • reviews_aggregate READ

    Aggregate published reviews (count + average rating rounded to 0.1) for a subject, display site, or the whole workspace. Useful to show a rating badge.

    scope: reviews:read
  • reviews_moderate WRITE-safe

    Set a review's status: publish it, reject it, or send it back to pending. Every review lands in pending; this is how one goes live on the public surface.

    scope: reviews:moderate
  • reviews_request WRITE-safe

    Create a review request for a subject (product/program/brand) and return the public link the customer follows to leave their review.

    scope: reviews:request
  • sites_rooms_list READ

    List a site's realtime rooms (voice or chat spaces its end-users can join). Returns each room's slug, name, status, participant cap and the subscription plan that opens its door, if any. Scoped to this one site: two sites of the same workspace can both have a room called "general" and they are different rooms.

    scope: sites:read
  • sites_rooms_create WRITE-safe

    Create a realtime room on a site. Give it a name; the slug is derived from that name unless you supply one. Pass required_plan_id to gate the room behind an end-user subscription plan (from collections_plans) — without it, any signed-in end-user of the site can enter. max_participants 0 means no cap. The room carries no audio by itself: it is the identity and the right to enter, the media server does the rest.

    scope: sites:write
  • sites_rooms_update WRITE-safe

    Update one room of a site. Every field is optional and only what you pass changes. Closing a room refuses entry without deleting it or its history. Setting required_plan_id to null opens the room to every signed-in end-user of the site.

    scope: sites:write
  • sites_rooms_delete DESTRUCTIVE

    Delete one room of a site. Irreversible. To stop entries without losing the room, set its status to closed instead.

    scope: sites:write
  • http_request WRITE-safe

    Call an external API over HTTP(S) and return { status, ok, headers, body, json }. Internal addresses are blocked (anti-SSRF). Use {{node:...}} references to inject values from earlier steps into the URL, the headers or the body.

    scope: automation:http
  • send_email WRITE-safe

    Send an email (subject + HTML body) to one address, from the workspace's verified sender. Attachments come either by URL (`url`) or as base64 content (`content_base64`, e.g. what generate_pdf returns). Every field accepts {{node:...}} references.

    scope: email:write
  • send_sms WRITE-safe

    Send an SMS (short text) to a phone number, from the workspace's own number. Honours the do-not-call list. Every field accepts {{node:...}} references (e.g. {{node:<trigger>.contact.phone}}).

    scope: voice:sms
  • generate_pdf WRITE-safe

    Generate a PDF (title + text content, one paragraph per line), store it in the workspace media library, and return { mediaId, filename, sizeBytes, base64 }. The `base64` plugs straight into send_email via {{node:<id>.base64}}.

    scope: media:write

presentations.*

  • presentations.delete DESTRUCTIVE

    Hard-delete a presentation (closing deck / audit slides) from the workspace. Irreversible.

    scope: presentations:delete
  • presentations.list READ

    List the workspace presentations (closing decks / audit slides), filterable by status (draft / unlisted / published). Each has an id, slug, title, status and updated_at.

    scope: presentations:read
  • presentations.create WRITE-safe

    Create a presentation (closing deck / audit slides) in the workspace. Give a title; the slug is derived if omitted. Optionally seed the deck with slides_html + speaker_notes_html, else it starts empty for editing. Status: draft (private) / unlisted (link-only) / published. Returns the id + slug.

    scope: presentations:write
  • presentations.set_status WRITE-safe

    Change a presentation's visibility status: draft (private), unlisted (link-only) or published.

    scope: presentations:write

products.*

  • products.list READ

    List products / offers in the workspace (optionally filter by active state).

    scope: products:read
  • products.get READ

    Get a single product with its detail counters (modules, files, active purchases).

    scope: products:read
  • products.files.list READ

    List downloadable files attached to a product.

    scope: products:read
  • products.create WRITE-safe

    Create a product/offer in the catalogue (e.g. a consulting package, an ebook, a membership). Give at least a title; price_cents is the price in the smallest currency unit (600000 = 6000€). kind defaults to 'consulting', and it's created INACTIVE (a draft) — activate it with products.set_active once reviewed. The slug is derived from the title. Returns the new product id + kind.

    scope: products:write
  • products.set_active WRITE-safe

    Activate or deactivate (archive) a product.

    scope: products:write
  • products.duplicate WRITE-safe

    Duplicate an existing product into a new INACTIVE draft (the Stripe price_id/payment_link are intentionally NOT copied, to avoid double-charging). Returns the new product id. Activate it with products.set_active once its own Stripe price is wired.

    scope: products:write
  • products.delete DESTRUCTIVE

    Hard-delete a product from the catalogue (workspace-scoped). Refused if the product still has active member purchases, to preserve access history — archive it with products.set_active instead. Irreversible.

    scope: products:delete

programme.*

  • programme.modules.list READ

    List curriculum modules for a product (programme).

    scope: programme:read
  • programme.lessons.list READ

    List lessons inside a curriculum module.

    scope: programme:read
  • programme.module.set_published WRITE-safe

    Publish or unpublish a curriculum module.

    scope: programme:write
  • programme.lesson.set_published WRITE-safe

    Publish or unpublish a curriculum lesson.

    scope: programme:write
  • programme.lesson.delete DESTRUCTIVE

    Hard-delete a lesson from a curriculum module (workspace-scoped). Removes its tasks/resources too. Returns not_found for a lesson owned by another workspace. Irreversible.

    scope: programme:delete
  • programme.task.delete DESTRUCTIVE

    Hard-delete a task from a lesson (workspace-scoped). Irreversible.

    scope: programme:delete
  • programme.resource.delete DESTRUCTIVE

    Hard-delete a resource (file or link) from a module/lesson/task (workspace-scoped). Irreversible.

    scope: programme:delete

seo.*

  • seo.get_profile READ

    Get the workspace SEO/GEO profile (brand name, aliases, domains, market) and the tracked competitors.

    scope: seo:read
  • seo.list_prompts READ

    List the prompts tracked across AI engines for this workspace, with their enabled flag and category.

    scope: seo:read
  • seo.visibility READ

    Get the AI visibility score (0-100) and the latest snapshot per tracked prompt (mention rate, citation rate, stability).

    scope: seo:visibility
  • seo.upsert_profile WRITE-safe

    Create or update the SEO/GEO profile. Brand name is required; other fields are optional and preserved when omitted.

    scope: seo:write
  • seo.add_prompt WRITE-safe

    Add a prompt to track across AI engines (a real question your prospects ask).

    scope: seo:write
  • seo.suggest_prompts WRITE-safe

    Auto-generate tracked prompts from the business profile (real prospect questions) and add them, de-duplicated against existing ones. Uses AI text generation (bounded by the plan quota).

    scope: seo:write
  • seo.set_prompt_enabled WRITE-safe

    Enable or disable a tracked prompt without deleting it.

    scope: seo:write
  • seo.delete_prompt WRITE-safe

    Delete a tracked prompt.

    scope: seo:write
  • seo.run_scan WRITE-safe

    Probe the AI engines now for all active prompts and persist visibility snapshots. Costs AI tokens, bounded by the plan quota.

    scope: seo:visibility
  • seo.list_topics READ

    List the tracked SEO article topics for this workspace, with status (suggested/queued/generating/done) and source.

    scope: seo:read
  • seo.list_articles READ

    List the workspace blog articles (published + drafts) joined with Google Search Console performance (indexed, position, clicks, impressions over 28 days).

    scope: seo:read
  • seo.suggest_topics WRITE-safe

    AI-suggest blog article topics grounded in the brand profile and Google Search Console opportunity queries (terms ranking on page 2+). De-duplicated against existing topics. Costs AI tokens, bounded by the plan quota.

    scope: seo:write
  • seo.generate_article WRITE-safe

    Generate a full blog draft from a tracked topic: SEO brief (web search) + article writing + SEO scoring. Creates a studio_draft (status draft, not auto-published) linked to the topic. Costs AI tokens, bounded by the plan quota.

    scope: seo:write
  • seo.set_autopilot WRITE-safe

    Enable or disable the SEO autopilot and set its weekly article cadence (0-14). When on, the cron suggests, queues and writes drafts within the cadence. Articles stay as drafts (approval gate kept).

    scope: seo:write

settings.*

  • settings.get READ

    Get the workspace's general settings: name, slug, brand color, brand hashtag, SEO title/description, and the member-app / public-site theme modes. The single read for 'what's my workspace called / how is it branded'.

    scope: settings:read
  • settings.update WRITE-safe

    Update the workspace's general identity: any of name, brand color (hex or null), brand hashtag, SEO title, SEO description, member-app theme mode, public-site theme mode. Only the fields you pass change; the rest are preserved. Does NOT touch logo/icon/favicon (use the upload flow for those).

    scope: settings:write

shipping.*

  • shipping.list READ

    List the store shipping rates (flat or weight-based, with any free-over threshold) used to quote delivery at checkout.

    scope: products:read
  • shipping.save WRITE-safe

    Replace the store's full set of shipping rates with the ones provided (this overwrites the existing rates — send the complete list). Each rate is flat or weight-based, in cents, with an optional free-over threshold. Workspace-scoped.

    scope: products:write

site.*

  • site.get_design_context READ

    The workspace's design language (DA): brand identity (name, colour, logo, favicon), theme design tokens (colours, fonts, radius), site menus, and the catalogue of available page-builder block types with their default props. Call this BEFORE authoring or editing pages so generated content matches the site's look and uses valid blocks. Read-only, public-safe (no custom CSS or theme internals).

    scope: pages:read

studio.*

  • studio.drafts.list READ

    List Studio drafts (content pieces). Filter by status / target_platform.

    scope: studio:read
  • studio.drafts.get READ

    Get a Studio draft by id (full content).

    scope: studio:read
  • studio.publications.list READ

    List Studio publications (drafts that have been scheduled or already pushed to a channel). Each row carries the scheduled_at / published_at / publish_error fields so an agent can audit what is live vs queued vs failed.

    scope: studio:read
  • studio.ideas.list READ

    List Studio ideas (upstream of drafts). Each idea has a title, hook, angle, status and score. Useful when a content agent needs the next batch of inspirations to turn into drafts.

    scope: studio:read
  • studio.seo_briefs.list READ

    List SEO briefs (keyword + search intent + target word count). Used by content agents to plan articles aligned with the workspace SEO strategy.

    scope: studio:read
  • studio.draft.approval_state READ

    Check whether a draft is approved for autopilot publishing, and by whom / when. Returns null if the draft does not exist or is not yet reviewed.

    scope: studio:read
  • studio.draft.lineage READ

    Resolve where a draft comes from : the competitor post, decoded pattern, and / or source draft that inspired it. Helps an agent retrace why a draft was generated before iterating.

    scope: studio:read
  • studio.draft.virality READ

    Latest virality score for a Studio entity (draft, idea, publication). Returns the Gemini-computed predicted score plus the reasoning breakdown.

    scope: studio:read
  • studio.inspiration_packs.list READ

    List inspiration packs (competitor post + decoded structure) available for the workspace to remix into new drafts.

    scope: studio:read
  • studio.draft.create WRITE-safe

    Create a new Studio draft.

    scope: studio:write
  • studio.draft.update WRITE-safe

    Update Studio draft fields.

    scope: studio:write
  • studio.draft.approve WRITE-safe

    Mark a Studio draft as approved-for-publish (publish_approved_at = now).

    scope: studio:write
  • studio.draft.unapprove WRITE-safe

    Revoke the publish approval on a Studio draft. Use this when an agent or the user spots a problem after approval and wants to block the next autopilot cycle.

    scope: studio:write
  • studio.draft.publish WRITE-safe

    Publish a Studio draft to LinkedIn now, or schedule it. Omit scheduled_at to post immediately; pass an ISO 8601 scheduled_at to queue it (a cron publishes it at that time once the draft is publish-approved). Publishes via the connected LinkedIn OAuth account, or, when none is connected, through the paired browser extension (goes live async). Requires the draft to have linkedin_text and either OAuth or a paired device. Posting is outward-facing and not reversible once live.

    scope: studio:write
  • studio.draft.publish_blog WRITE-safe

    Publish a Studio draft as a blog article on the workspace site (sets it live and pings IndexNow). The draft must have a slug, article body, meta_title, meta_description and be approved for publish (studio.draft.approve). This is outward-facing: the article becomes publicly readable and search-indexable. Returns the public blog URL.

    scope: studio:write
  • studio.draft.unpublish_blog WRITE-safe

    Take a published blog article back offline: clears its published date so it stops appearing on the blog and in the sitemap, and returns it to the approved state. Reversible with studio.draft.publish_blog. The row and its content are kept.

    scope: studio:write
  • studio.draft.set_cover WRITE-safe

    Set a Studio draft/blog article cover image, from a media-library item (media_id, e.g. one just added with media.upload) or a public image URL (image_url). Exactly one source. The image is re-hosted in the workspace so the blog serves it as the article cover, the og:image and the schema.org ImageObject. Pass alt for accessibility and SEO. Replaces any current cover.

    scope: studio:write
  • studio.draft.archive WRITE-safe

    Move a Studio draft to the archive (soft-hide from default lists). Reversible : the row stays in DB. Prefer this to delete unless the draft is junk.

    scope: studio:write
  • studio.idea.archive WRITE-safe

    Archive a Studio idea so it stops appearing in the active ideation pipeline. Reversible.

    scope: studio:write
  • studio.draft.delete DESTRUCTIVE

    Delete a Studio draft.

    scope: studio:delete
  • studio.publication.delete DESTRUCTIVE

    Delete a Studio publication record (channel push history). Does not retract anything from the actual channel ; only removes the row from the workspace ledger.

    scope: studio:delete

suppliers.*

  • suppliers.list READ

    List the dropship/fulfillment suppliers configured for the workspace store (name, website, contact email, notes).

    scope: products:read
  • suppliers.create WRITE-safe

    Add a dropship/fulfillment supplier to the workspace store. Returns the new supplier id.

    scope: products:write
  • suppliers.update WRITE-safe

    Update a store supplier (name, website, contact email, notes). Workspace-scoped.

    scope: products:write
  • suppliers.delete DESTRUCTIVE

    Delete a store supplier. Irreversible. Products referencing it keep their data but lose the supplier link.

    scope: products:write

support.*

  • support.threads.list READ

    List member support chat threads for this workspace (the in-app support inbox), filterable by status (open / pending_member / pending_team / resolved / archived) or a text query. Each row carries the member, subject, status, unread counts and last message preview.

    scope: support:read
  • support.thread.get READ

    Get a single member support thread with its full message history. Scoped to the current workspace.

    scope: support:read
  • support.reply WRITE-safe

    Post a team reply into a member support thread. Scoped to the current workspace; the message is attributed to the calling user.

    scope: support:write
  • support.set_status WRITE-safe

    Resolve or reopen a member support thread. action 'resolve' closes it; 'reopen' puts it back to open. Scoped to the current workspace.

    scope: support:write

team.*

  • team.list READ

    List workspace team members (workspace_members + profile join). Each row carries user_id, role (owner / admin / staff / member), status (active / invited / suspended), joined_at.

    scope: team:read
  • team.get READ

    Get a single workspace member with their profile (display name, avatar, email). Returns null if the user is not a member of the workspace.

    scope: team:read
  • team.roles.list READ

    List the workspace roles (system + custom) with, for each, its member count and how many permissions it grants. Use a role id here with team.member.set_role or team.roles.get.

    scope: team:read
  • team.roles.get READ

    Get a workspace role with the exact permission keys it grants and its member count, plus the catalog of assignable permissions (key + label). Feed the granted keys to team.roles.set_permissions to adjust them.

    scope: team:read
  • team.audit_log READ

    Workspace audit log : who did what (login, role change, integration connect, etc.). Filter by event type or recency.

    scope: team:read
  • team.integrations.list READ

    List third-party integrations connected to the workspace (Stripe, Google, Meta, LinkedIn, TikTok, etc.) with their connection state.

    scope: team:read
  • team.member.set_role WRITE-safe

    Change a workspace member's role (which sets their permissions). role_id is a workspace role id from team.get. Cannot change your own role, cannot target the workspace owner, and the owner role cannot be assigned. Needs the manage-roles permission.

    scope: team:manage_roles
  • team.member.suspend WRITE-safe

    Suspend a workspace member: they keep their account but lose access until reactivated, and the billable seat is freed. Cannot suspend yourself or the workspace owner. Reversible with team.member.reactivate. Needs the remove-member permission.

    scope: team:remove
  • team.member.reactivate WRITE-safe

    Reactivate a suspended workspace member: restores their access and re-adds the billable seat. Needs the remove-member permission.

    scope: team:remove
  • team.invite.resend WRITE-safe

    Re-send a workspace member's invite: emails them a fresh magic sign-in link to the members app. Use for a pending member who lost or never got the first invite. The target must already be a member of this workspace. Needs the invite permission.

    scope: team:write
  • team.roles.create WRITE-safe

    Create a custom workspace role. key is a lowercase slug (unique, not a reserved system key). Optionally duplicate_from_id copies another role's permissions as a starting point. Set the permissions afterwards with team.roles.set_permissions. Needs the manage-roles permission.

    scope: team:manage_roles
  • team.roles.update WRITE-safe

    Update a custom role's metadata (name, description, color, or whether it's the default role for new members). Does not touch its permissions — use team.roles.set_permissions for those. Needs the manage-roles permission.

    scope: team:manage_roles
  • team.roles.set_permissions WRITE-safe

    Replace a role's full permission set with the given keys (anything not listed is revoked). Valid keys and the current set come from team.roles.get. The owner role is locked. Needs the manage-roles permission.

    scope: team:manage_roles
  • team.roles.delete DESTRUCTIVE

    Delete a custom workspace role. System roles cannot be deleted. Members holding this role are reassigned to the workspace default role. Needs the manage-roles permission.

    scope: team:manage_roles
  • team.member.remove DESTRUCTIVE

    Permanently remove a member from the workspace: revokes their access and frees the billable seat. Cannot remove yourself or the workspace owner. The person keeps their user account but is no longer a member. Irreversible over MCP — re-invite to add them back.

    scope: team:remove
  • team.invite WRITE-safe

    Invite someone to the workspace team by email with a role: 'admin', 'coach', 'closer' or 'setter' (never 'owner'). Sends them an invite/magic-link email and creates their membership. A seat-charging plan may require a card on file. USE THIS for 'invite X to my team / add Y as a closer'. Consequential — surfaces an approval first.

    scope: team:write

voice.*

  • voice.list_calls READ

    List recent voice calls in the current workspace. Returns id, direction, status, duration, contact_id, disposition slug, created_at.

    scope: voice:read
  • voice.get_call_detail READ

    Get the full detail of a single voice call: call row, recording metadata, transcript summary, segments, score (if Tier 3 enabled).

    scope: voice:read
  • voice.list_call_lists READ

    List call lists in the current workspace with progress counts (total / completed / positive).

    scope: voice:read
  • voice.start_call WRITE-safe

    Pre-create a voice_calls row so a client (browser dialer or AI Voice Agent) can initiate a call. Returns the callId + caller-id E.164. Does NOT actually dial — the dialing is done by the client via Twilio Voice JS SDK or by the AI Voice Agent provider.

    scope: voice:write
  • voice.enrich_prospect_phone WRITE-safe

    Enrich a prospect (or arbitrary contact data) with phone numbers via Dropcontact. Optionally writes the best phone back to the prospects row when contact_id is provided. Costs 1 Dropcontact credit per row enriched.

    scope: voice:write
  • voice.add_to_dnc WRITE-safe

    Add a phone number to the workspace Do-Not-Call list. The number is blocked pre-dial across the queue runner, MCP voice.start_call, and AI Voice Agent campaigns.

    scope: voice:write
  • voice.campaigns.list READ

    List AI voice (cold-calling) campaigns for the workspace: name, provider, status, total calls, successful bookings, total cost and daily cap. Complements voice.list_calls (individual calls).

    scope: voice:read
  • voice.campaign.get READ

    Get one AI voice campaign in detail (script, voice, language, objective, caps, timestamps) plus its most recent calls and their outcomes.

    scope: voice:read

webinaires.*

  • webinaires.list READ

    List webinars in the workspace (featured first, then by scheduled date).

    scope: webinars:read
  • webinaires.get READ

    Get a single webinar by id.

    scope: webinars:read
  • webinaires.set_featured WRITE-safe

    Mark a webinar as the featured one (unfeatures the others).

    scope: webinars:write
  • webinaires.create WRITE-safe

    Create a webinar session. Give a title; the slug is derived from it if omitted. status defaults to 'draft' (set 'scheduled' once the date is set). scheduled_at is an ISO datetime. Returns the new webinar id.

    scope: webinars:write
  • webinaires.update WRITE-safe

    Update a webinar by id. Only the provided fields change; the rest are kept as-is (fetched first then merged). Pass null on subtitle/scheduled_at/replay_url to clear them. Answers "reschedule / rename / publish a webinar".

    scope: webinars:write
  • webinaires.archive WRITE-safe

    Archive a webinar (drops it from the active list; signups and audit history are kept).

    scope: webinars:write
  • webinaires.delete DESTRUCTIVE

    Hard-delete a webinar (workspace-scoped). Refused if it already has signups, to preserve the registration history — archive it with webinaires.archive instead. Irreversible.

    scope: webinars:write

wiki.*

  • wiki.list_tree READ

    List the whole wiki tree (docs, folders and files) of the current workspace, with parent/position/icon/visibility for each node.

    scope: wiki:read
  • wiki.get_doc READ

    Get a wiki doc by id, returning its title, icon and body as markdown.

    scope: wiki:read
  • wiki.create_doc WRITE-safe

    Create a new wiki doc, optionally under a parent folder or doc, with optional markdown body.

    scope: wiki:write
  • wiki.create_folder WRITE-safe

    Create a new wiki folder, optionally under a parent folder.

    scope: wiki:write
  • wiki.save_doc_body WRITE-safe

    Replace a wiki doc body with the given markdown (snapshots the previous version).

    scope: wiki:write
  • wiki.publish WRITE-safe

    Publish a wiki doc as a public page (snapshots title + body under a stable public slug). Returns the slug.

    scope: wiki:publish

workbench.*

  • workbench.tasks.list READ

    List Workbench tasks.

    scope: workbench:read
  • workbench.projects.list READ

    List Workbench projects.

    scope: workbench:read
  • workbench.milestones.list READ

    List Workbench milestones with progress + due date. Useful when an agent needs the next deliverables on a project before assigning new tasks.

    scope: workbench:read
  • workbench.kpis READ

    Workbench cockpit KPIs : tasks done in the last 7d (vs prior 7d), currently open / overdue / blocked counts, and the daily completion sparkline.

    scope: workbench:read
  • workbench.focus_tasks.list READ

    List the tasks currently assigned to the caller and still open (todo / in_progress / blocked). The user "focus list" — what the operator should do today.

    scope: workbench:read
  • workbench.active_projects READ

    List active projects with their cockpit data (color, deadline, owner, status). Trimmed to what the dashboard widget shows.

    scope: workbench:read
  • workbench.workload_heatmap READ

    Team workload heatmap : open task count per assignee per day for the next ~14 days. Used to spot overloads before assigning new work.

    scope: workbench:read
  • workbench.recent_activity READ

    Recent task / project / milestone events in the Workbench audit log (creation, status change, assignment, delete) over the last 24 hours.

    scope: workbench:read
  • workbench.task.create WRITE-safe

    Create a new Workbench task.

    scope: workbench:write
  • workbench.task.update WRITE-safe

    Update a Workbench task.

    scope: workbench:write
  • workbench.task.assign WRITE-safe

    Assign a Workbench task to a user.

    scope: workbench:write
  • workbench.task.update_status WRITE-safe

    Quick status change on a Workbench task (todo / in_progress / blocked / done / cancelled). Auto-sets completed_at when status becomes done, clears it otherwise. Cheaper than the full update tool when only the status changes.

    scope: workbench:write
  • workbench.task.follow_up WRITE-safe

    Create a follow-up task linked to another entity (e.g. after a Voice call : a task linked to the prospect with a due date and priority).

    scope: workbench:write
  • workbench.task.delete DESTRUCTIVE

    Delete a Workbench task.

    scope: workbench:delete

workspace.*

  • workspace.branding.get READ

    Get the workspace's configured branding: name, logo / icon / favicon URLs and brand color. These are the assets set in Settings → Brand, stored on the workspace itself, NOT in the media library — so use THIS (not media.search) to display or reference the workspace logo. has_logo is false when no logo is set yet; only then offer ui.request_upload.

    scope: agents:read