# Kata Send

> Cold email run by an AI agent. Give Kata a lead list and an offer: it checks every address, writes the emails, sends them, tests several versions and keeps the ones that bring sales. Every action is an MCP tool, so your own agent can run it end to end.

## For agents: how to get started

1. Sign up: a human opens https://katasend.com/signup with a work email and enters the 6-digit code sent there. New accounts get $10 of free sending (250 emails).
2. Get the key: in the app (https://katasend.com/app), Home > "Connect your agent" gives a setup prompt with the agent key.
3. Connect to the MCP server: https://api.katasend.com/mcp, header `Authorization: Bearer <agent key>`. Streamable HTTP, stateless, JSON responses.
4. Save the company with `set_company_brief`, then create a campaign, add leads, write the emails and launch.

```
claude mcp add --transport http kata https://api.katasend.com/mcp --header "Authorization: Bearer $KATA_KEY"
```

## Docs

- [Introduction](https://katasend.com/docs): what Kata does and how a campaign runs
- [Quickstart](https://katasend.com/docs/quickstart): from sign-up to the first email sent
- [Connect your agent](https://katasend.com/docs/mcp): MCP setup for Claude, ChatGPT, Cursor and others
- [MCP tools reference](https://katasend.com/docs/tools): every tool with its parameters
- [REST API](https://katasend.com/docs/api): the same actions over HTTP
- [Webhooks](https://katasend.com/docs/webhooks): push leads in, report conversions back
- [Conversions](https://katasend.com/docs/conversions): report sign-ups and sales so Kata optimizes for revenue
- [Campaigns](https://katasend.com/docs/campaigns), [Angles and split tests](https://katasend.com/docs/angles), [Lead lists](https://katasend.com/docs/lead-lists)
- [Mailboxes and warmup](https://katasend.com/docs/mailboxes), [Sending hours](https://katasend.com/docs/sending-hours), [Email checks](https://katasend.com/docs/email-checks), [Sender health](https://katasend.com/docs/sender-health), [Tracking](https://katasend.com/docs/tracking)
- [FAQ](https://katasend.com/docs/faq)

## MCP tools

- `send_emails`: Send cold email to many leads in one call: the main tool. Kata makes the lead list and the campaign itself, checks every address, skips leads already emailed, unsubscribed or bounced, sends from the warmed mailboxes in each lead's local hours (8-17 on weekdays, unless now=true) and adds the opt-out line and signature. Give brief (Kata writes 3 angles and keeps the best) or subject+body (your own email; variables {{first_name}}, {{company}}, {{link}} or any lead field). preview=true sends nothing and returns 3 emails as the leads would get them: then start_run. Returns run_id: follow it with get_run. Check capacity first when you send more than a few hundred.
- `send_email`: Send one email to one person now, at any hour, from the warmed mailboxes. Opt-out line and signature are added, opens, clicks and the reply are tracked, the reply lands in list_inbox. Works for a lead already emailed (not for one who replied: use reply). Optional follow_ups in the same thread. Returns run_id.
- `capacity`: How many emails can still go out today: own mailboxes, Kata's pool share and credits, emails already queued. Emails beyond today's room wait for the next days.
- `list_runs`: Runs started with send_emails or send_email, newest first: status (sending, preview, paused, cancelled), sent, queued, waiting (leads not emailed yet), replies, interested, clicks, sales, bounces.
- `get_run`: One run: status, totals (sent, queued, waiting, replies, interested, clicks, sales, bounces) and each email (angle, subject, sent, replies, interested, clicks).
- `start_run`: Start a run made with preview=true, or start a paused run again.
- `pause_run`: Pause a run: nothing more goes out until start_run.
- `cancel_run`: Stop a run for good: planned emails are dropped and its leads get nothing more from it. Replies already received stay.
- `get_new_replies`: Replies received since your last call, oldest first: who wrote, kind (interested, not_interested, unsubscribe, ooo, wrong_person, other), their text, the run and the message_id to answer with reply. Pass back next_cursor each time: no reply comes twice. First call: no cursor (every reply so far, 50 at a time while has_more). Kata already stopped the follow-ups of leads who replied (except out-of-office).
- `get_thread`: The whole conversation with one lead, oldest first: each email Kata sent (opened, clicked, bounced), each reply they wrote (with its kind) and each answer you sent, plus the lead's fields and status (waiting, contacted, replied, bounced, unsubscribed, converted). Read it before you answer.
- `list_sent`: Emails Kata sent, newest first, with opened, clicked, replied, interested and bounced. Filters: run_id, agent, since (ISO date), to (one address). Returns count and one page.
- `stop_emails`: Stop emailing these people: their planned emails and follow-ups are cancelled, in every run. unsubscribe=true also blocks the addresses for good (never emailed again).
- `set_webhook`: Have Kata POST each reply, bounce and sale to your server, signed (X-Kata-Signature = HMAC-SHA256 of the body with the secret). url: set or change it (https). remove=true: delete it. test=true: send a test event now. No argument: show the current webhook and its last delivery.
- `status`: Overview: sends today, capacity, replies, interested leads, domains, mailboxes, company memory size, campaigns (each with state: ok, error with the reason it cannot send, completed when every lead went through the sequence, off when not active), and wrong_person: recent replies saying they are not the right person (with any address they gave in referral) so you can ask for the right contact.
- `health`: Health score (0-100) of every sending domain and mailbox over the last 30 days: domain 50%, recipient behavior 30%, address 10%, IP/provider 10%. When Instantly warmup data is known (10 or more warmup emails landed in 7 days), inbox placement counts 15% (domain 45%, recipients 25%, address 10%, provider 5%): inbox_rate and placement {inbox, spam} per mailbox. Kata pauses a mailbox by itself when more than 10% of 20 or more warmup emails land in spam over 7 days. Use it to decide which mailboxes to pause or slow down.
- `get_integrations`: Which integrations are configured (AgentMail key, Cloudflare token), with the last 4 characters and what the check found (plan, limits, domains, zones). Never returns the keys.
- `set_integration`: Save an integration key after checking it with the service: agentmail_api_key (AgentMail), resend_api_key (Resend, full-access key that can read domains), cf_api_token (Cloudflare API token with Zone:Read and DNS:Edit on the sending domains), or outreachguy_api_key (OutreachGuy: each lead who replies interested or converts is handed over to OutreachGuy with its email thread and sale value). The key is stored encrypted. Warn the user that a key pasted in a chat stays in the conversation history; the Integrations page in Kata is the safer place.
- `set_company_brief`: Write the company memory (company.md), read by the AI everywhere: what the company does, for whom, proof (numbers, clients), tone, what to avoid. brief replaces the whole company.md. Only the fields you pass change.
- `get_company_brief`: Read the company memory (company.md), name and website.
- `read_campaign_brief`: Read a campaign's brief.md: target, offer, proof, expected action, link, then notes and updates.
- `update_campaign_brief`: Replace a campaign's brief.md with the full new content. The campaign link is the line "Link: https://…" and only that line (other URLs in the brief are plain text); it is the destination of {{link}} and may hold contact variables ({{email}}, {{first_name}}, any data key), filled and URL-encoded per lead. Removing the Link: line removes the campaign link. Keep it current without asking: target, offer, proof, action, link, then a "Notes and updates" part. Plain text, no markdown headings: the user reads and edits it (angles tried, decisions, results, next steps). Read it first and keep what is still true.
- `check_campaign_brief`: Check that a campaign's brief.md has what the AI needs to write and send. Returns ready, missing (to ask the user), tips, and checked: every point looked at, with ok and a note. ready covers the five essentials (target, offer, why, action, link = the Link: line). checked also lists informational sending checks that do not change ready: link_variables (the {{vars}} of the link exist on enrolled contacts), angles (each step has a live angle), tracked_links (live angles with hand-written URLs, which are not tracked). The result shows on the campaign page.
- `get_campaign_mailboxes`: Which mailboxes a campaign sends from. mode all = every active mailbox; mode selected = only the chosen ones. Lists every mailbox with chosen/used, status, daily cap and sent today.
- `set_campaign_mailboxes`: Choose the mailboxes a campaign sends from. all=true: every active mailbox (default). emails: exactly these. add / remove: change the current list. Only new first emails follow the choice; follow-ups stay in the mailbox of their thread. A chosen mailbox still has to be active to send.
- `check_emails`: Check email addresses. mode free (default, no cost, up to 2000): syntax, typos (gmial.com, with the fix), disposable domains, generic addresses (info@…), and whether the domain has a mail server. mode deep (includes free, max 200, about 2 to 10 seconds per 10 addresses): then asks whether each mailbox really exists. Kata's SMTP verifier asks the recipient's server (free); when that server will not answer, MillionVerifier through Bourse (about $0.002 per address, paid); catch-all addresses go to a decision model (about $0.00003). Addresses the free pass rejects never reach the paid steps. The result says what it cost (cost.usd). Kata already runs free on every import and deep on its own before each contact's first email: use deep only when the user wants a list checked now, tell them it can cost up to $0.002 per address, and ask before more than 100. Give emails, or campaign_id for its contacts not checked yet. Results go to the email_checks table (status, reason, source, decision send/skip). suppress_invalid=true takes rejected addresses out of their sequences: only with the user's approval.
- `warmup_status`: Warmup state of the mailboxes in Instantly: in Instantly or not, warmup on/off/paused/error.
- `warmup_enable`: Turn warmup on in Instantly for mailboxes (emails, or all of a domain). AgentMail mailboxes not yet in Instantly are added automatically by IMAP/SMTP. Other providers must be connected in Instantly first. Ask the user first.
- `warmup_disable`: Turn warmup off in Instantly for mailboxes (emails or a domain). remove=true also removes them from Instantly. Ask the user first.
- `generate_image`: Make an image with GPT Image 2.5 Sunburst (costs Bourse credits: tell the user). Returns a public url and markdown ![image](url). To put it in an email, write that markdown line in the email body: Kata sends it as an <img> in an HTML part (the text part gets the link). Images in a first cold email lower deliverability: advise against it, but do it if the user wants.
- `send_test_email`: Send one test email now to any address (usually the user's own), exactly as a lead would get it, from any Kata mailbox, paused ones included. Outside the scheduler: no campaign, mailbox status, enrollment or lead changes. Content: variant_id, or campaign_id (+ step) to use its best angle, or your own subject and body. Variables come from contact (a lead in Kata, or any address: it then gets sample fields) and vars; {{link}} is the campaign link with them filled in (URL-encoded), without token and not tracked. No approval needed beyond the user asking for a test.
- `preview_email`: Show an email exactly as a lead would get it (variables filled, opt-out line and signature added), without sending. Same inputs as send_test_email, to is optional. Returns link_in_email (what the email shows for {{link}}), link_destination (the final URL: the Link: line of brief.md with the lead's variables URL-encoded, plus kata=<token>; PREVIEW stands for the token), link_tracked (true when the mailbox's domain has a link domain: the click is counted, then redirected), and untracked_links: URLs written by hand in the body. Those go out as written (variables URL-encoded) but their clicks are not counted and they get no kata token: use {{link}} for anything you want tracked.
- `create_mailbox`: Add one mailbox to Kata, active. provider agentmail (default): creates a new inbox in the AgentMail account; domain is a verified AgentMail domain already in Kata, or empty for @agentmail.to. provider resend: adds an address on a verified Resend domain already in Kata; give the full email. provider zapbox: connects an existing Zapmail (Google Workspace) mailbox; give its full email. Use a real first name. Ask the user first.
- `sync_mailboxes`: Import inboxes from AgentMail and verified domains from Resend into Kata. AgentMail mailboxes are added paused. Resend domains are added as sending domains. Never changes the status of a mailbox already in Kata (it also runs every 15 minutes).
- `update_campaign`: Rename a campaign, replace its brief.md (brief) or its link (target_url), or set its tracking (track_opens, track_clicks), or set its sending hours: each email goes out in its lead's local time (hours, default 8-17, weekdays only by default); the time zone comes from the lead's country column, else its email domain (.ie, .fr…), else the campaign's country; a lead with none of them can get it at any hour. One source of truth for the link: the "Link:" line of brief.md. target_url is a shortcut that rewrites that line (it wins over a Link: line inside brief when both are given); campaigns.target_url is only a copy of it. The link may hold contact variables, e.g. https://site.com/start?email={{email}}&fn={{first_name}}: {{link}} fills them per lead, URL-encoded (sean+ie@x.com becomes sean%2Bie%40x.com), and adds kata=<token> for the postback. Returns link: the URL, its variables and an example. Only the fields you pass change.
- `connect_domain`: Connect a domain from the Cloudflare account to AgentMail: writes the DNS records, starts verification, then creates the mailboxes (real first names recommended, 3 per domain). Stops if the domain already receives email elsewhere, unless force=true.
- `check_domains`: Check pending domains and create their mailboxes once verified.
- `create_campaign`: Create a campaign (status draft) and its brief.md. The brief gives the target, offer, proof and expected action; the AI reads it together with company.md. Then run check_campaign_brief.
- `generate_angles`: The AI writes variants (different angles) for one step. Step 0 = first email. Opus writes more candidates than needed, a strict reviewer scores each 0-100, and they are rewritten from its notes for up to 3 passes while the score rises; the best `count` are kept. The result gives each score and the score per pass.
- `list_layouts`: Email layout templates. The first cold email should stay plain (best inbox placement) unless the user asks otherwise. Images for the image slot come from generate_image. Layouts other than plain add HTML formatting (table-based, bulletproof button, dark-mode friendly). Gmail, Outlook and Zapmail mailboxes send the text version only: say so when a layout is chosen for a campaign whose mailboxes are Gmail, Outlook or Zapmail only.
- `add_variant`: Add a variant written by hand. Variables: {{first_name}}, {{company}}, {{email}}, any data key, {{sender_first}}; {{link}} = the campaign link (tracked when the mailbox has a link domain, always with kata=<token>). A variable inside a URL is URL-encoded; {{x|url}} encodes anywhere, {{x|raw}} never. A URL written by hand in the body is sent as is: not tracked, no token. The first email should stay layout plain unless the user asks; images come from generate_image.
- `import_leads`: Import contacts from a CSV (email column required; first_name, company and any other column become variables; a priority column orders the sends: 1 first, then 2, 3…, empty last). Each new address gets a free check (syntax, disposable, domain without mail server): invalid ones get status invalid and never enter a sequence; the result says how many (email_check). The full mailbox check runs at pull time, right before each lead enters the sequence. Pass either the CSV text (csv) or an uploaded file key (file, e.g. uploads/....csv). With campaign_id, contacts enter the sequence directly. With list_id, they join that lead list; the cron pulls them into the campaigns it feeds at send time.
- `set_campaign_status`: Activate, pause or archive a campaign. A campaign is the top switch: draft or paused = nothing planned for it, whatever the mailboxes. active = its emails are planned on the next scheduler run (every minute), only from its mailboxes that are themselves active. archived = paused and hidden from the main views (use it for finished or shelved campaigns; unarchive by setting active or paused). Run scheduler_dry_run first to see what would go out. Activating sends the campaign's first email at once when a planned lead is inside its local sending hours (the answer says to whom, or when it goes out), so the user sees it works; the others are spread over the day. Never activate without the user's approval.
- `run_scheduler`: REALLY SENDS. Runs the scheduler now, as the cron does every minute: plans the emails of active campaigns from active mailboxes, then sends every planned email whose time has come. It does nothing the cron would not do a minute later, but it is real sending. To look without sending, use scheduler_dry_run. Ask the user first.
- `scheduler_dry_run`: What the next scheduler run would plan, without sending or writing anything: for each email the contact, campaign, step, mailbox, variant (angle), subject, planned time (UTC) and final link. Also explains what blocks sending, in this order: (1) campaign status (only active campaigns send; set_sending only flips every campaign at once), (2) mailbox status and its domain status (both must be active), (3) the campaign's chosen mailboxes (none chosen = every active mailbox), (4) daily cap per mailbox, (5) the lead's local sending hours (campaign setting), this shows tomorrow's first run), (6) contacts suppressed, stopped or not due yet. Also lists emails already planned and waiting. as_if_active=true simulates draft or paused campaigns as active (mailboxes stay as they are). No AI personalization in the preview.
- `evolve`: Retire losing variants and, if there is room, have a new one written from the best.
- `leads_to_call`: Interested contacts not handled yet, with their reply.
- `campaign_report`: Performance of one campaign (or all): state (ok, error with the reason, completed, off), totals (sent, sent today, replies, interested, conversions, bounces = hard bounces, soft_bounces, contacts in sequence), the last bounce reasons, and per-variant stats (step, angle, subject, status, sent, successes, rate, p_best = probability of being the best variant, value, value_per_1000 = postback value per 1,000 emails sent). value: value per 1,000 sent for the campaign, its first email and its follow-ups, and ranked_by: the metric that ranks the angles (value_per_1000 once the campaign has 3 conversions with a value, else rate).
- `list_context`: List context files (no content). Company files are always in your context; campaign files must be read with read_context. With campaign_id: company files plus that campaign's files.
- `read_context`: Read the full content of one context file.
- `save_context`: Create or replace a context file (same scope, campaign and name = replaced). scope company: used everywhere (agent and emails). scope campaign: used for that campaign's emails and read on demand. Ask the user before saving.
- `delete_context`: Delete a context file. Ask the user first.
- `list_contacts`: List contacts (leads) with their data (CSV columns), status, value and sequences. Filters combine with AND. Returns count (all matches) and one page.
- `get_contact`: One contact by email or id: fields, data, suppression, enrollments, every message (with body) and events (replies, clicks, bounces).
- `update_contacts`: Edit contacts: set first_name/company and merge keys into data (a value sets the key, null removes it). One contact (email/id) or bulk by filters. Bulk needs the user's approval: run with dry_run first and tell the user the count. Returns matched and changed.
- `delete_contacts`: Delete contacts that were never emailed, with their enrollments and queued emails. Contacts already emailed are kept and listed (use suppress for them). Run dry_run first and get the user's approval.
- `stop_sequence`: Stop the sequence for these contacts (all campaigns, or one campaign) and cancel their queued emails. They are not suppressed.
- `suppress`: Unsubscribe addresses for good: add them to the suppression list, stop every sequence, cancel queued emails, mark the contacts unsubscribed. undo=true removes them from the suppression list only.
- `set_auto_reply`: Automatic answer to hot leads: when a lead replies interested and nobody answers it (reply) or marks it Done (mark_handled) within `hours`, Kata sends the AI answer itself, from the thread's mailbox, using the brief and what the lead did (pages visited, order form, conversion). One automatic answer per lead. hours: 0 (off), 1, 6, 12, 24 (default), 48 or 72. Without hours: returns the current setting and the leads waiting with when each answer goes out.
- `mark_handled`: The Done button on leads to call: mark an interested contact as handled (called, meeting booked). undo=true puts it back in leads_to_call.
- `enroll_contacts`: Put existing contacts into a campaign's sequence (they start at step 0). Selected by the same filters as list_contacts. Skips suppressed, bounced, unsubscribed, those already in that campaign or waiting in another one, those who already got an email from any campaign unless include_contacted, and replied/converted unless include_replied. Run dry_run first and get the user's approval.
- `list_lists`: Lead lists: id, name, description, members, unreachable (bounced or unsubscribed) and the campaigns each one feeds. A list is a source: connected to a campaign, the cron pulls its eligible leads into the sequence at send time.
- `create_list`: Create a lead list. Optionally fill it right away with the same filters as list_contacts (e.g. file from import_leads, data_match, search). Contacts are not duplicated: a list only groups them. from_unlisted: true makes the list from the leads that entered campaigns without a list (the 'Leads without a list' block of the Canvas) and connects it to those campaigns, with no new enrollment.
- `update_list`: Rename a lead list or change its description.
- `add_to_list`: Add existing contacts to a lead list, selected by the list_contacts filters. They wait in the list for the cron to pull them into the campaigns it feeds. To add new people, import_leads with list_id.
- `remove_from_list`: Remove contacts from a lead list (filters as list_contacts; list_id alone is refused, add all: true to empty it). Their sequences in the campaigns this list feeds stop, unless keep_sequences or another connected list still holds them. Contacts stay in Kata. Run dry_run first and get the user's approval.
- `connect_list`: Draw or erase the arrow from a lead list to a campaign. connect (default true): the campaign pulls eligible leads from this list at send time, verifying each email before pulling. connect false: the campaign stops pulling new leads; sequences already started go on. Run dry_run first and get the user's approval when the campaign is active.
- `delete_list`: Delete a lead list and its arrows. Contacts and their sequences stay. Ask the user first; dry_run shows the counts.
- `archive_list`: Archive or unarchive a lead list. Archived lists hide from the Leads page, the sidebar and list pickers, and stop feeding their campaigns (disconnected; leads already started go on). Their leads are not deleted. undo=true unarchives.
- `archive_leads`: Archive or unarchive leads. Archived leads are hidden from the default leads table, never emailed again (their pending enrollments are stopped), and do not count in list totals. Give emails or use the same filters as list_contacts. undo=true unarchives them.
- `add_leads`: Add leads to a lead list, new or already in Kata: the simplest way for one lead or a few (for a CSV file, use import_leads). Each lead: email (required), first_name, company, priority (1 is sent first, then 2, 3…; none goes last), and any other field, which becomes a variable (country, phone…). New addresses get the free email check; invalid ones are kept out. The leads wait in the list for the cron to pull them into the campaigns it feeds (verified before pulling, split between campaigns). Max 1000 per call. Tell the user when the list feeds an active campaign: those people will get emails.
- `list_webhook`: The webhook URL of a lead list: another tool (a form, Zapier, n8n, a CRM) POSTs leads to it and they join the list on their own, with the free email check. The cron pulls them into the campaigns the list feeds at send time, with a full email check before pulling. Body: one lead {email, first_name, company, priority, other fields become variables} or {leads: [...]} up to 1000. priority 1 is sent first, then 2, 3…; no priority goes after the others. rotate=true makes a new URL (the old one stops working).
- `list_mailboxes`: Sending mailboxes: domain, provider, status (active/paused), daily_cap, note (why paused), sent today, total sent, bounces (hard), domain status, and inbox placement of the Instantly warmup emails over 7 days (warmup_inbox_7d, warmup_spam_7d, inbox_rate when 10 or more landed). A mailbox sends only when it and its domain are active AND an active campaign uses it. Kata never activates a mailbox on its own: only set_mailbox, create_mailbox (a new mailbox) or the user in the UI do, and each change is logged (events type audit). Kata pauses one by itself when hard bounces pass 3%, or when more than 10% of its warmup emails land in spam.
- `set_mailbox`: Activate or pause a mailbox, change its daily_cap, or set its email signature (the line under the sender name). Give email (one address) or domain (all its addresses; activating them also resumes the domain). An active mailbox sends only for active campaigns that use it. Each change is logged (events type audit). Never activate without the user's approval.
- `set_domain`: Resume a domain Kata paused for bounces, or pause it. Daily limits are set per mailbox (set_mailbox), not per domain.
- `setup_link_domain`: Give a sending domain its own link domain (go.<domain>, else get/try/info) for click and unsubscribe links. Only possible when the domain is in the user's Cloudflare (token in Integrations with DNS Edit): registers the hostname on Kata's zone and writes the CNAME. Active a few minutes later (check_link_domains). Without it, links go straight to the campaign page and clicks are not counted.
- `check_link_domains`: Check the link domains being set up: they become active once Cloudflare has issued their certificate.
- `remove_mailbox`: Remove a mailbox from Kata (it stays at the provider; sync will not bring it back). Its queued emails are cancelled. Ask the user first.
- `remove_domain`: Remove a domain and all its mailboxes from Kata (not from the provider or DNS). Ask the user first.
- `list_variants`: Variants (angles) of a campaign with full subject and body, status and stats (sent, clicks, replies, interested, conversions, rate, p_best), plus the sequence steps.
- `set_variant`: Retire a variant or put it back in the test (status), or edit its angle, subject, body, layout or slots. Only the fields you pass change. Editing a variant that already sent mixes its stats: prefer add_variant and retire the old one.
- `get_strategy`: The follow-up strategy of a campaign: its branches (follow-up step, condition, delay, on/off, what it sends, live emails) with sent, opens, clicks, replies and interested per branch, the fixed limits, and the log of changes. Read it before changing the strategy.
- `set_branch`: You run the follow-up strategy like a salesperson: the first email is a split test, then each lead gets the follow-up that fits what they did. A branch = follow-up step + condition + delay + its emails. cond: any (everyone who did not reply; the fallback), no_open (opened nothing; only meaningful when opens are tracked), opened (opened, no click), clicked (clicked, no reply). The most specific branch wins; a lead no branch fits gets no more email. Replies never get an automatic follow-up: answer them with reply. Add a branch (step, cond, delay_days, label = what it sends in a few words, e.g. "short bump, new subject"), then write its emails with add_variant or generate_angles with its branch_id. Change one by passing id (delay_days, status active|paused, label, cond), or remove=true. Always give why: it goes to the change log the user reads. Fixed limits: at most 4 emails per lead (step 1 to 3), at least 1 day between emails. Review get_strategy regularly and adapt: cut branches that bring nothing, give hot leads (clicked) a faster, more personal email.
- `review_strategy`: Run the daily strategy review of a campaign now (it also runs by itself once a day for active campaigns with the autopilot on). It adds a personal "Clicked, no reply" follow-up when leads clicked without replying, splits leads who never opened into a follow-up with a new subject once enough first emails were tracked, and pauses follow-ups that sent 150 emails without a reply or click. Returns the changes and what it waits for. dry_run: true shows the changes without making them.
- `set_steps`: Old way, kept for simple campaigns: prefer set_branch (follow-ups by what the lead did). Set a campaign's sequence: follow-up delays in days after the previous email, e.g. [3, 5] = first email, follow-up 1 three days later, follow-up 2 five days after that. [] = no follow-up. Each follow-up step needs its variants (generate_angles with step).
- `delete_campaign`: Delete a campaign that never sent (variants, steps, enrollments, campaign files; contacts stay). A campaign that sent is refused: pause it instead. Ask the user first; dry_run shows what goes.
- `list_messages`: Emails, newest first: scheduled, sent or failed, with a body preview. Filters: campaign_id, status, flag (clicked/replied/interested/converted/bounced), contact email. Returns count and one page.
- `get_message`: One email in full: subject, body, mailbox, contact, campaign, angle, status, flags and its events (reply text, click, bounce).
- `set_sending`: Global switch, a shortcut over campaign statuses (there is no separate flag): on=false pauses every active campaign and cancels the emails already planned; on=true sets every paused campaign back to active (drafts stay drafts). Mailbox statuses are not touched. Resuming needs the user's approval.
- `reply`: Reply to a lead in the same thread, from the mailbox that wrote to them (AgentMail, Resend, Gmail, Outlook, Kata's pool; Zapmail with its thread ids, like follow-ups; Zapmail replies are polled every 5 minutes). Give message_id (one email Kata sent) or email (the lead: the last email sent to them), and text. draft_only=true sends nothing: with text it returns the email as it would go, without text the AI writes a draft from the brief, the company memory and the thread (instructions steers it). Show the draft to the user and send only with their approval. The reply goes out even if the mailbox is paused (a 1:1 answer, not a campaign send) and shows in the lead's timeline (event reply_sent). The sender name and signature are added. Sending marks the lead read in the Inbox (list_inbox gives message_id and email).
- `list_inbox`: The Inbox: every reply received, one row per lead (its latest reply), newest first. Each row: contact_id, email, first_name, company, status (the reply kind: interested, not_interested, unsubscribe, ooo, wrong_person, other), unread (not opened in Kata yet), answered (you replied after it), replies (how many), message_id (pass it to reply), campaign, mailbox, subject, text (what they wrote), at. Also counts per status, the unread total, and the campaigns and mailboxes that got replies. Filters: status, campaign_id, mailbox, unread=true, q (text in email, name, company, subject or reply). 50 rows a page (limit up to 200), page from 0. Spam complaints and unsubscribe-link clicks are not listed.
- `set_reply_status`: Correct the AI tag of a lead's latest reply (what the user does from the Inbox). status: interested, not_interested, unsubscribe, ooo, wrong_person or other. Nothing restarts: any status except ooo stops the lead's sequence, ooo leaves it as it is. unsubscribe suppresses the address; moving away from unsubscribe lifts that suppression. interested puts the lead in leads_to_call and counts as a success for the angle. Ask the user before you change a tag.
- `export_csv`: Export to CSV and get a download link (valid 24 hours, works for anyone who has it; give it to the user). kind events (default) = the activity log: sent, click, reply, reply_sent, bounce, visit, conversion, pause…; kind messages = the emails with status, flags, bounce type and reason. Filters: campaign_id, type (an event type for events, a status scheduled|sent|failed for messages), mailbox, period 7d|30d|90d|all (default all). 50,000 rows at most.
- `enrich_leads`: Enrich leads from their work email through Bourse (Tomba person + company lookup): job_title, seniority, role, company, company_domain, location, country, linkedin, twitter, company_industry, company_size, company_linkedin, company_description. Only empty fields of the lead's data are filled; enriched_at is set, and leads already enriched are skipped (only_missing=false to redo them). Personal inboxes (gmail, outlook…) are skipped. Costs about $0.021 per address found, nothing on a miss. Without confirm it spends nothing: it returns the count and the cost; tell the user, then call again with confirm=true and the same filters. Give emails, list_id or campaign_id. max: default 50, up to 200 per call.
- `get_postback`: The postback URL the user's backend calls to report a conversion (GET or POST, with email or kata=<token>, optional value, event and data: free lead fields saved on the contact, not a conversion when sent alone), and the last conversion received.
- `query`: Run ONE read-only SQL SELECT (or WITH … SELECT) on the Kata SQLite database, max 200 rows. For anything the other tools do not cover. Dates are Unix ms. Tables: contacts(id, email, first_name, company, data JSON text: use json_extract(data,'$.country'), status new|enrolled|replied|bounced|unsubscribed|converted, value, soft_bounces, created_at, handled_at); campaigns(id, name, status draft|active|paused, target_url, brief, created_at); steps(campaign_id, step, delay_days); variants(id, campaign_id, step, angle, subject, body, status active|retired, parent_id, origin human|ai); enrollments(id, campaign_id, contact_id, step = next step, next_at, status pending|scheduled|done|stopped, mailbox); messages(id, token, enrollment_id, campaign_id, contact_id, mailbox, variant_id, step, subject, body, status scheduled|sending|sent|failed, send_at, sent_at, error, clicked, replied, interested, converted, bounced = hard bounce, bounce_type hard|soft, bounce_code, bounce_reason, value); events(id, type sent|click|open|reply|reply_sent|bounce|visit|unsubscribe|conversion|data|pause|evolve|error|domain, message_id, contact_id, detail, at; reply detail starts with the kind interested|not_interested|unsubscribe|ooo|wrong_person|other, bounce detail with hard|soft and the SMTP code); suppression(email, reason, at); mailboxes(email, domain, display_name, daily_cap, status, provider, note); domains(domain, daily_cap, status, provider, verify_status, note); context_files(id, scope, campaign_id, name, kind, content).

## Pricing

- Kata's shared inboxes: $0.04 per email (1 credit = 1 email). No daily cap beyond your credits. $10 free to start (250 credits).
- Your own inboxes: Starter $29/month (50,000 emails), Growth $79 (150,000), Scale $249 (500,000).
- No limits on contacts, inboxes, domains or seats. Optional research on every lead: $0.05 per lead.

## Optional

- [Landing page as markdown](https://katasend.com/?agent=1)
- [Terms of Service](https://katasend.com/terms)
- [Privacy Policy](https://katasend.com/privacy)
