{"version":1,"actions":[{"key":"chatbots.bot.list","app":"chatbots","title":"List Chatbots","description":"List the chatbots in your organization with their status (draft, live or paused).","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"chatbots.bot.get","app":"chatbots","title":"Get a Chatbot's Settings","description":"Show one chatbot's settings: greeting, instructions, lead email, fallback, allowed websites and status.","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.bot.create","app":"chatbots","title":"Create a Chatbot","description":"Create a new chatbot as a draft. Pick what it is for (sales, scheduling, support, recruiting or generic); a blank greeting or instructions start from that purpose's suggested wording. Turn it live later by updating its status.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"purpose":{"type":"string","enum":["sales","scheduling","support","recruiting","generic"],"description":"What the chatbot is for. Defaults to generic."},"greeting":{"type":"string","maxLength":2000,"description":"The first message visitors see. Leave out to use the suggested greeting."},"instructions":{"type":"string","maxLength":8000,"description":"How the chatbot should behave. Leave out to use the suggested instructions."}},"required":["name"],"additionalProperties":false}},{"key":"chatbots.bot.update","app":"chatbots","title":"Update a Chatbot","description":"Change a chatbot's settings. Only the fields you send change. Status \"live\" turns the chatbot on for the websites it is installed on; \"paused\" turns it off.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":120},"purpose":{"type":"string","enum":["sales","scheduling","support","recruiting","generic"]},"greeting":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"The first message visitors see. Supports **bold**."},"instructions":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"description":"How the chatbot should behave and what to avoid."},"knowledge":{"anyOf":[{"type":"string","maxLength":60000},{"type":"null"}],"description":"Notes the chatbot always knows."},"notifyEmail":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"description":"Where new leads and handoffs are emailed."},"dailyMessageCap":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}]},"status":{"type":"string","enum":["draft","live","paused"]},"fallbackMode":{"type":"string","enum":["handoff","contact"],"description":"handoff = take the visitor's details; contact = send them to your phone or contact page."},"contactUrl":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"contactPhone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"knowledgeOnly":{"type":"boolean","description":"Answer only from the notes and sources."},"allowedDomains":{"type":"array","items":{"type":"string"},"maxItems":20,"description":"Websites the chatbot may run on, like yourbusiness.com."}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.bot.new_preview_link","app":"chatbots","title":"Make a New Preview Link","description":"Replace a chatbot's private preview link with a new one. Anyone holding the old link loses access to the preview. Returns the new link's path, which opens on your chatbots address.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.bot.delete","app":"chatbots","title":"Delete a Chatbot","description":"Delete a chatbot. It stops answering on every website it is installed on and disappears from your list. Its leads and conversations are kept.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.version.list","app":"chatbots","title":"List a Chatbot's Version History","description":"List the saved versions of a chatbot's settings and knowledge, newest first, with what changed in each and who changed it. Use a version's id to restore it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["settings","knowledge"],"description":"Only settings versions or only knowledge versions. Leave out for both."},"limit":{"type":"integer","minimum":1,"maximum":200,"description":"How many to return (default 50)."}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.version.restore","app":"chatbots","title":"Restore an Earlier Version","description":"Put a chatbot's settings or knowledge back the way they were in an earlier version. Nothing is lost: the restore is saved as a new version, so it can be undone the same way. Restoring settings never changes whether the chatbot is live.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid","description":"The id from the version history."}},"required":["botId","versionId"],"additionalProperties":false}},{"key":"chatbots.source.list","app":"chatbots","title":"List a Chatbot's Knowledge Sources","description":"List the websites, pages and files a chatbot answers from, with their size and when each was last read. Use a source's id to refresh or remove it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.source.get","app":"chatbots","title":"Read a Knowledge Source","description":"Show the text the chatbot learned from one knowledge source (the first 20,000 characters, and whether there is more).","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"}},"required":["sourceId"],"additionalProperties":false}},{"key":"chatbots.source.add_page","app":"chatbots","title":"Add a web page to a chatbot's knowledge","description":"Read one web page and add its text to what the chatbot knows. The page must be public; pages built entirely in JavaScript can't be read.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri","description":"The full page address, starting with https://"}},"required":["botId","url"],"additionalProperties":false}},{"key":"chatbots.source.crawl_site","app":"chatbots","title":"Import a whole website into a chatbot's knowledge","description":"Read a website (up to 250 pages, following its sitemap or links) and add it to what the chatbot knows as one source. Menus, headers and footers are kept once. Takes up to a minute.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri","description":"The site's address, starting with https://"},"exclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Paths to skip, like \"/blog/*\" or \"/team/jane\". A * matches anything. Kept and reused when the source is refreshed."}},"required":["botId","url"],"additionalProperties":false}},{"key":"chatbots.source.upload_file","app":"chatbots","title":"Add a file to a chatbot's knowledge","description":"Add a document to what the chatbot knows. Send either the file's text (content, with a name like price-list.md) or the address of a file to download (url). PDFs with real text, HTML and any plain-text format (txt, md, csv, json) work; scanned PDFs have no text to read. Files are limited to 10 MB and the first 60,000 characters are kept. Files can't be refreshed later: add the new version and remove the old one.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":200,"description":"The file name shown in the source list. Required with content; taken from the address otherwise."},"content":{"type":"string","minLength":1,"maxLength":2000000,"description":"The file's text. HTML is cleaned to plain text when the name ends in .html."},"url":{"type":"string","format":"uri","description":"The address of a file to download, starting with https://"}},"required":["botId"],"additionalProperties":false}},{"key":"chatbots.source.remove","app":"chatbots","title":"Remove a Knowledge Source","description":"Remove a website, page or file from what a chatbot knows. The chatbot stops using it right away. The previous knowledge stays in the version history and can be restored.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"}},"required":["sourceId"],"additionalProperties":false}},{"key":"chatbots.source.refresh","app":"chatbots","title":"Refresh a Knowledge Source","description":"Read a website or page source again so the chatbot has its latest content, skipping the same paths as before. Uploaded files can't be refreshed.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"sourceId":{"type":"string","format":"uuid"}},"required":["sourceId"],"additionalProperties":false}},{"key":"chatbots.lead.list","app":"chatbots","title":"List Chatbot Leads","description":"List the people your chatbots collected as leads, newest first: name, email or phone, what they were after, and where each stands (new, contacted, won or lost).","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"botId":{"type":"string","format":"uuid","description":"Only this chatbot's leads."},"status":{"type":"string","enum":["new","contacted","won","lost"]},"limit":{"type":"integer","minimum":1,"maximum":500,"description":"How many to return (default 100)."}},"additionalProperties":false}},{"key":"chatbots.lead.set_status","app":"chatbots","title":"Set a Lead's Status","description":"Move a chatbot lead along: new, contacted, won or lost.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["new","contacted","won","lost"]}},"required":["leadId","status"],"additionalProperties":false}},{"key":"chatbots.handoff.list","app":"chatbots","title":"List Handoff Requests","description":"List the requests your chatbots passed to a person: visitors who asked for help the chatbot couldn't give. Shows open requests unless you ask for resolved ones or all.","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["open","resolved","all"],"description":"Defaults to open."},"botId":{"type":"string","format":"uuid","description":"Only this chatbot's requests."},"limit":{"type":"integer","minimum":1,"maximum":500,"description":"How many to return (default 100)."}},"additionalProperties":false}},{"key":"chatbots.handoff.get","app":"chatbots","title":"Read a Handoff Request","description":"Show one handoff request with the visitor's details and the conversation that led to it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"chatbots:read","input":{"type":"object","properties":{"handoffId":{"type":"string","format":"uuid"}},"required":["handoffId"],"additionalProperties":false}},{"key":"chatbots.handoff.resolve","app":"chatbots","title":"Resolve a Handoff Request","description":"Mark a handoff request as dealt with, so it leaves your open list.","kind":"write","risk":{},"access":{"role":"member"},"scope":"chatbots:write","input":{"type":"object","properties":{"handoffId":{"type":"string","format":"uuid"}},"required":["handoffId"],"additionalProperties":false}},{"key":"chatbots.handoff.staff_resolve","app":"chatbots","title":"Resolve a handoff request for a client (staff)","description":"For platform staff working the handoff queue: mark any client's handoff request as dealt with, with an optional note. Recorded in the staff activity log.","kind":"write","risk":{},"access":{"role":"staff","capability":"handoffs:manage"},"scope":"operations:write","input":{"type":"object","properties":{"handoffId":{"type":"string","format":"uuid"},"note":{"type":"string","maxLength":2000,"description":"Why or how it was resolved."}},"required":["handoffId"],"additionalProperties":false}},{"key":"reputation.survey.list","app":"reputation","title":"List Surveys","description":"List your satisfaction surveys with their status (active, draft or archived), scale and which one is the default.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.survey.get","app":"reputation","title":"Get a Survey","description":"Show one survey in full: its question, labels, thank-you wording for each kind of answer, extra questions, email and text wording, and its look.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.create","app":"reputation","title":"Create a Survey","description":"Create a new survey styled with your brand. Your first survey becomes the default one that invitations use.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"metric":{"type":"string","enum":["nps","csat5","csat10"],"description":"The rating scale: nps = 0 to 10 likelihood to recommend; csat5 = 1 to 5 stars; csat10 = 1 to 10."},"preset":{"type":"string","enum":["classic","luxe","clinical","warm","minimal"],"description":"A starting look: classic, luxe, clinical, warm or minimal."}},"additionalProperties":false}},{"key":"reputation.survey.update","app":"reputation","title":"Update a Survey","description":"Change a survey's name, scale, alert threshold, wording or look. Only the fields you send change; wording and look fields are merged into what is saved. Wording may use {practice}, {first_name}, {provider} and {location}.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."},"name":{"type":"string","minLength":1,"maxLength":120},"metric":{"type":"string","enum":["nps","csat5","csat10"],"description":"The rating scale: nps = 0 to 10 likelihood to recommend; csat5 = 1 to 5 stars; csat10 = 1 to 10."},"alertAtOrBelow":{"type":"integer","description":"Scores at or below this send a same-day alert to your alert emails."},"content":{"type":"object","additionalProperties":{},"description":"Wording to change: question, lowLabel, highLabel, commentPlaceholder, submitLabel, askMayContact, mayContactLabel, segments (promoter, passive, detractor: followup, thanksTitle, thanksBody, reviewAsk), extraQuestions, emailSubject, emailHeading, emailIntro, emailSignoff, reminderSubject, smsBody, footerNote."},"theme":{"type":"object","additionalProperties":{},"description":"Look to change: preset, background, surface, text, muted, accent, accentText, border (hex colors), headingFont, bodyFont, radius, buttonStyle, layout, logoUrl, headerImageUrl, headingCaps."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.activate","app":"reputation","title":"Activate a Survey","description":"Make an archived or draft survey active again, so invitations can use it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.archive","app":"reputation","title":"Archive a Survey","description":"Archive a survey so no new invitations use it. Surveys already sent can still be answered. The default survey can't be archived.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.make_default","app":"reputation","title":"Make a Survey the Default","description":"Make this survey the default one that invitations, CSV uploads and connected systems use when no survey is named.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.duplicate","app":"reputation","title":"Copy a Survey","description":"Make an active copy of a survey, with the same wording and look, to edit separately.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.delete","app":"reputation","title":"Delete a Survey","description":"Delete a survey and cancel its invitations that haven't gone out yet. Its responses are kept. The default survey can't be deleted.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.survey.send_test","app":"reputation","title":"Email Yourself a Test Survey","description":"Email the saved version of a survey to your own address so you can see what patients and customers receive. It never goes to anyone else.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"surveyId":{"type":"string","format":"uuid","description":"The survey's id, from List surveys."}},"required":["surveyId"],"additionalProperties":false}},{"key":"reputation.invitation.list","app":"reputation","title":"List Survey Invitations","description":"List the 100 most recent survey invitations with their status (scheduled, sent, answered, skipped, failed or canceled), channel and when they go out.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["scheduled","sending","sent","opened","responded","failed","skipped","canceled"]}},"additionalProperties":false}},{"key":"reputation.invitation.send","app":"reputation","title":"Send a Survey to One Person","description":"Survey one person by email or text. It goes out after your usual delay from the visit, inside your sending hours, unless sendNow is true. Each survey sent costs tokens. People who unsubscribed or were surveyed recently are skipped.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"email":{"type":"string","maxLength":254},"phone":{"type":"string","maxLength":40,"description":"A mobile number. Texts go only to people who agreed to receive them."},"firstName":{"type":"string","maxLength":100},"lastName":{"type":"string","maxLength":100},"smsConsent":{"type":"boolean","description":"true only if this person agreed to receive texts."},"visitAt":{"type":"string","maxLength":60,"description":"When the visit was, in your time zone, like 2026-10-16T14:30."},"surveyId":{"type":"string","format":"uuid","description":"Which survey. Defaults to your default survey."},"locationId":{"type":"string","format":"uuid"},"providerId":{"type":"string","format":"uuid"},"channel":{"type":"string","enum":["auto","email","sms"],"description":"auto = email when there is one, otherwise text."},"sendNow":{"type":"boolean","description":"Send right away (inside sending hours) instead of waiting the usual delay."}},"additionalProperties":false}},{"key":"reputation.invitation.import","app":"reputation","title":"Send Surveys from a CSV","description":"Schedule a survey for every row of an appointment list in CSV form (up to 5,000 rows). It needs an email or phone column; name, visit date, location and provider columns are used when present. Each survey sent costs tokens.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":5000000,"description":"The CSV file's contents, header row first."},"surveyId":{"type":"string","format":"uuid","description":"Which survey. Defaults to your default survey."},"locationId":{"type":"string","format":"uuid","description":"The location for rows that don't name one."},"smsConsent":{"type":"boolean","description":"true only if everyone in the file agreed to receive texts."}},"required":["csv"],"additionalProperties":false}},{"key":"reputation.invitation.send_due","app":"reputation","title":"Send Due Surveys Now","description":"Send every survey and reminder that is due right now instead of waiting for the next automatic run. Each survey sent costs tokens; if the wallet runs out, sending pauses until it is topped up.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.invitation.cancel","app":"reputation","title":"Cancel a Scheduled Survey","description":"Cancel a survey that hasn't gone out yet. One that was already sent can't be canceled.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"invitationId":{"type":"string","format":"uuid","description":"The invitation's id, from List survey invitations."}},"required":["invitationId"],"additionalProperties":false}},{"key":"reputation.visit.report","app":"reputation","title":"Report a Visit","description":"Report a visit the way a booking or records system does, naming the location and provider by name, and the survey is scheduled for it. Sending the same externalId twice never surveys anyone twice. Each survey sent costs tokens.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"externalId":{"type":"string","minLength":1,"maxLength":200},"firstName":{"type":"string","maxLength":100},"lastName":{"type":"string","maxLength":100},"email":{"type":"string","maxLength":254},"phone":{"type":"string","maxLength":40},"smsConsent":{"type":"boolean"},"visitAt":{"type":"string","maxLength":60},"location":{"type":"string","maxLength":120},"provider":{"type":"string","maxLength":120},"survey":{"type":"string","format":"uuid"},"sendNow":{"type":"boolean"}},"additionalProperties":false}},{"key":"reputation.summary.get","app":"reputation","title":"Get the Satisfaction Summary","description":"Show the headline numbers for a period: NPS or average score, responses, surveys sent, response rate, how many were happy, neutral or unhappy, follow-ups waiting and review link clicks, with a weekly trend.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"days":{"type":"number","enum":[7,30,90,365],"description":"The period, in days. Defaults to 90."}},"additionalProperties":false}},{"key":"reputation.response.list","app":"reputation","title":"List Responses","description":"List survey responses, newest first: score, how they felt, comment, answers and follow-up status. Contact details are not included. Use the returned next value as before to get older ones.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"since":{"type":"string","description":"Only responses on or after this date or time (ISO 8601)."},"before":{"type":"string","description":"Only responses before this date or time (ISO 8601)."},"limit":{"type":"integer","minimum":1,"maximum":500},"segment":{"type":"string","enum":["promoter","passive","detractor"],"description":"promoter = happy, passive = neutral, detractor = unhappy."},"followupOpen":{"type":"boolean","description":"true = only responses still waiting on a follow-up."}},"additionalProperties":false}},{"key":"reputation.response.get","app":"reputation","title":"Get a Response","description":"Show one survey response with its follow-up status and your team's notes on it. Contact details are not included.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"responseId":{"type":"string","format":"uuid","description":"The response's id, from List responses."}},"required":["responseId"],"additionalProperties":false}},{"key":"reputation.response.set_follow_up","app":"reputation","title":"Set a Response's Follow-Up","description":"Open a follow-up on a response, mark it resolved, or clear it, with an optional note that is added to the response's history.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"responseId":{"type":"string","format":"uuid","description":"The response's id, from List responses."},"status":{"type":"string","enum":["open","resolved","none"],"description":"open = needs a follow-up; resolved = done; none = no follow-up needed."},"note":{"type":"string","maxLength":5000}},"required":["responseId","status"],"additionalProperties":false}},{"key":"reputation.response.add_note","app":"reputation","title":"Add a Note to a Response","description":"Add an internal note to a survey response, visible to your team only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"responseId":{"type":"string","format":"uuid","description":"The response's id, from List responses."},"body":{"type":"string","minLength":1,"maxLength":5000}},"required":["responseId","body"],"additionalProperties":false}},{"key":"reputation.response.delete","app":"reputation","title":"Delete a Response","description":"Delete a survey response. It no longer shows in any list, count, export or report.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"responseId":{"type":"string","format":"uuid","description":"The response's id, from List responses."}},"required":["responseId"],"additionalProperties":false}},{"key":"reputation.review.list","app":"reputation","title":"List Reviews","description":"List the public reviews in your reviews inbox, newest first, with their rating, text and reply status. Shows up to 200.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"filter":{"type":"string","enum":["unreplied","low"],"description":"unreplied = no posted reply yet; low = 3 stars or fewer."},"platform":{"type":"string","enum":["google","yelp","healthgrades","facebook","zocdoc","vitals","webmd","realself","zillow","bbb","other"],"description":"Where the review was posted: google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other."}},"additionalProperties":false}},{"key":"reputation.review.add","app":"reputation","title":"Add a Review","description":"Add a public review to your reviews inbox by hand, with its rating, text, author and link.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"platform":{"type":"string","enum":["google","yelp","healthgrades","facebook","zocdoc","vitals","webmd","realself","zillow","bbb","other"],"description":"Where the review was posted: google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other."},"rating":{"type":"integer","minimum":1,"maximum":5,"description":"Star rating, 1 to 5."},"body":{"type":"string","maxLength":10000,"description":"The review's text."},"authorName":{"type":"string","maxLength":200},"reviewUrl":{"type":"string","format":"uri","description":"Link to the review, starting with https://"},"postedAt":{"type":"string","description":"When it was posted (a date or ISO 8601 time). Defaults to now."},"locationId":{"type":"string","format":"uuid","description":"Which of your locations it is about, from List locations."}},"additionalProperties":false}},{"key":"reputation.review.import","app":"reputation","title":"Import Reviews from a CSV","description":"Import reviews from CSV text with a header row. Recognized columns: rating, review (or text), author, date, platform, url, id and location. Rows with an id that was imported before are skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":5000000,"description":"The CSV file's contents, header row first."},"platform":{"type":"string","enum":["google","yelp","healthgrades","facebook","zocdoc","vitals","webmd","realself","zillow","bbb","other"],"description":"The platform for rows without a platform column. Defaults to google."}},"required":["csv"],"additionalProperties":false}},{"key":"reputation.review.reply","app":"reputation","title":"Save a Review Reply","description":"Save a draft reply to a review, or mark the reply as posted once you have posted it on the review site. This does not post anything for you. An empty reply clears it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"reviewId":{"type":"string","format":"uuid","description":"The review's id, from List reviews."},"replyBody":{"type":"string","maxLength":10000},"posted":{"type":"boolean","description":"true = you have posted this reply on the review site."}},"required":["reviewId","replyBody"],"additionalProperties":false}},{"key":"reputation.review.delete","app":"reputation","title":"Remove a Review","description":"Remove a review from your reviews inbox. It stays on the review site; this only removes it from your list.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"reviewId":{"type":"string","format":"uuid","description":"The review's id, from List reviews."}},"required":["reviewId"],"additionalProperties":false}},{"key":"reputation.contact.list","app":"reputation","title":"List Contacts","description":"List or search the people you've sent surveys to, newest first, 50 at a time, with whether they still receive surveys. To act on one person, look them up by their exact email address.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{"search":{"type":"string","maxLength":100,"description":"Part of a name, email or phone number."},"email":{"type":"string","format":"email","description":"Find one person by their exact email address."},"page":{"type":"integer","minimum":1}},"additionalProperties":false}},{"key":"reputation.contact.unsubscribe","app":"reputation","title":"Stop Surveys to a Person","description":"Stop sending surveys to one person and cancel any of theirs that haven't gone out yet.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"contactId":{"type":"string","format":"uuid","description":"The person's id, from List contacts."}},"required":["contactId"],"additionalProperties":false}},{"key":"reputation.contact.resubscribe","app":"reputation","title":"Resume Surveys to a Person","description":"Turn surveys back on for someone whose surveys were stopped. Only do this if they asked for it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"contactId":{"type":"string","format":"uuid","description":"The person's id, from List contacts."}},"required":["contactId"],"additionalProperties":false}},{"key":"reputation.contact.delete","app":"reputation","title":"Delete a Contact","description":"Delete a person from your contacts and cancel their surveys that haven't gone out yet. Their past responses are kept.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"contactId":{"type":"string","format":"uuid","description":"The person's id, from List contacts."}},"required":["contactId"],"additionalProperties":false}},{"key":"reputation.settings.get","app":"reputation","title":"Get Reputation Settings","description":"Show your Reputation settings: time zone, sending hours, delay after a visit, reminders, how often one person can be surveyed, alert emails, healthcare mode, sender address and custom survey domain.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.settings.update","app":"reputation","title":"Update Reputation Settings","description":"Change your general Reputation settings. Only the fields you send change. Healthcare mode keeps names, providers and visit details out of every email.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"fromName":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"description":"The practice or business name patients see as the sender."},"replyTo":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"description":"Where replies to survey emails go."},"timezone":{"type":"string","description":"An IANA time zone, like America/New_York."},"healthcareMode":{"type":"boolean"},"sendDelayMinutes":{"type":"integer","minimum":0,"maximum":10080,"description":"How long after a visit the survey goes out."},"quietStart":{"type":"integer","minimum":0,"maximum":23,"description":"Hour (0 to 23) when the sending window opens."},"quietEnd":{"type":"integer","minimum":1,"maximum":24,"description":"Hour (1 to 24) when the sending window closes; must be after quietStart."},"reminderEnabled":{"type":"boolean","description":"Send one reminder to people who haven't answered."},"reminderAfterDays":{"type":"integer","minimum":1,"maximum":30},"minDaysBetween":{"type":"integer","minimum":0,"maximum":365,"description":"The fewest days between two surveys to the same person."},"alertEmails":{"type":"array","items":{"type":"string","format":"email"},"maxItems":20,"description":"Who is emailed the same day a low score comes in."}},"additionalProperties":false}},{"key":"reputation.settings.set_sender","app":"reputation","title":"Set the Sending Address","description":"Set the email address surveys are sent from, like feedback@yourpractice.com. Your domain must be verified before it is used; until then surveys come from our standard address with your name. Send an empty address to go back to the standard one.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"fromEmail":{"anyOf":[{"type":"string","maxLength":254},{"type":"null"}]}},"required":["fromEmail"],"additionalProperties":false}},{"key":"reputation.settings.set_domain","app":"reputation","title":"Set a Custom Survey Domain","description":"Use your own web address for survey links, like feedback.yourpractice.com. It must be a subdomain pointed at us in your DNS. Send an empty domain to go back to the standard address.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"customDomain":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}]}},"required":["customDomain"],"additionalProperties":false}},{"key":"reputation.location.list","app":"reputation","title":"List Locations","description":"List your office locations, which surveys, providers, review links and reports can be tied to.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.location.add","app":"reputation","title":"Add a Location","description":"Add an office location, so responses and review links can be tied to it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"address":{"type":"string","maxLength":300},"phone":{"type":"string","maxLength":40}},"required":["name"],"additionalProperties":false}},{"key":"reputation.location.remove","app":"reputation","title":"Remove a Location","description":"Remove a location and hide its review links. Its past responses keep their history.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"locationId":{"type":"string","format":"uuid","description":"The location's id, from List locations."}},"required":["locationId"],"additionalProperties":false}},{"key":"reputation.provider.list","app":"reputation","title":"List Providers","description":"List the providers (doctors, staff or agents) that surveys and reports can be tied to.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.provider.add","app":"reputation","title":"Add a Provider","description":"Add a provider, optionally at one of your locations, so responses can be tied to them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"title":{"type":"string","maxLength":120,"description":"Like MD, DDS or Hygienist."},"locationId":{"type":"string","format":"uuid","description":"The location's id, from List locations."}},"required":["name"],"additionalProperties":false}},{"key":"reputation.provider.remove","app":"reputation","title":"Remove a Provider","description":"Remove a provider from your list. Their past responses keep their history.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"providerId":{"type":"string","format":"uuid","description":"The provider's id, from List providers."}},"required":["providerId"],"additionalProperties":false}},{"key":"reputation.review_site.list","app":"reputation","title":"List Review Links","description":"List the public review links (Google, Yelp and others) offered to everyone who answers a survey, and whether each is shown.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.review_site.add","app":"reputation","title":"Add a Review Link","description":"Add a link to one of your public review pages. It is offered on every thank-you page, whatever the score. For Google, a Place ID (starting ChIJ) is turned into the write-a-review link.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"platform":{"type":"string","enum":["google","yelp","healthgrades","facebook","zocdoc","vitals","webmd","realself","zillow","bbb","other"],"description":"google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other."},"url":{"type":"string","minLength":1,"maxLength":2000,"description":"The full https:// link to your review page, or a Google Place ID."},"label":{"type":"string","maxLength":80,"description":"Button text. Defaults to Review us on <platform>."},"locationId":{"type":"string","format":"uuid","description":"Show it only for surveys from this location."}},"required":["url"],"additionalProperties":false}},{"key":"reputation.review_site.set_active","app":"reputation","title":"Show or Hide a Review Link","description":"Show or hide one review link on the thank-you pages without deleting it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"reviewSiteId":{"type":"string","format":"uuid","description":"The review link's id, from List review links."},"active":{"type":"boolean"}},"required":["reviewSiteId","active"],"additionalProperties":false}},{"key":"reputation.review_site.remove","app":"reputation","title":"Delete a Review Link","description":"Delete a review link for good. To take it off the thank-you pages for now, hide it instead.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"reviewSiteId":{"type":"string","format":"uuid","description":"The review link's id, from List review links."}},"required":["reviewSiteId"],"additionalProperties":false}},{"key":"reputation.api_key.list","app":"reputation","title":"List Connection Keys","description":"List the keys your booking or records systems use to report visits, with when each was last used. The keys themselves are never shown again.","kind":"read","risk":{},"access":{"role":"member"},"scope":"reputation:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.api_key.create","app":"reputation","title":"Create a Connection Key","description":"Create a key for a booking or records system to report visits so surveys go out automatically. The key is shown only once, in this result: copy it now, because it can't be shown again.","kind":"write","risk":{},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"name":{"type":"string","maxLength":80,"description":"What will use it, like Front desk scheduler."}},"additionalProperties":false}},{"key":"reputation.api_key.revoke","app":"reputation","title":"Revoke a Connection Key","description":"Revoke a connection key. Anything using it stops working immediately.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"reputation:write","input":{"type":"object","properties":{"keyId":{"type":"string","format":"uuid","description":"The key's id, from List connection keys."}},"required":["keyId"],"additionalProperties":false}},{"key":"reputation.setup.list","app":"reputation","title":"List Pending Customer Setup","description":"Staff only: customer survey domains and sending addresses waiting on our team to finish setting up, oldest first.","kind":"read","risk":{},"access":{"role":"staff","capability":"reputation:manage"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"reputation.setup.recheck","app":"reputation","title":"Recheck a Customer's Domain","description":"Staff only: check a customer's custom survey domain or sending address again and record the result. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"reputation:manage"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The customer organization's id, from List pending customer setup."},"kind":{"type":"string","enum":["survey","sender"],"description":"survey = the custom survey domain; sender = the sending address."}},"required":["orgId","kind"],"additionalProperties":false}},{"key":"reputation.setup.mark_sender_verified","app":"reputation","title":"Mark a Sending Address Verified","description":"Staff only: mark a customer's sending address verified when the email provider can't confirm it but a person has. Surveys start coming from it right away. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"reputation:manage"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The customer organization's id, from List pending customer setup."}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.campaign.list","app":"ads","title":"List Ad Campaigns","description":"List every ad campaign in your organization across Google Ads, ChatGPT ads and Microsoft Advertising, with status, daily budget and results (spend, clicks, conversions) over a recent period, plus totals per platform. Money is in millionths of the account currency.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"days":{"type":"number","enum":[7,30,90],"description":"Results over the last 7, 30 or 90 days. Default 30."},"platform":{"type":"string","enum":["openai","google","microsoft"]},"status":{"type":"string","enum":["enabled","paused","removed"]},"accountId":{"type":"string","format":"uuid","description":"Only campaigns in this ad account."},"familyId":{"type":"string","format":"uuid","description":"Only campaigns in this family (a source campaign and its clones)."}},"additionalProperties":false}},{"key":"ads.campaign.get","app":"ads","title":"Get an Ad Campaign","description":"Show one ad campaign with its targeting, ad groups, ads and keywords, and its daily results over the last 7, 30 or 90 days.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"days":{"type":"number","enum":[7,30,90],"description":"Results over the last 7, 30 or 90 days. Default 30."}},"required":["campaignId"],"additionalProperties":false}},{"key":"ads.campaign.pause","app":"ads","title":"Pause an Ad Campaign","description":"Pause one campaign on its ad platform so it stops spending. Recorded in the change log; if its family asks for status changes, the other members get a proposed change to review.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"ads.campaign.resume","app":"ads","title":"Resume an Ad Campaign","description":"Resume one paused campaign on its ad platform. It starts spending the client's ad budget again. Refused if it would take the organization over its daily budget limit.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"ads.campaign.set_budget","app":"ads","title":"Change a Campaign's Daily Budget","description":"Change one campaign's daily budget on its ad platform. A higher budget can spend more of the client's ad money; refused if it would take the organization over its daily budget limit.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"dailyBudget":{"type":"number","exclusiveMinimum":0,"maximum":1000000,"description":"The new daily budget in the ad account's currency, like 25 or 42.50."}},"required":["campaignId","dailyBudget"],"additionalProperties":false}},{"key":"ads.campaign.clone","app":"ads","title":"Clone Campaigns into Drafts","description":"Make one editable draft per chosen campaign for Google Ads or Microsoft Advertising, optionally using a saved recipe. Creates nothing on any ad platform: each draft is reviewed and approved first, and every clone is created paused. To have AI rewrite the drafts, use the rewrite action afterward.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"campaignIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200},"platform":{"type":"string","enum":["google","microsoft"],"description":"Where the clones will go."},"accountId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The ad account the clones will be created in. Can be chosen later on each draft."},"recipeId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"A saved recipe whose budget, bidding and targeting rules to apply."}},"required":["campaignIds","platform"],"additionalProperties":false}},{"key":"ads.draft.list","app":"ads","title":"List Clone Drafts","description":"List clone drafts, newest first, with their status (draft, waiting for staff approval, approved, created, failed or discarded), any problems, and whether each is ready to approve.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["draft","awaiting_approval","approved","creating","created","failed","discarded"]},"limit":{"type":"integer","minimum":1,"maximum":500}},"additionalProperties":false}},{"key":"ads.draft.get","app":"ads","title":"Get a Clone Draft","description":"Show one clone draft in full: name, budget, bidding, targeting, ad groups with ads and keywords, its problems, and what still blocks approving it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"}},"required":["draftId"],"additionalProperties":false}},{"key":"ads.draft.update","app":"ads","title":"Edit a Clone Draft","description":"Change a clone draft. Only the fields you send change; ad groups and negative keywords, when sent, replace the whole list. Any edit sends the draft back to Draft, and it is always saved paused.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"},"accountId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The ad account the campaign will be created in; null clears it."},"spec":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"dailyBudgetMicros":{"type":"integer","exclusiveMinimum":0,"description":"Daily budget in millionths of the currency: 25.00 is 25000000."},"bidStrategy":{"type":"object","properties":{"type":{"type":"string","enum":["maximize_clicks","maximize_conversions","target_cpa","manual_cpc","enhanced_cpc"]},"targetCpaMicros":{"type":"integer","exclusiveMinimum":0},"maxCpcMicros":{"type":"integer","exclusiveMinimum":0}},"required":["type"],"additionalProperties":false},"networks":{"type":"object","properties":{"searchPartners":{"type":"boolean"},"audienceNetwork":{"type":"boolean"}},"required":["searchPartners","audienceNetwork"],"additionalProperties":false,"description":"Search partners and the audience network; both off unless set."},"targeting":{"type":"object","properties":{"locations":{"type":"array","items":{"type":"object","additionalProperties":{}}},"excludedLocations":{"type":"array","items":{"type":"object","additionalProperties":{}}},"languages":{"type":"array","items":{"type":"string"}},"schedule":{"type":"array","items":{"type":"object","additionalProperties":{}}},"devices":{"type":"object","additionalProperties":{"type":"number"},"description":"Bid adjustment per device, like { mobile: 1.2 }."}},"additionalProperties":false,"description":"Only the parts you send change. Use the shapes the get action returns."},"finalUrlSuffix":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Tracking added to every landing page link, like utm_source=google&utm_medium=cpc."},"conversionGoal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}]},"adGroups":{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":100,"description":"Every ad group with its ads and keywords, in the shape the get action returns."},"negativeKeywords":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":80},"matchType":{"type":"string","enum":["exact","phrase","broad"]}},"required":["text","matchType"],"additionalProperties":false},"maxItems":5000,"description":"Campaign-level negative keywords."},"social":{"type":"object","additionalProperties":{},"description":"Social platforms only: objective, identity and creative."}},"additionalProperties":false}},"required":["draftId"],"additionalProperties":false}},{"key":"ads.draft.rewrite","app":"ads","title":"Rewrite a Draft with AI","description":"Have AI rewrite a draft's ads and keywords for its new platform, reading the landing page. Costs 1 token, refunded if the rewrite fails. Read every line before approving.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"},"requestId":{"type":"string","pattern":"^[A-Za-z0-9_-]{4,64}$","description":"A new id (4 to 64 letters, digits, - or _) for each deliberate rewrite. Sending the same id again never charges twice."}},"required":["draftId","requestId"],"additionalProperties":false}},{"key":"ads.draft.rewrite_many","app":"ads","title":"Rewrite Several Drafts with AI","description":"Have AI rewrite the ads and keywords of up to 50 drafts. Costs 1 token per draft that succeeds; nothing is charged for one that fails.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":50},"requestId":{"type":"string","pattern":"^[A-Za-z0-9_-]{4,64}$","description":"A new id (4 to 64 letters, digits, - or _) for each deliberate rewrite. Sending the same id again never charges twice."}},"required":["draftIds","requestId"],"additionalProperties":false}},{"key":"ads.draft.approve","app":"ads","title":"Approve a Clone Draft","description":"Approve a draft once it has no problems left, an ad account is chosen, and its budget fits the organization's daily budget limit. Creates nothing yet. Where staff approval is required, it goes to staff instead.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"}},"required":["draftId"],"additionalProperties":false}},{"key":"ads.draft.approve_many","app":"ads","title":"Approve Several Clone Drafts","description":"Approve up to 200 drafts at once. Each is checked on its own (problems, ad account, daily budget limit); the ones that can't be approved are listed with the reason.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200}},"required":["draftIds"],"additionalProperties":false}},{"key":"ads.draft.create","app":"ads","title":"Create a Campaign from a Draft","description":"Create the campaign on its ad platform from an approved draft. It is always created paused, so it spends nothing until someone resumes it, but it changes the live ad account.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"}},"required":["draftId"],"additionalProperties":false}},{"key":"ads.draft.create_many","app":"ads","title":"Create Campaigns from Several Drafts","description":"Create campaigns from up to 200 approved drafts on their ad platforms, each paused. Each is checked against the daily budget limit on its own; failures are listed with the reason.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200}},"required":["draftIds"],"additionalProperties":false}},{"key":"ads.draft.discard","app":"ads","title":"Discard a Clone Draft","description":"Discard a draft that hasn't been created. Nothing on any ad platform changes.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"}},"required":["draftId"],"additionalProperties":false}},{"key":"ads.recipe.list","app":"ads","title":"List Clone Recipes","description":"List the saved clone recipes: reusable budget, bidding, naming and targeting rules applied when campaigns are cloned from one platform to another.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.recipe.get","app":"ads","title":"Get a Clone Recipe","description":"Show one saved clone recipe with every rule it applies.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"recipeId":{"type":"string","format":"uuid"}},"required":["recipeId"],"additionalProperties":false}},{"key":"ads.recipe.save","app":"ads","title":"Save a Clone Recipe","description":"Create a clone recipe, or change one by sending its id. When changing, only the fields and settings you send change. Recipes go from ChatGPT ads to Google Ads or Microsoft Advertising, or from Google Ads to Microsoft Advertising.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"recipeId":{"type":"string","format":"uuid","description":"Leave out to create a new recipe."},"name":{"type":"string","minLength":1,"maxLength":120},"fromPlatform":{"type":"string","enum":["openai","google","microsoft","meta","tiktok","linkedin"]},"toPlatform":{"type":"string","enum":["openai","google","microsoft","meta","tiktok","linkedin"]},"settings":{"type":"object","properties":{"budget":{"anyOf":[{"type":"object","properties":{"mode":{"type":"string","const":"percent"},"percent":{"type":"number","exclusiveMinimum":0,"maximum":1000}},"required":["mode","percent"],"additionalProperties":false},{"type":"object","properties":{"mode":{"type":"string","const":"fixed"},"amountMicros":{"type":"integer","exclusiveMinimum":0}},"required":["mode","amountMicros"],"additionalProperties":false}],"description":"percent: a share of the source campaign's daily budget (100 = the same). fixed: a daily budget in millionths of the currency."},"bidStrategy":{"type":"object","properties":{"type":{"type":"string","enum":["maximize_clicks","maximize_conversions","target_cpa","manual_cpc","enhanced_cpc"]},"targetCpaMicros":{"type":"integer","exclusiveMinimum":0},"maxCpcMicros":{"type":"integer","exclusiveMinimum":0}},"required":["type"],"additionalProperties":false},"nameTemplate":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"How clones are named, like {name} (Google)."},"utmTemplate":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Tracking added to every landing page link."},"networks":{"type":"object","properties":{"searchPartners":{"type":"boolean"},"audienceNetwork":{"type":"boolean"}},"required":["searchPartners","audienceNetwork"],"additionalProperties":false},"locations":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}],"description":"Replaces the mapped locations when set."},"languages":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}]},"devices":{"anyOf":[{"type":"object","additionalProperties":{"type":"number"}},{"type":"null"}],"description":"Bid adjustment per device, like { mobile: 1.2 }."},"schedule":{"anyOf":[{"type":"array","items":{"type":"object","additionalProperties":{}}},{"type":"null"}]},"conversionGoal":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}]},"keywordMatchType":{"type":"string","enum":["exact","phrase","broad"],"description":"Match type for keywords that arrive without one."},"negativeKeywords":{"type":"array","items":{"type":"string","maxLength":80},"maxItems":5000,"description":"Negative keywords added to every clone."}},"additionalProperties":false}},"additionalProperties":false}},{"key":"ads.recipe.delete","app":"ads","title":"Delete a Clone Recipe","description":"Delete a saved clone recipe. Drafts already made with it keep their settings.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"recipeId":{"type":"string","format":"uuid"}},"required":["recipeId"],"additionalProperties":false}},{"key":"ads.family.list","app":"ads","title":"List Campaign Families","description":"List campaign families (a source campaign and its clones) with their member campaigns and, per kind of change, whether a change on one member is proposed to the others (ask) or stays where it was made (off).","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.family.get","app":"ads","title":"Get a Campaign Family","description":"Show one campaign family: its members, its off or ask setting per kind of change, and its open and recent proposed changes.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"familyId":{"type":"string","format":"uuid"}},"required":["familyId"],"additionalProperties":false}},{"key":"ads.family.set_sync","app":"ads","title":"Set How a Family Shares Changes","description":"For one kind of change (copy, keywords, status or budget), choose ask, so a change on one member becomes a proposed change for the others to approve, or off, so it stays on the campaign it was made on. Nothing is ever applied to other members automatically.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"familyId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["copy","keywords","status","budget"]},"mode":{"type":"string","enum":["off","ask"]}},"required":["familyId","kind","mode"],"additionalProperties":false}},{"key":"ads.family.pause_all","app":"ads","title":"Pause Every Campaign in a Family","description":"Pause every member of a campaign family on its ad platform, so none of them spends. Members that are already paused or can't be changed from here are skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"familyId":{"type":"string","format":"uuid"}},"required":["familyId"],"additionalProperties":false}},{"key":"ads.family.resume_all","app":"ads","title":"Resume Every Campaign in a Family","description":"Resume every paused member of a campaign family on its ad platform. They start spending the client's ad budget; each is refused if it would go over the daily budget limit.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"familyId":{"type":"string","format":"uuid"}},"required":["familyId"],"additionalProperties":false}},{"key":"ads.family.remove_member","app":"ads","title":"Remove a Campaign from Its Family","description":"Take one campaign out of its family, so changes on it are no longer proposed to the others and theirs to it. The campaign itself is unchanged.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"ads.proposal.list","app":"ads","title":"List Proposed Changes","description":"List changes proposed between family members, newest first, each with a plain-English summary. Shows open ones unless another status is asked for.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["open","approved","rejected","applied","failed"]},"familyId":{"type":"string","format":"uuid"},"limit":{"type":"integer","minimum":1,"maximum":500}},"additionalProperties":false}},{"key":"ads.proposal.approve","app":"ads","title":"Approve a Proposed Change","description":"Approve one open proposed change: it is applied now to its campaign on the live ad platform. A resume or a budget increase is checked against the daily budget limit first.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"proposalId":{"type":"string","format":"uuid"}},"required":["proposalId"],"additionalProperties":false}},{"key":"ads.proposal.reject","app":"ads","title":"Reject a Proposed Change","description":"Reject one open proposed change. Nothing is applied to any campaign.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"proposalId":{"type":"string","format":"uuid"}},"required":["proposalId"],"additionalProperties":false}},{"key":"ads.account.list","app":"ads","title":"List Ad Accounts","description":"List the organization's connected ad accounts (Google Ads, ChatGPT ads, Microsoft Advertising and sample accounts) with their sync status and when each was last brought up to date.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.account.add_samples","app":"ads","title":"Add Sample Ad Accounts","description":"Add three sample ad accounts filled with test campaigns, to try Paid Ads without connecting a real account. They are labeled as samples everywhere and can be disconnected any time. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.account.add_chatgpt","app":"ads","title":"Add a ChatGPT Ads Account","description":"Add a ChatGPT ads account, kept up to date by importing its Ads Manager exports. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"accountId":{"type":"string","minLength":1,"maxLength":64,"description":"The account id shown in ChatGPT Ads Manager."},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"Three-letter currency code. Default USD."}},"required":["name","accountId"],"additionalProperties":false}},{"key":"ads.account.sync","app":"ads","title":"Sync an Ad Account Now","description":"Read the latest campaigns and results from one ad account now, instead of waiting for the daily sync. Only reads from the platform; ChatGPT ads accounts are kept current by CSV import instead.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"}},"required":["accountId"],"additionalProperties":false}},{"key":"ads.account.disconnect","app":"ads","title":"Disconnect an Ad Account","description":"Disconnect an ad account from Paid Ads. Its campaigns stay in the history and nothing on the platform changes. Owners and admins only.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"}},"required":["accountId"],"additionalProperties":false}},{"key":"ads.account.preview_csv","app":"ads","title":"Preview a ChatGPT Ads Export","description":"Read a ChatGPT Ads Manager CSV export and show the campaigns and days of results it contains, with any warnings, without saving anything.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"csv":{"type":"string","minLength":1,"maxLength":10485760,"description":"The CSV file exported from ChatGPT Ads Manager, as text."}},"required":["accountId","csv"],"additionalProperties":false}},{"key":"ads.account.import_csv","app":"ads","title":"Import a ChatGPT Ads Export","description":"Import a ChatGPT Ads Manager CSV export into a ChatGPT ads account: its campaigns and daily results. Preview it first to check what it contains.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"csv":{"type":"string","minLength":1,"maxLength":10485760,"description":"The CSV file exported from ChatGPT Ads Manager, as text."},"defaultDay":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The day (YYYY-MM-DD) for results when the file has no date column."}},"required":["accountId","csv"],"additionalProperties":false}},{"key":"ads.sheet.get","app":"ads","title":"Get the Linked Editing Sheet","description":"Show the spreadsheet linked for editing drafts (if any), when it was last synced, and its recent syncs with their status.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.sheet.get_run","app":"ads","title":"Get a Sheet Sync","description":"Show one sync of the editing sheet: every change it would make to the drafts, any problems found in the sheet, and, once applied, what changed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"}},"required":["runId"],"additionalProperties":false}},{"key":"ads.sheet.link_sample","app":"ads","title":"Link the Sample Editing Sheet","description":"Link the built-in sample spreadsheet, to try editing drafts from a sheet before linking your own Google Sheet. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.sheet.sync","app":"ads","title":"Sync the Editing Sheet","description":"Read the linked sheet and list what it would change in the drafts, as a sync to review. Nothing is applied until the sync is applied.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.sheet.apply_run","app":"ads","title":"Apply a sheet sync to the drafts","description":"Apply a reviewed sheet sync: create, update or discard drafts as it lists. Writes drafts only; nothing is approved or created on any ad platform, and every campaign is still created paused.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"}},"required":["runId"],"additionalProperties":false}},{"key":"ads.sheet.discard_run","app":"ads","title":"Discard a Sheet Sync","description":"Throw away a sheet sync without applying it. No draft changes.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"runId":{"type":"string","format":"uuid"}},"required":["runId"],"additionalProperties":false}},{"key":"ads.sheet.unlink","app":"ads","title":"Unlink the Editing Sheet","description":"Unlink the spreadsheet used for editing drafts and forget its access. Drafts stay as they are. Owners and admins only.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.report.get","app":"ads","title":"Get the Ads Report","description":"The organization's ads report: spend, clicks, conversions and cost per conversion, by platform, campaign family and campaign, for the last 7, 30 or 90 days or a date range. Money is in millionths of the currency.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"days":{"type":"number","enum":[7,30,90],"description":"A rolling range: the last 7, 30 or 90 days as of each view. Default 30."},"from":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range start (YYYY-MM-DD); send with to."},"to":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range end (YYYY-MM-DD)."}},"additionalProperties":false}},{"key":"ads.onboarding.get","app":"ads","title":"Get the Setup Checklist","description":"The organization's Paid Ads setup checklist: for each ad platform, what is needed, where it stands (connected or needs attention, from its real ad accounts) and the next steps.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.report_link.list","app":"ads","title":"List Report Links","description":"List the read-only report links made for this organization, with each link's address, range, expiry and views. Owners and admins only.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.report_link.create","app":"ads","title":"Make a Report Link","description":"Make a read-only link to this organization's ads report that anyone with the link can open until it expires (90 days at most). Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"label":{"type":"string","maxLength":120,"description":"A name for the link, like March review."},"days":{"type":"number","enum":[7,30,90],"description":"A rolling range: the last 7, 30 or 90 days as of each view. Default 30."},"from":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range start (YYYY-MM-DD); send with to."},"to":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range end (YYYY-MM-DD)."},"expiresInDays":{"type":"integer","minimum":1,"maximum":90,"description":"How long the link works, 1 to 90 days. Default 30."}},"additionalProperties":false}},{"key":"ads.report_link.revoke","app":"ads","title":"Revoke a Report Link","description":"Revoke a report link. It stops working right away. Owners and admins only.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"linkId":{"type":"string","format":"uuid"}},"required":["linkId"],"additionalProperties":false}},{"key":"ads.settings.get","app":"ads","title":"Get Paid Ads Settings","description":"Show the organization's daily budget limit across every ad platform (none means no limit) and its no-conversions alert thresholds. Money is in millionths of US dollars.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.settings.update","app":"ads","title":"Change Paid Ads Settings","description":"Change the organization's daily budget limit (the most every enabled campaign on every platform may spend per day together, in US dollars; null for no limit) or its no-conversions alert. Only the fields you send change. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"ads:write","input":{"type":"object","properties":{"maxDailyBudget":{"anyOf":[{"type":"number","exclusiveMinimum":0},{"type":"null"}],"description":"US dollars per day across every platform, like 500; null removes the limit."},"noConversionDays":{"type":"integer","minimum":1,"maximum":90,"description":"Alert when a campaign has no conversions over this many days."},"noConversionSpend":{"type":"number","minimum":0,"description":"Only once it has spent at least this much (US dollars) in that window."}},"additionalProperties":false}},{"key":"ads.change.list","app":"ads","title":"Read the Change Log","description":"The Paid Ads change log, newest first: who changed what and when, with before and after, for campaigns, drafts, proposed changes, accounts and settings.","kind":"read","risk":{},"access":{"role":"member"},"scope":"ads:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"limit":{"type":"integer","minimum":1,"maximum":500}},"additionalProperties":false}},{"key":"ads.ops_draft.list","app":"ads","title":"List Drafts Waiting on Staff","description":"Staff: clone drafts across every client organization that wait for staff approval, and clones a platform refused to create in the last weeks, with each client's name.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.ops_draft.decide","app":"ads","title":"Approve or send back a client's draft","description":"Staff: approve a client's clone draft that waits for staff approval (the client can then create it, paused), or send it back to the client as a draft. Checked against the client's daily budget limit.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client's organization."},"draftId":{"type":"string","format":"uuid"},"decision":{"type":"string","enum":["approve","return"]}},"required":["orgId","draftId","decision"],"additionalProperties":false}},{"key":"ads.ops_account.list","app":"ads","title":"List Every Client's Ad Accounts","description":"Staff: every organization's connected ad accounts, failing ones first, with the client's name, status and last sync.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{"failingOnly":{"type":"boolean"}},"additionalProperties":false}},{"key":"ads.ops_account.sync","app":"ads","title":"Sync a Client's Ad Account","description":"Staff: re-run the sync for one client's ad account now. Only reads from the platform.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client's organization."},"accountId":{"type":"string","format":"uuid"}},"required":["orgId","accountId"],"additionalProperties":false}},{"key":"ads.ops_client.list","app":"ads","title":"List Onboarded Clients","description":"Staff: the client organizations onboarded to Paid Ads, with their contact, status (onboarding, active or archived) and partner.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{"includeArchived":{"type":"boolean"}},"additionalProperties":false}},{"key":"ads.ops_client.get","app":"ads","title":"Get a Client's Onboarding","description":"Staff: one client's onboarding: contact, status, the ad platforms on its checklist with their ids and link steps, and where each stands.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client's organization."}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.ops_client.add","app":"ads","title":"Onboard a New Client","description":"Staff: onboard a client. Creates its organization under the partner (or finds one with that name), records its contact and the ad accounts it uses, and can invite the contact, by email if asked.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"partnerId":{"type":"string","format":"uuid","description":"The partner the client belongs to."},"name":{"type":"string","minLength":1,"maxLength":120},"contactName":{"type":"string","maxLength":200},"contactEmail":{"type":"string","format":"email"},"accountIds":{"type":"object","additionalProperties":{"type":"string","maxLength":2000},"description":"Ad account ids per platform key (google, microsoft, openai, ...), several separated by commas."},"invite":{"type":"boolean","description":"Invite the contact to the organization."},"sendEmail":{"type":"boolean","description":"Email the invitation (otherwise the link is returned to send yourself)."}},"required":["partnerId","name"],"additionalProperties":false}},{"key":"ads.ops_client.onboard_existing","app":"ads","title":"Start Onboarding an Existing Organization","description":"Staff: make an organization that already exists a Paid Ads client being onboarded. Nothing is created and no one is invited.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.ops_client.check_csv","app":"ads","title":"Check a Clients CSV","description":"Staff: check a CSV of clients and show what each row would do, with any problems, without importing anything.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":1000000,"description":"The clients CSV as text: a name column, optional contact and one column per ad platform."}},"required":["csv"],"additionalProperties":false}},{"key":"ads.ops_client.import_csv","app":"ads","title":"Import Clients from a CSV","description":"Staff: onboard every valid row of a clients CSV (500 at most) under one partner, and optionally invite each contact, by email if asked. Nothing imports while the file has problems.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"partnerId":{"type":"string","format":"uuid"},"csv":{"type":"string","minLength":1,"maxLength":1000000,"description":"The clients CSV as text: a name column, optional contact and one column per ad platform."},"invite":{"type":"boolean"},"sendEmail":{"type":"boolean"}},"required":["partnerId","csv"],"additionalProperties":false}},{"key":"ads.ops_client.save_contact","app":"ads","title":"Save a Client's Contact","description":"Staff: save the contact name and email for a client being onboarded. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"contactName":{"type":"string","maxLength":200},"contactEmail":{"type":"string","maxLength":200}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.ops_client.set_status","app":"ads","title":"Set a Client's Status","description":"Staff: mark a client onboarding, active, or archived (archived clients are hidden from the client list).","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["onboarding","active","archived"]}},"required":["orgId","status"],"additionalProperties":false}},{"key":"ads.ops_client.add_platform","app":"ads","title":"Add a platform to a client's checklist","description":"Staff: add an ad platform the client uses, with its account id, to the client's setup checklist.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"platform":{"type":"string","minLength":1,"maxLength":40,"description":"Platform key, like google, microsoft or openai."},"accountId":{"type":"string","maxLength":80}},"required":["orgId","platform"],"additionalProperties":false}},{"key":"ads.ops_client.remove_platform","app":"ads","title":"Remove a platform from a client's checklist","description":"Staff: remove one ad platform from a client's setup checklist. Connected ad accounts are not touched.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"platformId":{"type":"string","format":"uuid","description":"The checklist entry's id."}},"required":["orgId","platformId"],"additionalProperties":false}},{"key":"ads.ops_client.record_link_step","app":"ads","title":"Record a Manager-Link Step by Hand","description":"Staff: mark that a manager-account link request was sent or accepted outside the app, or clear those marks. Connected still comes only from a real ad account connection.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"platformId":{"type":"string","format":"uuid"},"step":{"type":"string","enum":["requested","accepted","reset"]}},"required":["orgId","platformId","step"],"additionalProperties":false}},{"key":"ads.ops_client.invite","app":"ads","title":"Invite Someone to a Client's Organization","description":"Staff: invite a person to a client's organization as an owner or member, by email if asked (otherwise the invitation link is returned to send yourself).","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["owner","member"]},"sendEmail":{"type":"boolean"}},"required":["orgId","email"],"additionalProperties":false}},{"key":"ads.ops_client.send_link_request","app":"ads","title":"Send a Manager-Account Link Request","description":"Staff: send a link request from the agency's manager account to the client's ad account through the ad platform, which notifies the client to accept it. Run from the agency's organization.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client's organization."},"platformId":{"type":"string","format":"uuid","description":"The client's checklist entry for that platform."},"managerId":{"type":"string","format":"uuid","description":"The agency's manager account."},"customerNumber":{"type":"string","maxLength":40,"description":"Microsoft only: the client's customer number, when needed."}},"required":["orgId","platformId","managerId"],"additionalProperties":false}},{"key":"ads.ops_client.check_link","app":"ads","title":"Check a Manager-Account Link","description":"Staff: ask the ad platform whether the client accepted the manager-account link request. Run from the agency's organization.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"platformId":{"type":"string","format":"uuid"},"managerId":{"type":"string","format":"uuid"}},"required":["orgId","platformId","managerId"],"additionalProperties":false}},{"key":"ads.ops_client.add_accounts","app":"ads","title":"Add a client's ad accounts through a manager","description":"Staff: add the client's ad accounts reachable through the agency's manager account, only the ids on the client's checklist, to the client's organization. Run from the agency's organization.","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"managerId":{"type":"string","format":"uuid"}},"required":["orgId","managerId"],"additionalProperties":false}},{"key":"ads.ops_report_link.list","app":"ads","title":"List a Client's Report Links","description":"Staff: the read-only report links made for one client's organization.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.ops_report_link.create","app":"ads","title":"Make a report link for a client","description":"Staff: make a read-only link to one client's ads report that anyone with the link can open until it expires (90 days at most).","kind":"write","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"label":{"type":"string","maxLength":120,"description":"A name for the link, like March review."},"days":{"type":"number","enum":[7,30,90],"description":"A rolling range: the last 7, 30 or 90 days as of each view. Default 30."},"from":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range start (YYYY-MM-DD); send with to."},"to":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Fixed range end (YYYY-MM-DD)."},"expiresInDays":{"type":"integer","minimum":1,"maximum":90,"description":"How long the link works, 1 to 90 days. Default 30."}},"required":["orgId"],"additionalProperties":false}},{"key":"ads.ops_report_link.revoke","app":"ads","title":"Revoke a Client's Report Link","description":"Staff: revoke one of a client's report links. It stops working right away.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"linkId":{"type":"string","format":"uuid"}},"required":["orgId","linkId"],"additionalProperties":false}},{"key":"ads.ops_manager.list","app":"ads","title":"List the Agency's Manager Accounts","description":"Staff: the Google Ads manager and Microsoft agency accounts connected in your current organization (the agency), with their status. Sign-ins are never shown.","kind":"read","risk":{},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"ads.ops_manager.disconnect","app":"ads","title":"Disconnect a Manager Account","description":"Staff: disconnect one of the agency's manager accounts. Client ad accounts already added keep working until their own sign-in is removed.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"ads:operate"},"scope":"operations:write","input":{"type":"object","properties":{"managerId":{"type":"string","format":"uuid"}},"required":["managerId"],"additionalProperties":false}},{"key":"websites.website.add","app":"websites","title":"Add a Website to My Websites","description":"Add a website address to My Websites so it can be audited or have work requested on it. Adding one you archived brings it back.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"url":{"type":"string","minLength":3,"maxLength":500,"description":"The website address, like example.com."},"label":{"type":"string","maxLength":120,"description":"A short name, like Main practice site."}},"required":["url"],"additionalProperties":false}},{"key":"websites.website.archive","app":"websites","title":"Archive a Website","description":"Remove a website from My Websites. Its audits and past requests are kept, and adding the address again restores it.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"websiteId":{"type":"string","format":"uuid","description":"The website's id, from websites.website.list."}},"required":["websiteId"],"additionalProperties":false}},{"key":"websites.website.list","app":"websites","title":"List My Websites","description":"List the websites your organization manages (My Websites), with how many open Client Work requests and audits each one has.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"websites.website.rename","app":"websites","title":"Rename a Website","description":"Change the label shown for one of My Websites. Send an empty label to clear it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"websiteId":{"type":"string","format":"uuid","description":"The website's id, from websites.website.list."},"label":{"type":"string","maxLength":120}},"required":["websiteId","label"],"additionalProperties":false}},{"key":"websites.site.archive","app":"websites","title":"Archive a Built Site","description":"Archive a built site so it no longer appears as active. Its history and saved versions are kept.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.site.create","app":"websites","title":"Create a Site from a Template","description":"Start a new draft site from a template. It gets a free web address made from its slug right away; nothing is published or charged until you publish it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"kind":{"type":"string","enum":["website","landing_page","listing_site"]},"templateSlug":{"type":"string","minLength":1,"maxLength":120,"description":"A template slug from websites.template.list."},"templateVariant":{"type":"string","maxLength":120,"description":"One of the template's variant keys; defaults to its first."},"name":{"type":"string","minLength":1,"maxLength":200},"slug":{"type":"string","maxLength":64,"description":"Short address name, like 'jane-smith'. Defaults to the name, simplified."}},"required":["kind","templateSlug","name"],"additionalProperties":false}},{"key":"websites.site.get","app":"websites","title":"Get a Built Site","description":"Show one built site in full: name, address slug, settings, every page and its blocks, status and addresses.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.site.list","app":"websites","title":"List Built Sites","description":"List the sites built with the website builder in your organization, with status (draft, published, archived) and addresses.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"kind":{"type":"string","enum":["website","landing_page","listing_site"]},"status":{"type":"string","enum":["draft","published","archived","expired"]}},"additionalProperties":false}},{"key":"websites.template.list","app":"websites","title":"List Site Templates","description":"List the starter templates a new site can be built from, with their kinds and design variants.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"kind":{"type":"string","enum":["website","landing_page","listing_site"]}},"additionalProperties":false}},{"key":"websites.site_version.list","app":"websites","title":"List a Site's Published Versions","description":"List a site's publish history, newest first: when each version went live, who published it, and what changed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.site.publish","app":"websites","title":"Publish a Site","description":"Publish a site so visitors see its current pages, and save this version to its history. Each publish spends tokens from your balance.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.site_version.restore","app":"websites","title":"Restore a Published Version","description":"Bring back an earlier published version of a site. Mode draft loads it into the editor for review (only while the site is a draft); mode publish restores it and publishes it now, which spends tokens like any publish.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"publishId":{"type":"string","format":"uuid","description":"The version's id, from websites.site_version.list."},"mode":{"type":"string","enum":["draft","publish"]}},"required":["siteId","publishId","mode"],"additionalProperties":false}},{"key":"websites.site.unpublish","app":"websites","title":"Unpublish a Site","description":"Take a published site offline and return it to draft. Publishing it again later spends tokens again.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.site.update","app":"websites","title":"Edit a Built Site","description":"Change a site's name, address slug, settings or pages. Only the fields you send change; pages replaces the whole page list. Edits to a published site show to visitors right away.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"name":{"type":"string","minLength":1,"maxLength":200},"slug":{"type":"string","minLength":1,"maxLength":64},"config":{"type":"object","additionalProperties":{},"description":"Site settings: brand colors, fonts, navigation and search details."},"pages":{"type":"array","items":{"type":"object","additionalProperties":{}},"maxItems":100,"description":"The full list of pages, each with its path, title and blocks. Read the site first and send back the edited list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.domain.add","app":"websites","title":"Add a Custom Domain","description":"Connect a domain you own to a site. Spends tokens from your balance. Returns two DNS records to add at your domain provider: a TXT record proving you own it and a record pointing it at the site.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"domain":{"type":"string","minLength":3,"maxLength":253,"description":"A bare domain like example.com, without https:// or a path."}},"required":["siteId","domain"],"additionalProperties":false}},{"key":"websites.domain.check","app":"websites","title":"Check a Domain's Setup","description":"Look up a custom domain's DNS records again, the same as the Check now button. Marks ownership verified and the domain live once its records are found.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"domain":{"type":"string","minLength":3,"maxLength":253,"description":"A bare domain like example.com, without https:// or a path."}},"required":["siteId","domain"],"additionalProperties":false}},{"key":"websites.domain.list","app":"websites","title":"List a Site's Domains","description":"List the web addresses attached to a site: its free address and any custom domains, with whether each is live, ownership-verified, and the DNS records still needed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"websites.domain.make_primary","app":"websites","title":"Make a Domain the Main Address","description":"Make a verified, live domain the site's main address. The domain must already show as active.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"domain":{"type":"string","minLength":3,"maxLength":253,"description":"A bare domain like example.com, without https:// or a path."}},"required":["siteId","domain"],"additionalProperties":false}},{"key":"websites.domain.remove","app":"websites","title":"Remove a Domain from a Site","description":"Disconnect a domain from a site. Visitors to that address stop seeing the site.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The site's id, from websites.site.list."},"domain":{"type":"string","minLength":3,"maxLength":253,"description":"A bare domain like example.com, without https:// or a path."}},"required":["siteId","domain"],"additionalProperties":false}},{"key":"websites.request_item.add","app":"websites","title":"Add Items to a Request","description":"Add one or more items of work to one of your requests, each with the page it applies to if you know it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":2000},"url":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"The page this applies to, if known."}},"required":["description"],"additionalProperties":false},"minItems":1,"maxItems":100}},"required":["requestId","items"],"additionalProperties":false}},{"key":"websites.request.approve_completion","app":"websites","title":"Approve Finished Work and Pay","description":"Approve the finished work on a request that is ready for your review. This bills the completed hours and fixed-price items in tokens and closes the request. The team is emailed.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.request.approve_scope","app":"websites","title":"Approve the List of Work","description":"Approve the itemized list the team sent so work can start. This authorizes the work: when it is done and you approve it, the hours are billed in tokens. The team is emailed.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.request.attach_file","app":"websites","title":"Attach a File to a Request","description":"Upload a file, such as a photo or a document, to one of your requests or to one item of it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"itemId":{"anyOf":[{"type":"string","format":"uuid","description":"The item's id, from websites.request.get."},{"type":"null"}],"description":"The item's id, from websites.request.get."},"filename":{"type":"string","minLength":1,"maxLength":200},"contentType":{"type":"string","maxLength":200,"description":"Like image/png or application/pdf."},"contentBase64":{"type":"string","minLength":1,"maxLength":5600000,"description":"The file's contents, base64-encoded. At most 4 MB."}},"required":["requestId","filename","contentBase64"],"additionalProperties":false}},{"key":"websites.request.cancel","app":"websites","title":"Cancel a Request","description":"Cancel one of your open requests. Nothing more is done on it and nothing is billed for it.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.request.comment","app":"websites","title":"Send a Message on a Request","description":"Post a message on one of your requests, or on one item of it. The team and the other people following the request are emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"itemId":{"anyOf":[{"type":"string","format":"uuid","description":"The item's id, from websites.request.get."},{"type":"null"}],"description":"The item's id, from websites.request.get."},"body":{"type":"string","minLength":1,"maxLength":10000}},"required":["requestId","body"],"additionalProperties":false}},{"key":"websites.request.create_from_audit","app":"websites","title":"Request Fixes from an Audit","description":"Open a website request from one of your audit reports, with the findings to fix as items. The team is emailed. Nothing is charged until you approve the list and the finished work.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"auditRunId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The audit report's id."},"siteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The audited website, from websites.website.list."},"items":{"type":"array","items":{"type":"string","minLength":1,"maxLength":2000},"maxItems":40,"description":"The findings to fix, one per item."}},"required":["title"],"additionalProperties":false}},{"key":"websites.request.create","app":"websites","title":"Open a Client Work Request","description":"Ask the team for work, optionally with a list of items. The team is emailed. Nothing is charged until you approve the list and then approve the finished work.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"service":{"type":"string","enum":["website","google_business","social","content_seo","other"],"description":"What kind of work: website, google_business (Google Business Profile), social, content_seo or other."},"siteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"For website work: one of My Websites (websites.website.list)."},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":2000},"url":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"The page this applies to, if known."}},"required":["description"],"additionalProperties":false},"maxItems":100}},"required":["title"],"additionalProperties":false}},{"key":"websites.request_item.decline","app":"websites","title":"Decline an Item","description":"Turn down one proposed item of work on your request so it is left out of the approved list.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"itemId":{"type":"string","format":"uuid","description":"The item's id, from websites.request.get."}},"required":["requestId","itemId"],"additionalProperties":false}},{"key":"websites.request.get","app":"websites","title":"Get a Client Work Request","description":"Show one Client Work request: its status, each item of work with estimated and actual hours, the message thread, attached files and the hourly rate in tokens.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.request.list","app":"websites","title":"List Client Work Requests","description":"List your organization's Client Work requests (website, Google Business Profile, social, content and other work), newest first, with their status.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"includeClosed":{"type":"boolean","description":"Also list completed, closed and canceled requests."}},"additionalProperties":false}},{"key":"websites.request.mute","app":"websites","title":"Mute or Unmute a Request","description":"Stop, or start again, getting emails about one request. Your other requests are not affected.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid"},"mute":{"type":"boolean"}},"required":["requestId","mute"],"additionalProperties":false}},{"key":"websites.request.reopen","app":"websites","title":"Reopen a Request for Follow-Up","description":"Start a follow-up request linked to a completed one, keeping the original and its history. Everyone following it is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.request.request_changes","app":"websites","title":"Send Finished Work Back for Changes","description":"Instead of approving finished work, say what still needs doing. The request goes back to in progress at no charge and the team is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"reason":{"type":"string","maxLength":5000}},"required":["requestId","reason"],"additionalProperties":false}},{"key":"websites.request_item.set_page","app":"websites","title":"Say which page an item is for","description":"Record the page or place on your site an item of work applies to, like a full address or 'the footer'.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.request.list."},"itemId":{"type":"string","format":"uuid","description":"The item's id, from websites.request.get."},"targetUrl":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["requestId","itemId","targetUrl"],"additionalProperties":false}},{"key":"websites.ops_request.assign","app":"websites","title":"Assign a Request","description":"Staff: make a team member the owner of a request. They are emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"assigneeId":{"type":"string","format":"uuid","description":"The team member's user id."}},"required":["requestId","assigneeId"],"additionalProperties":false}},{"key":"websites.ops_request.create","app":"websites","title":"Open a Request for a Client","description":"Staff: open a Client Work request for a client organization, optionally with a list of items. The team is emailed. Nothing is billed until the client approves the list and the finished work.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client organization, from websites.ops_client.list."},"title":{"type":"string","minLength":1,"maxLength":200},"service":{"type":"string","enum":["website","google_business","social","content_seo","other"]},"siteId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"For website work: one of the client's websites."},"items":{"type":"array","items":{"type":"object","properties":{"description":{"type":"string","minLength":1,"maxLength":2000},"url":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["description"],"additionalProperties":false},"maxItems":100},"auditRunId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"When converting audit findings: the audit report's id."},"remediationId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"When converting a fix-it request from an audit: its id, so it is marked as converted."}},"required":["orgId","title"],"additionalProperties":false}},{"key":"websites.ops_request.get","app":"websites","title":"Get a Request (Staff View)","description":"Staff: show one Client Work request with its items, the whole thread including team-only notes, and attached files.","kind":"read","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:read","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.ops_client.list","app":"websites","title":"Find a Client Organization","description":"Staff: list client organizations work can be opened for, with their partner, optionally filtered by name.","kind":"read","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:read","input":{"type":"object","properties":{"query":{"type":"string","maxLength":200,"description":"Part of the organization or partner name."}},"additionalProperties":false}},{"key":"websites.ops_request.list","app":"websites","title":"List the Client Work Queue","description":"Staff: list Client Work requests across every client, oldest first, with each client and partner name.","kind":"read","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:read","input":{"type":"object","properties":{"includeClosed":{"type":"boolean","description":"Also list completed, closed and canceled requests."}},"additionalProperties":false}},{"key":"websites.ops_request.send_scope","app":"websites","title":"Send the list to the client for approval","description":"Staff: send a request's finished list of items to the client and ask them to approve it. The client is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.ops_request.set_details","app":"websites","title":"Set a request's priority or due date","description":"Staff: change a request's priority (low, normal, high) or due date. Send a null due date to clear it.","kind":"write","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"priority":{"type":"string","enum":["low","normal","high"]},"dueAt":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"description":"A date like 2026-11-01."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.ops_request_item.add","app":"websites","title":"Add an item to a client's request","description":"Staff: add an item of work to a request, billed by the hour (with an estimate) or at a fixed price in tokens. The client is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"description":{"type":"string","minLength":1,"maxLength":2000},"targetUrl":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"kind":{"type":"string","enum":["hourly","flat"],"description":"hourly (default) or flat, a fixed price."},"estHours":{"anyOf":[{"type":"number","exclusiveMinimum":0,"maximum":1000},{"type":"null"}]},"flatTokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"For a fixed-price item: its price in tokens."}},"required":["requestId","description"],"additionalProperties":false}},{"key":"websites.ops_request.attach_file","app":"websites","title":"Attach a file to a request (staff)","description":"Staff: upload a file to a client's request or to one item of it.","kind":"write","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"itemId":{"anyOf":[{"type":"string","format":"uuid","description":"The item's id, from websites.ops_request.get."},{"type":"null"}],"description":"The item's id, from websites.ops_request.get."},"filename":{"type":"string","minLength":1,"maxLength":200},"contentType":{"type":"string","maxLength":200,"description":"Like image/png or application/pdf."},"contentBase64":{"type":"string","minLength":1,"maxLength":5600000,"description":"The file's contents, base64-encoded. At most 4 MB."}},"required":["requestId","filename","contentBase64"],"additionalProperties":false}},{"key":"websites.ops_request.comment","app":"websites","title":"Post on a Request (Staff)","description":"Staff: reply to the client on a request or one item of it, which emails them, or leave a team-only note the client never sees.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"itemId":{"anyOf":[{"type":"string","format":"uuid","description":"The item's id, from websites.ops_request.get."},{"type":"null"}],"description":"The item's id, from websites.ops_request.get."},"body":{"type":"string","minLength":1,"maxLength":10000},"internal":{"type":"boolean","description":"true = team-only note (no email); false (default) = a reply the client sees."}},"required":["requestId","body"],"additionalProperties":false}},{"key":"websites.ops_request.reopen","app":"websites","title":"Reopen a Request (Staff)","description":"Staff: start a follow-up request linked to a completed one. Everyone following it, including the client, is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.ops_request_item.update","app":"websites","title":"Update an Item (Staff)","description":"Staff: change an item's status, estimated hours, actual hours worked or the page it applies to. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."},"itemId":{"type":"string","format":"uuid","description":"The item's id, from websites.ops_request.get."},"status":{"type":"string","enum":["proposed","approved","in_progress","done","declined"]},"estHours":{"anyOf":[{"type":"number","minimum":0,"maximum":1000},{"type":"null"}]},"actualHours":{"anyOf":[{"type":"number","minimum":0,"maximum":1000},{"type":"null"}],"description":"Hours actually worked; billed when the client approves completion."},"targetUrl":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["requestId","itemId"],"additionalProperties":false}},{"key":"websites.ops_request.start_work","app":"websites","title":"Start Work on a Request","description":"Staff: start work on a request whose list the client approved. It moves to in progress.","kind":"write","risk":{},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.ops_request.submit_for_review","app":"websites","title":"Submit Finished Work to the Client","description":"Staff: tell the client the work is done and ask them to check and approve it. The client is emailed.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"edits:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from websites.ops_request.list."}},"required":["requestId"],"additionalProperties":false}},{"key":"websites.notification_settings.get","app":"websites","title":"Get My Email Settings","description":"Show how you get Client Work emails: right away, as a daily digest, or not at all, which kinds are switched off, and which requests you muted.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"websites.notification.list","app":"websites","title":"List My Notifications","description":"List your recent Client Work notifications, newest first, with which ones are unread.","kind":"read","risk":{},"access":{"role":"member"},"scope":"websites:read","input":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":100}},"additionalProperties":false}},{"key":"websites.notification.mark_read","app":"websites","title":"Mark Notifications Read","description":"Mark one notification as read, or all of your unread notifications when no id is given.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"notificationId":{"type":"string","format":"uuid"}},"additionalProperties":false}},{"key":"websites.notification_settings.update","app":"websites","title":"Change My Email Settings","description":"Change how you get Client Work emails (right away, a daily digest, or off) and switch individual kinds on or off. Only what you send changes.","kind":"write","risk":{},"access":{"role":"member"},"scope":"websites:write","input":{"type":"object","properties":{"mode":{"type":"string","enum":["immediate","digest","off"]},"events":{"type":"object","properties":{"edit.created":{"type":"boolean"},"edit.item_added":{"type":"boolean"},"edit.quote":{"type":"boolean"},"edit.scope_approved":{"type":"boolean"},"edit.comment":{"type":"boolean"},"edit.review":{"type":"boolean"},"edit.completed":{"type":"boolean"},"edit.rejected":{"type":"boolean"},"edit.assigned":{"type":"boolean"},"edit.reopened":{"type":"boolean"}},"additionalProperties":false,"description":"Which kinds of email to get: edit.created (new request), edit.item_added, edit.quote (list ready for approval), edit.scope_approved, edit.comment, edit.review (work ready to check), edit.completed, edit.rejected (changes requested), edit.assigned, edit.reopened. true = on, false = off."}},"additionalProperties":false}},{"key":"audit.category.list","app":"audit","title":"List Audit Types and Prices","description":"List the kinds of website audit you can run (accessibility, performance, search, AI chatbots), whether each has a deep version, and roughly how many tokens each costs.","kind":"read","risk":{},"access":{"role":"member"},"scope":"audit:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"audit.run.list","app":"audit","title":"List Audits","description":"List your organization's 50 most recent website audits with their type, status and when they finished.","kind":"read","risk":{},"access":{"role":"member"},"scope":"audit:read","input":{"type":"object","properties":{"category":{"type":"string","enum":["accessibility","performance","seo","aeo"],"description":"accessibility, performance, seo (search) or aeo (how AI chatbots see the site)."},"siteId":{"type":"string","format":"uuid","description":"Only audits of this website, from audit.site.list."}},"additionalProperties":false}},{"key":"audit.run.get","app":"audit","title":"Get an Audit's Results","description":"Show one audit: whether it is queued, running, finished or failed, and each check's score and summary once it is done.","kind":"read","risk":{},"access":{"role":"member"},"scope":"audit:read","input":{"type":"object","properties":{"runId":{"type":"string","format":"uuid","description":"The audit's id, from audit.run.list or audit.run.start."}},"required":["runId"],"additionalProperties":false}},{"key":"audit.run.start","app":"audit","title":"Run a Website Audit","description":"Start an audit of a web address. Spends tokens from your balance (about 30 to 50 a run, twice that for a deep audit). The audit is queued and usually finishes within minutes.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2000,"description":"The full address to audit, starting with https://"},"category":{"type":"string","enum":["accessibility","performance","seo","aeo"],"description":"accessibility, performance, seo (search) or aeo (how AI chatbots see the site)."},"depth":{"type":"string","enum":["scan","deep"],"description":"deep checks more pages and costs twice as much, where available."},"siteId":{"type":"string","format":"uuid","description":"Link the audit to one of your websites, from audit.site.list."}},"required":["url","category"],"additionalProperties":false}},{"key":"audit.site.list","app":"audit","title":"List Audited Websites","description":"List the websites your organization audits, with their labels.","kind":"read","risk":{},"access":{"role":"member"},"scope":"audit:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"audit.site.get_schedules","app":"audit","title":"Get a Website's Audit Schedule","description":"Show which audits run automatically for one website, how often (weekly or monthly), and when each runs next.","kind":"read","risk":{},"access":{"role":"member"},"scope":"audit:read","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from audit.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"audit.site.add","app":"audit","title":"Add a Website to Audit","description":"Add a website to your organization so it can be audited and scheduled. Adding an address you deleted brings it back.","kind":"write","risk":{},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2000,"description":"The website's address, starting with https://"},"label":{"type":"string","minLength":1,"maxLength":120,"description":"A short name, like Main practice site."}},"required":["url","label"],"additionalProperties":false}},{"key":"audit.site.set_schedules","app":"audit","title":"Schedule Recurring Audits","description":"Turn automatic audits on or off for one website, per type, weekly or monthly. Each scheduled audit spends tokens when it runs. Types you leave out keep their current schedule.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from audit.site.list."},"schedules":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string","enum":["accessibility","performance","seo","aeo"]},"cadence":{"type":"string","enum":["off","weekly","monthly"]},"enabled":{"type":"boolean"}},"required":["category","cadence"],"additionalProperties":false},"minItems":1,"maxItems":4}},"required":["siteId","schedules"],"additionalProperties":false}},{"key":"audit.site.delete","app":"audit","title":"Delete an Audited Website","description":"Remove a website from your audited websites and stop its scheduled audits. Past reports are kept and it can be restored.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from audit.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"audit.site.restore","app":"audit","title":"Restore a Deleted Website","description":"Bring back a website you deleted from your audited websites.","kind":"write","risk":{},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from audit.site.list."}},"required":["siteId"],"additionalProperties":false}},{"key":"audit.remediation.request","app":"audit","title":"Ask Us to Fix a Website","description":"Ask the team for a quote to fix the problems an audit found on a website. The team is emailed, and so are you, with a confirmation.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"audit:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"One of your websites, from audit.site.list. Or send url instead."},"url":{"type":"string","maxLength":2000,"description":"The website's address, when it isn't one of your websites yet."},"phone":{"type":"string","maxLength":60},"message":{"type":"string","maxLength":4000,"description":"Anything the team should know."}},"additionalProperties":false}},{"key":"audit.ops_remediation.list","app":"audit","title":"List Fix-It Requests (Staff)","description":"Staff: list requests to fix websites from every partner, newest first, with contact details and status. Open ones by default.","kind":"read","risk":{},"access":{"role":"staff","capability":"remediation:manage"},"scope":"operations:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["new","contacted","quoted","won","lost"]},"includeClosed":{"type":"boolean","description":"Also list won and lost requests."}},"additionalProperties":false}},{"key":"audit.ops_remediation.set_status","app":"audit","title":"Update a Fix-It Request's Status (Staff)","description":"Staff: move a request to fix a website along the pipeline: new, contacted, quoted, won or lost.","kind":"write","risk":{},"access":{"role":"staff","capability":"remediation:manage"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["new","contacted","quoted","won","lost"]}},"required":["requestId","status"],"additionalProperties":false}},{"key":"coldemail.campaign.list","app":"coldemail","title":"List Cold Email Campaigns","description":"List your cold email campaigns with their status (draft, active, paused, completed or archived), whether test mode is on, and headline numbers: sent, opened, replied and bounced.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.campaign.get","app":"coldemail","title":"Get a Campaign","description":"Show one campaign in full: its schedule and sending limits, which inboxes send it, tracking settings, every step of the sequence with its other versions, and its numbers.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.campaign.create","app":"coldemail","title":"Create a Campaign","description":"Create a new cold email campaign as a draft. Nothing sends until it has steps, inboxes and recipients and you launch it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200}},"required":["name"],"additionalProperties":false}},{"key":"coldemail.campaign.update","app":"coldemail","title":"Change a Campaign's Settings","description":"Change a campaign's name, schedule, sending limits, tracking or which inboxes send it. Only the fields you send change. To start or stop sending, use launch, pause or end instead.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":200},"timezone":{"type":"string","maxLength":64,"description":"Time zone of the sending window, like America/Chicago."},"sendHourStart":{"type":"integer","minimum":0,"maximum":23,"description":"First hour emails may go out (0 to 23)."},"sendHourEnd":{"type":"integer","minimum":1,"maximum":24,"description":"Hour sending stops, not included; 24 means through midnight."},"sendDays":{"type":"array","items":{"type":"integer","minimum":1,"maximum":7},"maxItems":7,"description":"Days of the week to send: 1 is Monday, 7 is Sunday."},"stopOnReply":{"type":"boolean","description":"Stop the sequence for a person once they reply."},"dailyCap":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"Most emails the campaign sends a day; null for no cap."},"useLeadTimezone":{"type":"boolean","description":"Use each recipient's own time zone for the sending window."},"trackOpens":{"type":"boolean"},"trackClicks":{"type":"boolean"},"stopOnClick":{"type":"boolean","description":"Stop the sequence for a person once they click a link."},"minGapMinutes":{"anyOf":[{"type":"integer","minimum":0,"maximum":240},{"type":"null"}],"description":"Minimum minutes between two emails from the same inbox."},"maxNewPerDay":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}],"description":"Most new recipients started each day."},"inboxIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":200,"description":"Inboxes that send this campaign (replaces the current list)."},"groupIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":50,"description":"Inbox groups that send this campaign (replaces the current list)."}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.campaign.launch","app":"coldemail","title":"Launch or Resume a Campaign","description":"Start sending a draft campaign, or resume a paused one (this clears an automatic pause). Emails go out to its recipients within the sending window and each one costs tokens; in test mode only your test recipients are mailed.","kind":"write","risk":{"emailsOthers":true,"money":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.campaign.pause","app":"coldemail","title":"Pause a Campaign","description":"Stop an active campaign from sending. Recipients keep their place, so resuming carries on where it left off.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.campaign.end","app":"coldemail","title":"Complete or Archive a Campaign","description":"Mark a campaign completed or archived. It stops sending for good; its results stay.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["completed","archived"]}},"required":["campaignId","status"],"additionalProperties":false}},{"key":"coldemail.campaign.set_test_mode","app":"coldemail","title":"Turn Test Mode on or Off","description":"While test mode is on, a campaign only emails your test recipients (set in Settings). Turning it off on an active campaign starts emailing its real recipients.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"on":{"type":"boolean"}},"required":["campaignId","on"],"additionalProperties":false}},{"key":"coldemail.campaign.delete","app":"coldemail","title":"Delete a Campaign","description":"Delete a campaign with its steps, recipients and results. This can't be undone; archiving keeps the results.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.campaign.create_follow_up","app":"coldemail","title":"Add a Follow-Up Campaign","description":"Create a follow-up campaign that starts for each person whose reply in this campaign is marked with the chosen category. It copies the schedule, inboxes and test mode, and sends nothing until you add its first step.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign whose replies start the follow-up."},"triggerCategory":{"type":"string","enum":["interested","meeting_request","information_request","not_interested","wrong_person","out_of_office","other"],"description":"The reply category that starts it for a person."},"name":{"type":"string","maxLength":200}},"required":["campaignId","triggerCategory"],"additionalProperties":false}},{"key":"coldemail.step.add","app":"coldemail","title":"Add a Sequence Step","description":"Add an email to a campaign's sequence. Leave out the position to add it at the end. The change is saved in the sequence history.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"stepOrder":{"type":"integer","minimum":1,"maximum":50,"description":"Position in the sequence, starting at 1."},"waitDays":{"type":"integer","minimum":0,"maximum":365,"description":"Days to wait after the previous step (0 for the first)."},"subject":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"Subject line; leave empty on a follow-up to reply in the same thread. Supports {{first_name}}, {{company}} and other recipient fields, {{first_name|there}} for a fallback, and {a|b} to vary wording."},"body":{"type":"string","minLength":1,"maxLength":20000,"description":"The email text. Supports {{first_name}}, {{company}} and other recipient fields, {{first_name|there}} for a fallback, and {a|b} to vary wording."},"weight":{"type":"integer","minimum":0,"maximum":100,"description":"How often this version is chosen against the step's other versions; 0 pauses it."}},"required":["campaignId","body"],"additionalProperties":false}},{"key":"coldemail.step.update","app":"coldemail","title":"Edit a Sequence Step","description":"Change one step of a campaign's sequence: its wording, subject, wait or position. Only the fields you send change, and the next emails use the new text.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"stepId":{"type":"string","format":"uuid"},"stepOrder":{"type":"integer","minimum":1,"maximum":50},"waitDays":{"type":"integer","minimum":0,"maximum":365},"subject":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"body":{"type":"string","minLength":1,"maxLength":20000},"weight":{"type":"integer","minimum":0,"maximum":100}},"required":["campaignId","stepId"],"additionalProperties":false}},{"key":"coldemail.step.delete","app":"coldemail","title":"Remove a Sequence Step","description":"Remove one step (and its other versions) from a campaign's sequence. The sequence history keeps the old version so it can be restored.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"}},"required":["stepId"],"additionalProperties":false}},{"key":"coldemail.step_version.add","app":"coldemail","title":"Add an A/B version to a step","description":"Add another version (B, C and so on) of a step to test against the original. Each recipient gets one version, chosen by weight.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"subject":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"body":{"type":"string","minLength":1,"maxLength":20000,"description":"The email text. Supports {{first_name}}, {{company}} and other recipient fields, {{first_name|there}} for a fallback, and {a|b} to vary wording."},"weight":{"type":"integer","minimum":0,"maximum":100}},"required":["stepId","body"],"additionalProperties":false}},{"key":"coldemail.step_version.update","app":"coldemail","title":"Edit an A/B version","description":"Change version B, C and so on of a step. Only the fields you send change. Weight 0 pauses that version.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"label":{"type":"string","pattern":"^[B-Z]$","description":"Which version: B, C and so on (the step itself is version A)."},"subject":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"body":{"type":"string","minLength":1,"maxLength":20000},"weight":{"type":"integer","minimum":0,"maximum":100}},"required":["stepId","label"],"additionalProperties":false}},{"key":"coldemail.step_version.delete","app":"coldemail","title":"Remove an A/B version","description":"Remove one extra version (B, C and so on) of a step. The sequence history keeps it so it can be restored.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"versionId":{"type":"string","format":"uuid","description":"The version's id, from the campaign's steps."}},"required":["versionId"],"additionalProperties":false}},{"key":"coldemail.sequence.write_ai","app":"coldemail","title":"Write a Sequence with AI","description":"Write a campaign's emails with AI from a short brief, using your company profile. Costs 1 token. The steps are added after any existing ones, or replace them if asked and nothing has been sent yet. Read and edit them before launching.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"audience":{"type":"string","minLength":1,"maxLength":600,"description":"Who you're writing to."},"offer":{"type":"string","minLength":1,"maxLength":1500,"description":"What you're offering them."},"goal":{"type":"string","maxLength":300,"description":"What a good reply looks like; defaults to agreeing to a short call."},"tone":{"type":"string","enum":["friendly","direct","formal"]},"steps":{"type":"integer","minimum":1,"maximum":5,"description":"How many emails, 1 to 5 (default 3)."},"abTest":{"type":"boolean","description":"Also write a B version of each email."},"replace":{"type":"boolean","description":"Replace the current steps (only before anything has been sent)."},"requestId":{"type":"string","maxLength":40,"description":"Any unique text; repeating a request with the same value never charges twice."}},"required":["campaignId","audience","offer"],"additionalProperties":false}},{"key":"coldemail.sequence.history","app":"coldemail","title":"List a Sequence's Saved Versions","description":"List the saved versions of a campaign's sequence, newest first, with what changed in each and who changed it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.sequence.restore","app":"coldemail","title":"Restore an Earlier Sequence","description":"Put an earlier saved version of a campaign's sequence back. Emails already sent and people partway through keep their place; the next emails use the restored text. Refused if it would remove a step that has already been sent.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid","description":"From the sequence history."}},"required":["campaignId","versionId"],"additionalProperties":false}},{"key":"coldemail.recipient.list","app":"coldemail","title":"List a Campaign's Recipients","description":"List the people in a campaign with their status, reply category and current step. Page with the next value returned.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"limit":{"type":"integer","minimum":1,"maximum":500},"after":{"type":"string","format":"uuid","description":"The next value from the previous page."},"status":{"type":"string","maxLength":40,"description":"Only people in this status, like active, replied or bounced."},"category":{"type":"string","maxLength":40,"description":"Only people whose reply has this category, like interested."}},"required":["campaignId"],"additionalProperties":false}},{"key":"coldemail.recipient.add","app":"coldemail","title":"Add Recipients to a Campaign","description":"Add up to 5,000 people to a campaign. Each is checked first: your blocklist, the global bounce and spam-report lists, do not contact, disposable addresses and domains that can't receive mail are skipped. If the campaign is running, they start receiving its emails.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"recipients":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","maxLength":254},"first_name":{"type":"string","maxLength":200},"last_name":{"type":"string","maxLength":200},"company":{"type":"string","maxLength":200},"title":{"type":"string","maxLength":200},"city":{"type":"string","maxLength":200},"state":{"type":"string","maxLength":200},"timezone":{"type":"string","maxLength":60},"tags":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":20},"variables":{"type":"object","additionalProperties":{"type":["string","number","boolean"]},"description":"Extra fields the emails can use, like {{city_name}}."}},"required":["email"],"additionalProperties":false},"minItems":1,"maxItems":5000},"skipGeneric":{"type":"boolean","description":"Skip generic addresses like info@ or office@ (default yes)."},"skipNoMail":{"type":"boolean","description":"Skip addresses whose domain can't receive mail (default yes)."},"skipOtherCampaigns":{"type":"boolean","description":"Skip people already in another campaign (default no)."},"tags":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":10,"description":"Tags added to everyone's contact."}},"required":["campaignId","recipients"],"additionalProperties":false}},{"key":"coldemail.recipient.import_csv","app":"coldemail","title":"Import Recipients from a CSV","description":"Add people to a campaign from CSV text with a header row (up to 25,000 rows), with the same checks as adding them one by one. Columns are matched by their headers unless you say which column is which. If the campaign is running, they start receiving its emails.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid"},"csv":{"type":"string","minLength":1,"maxLength":10000000},"mapping":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"field"},"key":{"type":"string","enum":["email","first_name","last_name","company","title","city","state","timezone","tags"]}},"required":["kind","key"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"custom"},"key":{"type":"string","minLength":1,"maxLength":60}},"required":["kind","key"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"skip"}},"required":["kind"],"additionalProperties":false}]},"maxItems":200,"description":"One entry per column, in order: a known field (email, first_name, company…), a custom field, or skip."},"skipGeneric":{"type":"boolean","description":"Skip generic addresses like info@ (default yes)."},"skipNoMail":{"type":"boolean","description":"Skip addresses whose domain can't receive mail (default yes)."},"skipOtherCampaigns":{"type":"boolean","description":"Skip people already in another campaign (default no)."},"tags":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":10}},"required":["campaignId","csv"],"additionalProperties":false}},{"key":"coldemail.inbox.list","app":"coldemail","title":"List Inboxes","description":"List the inboxes that send your cold email, with their daily limit, warmup, status (and why one is paused), how replies are read, and the inbox groups. Passwords and keys are never shown.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.inbox.get","app":"coldemail","title":"Get an Inbox","description":"Show one inbox in full, including its latest DNS check, blocklist check and inbox placement tests. Passwords and keys are never shown.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.add","app":"coldemail","title":"Connect an Inbox","description":"Connect a mailbox to send from, either your own mailbox over SMTP (with IMAP to read replies) or a SendGrid sender. Google and Microsoft sign-in has to be done on the Inboxes page. The password or key is stored encrypted.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"transport":{"type":"string","enum":["smtp","sendgrid"],"description":"smtp = your own mailbox; sendgrid = send through SendGrid."},"fromEmail":{"type":"string","format":"email"},"fromName":{"type":"string","maxLength":120},"dailyLimit":{"type":"integer","minimum":1,"maximum":10000,"description":"Most emails a day (default 40; at most 500 for a mailbox)."},"warmupEnabled":{"type":"boolean","description":"Warm the mailbox up: start small and build its sending reputation."},"smtpHost":{"type":"string","maxLength":200},"smtpPort":{"type":"integer","minimum":1,"maximum":65535},"smtpUsername":{"type":"string","maxLength":200},"smtpPassword":{"type":"string","maxLength":500,"description":"For Gmail or Outlook, an app password."},"imapHost":{"type":"string","maxLength":200,"description":"To read replies; leave empty to set it up later."},"imapPort":{"type":"integer","minimum":1,"maximum":65535},"imapUsername":{"type":"string","maxLength":200},"imapPassword":{"type":"string","maxLength":500},"sendgridApiKey":{"type":"string","maxLength":200,"description":"Your own SendGrid key (starts with SG.). Leave empty to use the account your provider supplies, if any."}},"required":["transport","fromEmail"],"additionalProperties":false}},{"key":"coldemail.inbox.set_daily_limit","app":"coldemail","title":"Change an Inbox's Daily Limit","description":"Change the most emails an inbox sends a day: up to 500 for a mailbox, 10,000 for a SendGrid sender. Warmup still ramps a new inbox up to it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"},"dailyLimit":{"type":"integer","minimum":1,"maximum":10000}},"required":["inboxId","dailyLimit"],"additionalProperties":false}},{"key":"coldemail.inbox.set_sendgrid_key","app":"coldemail","title":"Set a SendGrid Inbox's Key","description":"Add or replace the SendGrid API key a SendGrid inbox sends with, and connect its delivery reports. The key is stored encrypted.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"},"sendgridApiKey":{"type":"string","minLength":10,"maxLength":200}},"required":["inboxId","sendgridApiKey"],"additionalProperties":false}},{"key":"coldemail.inbox.set_reply_settings","app":"coldemail","title":"Set how an inbox's replies are read","description":"Choose how replies to an inbox are picked up: imap reads the mailbox (any provider; Gmail and Outlook need an app password), parse uses a reply subdomain you point at SendGrid, and none turns reply tracking off.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"},"mode":{"type":"string","enum":["imap","parse","none"]},"imapHost":{"type":"string","maxLength":200},"imapPort":{"type":"integer","minimum":1,"maximum":65535},"imapUsername":{"type":"string","maxLength":200},"imapPassword":{"type":"string","maxLength":500,"description":"Leave empty to keep the saved one."},"replyDomain":{"type":"string","maxLength":200,"description":"For parse: a subdomain like reply.yourdomain.com."}},"required":["inboxId","mode"],"additionalProperties":false}},{"key":"coldemail.inbox.delete","app":"coldemail","title":"Remove an Inbox","description":"Disconnect and remove an inbox. Campaigns stop sending from it.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.send_test","app":"coldemail","title":"Send a Test Email to Yourself","description":"Send one real email from an inbox to your own address, through the same route a campaign uses, to prove it can send. It only ever goes to you, isn't billed, and a failure shows the provider's own reason.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.check_dns","app":"coldemail","title":"Check an Inbox's DNS","description":"Check the inbox's domain for SPF, DKIM, DMARC and mail records now, with plain fixes for anything missing. The result is saved on the inbox.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.check_blocklists","app":"coldemail","title":"Check an Inbox's Domains Against Blocklists","description":"Check the inbox's sending, reply and tracking domains against the main domain blocklists now. The result is saved on the inbox.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.placement_test","app":"coldemail","title":"Run an Inbox Placement Test","description":"Send one test email from an inbox to our test mailboxes at the major providers and report whether it lands in the inbox, promotions or spam (results within about 30 minutes). Costs 1 token.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"},"requestId":{"type":"string","maxLength":40,"description":"Any unique text; repeating a request with the same value never charges twice."}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox.resume","app":"coldemail","title":"Resume a Paused Inbox","description":"Turn a paused inbox back on (it pauses itself after repeated failed sends or a blocklist listing). Its active campaigns start emailing their recipients again; if the cause isn't fixed, it pauses again.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"inboxId":{"type":"string","format":"uuid"}},"required":["inboxId"],"additionalProperties":false}},{"key":"coldemail.inbox_group.save","app":"coldemail","title":"Create or Change an Inbox Group","description":"Create an inbox group (leave out the id) or change one: its name and which inboxes are in it. A campaign can send from a whole group.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"groupId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":80,"description":"Required for a new group."},"inboxIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":200,"description":"The inboxes in the group (replaces the current list)."}},"additionalProperties":false}},{"key":"coldemail.inbox_group.delete","app":"coldemail","title":"Delete an Inbox Group","description":"Delete an inbox group. Campaigns that used it keep their individually chosen inboxes.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"groupId":{"type":"string","format":"uuid"}},"required":["groupId"],"additionalProperties":false}},{"key":"coldemail.settings.get","app":"coldemail","title":"Get Cold Email Settings","description":"Show your Cold Email settings: the business mailing address on every email, test recipients, the company profile used for AI writing, sending domains and their DNS records, the tracking domain, whether a booking link is set, and how many entries the blocklist has.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.settings.set_postal_address","app":"coldemail","title":"Set Your Business Mailing Address","description":"Set the physical mailing address that the law requires at the bottom of every commercial email. Nothing sends until it is set.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"address":{"type":"string","minLength":10,"maxLength":500}},"required":["address"],"additionalProperties":false}},{"key":"coldemail.test_recipient.add","app":"coldemail","title":"Add a Test Recipient","description":"Add an address that campaigns in test mode send to. In test mode, only these addresses are emailed.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"additionalProperties":false}},{"key":"coldemail.test_recipient.remove","app":"coldemail","title":"Remove a Test Recipient","description":"Stop sending test-mode emails to an address.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"additionalProperties":false}},{"key":"coldemail.blocklist.list","app":"coldemail","title":"List the Blocklist","description":"List your do-not-mail list, newest first: addresses and whole domains, and where each came from (added by your team, an unsubscribe, an opt-out reply, a complaint or a bounce).","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"search":{"type":"string","maxLength":200},"limit":{"type":"integer","minimum":1,"maximum":1000},"before":{"type":"string","description":"The next value from the previous page."}},"additionalProperties":false}},{"key":"coldemail.blocklist.add","app":"coldemail","title":"Block Addresses or Domains","description":"Add email addresses or whole domains (like competitor.com) to your do-not-mail list. No campaign emails them again.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"string","minLength":1,"maxLength":254},"minItems":1,"maxItems":5000},"note":{"type":"string","maxLength":200}},"required":["entries"],"additionalProperties":false}},{"key":"coldemail.blocklist.remove","app":"coldemail","title":"Unblock an Address or Domain","description":"Remove an entry your team added to the blocklist, so campaigns can email it again. Unsubscribes, opt-out replies, complaints and bounces can't be removed.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"entryId":{"type":"string","format":"uuid","description":"From the blocklist."}},"required":["entryId"],"additionalProperties":false}},{"key":"coldemail.profile.update","app":"coldemail","title":"Update the Company Profile","description":"Change what AI writing knows about your company: what you do, your offer, answers to common questions, your signature and your booking link (used for {{booking_link}}). Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"about":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"offer":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"faq":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}]},"signature":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]},"bookingUrl":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"description":"Your scheduling page, starting with https://."}},"additionalProperties":false}},{"key":"coldemail.booking_link.reset","app":"coldemail","title":"Create a New Booking Webhook","description":"Create the webhook address your booking tool (Calendly, Cal.com) calls when someone books, so their sequence stops and they are marked meeting booked. Replacing it stops the old address working at once.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.sending_domain.add","app":"coldemail","title":"Add a Sending Domain","description":"Add a domain you send from, to prove you own it. Returns a TXT record to add at your DNS provider; then run the check. Needed when your inboxes send through a shared delivery account.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"domain":{"type":"string","minLength":3,"maxLength":253,"description":"Just the part after the @, like yourcompany.com."}},"required":["domain"],"additionalProperties":false}},{"key":"coldemail.sending_domain.check","app":"coldemail","title":"Check a Sending Domain","description":"Look up a sending domain's TXT record now and mark it verified if it matches. DNS changes can take up to an hour to appear.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"domainId":{"type":"string","format":"uuid"}},"required":["domainId"],"additionalProperties":false}},{"key":"coldemail.sending_domain.remove","app":"coldemail","title":"Remove a Sending Domain","description":"Remove a sending domain. Inboxes sending from it through a shared delivery account stop until it is verified again.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"domainId":{"type":"string","format":"uuid"}},"required":["domainId"],"additionalProperties":false}},{"key":"coldemail.tracking_domain.set","app":"coldemail","title":"Set a Custom Tracking Domain","description":"Use your own subdomain (like track.yourdomain.com) for open and click tracking. Returns the CNAME record to add; then run the check. Our team connects it once it resolves.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"domain":{"type":"string","minLength":5,"maxLength":253}},"required":["domain"],"additionalProperties":false}},{"key":"coldemail.tracking_domain.check","app":"coldemail","title":"Check the Tracking Domain","description":"Look up the tracking domain's CNAME record now. DNS changes can take up to an hour to appear.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.tracking_domain.remove","app":"coldemail","title":"Remove the Tracking Domain","description":"Stop using your custom tracking domain. Tracked links go back to the standard address.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.reply.list","app":"coldemail","title":"List Replies","description":"List replies from recipients, newest first, with the person, the campaign and the category. Out-of-office and bounce notices are left out unless you ask for them.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500},"since":{"type":"string","format":"date-time","description":"Only replies after this time."},"before":{"type":"string","description":"The next value from the previous page."},"category":{"type":"string","enum":["interested","meeting_request","information_request","not_interested","do_not_contact","out_of_office","wrong_person","bounce","other","meeting_booked"]},"campaignId":{"type":"string","format":"uuid"},"includeAutomatic":{"type":"boolean","description":"Include out-of-office replies and bounce notices."}},"additionalProperties":false}},{"key":"coldemail.conversation.get","app":"coldemail","title":"Get a Conversation","description":"Show one recipient's whole conversation: every email sent and received, team notes, any saved reply draft, and whether it is snoozed or archived.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid","description":"The recipient's id, from a reply or a campaign's recipients."}},"required":["leadId"],"additionalProperties":false}},{"key":"coldemail.reply.set_category","app":"coldemail","title":"Set a Reply's Category","description":"Correct how a reply is categorized; your choice wins over the automatic one. It takes effect at once: do not contact blocks the person in every campaign, interested and similar categories can start a follow-up campaign that emails them, and out of office lets the sequence carry on.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"messageId":{"type":"string","format":"uuid","description":"The reply's id."},"category":{"type":"string","enum":["interested","meeting_request","information_request","not_interested","do_not_contact","out_of_office","wrong_person","bounce","other","meeting_booked"]}},"required":["messageId","category"],"additionalProperties":false}},{"key":"coldemail.conversation.send_reply","app":"coldemail","title":"Reply to a Recipient","description":"Send a reply in a conversation from the inbox it went out from, in the same email thread, quoting their message. Not billed. Refused for anyone who opted out or is on a do-not-mail list.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"body":{"type":"string","minLength":1,"maxLength":20000}},"required":["leadId","body"],"additionalProperties":false}},{"key":"coldemail.conversation.draft_reply","app":"coldemail","title":"Draft a Reply with AI","description":"Write a suggested reply with AI from the conversation and your company profile. Costs 1 token. The draft is saved on the conversation; nothing is sent.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"requestId":{"type":"string","maxLength":40,"description":"Any unique text; repeating a request with the same value never charges twice."}},"required":["leadId"],"additionalProperties":false}},{"key":"coldemail.conversation.discard_draft","app":"coldemail","title":"Discard a Saved Reply Draft","description":"Throw away the reply draft saved on a conversation.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"}},"required":["leadId"],"additionalProperties":false}},{"key":"coldemail.conversation.snooze","app":"coldemail","title":"Snooze a Conversation","description":"Hide a conversation from the inbox until a set time. It comes back then, or sooner if they write again.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"until":{"type":"string","enum":["tomorrow","3days","week","date"]},"date":{"type":"string","description":"When until is date: the date and time it comes back."}},"required":["leadId","until"],"additionalProperties":false}},{"key":"coldemail.conversation.set_state","app":"coldemail","title":"Archive, Unarchive or Mark Unread","description":"Archive a conversation, move it back to the inbox, end a snooze, or mark its latest reply unread.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"op":{"type":"string","enum":["archive","unarchive","unsnooze","unread"]}},"required":["leadId","op"],"additionalProperties":false}},{"key":"coldemail.conversation.add_note","app":"coldemail","title":"Add a Team Note","description":"Add a private note to a conversation. Only your team sees it; it is never sent.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"body":{"type":"string","minLength":1,"maxLength":5000}},"required":["leadId","body"],"additionalProperties":false}},{"key":"coldemail.conversation.tag","app":"coldemail","title":"Tag the Person in a Conversation","description":"Add or remove tags on the contact behind a conversation, so you can find or import them later.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid"},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"minItems":1,"maxItems":10},"op":{"type":"string","enum":["add","remove"]}},"required":["leadId","tags"],"additionalProperties":false}},{"key":"coldemail.conversation.bulk_update","app":"coldemail","title":"Update Several Conversations","description":"Mark up to 150 conversations read, archive or unarchive them, or set the category of each one's latest reply (which takes effect as it would one at a time, including follow-up campaigns that email them).","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"leadIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":150},"op":{"type":"string","enum":["read","archive","unarchive","category"]},"category":{"type":"string","enum":["interested","meeting_request","information_request","not_interested","do_not_contact","out_of_office","wrong_person","bounce","other","meeting_booked"],"description":"When op is category: the category to set."}},"required":["leadIds","op"],"additionalProperties":false}},{"key":"coldemail.contact.list","app":"coldemail","title":"List Contacts","description":"List your organization's contacts, newest first, with their tags and whether they are marked do not contact. Filter by tag or search by name, email or company.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"tag":{"type":"string","maxLength":60},"search":{"type":"string","maxLength":200},"limit":{"type":"integer","minimum":1,"maximum":200},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},{"key":"coldemail.contact.add_tags","app":"coldemail","title":"Tag Contacts","description":"Add tags to up to 200 contacts, for example to import them into a LinkedIn campaign later.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"minItems":1,"maxItems":10}},"required":["contactIds","tags"],"additionalProperties":false}},{"key":"coldemail.contact.remove_tags","app":"coldemail","title":"Remove Tags from Contacts","description":"Remove tags from up to 200 contacts.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200},"tags":{"type":"array","items":{"type":"string","minLength":1,"maxLength":60},"minItems":1,"maxItems":10}},"required":["contactIds","tags"],"additionalProperties":false}},{"key":"coldemail.contact.mark_do_not_contact","app":"coldemail","title":"Mark Contacts Do Not Contact","description":"Mark up to 200 contacts do not contact across your whole organization. Their campaigns stop now, and no Cold Email or LinkedIn campaign reaches them again.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200}},"required":["contactIds"],"additionalProperties":false}},{"key":"coldemail.contact.clear_do_not_contact","app":"coldemail","title":"Clear Do Not Contact","description":"Undo a mistaken do-not-contact mark on up to 200 contacts. No campaign restarts; add them to a campaign again to reach them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200}},"required":["contactIds"],"additionalProperties":false}},{"key":"coldemail.client_report.list","app":"coldemail","title":"List Client Report Links","description":"List the private, read-only report links you share with clients, the campaigns each shows, and when each was last viewed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.client_report.create","app":"coldemail","title":"Create a Client Report Link","description":"Create a private, read-only link showing chosen campaigns' results, to send to a client. Anyone with the link can view it until you revoke it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"Usually the client's name."},"campaignIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100},"showReplies":{"type":"boolean","description":"Also show replies."}},"required":["name","campaignIds"],"additionalProperties":false}},{"key":"coldemail.client_report.update","app":"coldemail","title":"Change a Client Report Link","description":"Change which campaigns a client report shows, or whether it shows replies. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"reportId":{"type":"string","format":"uuid"},"campaignIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":100},"showReplies":{"type":"boolean"}},"required":["reportId"],"additionalProperties":false}},{"key":"coldemail.client_report.revoke","app":"coldemail","title":"Revoke a Client Report Link","description":"Stop a client report link working, at once and for good.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"reportId":{"type":"string","format":"uuid"}},"required":["reportId"],"additionalProperties":false}},{"key":"coldemail.linkedin_account.list","app":"coldemail","title":"List LinkedIn Accounts","description":"List the LinkedIn profiles your team works outreach from, with their daily and weekly invitation limits and status.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"coldemail.linkedin_account.get","app":"coldemail","title":"Get a LinkedIn Account","description":"Show one LinkedIn account's settings, its campaigns (with the connection note and follow-up messages) and how many people are in each stage.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"}},"required":["accountId"],"additionalProperties":false}},{"key":"coldemail.linkedin_person.list","app":"coldemail","title":"List People on a LinkedIn Account","description":"List the people on a LinkedIn account, newest first, optionally only those in one stage (queued, invited, accepted, replied and so on).","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","invited","accepted","replied","not_interested","do_not_contact","withdrawn","skipped","completed"]},"limit":{"type":"integer","minimum":1,"maximum":300}},"required":["accountId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.get","app":"coldemail","title":"Get Today's LinkedIn Queue","description":"Show today's to-do list for a LinkedIn account: invitations to send (with the note), people to find on LinkedIn, follow-up messages due, and old invitations to withdraw, within the account's daily limits.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"}},"required":["accountId"],"additionalProperties":false}},{"key":"coldemail.linkedin_account.create","app":"coldemail","title":"Add a LinkedIn Account","description":"Add a LinkedIn profile to work outreach from. Nothing is sent automatically: your team sends each invitation and message by hand from the daily queue.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":120,"description":"Usually the name of the person whose profile it is."},"timezone":{"type":"string","maxLength":64,"description":"The profile owner's time zone, like America/Chicago."},"profileUrl":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"status":{"type":"string","enum":["active","paused","restricted"]},"dailyInviteLimit":{"type":"integer","minimum":0,"maximum":200},"weeklyInviteLimit":{"type":"integer","minimum":0,"maximum":500},"dailyMessageLimit":{"type":"integer","minimum":0,"maximum":500},"withdrawAfterDays":{"type":"integer","minimum":1,"maximum":180,"description":"Withdraw an invitation nobody accepted after this many days."},"voiceNotes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"description":"How this person writes, for AI-personalized notes."}},"required":["label"],"additionalProperties":false}},{"key":"coldemail.linkedin_account.update","app":"coldemail","title":"Change a LinkedIn Account","description":"Change a LinkedIn account's name, limits, time zone, status or writing voice. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"label":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","maxLength":64,"description":"The profile owner's time zone, like America/Chicago."},"profileUrl":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"status":{"type":"string","enum":["active","paused","restricted"]},"dailyInviteLimit":{"type":"integer","minimum":0,"maximum":200},"weeklyInviteLimit":{"type":"integer","minimum":0,"maximum":500},"dailyMessageLimit":{"type":"integer","minimum":0,"maximum":500},"withdrawAfterDays":{"type":"integer","minimum":1,"maximum":180,"description":"Withdraw an invitation nobody accepted after this many days."},"voiceNotes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"description":"How this person writes, for AI-personalized notes."}},"required":["accountId"],"additionalProperties":false}},{"key":"coldemail.linkedin_account.delete","app":"coldemail","title":"Remove a LinkedIn Account","description":"Remove a LinkedIn account and its queue from your organization.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"}},"required":["accountId"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.create","app":"coldemail","title":"Create a LinkedIn Campaign","description":"Create a LinkedIn campaign on an account, as a draft with a starter connection note. Then write the note and follow-ups, import people and set it active.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160}},"required":["accountId","name"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.get","app":"coldemail","title":"Get a LinkedIn Campaign","description":"Show one LinkedIn campaign: its status, connection note, follow-up messages and whether notes are personalized with AI.","kind":"read","risk":{},"access":{"role":"member"},"scope":"coldemail:read","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"}},"required":["accountId","campaignId"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.update","app":"coldemail","title":"Change a LinkedIn Campaign","description":"Change a LinkedIn campaign's name, status, connection note (300 characters at most), follow-up messages or AI personalization. Only the fields you send change. Active campaigns feed the daily queue.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160},"status":{"type":"string","enum":["draft","active","paused","completed"]},"connectionNote":{"type":"string","maxLength":2000,"description":"Supports {{first_name}}, {{company}}, {{headline}} and {{first_name|there}} for a fallback."},"personalizeWithAi":{"type":"boolean","description":"Offer an AI-personalized note for each person (1 token each, only when used)."},"followups":{"type":"array","items":{"type":"object","properties":{"wait_days":{"type":"integer","minimum":0,"maximum":90},"body":{"type":"string","maxLength":8000}},"required":["wait_days","body"],"additionalProperties":false},"maxItems":5,"description":"Messages after someone accepts, in order (replaces the current list). Supports {{first_name}}, {{company}}, {{headline}} and {{first_name|there}} for a fallback."}},"required":["accountId","campaignId"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.delete","app":"coldemail","title":"Remove a LinkedIn Campaign","description":"Remove a LinkedIn campaign. Its people leave the daily queue.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"}},"required":["accountId","campaignId"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.import_csv","app":"coldemail","title":"Import People into a LinkedIn Campaign","description":"Add up to 10,000 people to a LinkedIn campaign from CSV text with a Profile URL column. Each joins your contacts; anyone already on the account, marked do not contact or on your blocklist is skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"csv":{"type":"string","minLength":1,"maxLength":10000000}},"required":["accountId","campaignId","csv"],"additionalProperties":false}},{"key":"coldemail.linkedin_campaign.import_contacts","app":"coldemail","title":"Import tagged contacts into a LinkedIn campaign","description":"Add everyone in your contacts with a tag to a LinkedIn campaign. People without a profile link are queued for someone to find on LinkedIn first; anyone marked do not contact is skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"campaignId":{"type":"string","format":"uuid"},"tag":{"type":"string","minLength":1,"maxLength":60}},"required":["accountId","campaignId","tag"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.mark_sent","app":"coldemail","title":"Record an invitation or message as sent","description":"Record that someone on your team sent a person's invitation (with its note) or follow-up message on LinkedIn. Nothing is sent from here; recording it twice changes nothing.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."},"kind":{"type":"string","enum":["invite","followup"]},"step":{"type":"integer","minimum":0,"maximum":10,"description":"For a follow-up: which one, as shown in the queue (0 is the first)."}},"required":["accountId","personId","kind"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.skip","app":"coldemail","title":"Skip a Person","description":"Take a person waiting for an invitation off the queue without inviting them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.save_profile_link","app":"coldemail","title":"Save a Person's LinkedIn Profile Link","description":"Save the profile link for a person who was imported without one, so they move onto the invitation list. Their contact gets the link too.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."},"profileUrl":{"type":"string","minLength":10,"maxLength":300,"description":"Like https://www.linkedin.com/in/their-name."}},"required":["accountId","personId","profileUrl"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.not_found","app":"coldemail","title":"Set aside a person who can't be found","description":"Set aside a person without a profile link whom nobody could find on LinkedIn.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.mark_connected","app":"coldemail","title":"Record a New Connection","description":"Record that a person accepted the invitation (or was already connected). Their first follow-up message is scheduled.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.mark_accepted_bulk","app":"coldemail","title":"Record Many New Connections","description":"Paste the names or profile links of people who accepted, one per line, and they are matched to pending invitations and recorded as connected.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"accepted":{"type":"string","minLength":1,"maxLength":100000}},"required":["accountId","accepted"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.mark_withdrawn","app":"coldemail","title":"Record a Withdrawn Invitation","description":"Record that someone on your team withdrew a person's unanswered invitation on LinkedIn.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.stop_followups","app":"coldemail","title":"Stop Follow-Ups to a Person","description":"Stop any further follow-up messages to a connection.","kind":"write","risk":{},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.log_reply","app":"coldemail","title":"Log a LinkedIn Reply","description":"Log what a person wrote back on LinkedIn, with its category (or auto to have it categorized). Follow-ups stop where they should, do not contact applies across every channel, and the account owners are emailed about interested replies.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."},"reply":{"type":"string","minLength":1,"maxLength":8000},"category":{"type":"string","enum":["auto","interested","meeting_request","information_request","not_interested","do_not_contact","out_of_office","wrong_person","other"]}},"required":["accountId","personId","reply"],"additionalProperties":false}},{"key":"coldemail.linkedin_queue.personalize_note","app":"coldemail","title":"Personalize a Connection Note with AI","description":"Write a personalized connection note for one person waiting to be invited, from the campaign's note and the account's writing voice. Costs 1 token. Nothing is sent.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"coldemail:write","input":{"type":"object","properties":{"accountId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"From the queue or the account's people."},"requestId":{"type":"string","maxLength":40,"description":"Any unique text; repeating a request with the same value never charges twice."}},"required":["accountId","personId"],"additionalProperties":false}},{"key":"coldemail.ops.set_platform_sending","app":"coldemail","title":"Allow or stop a client using our sending account","description":"Platform staff: let a client organization send its cold email through our own delivery account (turning it on needs a reason), or stop it. Recorded in the audit log.","kind":"write","risk":{},"access":{"role":"staff","capability":"coldemail:manage"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client organization."},"enabled":{"type":"boolean"},"note":{"type":"string","maxLength":500}},"required":["orgId","enabled"],"additionalProperties":false}},{"key":"coldemail.ops.verify_sending_domain","app":"coldemail","title":"Mark a Client's Sending Domain Verified","description":"Platform staff: mark a domain verified for a client organization without the DNS record, for a client whose DNS we manage. Needs a note saying how we know they own it. Recorded in the audit log.","kind":"write","risk":{},"access":{"role":"staff","capability":"coldemail:manage"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The client organization."},"domain":{"type":"string","minLength":3,"maxLength":253},"note":{"type":"string","minLength":1,"maxLength":500}},"required":["orgId","domain","note"],"additionalProperties":false}},{"key":"video.profile.list","app":"video","title":"List Video Profiles","description":"List the video profiles (a voice paired with an avatar, or voice only) you can use for new videos: your own plus those shared with this organization. Shows which one is your default.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.profile.get","app":"video","title":"Get a Video Profile","description":"Show one video profile's settings: its voice, avatar, language, captions and who it is shared with.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{"profileId":{"type":"string","format":"uuid","description":"The profile's id, from List video profiles."}},"required":["profileId"],"additionalProperties":false}},{"key":"video.profile.options","app":"video","title":"Video Profile Options","description":"List the voices and avatars you can pick from when making or changing a video profile: our standard voices and stock spokespeople, any cloned voice or custom avatar set up for you, and those from your connected ElevenLabs or HeyGen account. Also lists where a profile can be shared.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.profile.create","app":"video","title":"Create a Video Profile","description":"Create a video profile: a voice paired with an avatar (or voice only), with a language and caption style. Pick voices and avatars from Video profile options.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"voiceProvider":{"type":"string","enum":["generic","elevenlabs"],"description":"generic = one of our standard voices; elevenlabs = a cloned voice (ours, set up by concierge, or from your connected ElevenLabs account)."},"voiceId":{"type":"string","maxLength":120,"description":"The voice's id, from Video profile options."},"avatarProvider":{"type":"string","enum":["none","heygen_stock","heygen"],"description":"none = voice only; heygen_stock = one of our stock spokespeople; heygen = your custom avatar.","default":"none"},"avatarId":{"type":"string","maxLength":120,"description":"The avatar's id, from Video profile options. Empty when avatarProvider is none.","default":""},"language":{"type":"string","minLength":2,"maxLength":8,"description":"Language code, like en or es.","default":"en"},"captionMode":{"type":"string","enum":["none","burned","sidecar","both"],"description":"none = no captions; burned = captions drawn into the video; sidecar = a separate caption file; both.","default":"sidecar"},"scope":{"type":"string","minLength":1,"description":"\"personal\" for just you, or the id of an organization you own to share the profile with its members.","default":"personal"}},"required":["name","voiceProvider","voiceId"],"additionalProperties":false}},{"key":"video.profile.update","app":"video","title":"Update a Video Profile","description":"Change a video profile's name, voice, avatar, language, captions or who it is shared with. Only the fields you send change. You can change your own profiles and those shared with an organization you own.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"profileId":{"type":"string","format":"uuid","description":"The profile's id, from List video profiles."},"name":{"type":"string","minLength":1,"maxLength":120},"voiceProvider":{"type":"string","enum":["generic","elevenlabs"],"description":"generic = one of our standard voices; elevenlabs = a cloned voice (ours, set up by concierge, or from your connected ElevenLabs account)."},"voiceId":{"type":"string","maxLength":120,"description":"The voice's id, from Video profile options."},"avatarProvider":{"type":"string","enum":["none","heygen_stock","heygen"],"description":"none = voice only; heygen_stock = one of our stock spokespeople; heygen = your custom avatar."},"avatarId":{"type":"string","maxLength":120,"description":"The avatar's id, from Video profile options. Empty when avatarProvider is none."},"language":{"type":"string","minLength":2,"maxLength":8,"description":"Language code, like en or es."},"captionMode":{"type":"string","enum":["none","burned","sidecar","both"],"description":"none = no captions; burned = captions drawn into the video; sidecar = a separate caption file; both."},"scope":{"type":"string","minLength":1,"description":"\"personal\" for just you, or the id of an organization you own to share the profile with its members."}},"required":["profileId"],"additionalProperties":false}},{"key":"video.profile.delete","app":"video","title":"Delete a Video Profile","description":"Delete a video profile. Automations that use it will need another profile before they can run.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"profileId":{"type":"string","format":"uuid","description":"The profile's id, from List video profiles."}},"required":["profileId"],"additionalProperties":false}},{"key":"video.profile.set_default","app":"video","title":"Set Your Default Video Profile","description":"Make a video profile your default, so new videos and automations start with it selected.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"profileId":{"type":"string","format":"uuid","description":"The profile's id, from List video profiles."}},"required":["profileId"],"additionalProperties":false}},{"key":"video.area.list","app":"video","title":"List Market Areas","description":"List the cities, ZIP codes and neighborhoods you farm. Market report videos and automations are made for one of these areas. Areas are yours personally and follow you between organizations.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.area.create","app":"video","title":"Add a Market Area","description":"Add a city, ZIP code or neighborhood you want market report videos for. The label is what you see in lists, like Austin, TX 78704.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"type":{"type":"string","enum":["city","zip","neighborhood"]},"value":{"type":"string","minLength":1,"maxLength":120,"description":"The city name, five-digit ZIP code or neighborhood name."},"label":{"type":"string","minLength":1,"maxLength":200,"description":"How the area is shown in lists."},"boundaryId":{"type":"string","minLength":1,"maxLength":64,"description":"A market-data boundary id, when you have one. Leave out otherwise."}},"required":["type","value","label"],"additionalProperties":false}},{"key":"video.area.delete","app":"video","title":"Remove a Market Area","description":"Remove one of your market areas. Videos already made for it are kept.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"areaId":{"type":"string","format":"uuid","description":"The area's id, from List market areas."}},"required":["areaId"],"additionalProperties":false}},{"key":"video.automation.list","app":"video","title":"List Automations","description":"List this organization's automations: recurring market report videos, each with an area, template, video profile, schedule and whether it is active or paused.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.automation.get","app":"video","title":"Get an Automation","description":"Show one automation's settings, schedule, when it last ran and when it runs next.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{"automationId":{"type":"string","format":"uuid","description":"The automation's id, from List automations."}},"required":["automationId"],"additionalProperties":false}},{"key":"video.template.list","app":"video","title":"List Video Templates","description":"List the video templates for each kind of video (for example the market report templates an automation can use), with their ids.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{"contentType":{"type":"string","maxLength":64,"description":"Only templates for this kind of video, like market_report. Kinds come from List video types."}},"additionalProperties":false}},{"key":"video.automation.create","app":"video","title":"Create an Automation","description":"Set up a recurring market report video for one of your areas, filed under this organization. A monthly automation makes a video every month, and every run spends this organization's tokens; a manual one runs only when you start it.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"video:render","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"areaId":{"type":"string","format":"uuid","description":"One of your areas, from List market areas."},"templateId":{"type":"string","format":"uuid","description":"A market report template, from List video templates."},"videoProfileId":{"type":"string","format":"uuid","description":"The voice and avatar to use, from List video profiles."},"cadence":{"type":"string","enum":["monthly","manual"]},"enableDistribution":{"type":"boolean","default":false,"description":"Post each finished video to your connected social accounts."}},"required":["name","areaId","templateId","videoProfileId","cadence"],"additionalProperties":false}},{"key":"video.automation.pause","app":"video","title":"Pause an Automation","description":"Pause an automation so it stops making videos until you resume it. Only the person who set it up can pause it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"automationId":{"type":"string","format":"uuid","description":"The automation's id, from List automations."}},"required":["automationId"],"additionalProperties":false}},{"key":"video.automation.resume","app":"video","title":"Resume an Automation","description":"Resume a paused automation so it makes videos on its schedule again, each run spending this organization's tokens. Only the person who set it up can resume it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"automationId":{"type":"string","format":"uuid","description":"The automation's id, from List automations."}},"required":["automationId"],"additionalProperties":false}},{"key":"video.automation.delete","app":"video","title":"Delete an Automation","description":"Delete an automation so it never runs again. Videos it already made are kept. Only the person who set it up can delete it.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"automationId":{"type":"string","format":"uuid","description":"The automation's id, from List automations."}},"required":["automationId"],"additionalProperties":false}},{"key":"video.automation.run_now","app":"video","title":"Run an Automation Now","description":"Make one video from an automation right away, without waiting for its schedule. This spends tokens from the automation's organization; they are refunded if the video fails.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"video:render","input":{"type":"object","properties":{"automationId":{"type":"string","format":"uuid","description":"The automation's id, from List automations."}},"required":["automationId"],"additionalProperties":false}},{"key":"video.content_type.list","app":"video","title":"List Video Types","description":"List the kinds of video you can make (like a market report, a new listing or a just-closed sale), with the details each one needs.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.job.list","app":"video","title":"List Videos","description":"List this organization's videos, newest first, with their status (queued, in progress, completed or failed), a link to each finished video and the tokens it used.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["queued","fetching_data","scripting","awaiting_recording","synthesizing_voice","rendering_avatar","composing","distributing","completed","failed","refunded"]},"limit":{"type":"integer","minimum":1,"maximum":100,"default":50}},"additionalProperties":false}},{"key":"video.job.get","app":"video","title":"Get a Video","description":"Show one video's status, its progress through each step, why it failed if it did, and the link to the finished video.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{"videoId":{"type":"string","format":"uuid","description":"The video's id, from List videos."}},"required":["videoId"],"additionalProperties":false}},{"key":"video.video.create_new_listing","app":"video","title":"Make a New Listing Video","description":"Make a video announcing a new listing from its address, price, beds, baths, square feet and photos. This spends your organization's tokens (the price depends on the profile's voice and avatar); they are refunded if the video fails.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"video:render","input":{"type":"object","properties":{"propertyAddress":{"type":"string","minLength":3,"maxLength":200},"listingPriceUsd":{"type":"integer","exclusiveMinimum":0},"beds":{"type":"integer","minimum":0,"maximum":50},"baths":{"type":"number","minimum":0,"maximum":50},"sqft":{"type":"integer","minimum":0,"maximum":100000},"photoUrls":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":20,"description":"Public https links to the listing photos, in order."},"mlsId":{"type":"string","maxLength":60,"description":"The listing's MLS number, if any."},"videoProfileId":{"type":"string","format":"uuid","description":"The voice and avatar to use, from List video profiles."}},"required":["propertyAddress","listingPriceUsd","beds","baths","sqft","photoUrls","videoProfileId"],"additionalProperties":false}},{"key":"video.video.create_transaction_closed","app":"video","title":"Make a Just-Sold Video","description":"Make a video celebrating a closed sale from its address and sold price, with optional details and photos. This spends your organization's tokens (the price depends on the profile's voice and avatar); they are refunded if the video fails.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"video:render","input":{"type":"object","properties":{"propertyAddress":{"type":"string","minLength":3,"maxLength":200},"soldPriceUsd":{"type":"integer","exclusiveMinimum":0},"listedPriceUsd":{"type":"integer","exclusiveMinimum":0},"daysOnMarket":{"type":"integer","minimum":0},"buyerName":{"type":"string","maxLength":120,"description":"Only if the buyer agreed to be named."},"sellerName":{"type":"string","maxLength":120,"description":"Only if the seller agreed to be named."},"beds":{"type":"integer","minimum":0,"maximum":50},"baths":{"type":"number","minimum":0,"maximum":50},"sqft":{"type":"integer","minimum":0,"maximum":100000},"photoUrls":{"type":"array","items":{"type":"string","format":"uri"},"maxItems":20,"description":"Public https links to photos of the home."},"videoProfileId":{"type":"string","format":"uuid","description":"The voice and avatar to use, from List video profiles."}},"required":["propertyAddress","soldPriceUsd","videoProfileId"],"additionalProperties":false}},{"key":"video.video.create","app":"video","title":"Make a Video","description":"Make a video of any other kind from List video types, filling in the details that kind needs. For a market report, the details are the areaId of one of your areas. This spends your organization's tokens (the price depends on the profile's voice and avatar); they are refunded if the video fails.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"video:render","input":{"type":"object","properties":{"contentTypeKey":{"type":"string","minLength":1,"maxLength":64,"description":"The kind of video, from List video types."},"videoProfileId":{"type":"string","format":"uuid","description":"The voice and avatar to use, from List video profiles."},"subject":{"type":"object","additionalProperties":{},"description":"The details this kind of video needs, as listed by List video types."}},"required":["contentTypeKey","videoProfileId","subject"],"additionalProperties":false}},{"key":"video.connection.list","app":"video","title":"List Video Connections","description":"Show which of your own vendor accounts are connected to Video (ElevenLabs voices, HeyGen avatars, Metricool social publishing) and how many voices, avatars or brands each one brought in. Keys are never shown.","kind":"read","risk":{},"access":{"role":"member"},"scope":"video:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"video.connection.connect_elevenlabs","app":"video","title":"Connect ElevenLabs","description":"Connect your own ElevenLabs account so its voices can be used in your video profiles. Needs an Enterprise plan. The key is checked with ElevenLabs and stored encrypted. Not available in the assistant: enter the key on the Connections page.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"apiKey":{"type":"string","minLength":20,"maxLength":200,"description":"The API key from your account with that vendor."}},"required":["apiKey"],"additionalProperties":false}},{"key":"video.connection.connect_heygen","app":"video","title":"Connect HeyGen","description":"Connect your own HeyGen account so its avatars can be used in your video profiles. Needs an Enterprise plan. The key is checked with HeyGen and stored encrypted. Not available in the assistant: enter the key on the Connections page.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"apiKey":{"type":"string","minLength":20,"maxLength":200,"description":"The API key from your account with that vendor."}},"required":["apiKey"],"additionalProperties":false}},{"key":"video.connection.connect_metricool","app":"video","title":"Connect Metricool","description":"Connect your own Metricool account so finished videos can be posted to your social accounts. Needs an Enterprise plan. The key is checked with Metricool and stored encrypted. Not available in the assistant: enter the key on the Connections page.","kind":"write","risk":{},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"apiKey":{"type":"string","minLength":20,"maxLength":200,"description":"The API key from your account with that vendor."},"userId":{"type":"string","maxLength":64,"description":"Your Metricool user id, if your account has more than one."}},"required":["apiKey"],"additionalProperties":false}},{"key":"video.connection.disconnect","app":"video","title":"Disconnect a Video Vendor Account","description":"Disconnect your ElevenLabs, HeyGen or Metricool account from Video and delete its stored key. Profiles that use its voices or avatars, and social posting through Metricool, stop working until you connect it again.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"vendor":{"type":"string","enum":["elevenlabs","heygen","metricool"]}},"required":["vendor"],"additionalProperties":false}},{"key":"video.concierge.request","app":"video","title":"Ask for Concierge Setup","description":"Ask our team to set something up for you: a voice clone, a custom avatar, social publishing, or anything else. Your request is emailed to our concierge team, who reply to the email address you give.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"video:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"Your name."},"email":{"type":"string","minLength":1,"format":"email","maxLength":200,"description":"Where our team should reply."},"topic":{"type":"string","enum":["voice_clone","avatar","social_publishing","other"]},"message":{"type":"string","minLength":10,"maxLength":2000,"description":"What you'd like set up (at least 10 characters)."}},"required":["name","email","topic","message"],"additionalProperties":false}},{"key":"video.concierge.list","app":"video","title":"List Concierge Requests (Staff)","description":"For platform staff: list customers' concierge requests for voice clones, custom avatars and social publishing, newest first. Open requests by default.","kind":"read","risk":{},"access":{"role":"staff","capability":"video:concierge"},"scope":"operations:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["open","closed","all"],"default":"open"}},"additionalProperties":false}},{"key":"video.concierge.fulfill","app":"video","title":"Mark a Concierge Request Fulfilled (Staff)","description":"For platform staff: register the voice clone or custom avatar made for a customer, optionally create a starter video profile with it, close their request and email them that it is ready.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"video:concierge"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The request's id, from List concierge requests."},"agentId":{"type":"string","format":"uuid","description":"The customer's user id (agent_id on the request)."},"kind":{"type":"string","enum":["voice","avatar"]},"vendor":{"type":"string","enum":["elevenlabs","heygen"]},"externalId":{"type":"string","minLength":1,"maxLength":200,"description":"The voice or avatar id on our ElevenLabs or HeyGen account."},"name":{"type":"string","minLength":1,"maxLength":160,"description":"What the customer will see it called."},"tier":{"type":"string","maxLength":40},"previewUrl":{"type":"string","format":"uri","maxLength":500},"scope":{"type":"string","minLength":1,"description":"\"personal\" for the customer alone, or an organization id to share it with that organization."},"autoCreateProfile":{"type":"boolean","description":"Also create a starter video profile that uses it."}},"required":["requestId","agentId","kind","vendor","externalId","name","scope","autoCreateProfile"],"additionalProperties":false}},{"key":"content.article.list","app":"content","title":"List Articles","description":"List the articles in your content library, newest first: title, summary, link to the original and word count. Use an article's id to read it in full.","kind":"read","risk":{},"access":{"role":"member"},"scope":"content:read","input":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":100,"default":20},"offset":{"type":"integer","minimum":0,"default":0},"status":{"type":"string","enum":["queued","fetched","failed","skipped"],"default":"fetched","description":"fetched = ready to use (the default)."}},"additionalProperties":false}},{"key":"content.article.get","app":"content","title":"Read an Article","description":"Show one article from your content library in full, with its title, summary, body text and original link.","kind":"read","risk":{},"access":{"role":"member"},"scope":"content:read","input":{"type":"object","properties":{"articleId":{"type":"string","format":"uuid","description":"The article's id, from List articles."}},"required":["articleId"],"additionalProperties":false}},{"key":"content.profile.get","app":"content","title":"Get Your Marketing Profile","description":"Show your marketing profile: brokerage, license number, service area, specialties, logo, headshot, brand colors and the phone, website, calendar link, keyword and lead magnet your scripts' calls to action use.","kind":"read","risk":{},"access":{"role":"member"},"scope":"content:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"content.profile.update","app":"content","title":"Update Your Marketing Profile","description":"Change your marketing profile, which fills in your details wherever a script mentions your brokerage, service area, phone, website, calendar link, keyword or lead magnet. Only the fields you send change; send an empty value to clear one.","kind":"write","risk":{},"access":{"role":"member"},"scope":"content:write","input":{"type":"object","properties":{"brokerage":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"license_number":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}]},"service_area":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"description":"Where you work, like Austin and Round Rock, TX."},"specialties":{"type":"array","items":{"type":"string","minLength":1,"maxLength":80},"maxItems":20},"logo_url":{"anyOf":[{"type":"string","format":"uri","maxLength":500},{"type":"null"}],"description":"A public link to your logo image."},"headshot_url":{"anyOf":[{"type":"string","format":"uri","maxLength":500},{"type":"null"}],"description":"A public link to your headshot."},"brand_colors":{"type":"array","items":{"type":"string","minLength":1,"maxLength":40},"maxItems":10,"description":"Like #1a73e8."},"voice_clone_id":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"description":"The id of your cloned voice, if you have one."},"cta_phone":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}]},"cta_website":{"anyOf":[{"type":"string","format":"uri","maxLength":500},{"type":"null"}]},"cta_calendar_url":{"anyOf":[{"type":"string","format":"uri","maxLength":500},{"type":"null"}],"description":"Where people book time with you."},"cta_keyword":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"description":"The word people comment or text to get your lead magnet."},"cta_lead_magnet":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"What you offer in exchange, like a free home valuation."}},"additionalProperties":false}},{"key":"content.script.list","app":"content","title":"List an Article's Scripts (Staff)","description":"For platform staff: list the scripts and posts generated from one article (one per format), with their status and whether each was sent to Video, Newsletters or Websites.","kind":"read","risk":{},"access":{"role":"staff","capability":"content:manage"},"scope":"operations:read","input":{"type":"object","properties":{"articleId":{"type":"string","format":"uuid","description":"The article's id."}},"required":["articleId"],"additionalProperties":false}},{"key":"content.script.generate","app":"content","title":"Generate a Script (Staff)","description":"For platform staff: write a script or post from an article in one format (long YouTube video, TikTok, Reels, summary or rewrite). A script that already exists is returned free; a new one spends tokens from your active organization, refunded if writing it fails. Set force to write a fresh one.","kind":"write","risk":{"money":true},"access":{"role":"staff","capability":"content:manage"},"scope":"operations:write","input":{"type":"object","properties":{"articleId":{"type":"string","format":"uuid","description":"The article's id, from List articles."},"format":{"type":"string","enum":["video_youtube_long","video_tiktok_short","video_reels_short","text_rewrite","text_summary"]},"force":{"type":"boolean","description":"Write a new one even if this format already has a script (spends tokens again)."}},"required":["articleId","format"],"additionalProperties":false}},{"key":"content.script.send_to_video","app":"content","title":"Send a Script to Video (Staff)","description":"For platform staff: hand a finished video script (YouTube, TikTok or Reels format) to Video so it can be made into a video for your active organization. Sending the same script again doesn't make a second copy.","kind":"write","risk":{},"access":{"role":"staff","capability":"content:manage"},"scope":"operations:write","input":{"type":"object","properties":{"transformationId":{"type":"string","format":"uuid","description":"The script's id, from List an article's scripts."}},"required":["transformationId"],"additionalProperties":false}},{"key":"content.script.send_to_newsletter","app":"content","title":"Send a Post to Newsletters (Staff)","description":"For platform staff: turn a finished summary or rewrite into a draft newsletter campaign for your active organization. Nothing is emailed; the draft waits in Newsletters for review.","kind":"write","risk":{},"access":{"role":"staff","capability":"content:manage"},"scope":"operations:write","input":{"type":"object","properties":{"transformationId":{"type":"string","format":"uuid","description":"The script's id, from List an article's scripts."},"intro":{"type":"string","maxLength":2000,"description":"A short note shown above the article."},"subject":{"type":"string","maxLength":200,"description":"The email subject. Defaults to the article's title."}},"required":["transformationId"],"additionalProperties":false}},{"key":"content.script.send_to_website","app":"content","title":"Send a post to a website (staff)","description":"For platform staff: add a finished summary or rewrite as a blog post on one of your active organization's websites. It arrives as a draft to review unless publish is set.","kind":"write","risk":{},"access":{"role":"staff","capability":"content:manage"},"scope":"operations:write","input":{"type":"object","properties":{"transformationId":{"type":"string","format":"uuid","description":"The script's id, from List an article's scripts."},"siteId":{"type":"string","format":"uuid","description":"The website's id in Websites."},"slug":{"type":"string","maxLength":120,"description":"The post's web address ending. Websites may adjust it."},"heroImageUrl":{"type":"string","format":"uri","maxLength":500},"tags":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":20},"publish":{"type":"boolean","description":"Publish right away instead of saving a draft."}},"required":["transformationId","siteId"],"additionalProperties":false}},{"key":"core.account.get","app":"core","title":"Get Your Account","description":"Show your sign-in email and your personal brand: the name, headshot and voice notes used on things made for you.","kind":"read","risk":{},"access":{"role":"member"},"scope":"core:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.account.request_email_change","app":"core","title":"Change Your Sign-In Email","description":"Start changing the email address you sign in with. We email a confirmation link to the new address, and the change happens only when that link is clicked.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"newEmail":{"type":"string","format":"email","maxLength":254,"description":"The new email address to sign in with."}},"required":["newEmail"],"additionalProperties":false}},{"key":"core.account.delete","app":"core","title":"Delete Your Account","description":"Delete your own account and sign you out everywhere. Organizations only you use are closed with it. Refused if other people rely on an organization you alone own, or one of yours still has an active subscription. Support can restore an account deleted by mistake.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.account.save_brand","app":"core","title":"Save Your Personal Brand","description":"Change your personal brand: your name as it appears on things made for you, your headshot image address, and notes on your personal voice. Only the fields you send change. Your organization's logo, colors and business name are set on the organization instead.","kind":"write","risk":{},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"agentName":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Your name as shown on your materials. Send an empty value to clear it."},"headshotUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"A web address of your headshot image. Send null to clear it."},"agentVoiceNotes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Notes on how you like to sound. Send an empty value to clear it."}},"additionalProperties":false}},{"key":"core.token.list","app":"core","title":"List Your API Tokens","description":"List your personal API tokens: name, the start of each token, what each may do, spending limits, last use and whether it was revoked. Never shows a token itself.","kind":"read","risk":{},"access":{"role":"member"},"scope":"core:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.token.create","app":"core","title":"Create an API Token","description":"Create a personal API token for scripts and AI tools that act as you. The token is shown once, so this can't be done through the assistant: create it on the API tokens page in Settings.","kind":"write","risk":{},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"A name to recognize the token by later."},"scopes":{"type":"array","items":{"type":"string","enum":["identity:read","core:read","core:write","branding:read","orgs:read","orgs:write","wallet:read","wallet:write","content:read","content:write","newsletters:read","newsletters:write","newsletters:send","recruiting:read","recruiting:write","recruiting:unlock","recruiting:export","video:read","video:write","video:render","websites:read","websites:write","contacts:read","contacts:write","prospects:read","prospects:write","ads:read","ads:write","coldemail:read","coldemail:write","chatbots:read","chatbots:write","reputation:read","reputation:write","mailings:read","mailings:write","compliance:read","compliance:write","photos:read","photos:write","audit:read","audit:write","leads:read","leads:write","operations:read","operations:write","webhooks:read","webhooks:write","audit:intake","admin:partner","admin:super"]},"minItems":1,"description":"What the token may do, like wallet:read or orgs:write."},"dailyTokenCap":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"Most tokens this key may spend in a day."},"monthlyTokenCap":{"anyOf":[{"type":"integer","exclusiveMinimum":0},{"type":"null"}],"description":"Most tokens this key may spend in a month."},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"When the token stops working (ISO 8601). Leave out for no expiry."}},"required":["name","scopes"],"additionalProperties":false}},{"key":"core.token.revoke","app":"core","title":"Revoke an API Token","description":"Revoke one of your API tokens. Anything still using it stops working at once. This can't be undone; create a new token instead.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"tokenId":{"type":"string","format":"uuid","description":"The token's id, from List your API tokens."}},"required":["tokenId"],"additionalProperties":false}},{"key":"core.organization.list","app":"core","title":"List Your Organizations","description":"List every organization you belong to, how you reach it (owner, admin, member, or through a team) and which one is active. Everything you do applies to the active organization.","kind":"read","risk":{},"access":{"role":"member"},"scope":"orgs:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.organization.get","app":"core","title":"Get the Active Organization","description":"Show the active organization's name, its brand (business name, website, logos, colors, fonts, voice) and your role in it.","kind":"read","risk":{},"access":{"role":"member"},"scope":"orgs:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.organization.create","app":"core","title":"Create an Organization","description":"Create a new organization with you as its owner. If you already own one with the same name, nothing new is created and that one is returned. It does not become active until you switch to it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"The business or workspace name."}},"required":["name"],"additionalProperties":false}},{"key":"core.organization.rename","app":"core","title":"Rename the Organization","description":"Give the active organization a new name. Owners only.","kind":"write","risk":{},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"required":["name"],"additionalProperties":false}},{"key":"core.organization.archive","app":"core","title":"Delete the Organization","description":"Delete (archive) the active organization. Owners only. Refused while it has an active subscription, or if it is your only organization. Support can restore it.","kind":"write","risk":{"destructive":true},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.organization.switch","app":"core","title":"Switch the Active Organization","description":"Make another of your organizations the active one, in every product. Everything after this applies to that organization.","kind":"write","risk":{},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The organization's id, from List your organizations."}},"required":["orgId"],"additionalProperties":false}},{"key":"core.organization.save_brand","app":"core","title":"Save the Organization's Brand","description":"Change the active organization's brand: business name, website, logos, colors, fonts and writing voice. Only the fields you send change. Every product uses it. Owners only.","kind":"write","risk":{},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{"businessName":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"The business name shown on materials. Send an empty value to clear it."},"brokerage":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"The display name, when it differs from the business name. Send an empty value to clear it."},"website":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"The business website. Send null to clear it."},"logoUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of the logo image. Send null to clear it."},"darkLogoUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of a logo for dark backgrounds. Send null to clear it."},"faviconUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of the small browser-tab icon. Send null to clear it."},"primaryColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$"},{"type":"null"}],"description":"The main brand color, as a hex color like #1A73E8. Send null to clear it."},"secondaryColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$"},{"type":"null"}],"description":"The second brand color, as a hex color like #1A73E8. Send null to clear it."},"fontHeading":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Font for headings. Send an empty value to clear it."},"fontBody":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Font for body text. Send an empty value to clear it."},"voiceGuidelines":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"description":"How the business sounds in writing. Send an empty value to clear it."}},"additionalProperties":false}},{"key":"core.organization.list_members","app":"core","title":"List the Organization's Members","description":"List the people with a role in the active organization (owner, admin or member), with their user ids and email addresses.","kind":"read","risk":{},"access":{"role":"member"},"scope":"orgs:read","input":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Only the person with exactly this email address. Use it to find someone when addresses are shown masked."}},"additionalProperties":false}},{"key":"core.organization.promote_owner","app":"core","title":"Make Someone an Owner","description":"Make an existing member of the active organization an owner. Owners can rename or delete it, manage billing and change other owners. Owners only.","kind":"write","risk":{},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{"userId":{"type":"string","format":"uuid","description":"The person's user id, from List members or List teams."}},"required":["userId"],"additionalProperties":false}},{"key":"core.organization.demote_owner","app":"core","title":"Remove Someone's Owner Role","description":"Change an owner of the active organization back to an admin. The last remaining owner can't be changed. Owners only.","kind":"write","risk":{},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{"userId":{"type":"string","format":"uuid","description":"The person's user id, from List members or List teams."}},"required":["userId"],"additionalProperties":false}},{"key":"core.team.list","app":"core","title":"List Teams","description":"List the active organization's teams, each with its members, their user ids, email addresses and team roles.","kind":"read","risk":{},"access":{"role":"member"},"scope":"orgs:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.team.list_invitations","app":"core","title":"List Pending Invitations","description":"List invitations to the active organization's teams that haven't been accepted yet, with who was invited, to which team and when each expires.","kind":"read","risk":{},"access":{"role":"member"},"scope":"orgs:read","input":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Only the person with exactly this email address. Use it to find someone when addresses are shown masked."}},"additionalProperties":false}},{"key":"core.team.create","app":"core","title":"Create a Team","description":"Create a team in the active organization, with you as its owner. Organization owners only.","kind":"write","risk":{},"access":{"role":"org_owner"},"scope":"orgs:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"required":["name"],"additionalProperties":false}},{"key":"core.team.invite","app":"core","title":"Invite Someone to a Team","description":"Invite a person to one of the active organization's teams. They get an email with a link to join, valid for 14 days. Organization owners and the team's owners only.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"teamId":{"type":"string","format":"uuid","description":"The team's id, from List teams."},"email":{"type":"string","format":"email","maxLength":254,"description":"The email address to invite."},"role":{"type":"string","enum":["member","owner"],"default":"member","description":"Their role on the team. A team owner can invite others and edit the team's brand."}},"required":["teamId","email"],"additionalProperties":false}},{"key":"core.team.resend_invite","app":"core","title":"Resend an Invitation","description":"Email a pending team invitation again, with the same link and a fresh 14-day expiry. Organization owners and the team's owners only.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"invitationId":{"type":"string","format":"uuid","description":"The invitation's id, from List pending invitations."}},"required":["invitationId"],"additionalProperties":false}},{"key":"core.team.save_brand","app":"core","title":"Save a Team's Brand","description":"Change a team's brand, which overrides the organization's for things made by that team. Only the fields you send change; a cleared field falls back to the organization's. Organization owners and the team's owners only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"businessName":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"The business name shown on materials. Send an empty value to clear it."},"brokerage":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"The display name, when it differs from the business name. Send an empty value to clear it."},"website":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"The business website. Send null to clear it."},"logoUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of the logo image. Send null to clear it."},"darkLogoUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of a logo for dark backgrounds. Send null to clear it."},"faviconUrl":{"anyOf":[{"type":"string","format":"uri","maxLength":2000},{"type":"null"}],"description":"Web address of the small browser-tab icon. Send null to clear it."},"primaryColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$"},{"type":"null"}],"description":"The main brand color, as a hex color like #1A73E8. Send null to clear it."},"secondaryColor":{"anyOf":[{"type":"string","pattern":"^#[0-9a-fA-F]{3,8}$"},{"type":"null"}],"description":"The second brand color, as a hex color like #1A73E8. Send null to clear it."},"fontHeading":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Font for headings. Send an empty value to clear it."},"fontBody":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Font for body text. Send an empty value to clear it."},"voiceGuidelines":{"anyOf":[{"type":"string","maxLength":5000},{"type":"null"}],"description":"How the business sounds in writing. Send an empty value to clear it."},"teamId":{"type":"string","format":"uuid","description":"The team's id, from List teams."}},"required":["teamId"],"additionalProperties":false}},{"key":"core.team.remove_member","app":"core","title":"Remove Someone from a Team","description":"Take a person off one of the active organization's teams. Organization owners and the team's owners can remove anyone; anyone can remove themselves.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"orgs:write","input":{"type":"object","properties":{"teamId":{"type":"string","format":"uuid","description":"The team's id, from List teams."},"userId":{"type":"string","format":"uuid","description":"The person's user id, from List members or List teams."}},"required":["teamId","userId"],"additionalProperties":false}},{"key":"core.webhook.list","app":"core","title":"List Webhooks","description":"List the addresses the active organization sends event notifications to, the events each receives and whether it is on.","kind":"read","risk":{},"access":{"role":"member"},"scope":"webhooks:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.webhook.add","app":"core","title":"Add a Webhook","description":"Send the active organization's events to a web address of yours, signed so you can verify them. Its signing secret is shown on the Developers page. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"webhooks:write","input":{"type":"object","properties":{"url":{"type":"string","format":"uri","maxLength":2000,"description":"A full https:// address on the public internet."},"events":{"type":"array","items":{"type":"string","enum":["lead.received","video.render.completed","campaign.sent","coldemail.reply.received","coldemail.reply.category_changed","coldemail.lead.opted_out","coldemail.lead.bounced","coldemail.lead.completed","coldemail.lead.meeting_booked","coldemail.campaign.paused"]},"minItems":1,"description":"Which events to send."}},"required":["url","events"],"additionalProperties":false}},{"key":"core.webhook.remove","app":"core","title":"Remove a Webhook","description":"Stop sending events to one of the active organization's webhook addresses. Owners and admins only.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"webhooks:write","input":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The webhook's id, from List webhooks."}},"required":["id"],"additionalProperties":false}},{"key":"core.webhook.test","app":"core","title":"Send a Test Event","description":"Send a signed test event to one of the active organization's webhooks and report what it answered. Owners and admins only.","kind":"write","risk":{},"access":{"role":"member"},"scope":"webhooks:write","input":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The webhook's id, from List webhooks."}},"required":["id"],"additionalProperties":false}},{"key":"core.billing.get_balance","app":"core","title":"Get the Token Balance","description":"Show the active organization's token balance: tokens from the plan, purchased tokens, and tokens held for work in progress.","kind":"read","risk":{},"access":{"role":"member"},"scope":"wallet:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.billing.list_ledger","app":"core","title":"List Token History","description":"List the active organization's token history, newest first: purchases, plan grants, spending and refunds.","kind":"read","risk":{},"access":{"role":"member"},"scope":"wallet:read","input":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"How many entries to return."}},"additionalProperties":false}},{"key":"core.billing.get_plan","app":"core","title":"Get the Plan and Subscriptions","description":"Show the active organization's plan, its subscription status and billing period, and its recurring bundles.","kind":"read","risk":{},"access":{"role":"member"},"scope":"wallet:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.billing.list_options","app":"core","title":"List What Can Be Bought","description":"List the token packs, plans and bundles the active organization can buy, at the prices it would pay, and whether online checkout is available.","kind":"read","risk":{},"access":{"role":"member"},"scope":"wallet:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"core.billing.buy_tokens","app":"core","title":"Buy a Token Pack","description":"Start buying one of the token packs for the active organization. Nothing is charged here: it returns a secure checkout link for you to open and pay.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"packKey":{"type":"string","minLength":1,"maxLength":100,"description":"The pack's key, from List what can be bought."}},"required":["packKey"],"additionalProperties":false}},{"key":"core.billing.buy_custom_tokens","app":"core","title":"Buy a Custom Number of Tokens","description":"Start buying any number of tokens for the active organization, priced at its plan's top-up rate. Nothing is charged here: it returns a secure checkout link for you to open and pay.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"tokens":{"type":"integer","exclusiveMinimum":0,"maximum":100000000,"description":"How many tokens to buy."}},"required":["tokens"],"additionalProperties":false}},{"key":"core.billing.buy_bundle","app":"core","title":"Subscribe to a Bundle","description":"Start a monthly bundle subscription for the active organization, optionally for one of its websites. Nothing is charged here: it returns a secure checkout link for you to open and pay. Owners and admins only.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"bundleKey":{"type":"string","minLength":1,"maxLength":100,"description":"The bundle's key, from List what can be bought."},"siteId":{"type":"string","format":"uuid","description":"The website the bundle is for, when it covers one site."},"siteUrl":{"type":"string","format":"uri","maxLength":2000,"description":"That website's address."}},"required":["bundleKey"],"additionalProperties":false}},{"key":"core.billing.cancel_bundle","app":"core","title":"Cancel a Bundle Subscription","description":"Cancel one of the active organization's bundle subscriptions at the end of the period already paid for. It keeps working until then and is not charged again. Owners and admins only.","kind":"write","risk":{"money":true,"destructive":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"orgBundleId":{"type":"string","format":"uuid","description":"The subscription's id, from Get the plan and subscriptions."}},"required":["orgBundleId"],"additionalProperties":false}},{"key":"core.billing.start_subscription","app":"core","title":"Subscribe to a Plan","description":"Start a monthly plan subscription for the active organization, which grants tokens every month. Nothing is charged here: it returns a secure checkout link for you to open and pay. Owners and admins only.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"core:write","input":{"type":"object","properties":{"planKey":{"type":"string","minLength":1,"maxLength":100,"description":"The plan's key, from List what can be bought."}},"required":["planKey"],"additionalProperties":false}},{"key":"core.escalation.list","app":"core","title":"List Assistant Escalations","description":"List requests customers escalated from the assistant to a person, newest first: who asked, the summary, the reason and where each stands.","kind":"read","risk":{},"access":{"role":"staff","capability":"operations:*"},"scope":"operations:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["open","acknowledged","resolved"],"description":"Only escalations in this state."},"limit":{"type":"integer","minimum":1,"maximum":200,"default":50}},"additionalProperties":false}},{"key":"core.escalation.acknowledge","app":"core","title":"Acknowledge an Escalation","description":"Mark an assistant escalation as being worked on, so other staff know someone has it.","kind":"write","risk":{},"access":{"role":"staff","capability":"operations:*"},"scope":"operations:write","input":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The escalation's id, from List escalations."}},"required":["id"],"additionalProperties":false}},{"key":"core.escalation.resolve","app":"core","title":"Resolve an Escalation","description":"Close an assistant escalation, with an optional note on how it was resolved for other staff.","kind":"write","risk":{},"access":{"role":"staff","capability":"operations:*"},"scope":"operations:write","input":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The escalation's id, from List escalations."},"note":{"type":"string","maxLength":5000,"description":"How it was resolved, for other staff."}},"required":["id"],"additionalProperties":false}},{"key":"core.escalation.reply","app":"core","title":"Reply to an Escalation by Email","description":"Email the customer who escalated, in their provider's name, from its no-reply address with replies going to its support address. An open escalation becomes acknowledged.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"operations:*"},"scope":"operations:write","input":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The escalation's id, from List escalations."},"message":{"type":"string","minLength":1,"maxLength":10000,"description":"The reply, as plain text."}},"required":["id","message"],"additionalProperties":false}},{"key":"mailings.piece.list","app":"mailings","title":"List Mail Pieces","description":"List the postcards, cards, gifts and kits a mail campaign can send, with the id to use when choosing what goes out in a month.","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"mailings.template.list","app":"mailings","title":"List Campaign Templates","description":"List the ready-made yearly mail programs a campaign can start from, with what each one sends in each month.","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"mailings.campaign.list","app":"mailings","title":"List Mail Campaigns","description":"List this organization's mail campaigns, newest first, with each one's status (draft, active, paused or canceled).","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"mailings.campaign.get","app":"mailings","title":"Get a Mail Campaign","description":"Show one mail campaign: its status, what it sends in each month with the message printed on it, and which recipients are enrolled.","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"mailings.order.list","app":"mailings","title":"List Upcoming Mailings","description":"List what your active campaigns will mail over the next months: which piece goes out, in which month, to how many recipients.","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{"months":{"type":"integer","minimum":1,"maximum":12,"description":"How many months ahead to look; 6 if left out."}},"additionalProperties":false}},{"key":"mailings.campaign.start","app":"mailings","title":"Start a Mail Campaign","description":"Create a new mail campaign as a draft, copying a template's yearly schedule, or blank when no template is given. Nothing is mailed until the campaign is activated.","kind":"write","risk":{},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template to copy, from List campaign templates. Leave out for a blank campaign."}},"additionalProperties":false}},{"key":"mailings.campaign.set_month","app":"mailings","title":"Set a Month's Mailing","description":"Choose what a campaign mails in one month and the message printed on it, or send no piece to skip that month. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."},"month":{"type":"integer","minimum":1,"maximum":12,"description":"1 for January through 12 for December."},"pieceId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The piece to mail that month, from List mail pieces; null for no mailing that month."},"message":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"The message printed on the piece. Leave out to keep the current one."}},"required":["campaignId","month","pieceId"],"additionalProperties":false}},{"key":"mailings.campaign.activate","app":"mailings","title":"Activate a Mail Campaign","description":"Turn a campaign on. Each month's scheduled piece is then printed and mailed to every enrolled recipient, which is real physical mail that will be billed.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"mailings.campaign.pause","app":"mailings","title":"Pause a Mail Campaign","description":"Pause a campaign so nothing more is mailed until it is activated again. Its schedule and recipients are kept.","kind":"write","risk":{},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"mailings.campaign.cancel","app":"mailings","title":"Cancel a Mail Campaign","description":"Cancel a campaign for good: no more mail goes out from it. Use pause instead to stop it for a while.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"mailings.campaign.set_recipients","app":"mailings","title":"Set a Campaign's Recipients","description":"Replace the list of people a campaign mails to. Send the full list: anyone left out is taken off this campaign (they stay in your recipient list). Only your own recipients are accepted.","kind":"write","risk":{},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List mail campaigns."},"recipientIds":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":5000,"description":"Every recipient who should get this campaign's mail, from List recipients."}},"required":["campaignId","recipientIds"],"additionalProperties":false}},{"key":"mailings.recipient.list","app":"mailings","title":"List Recipients","description":"List the people in this organization's mailing list, by name, 100 at a time, with their mailing addresses. To act on one person, look them up by their exact name.","kind":"read","risk":{},"access":{"role":"member"},"scope":"mailings:read","input":{"type":"object","properties":{"search":{"type":"string","maxLength":100,"description":"Part of a name, street, city or ZIP code."},"name":{"type":"string","maxLength":200,"description":"Find people by their exact full name."},"page":{"type":"integer","minimum":1}},"additionalProperties":false}},{"key":"mailings.recipient.add","app":"mailings","title":"Add a Recipient","description":"Add a person and their mailing address to this organization's mailing list, so campaigns can mail to them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"address1":{"type":"string","minLength":1,"maxLength":200,"description":"Street address."},"address2":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Apartment, suite or unit."},"city":{"type":"string","minLength":1,"maxLength":100},"state":{"type":"string","minLength":1,"maxLength":50},"postalCode":{"type":"string","minLength":1,"maxLength":20,"description":"ZIP code."}},"required":["name","address1","city","state","postalCode"],"additionalProperties":false}},{"key":"mailings.recipient.remove","app":"mailings","title":"Remove a Recipient","description":"Remove a person from this organization's mailing list.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"mailings:write","input":{"type":"object","properties":{"recipientId":{"type":"string","format":"uuid","description":"The person's id, from List recipients."}},"required":["recipientId"],"additionalProperties":false}},{"key":"mailings.run.list","app":"mailings","title":"List This Month's Mailing Runs","description":"Staff only: every active campaign with a mailing due this month, across all partners, with the piece, the number of recipients and whether the order has been recorded sent.","kind":"read","risk":{},"access":{"role":"staff","capability":"mailings:fulfill"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"mailings.run.mark_sent","app":"mailings","title":"Mark a Mailing Run Sent","description":"Staff only: record that the order for one campaign's month has been placed with the printer, with an optional internal order reference. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"mailings:fulfill"},"scope":"operations:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List this month's mailing runs."},"year":{"type":"integer","minimum":2020,"maximum":2100},"month":{"type":"integer","minimum":1,"maximum":12},"pieceId":{"type":"string","format":"uuid","description":"The piece that was ordered, from List this month's mailing runs."},"vendorOrderRef":{"type":"string","maxLength":200,"description":"The order number, for staff records only."}},"required":["campaignId","year","month","pieceId"],"additionalProperties":false}},{"key":"compliance.website.list","app":"compliance","title":"List Websites","description":"List this organization's websites with how often each is scanned for accessibility, its latest accessibility score and whether the accessibility widget is installed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"compliance.website.get","app":"compliance","title":"Get a Website","description":"Show one website's accessibility setup: the scan schedule, the latest scan, the widget's look and status, and the snippet to paste into the site.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from List websites."}},"required":["siteId"],"additionalProperties":false}},{"key":"compliance.website.add","app":"compliance","title":"Add a Website","description":"Add a website to this organization so it can get the accessibility widget and be scanned. Adding the same address again returns the existing website. If the organization has the Accessibility bundle, monthly scans start on it right away.","kind":"write","risk":{},"access":{"role":"member"},"scope":"compliance:write","input":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2000,"description":"The website's address, like https://example.com."},"label":{"type":"string","maxLength":120,"description":"A short name to show instead of the address."},"origin":{"type":"string","enum":["lovable","skeleton","third-party","custom","unknown"],"description":"How the site was built: lovable, skeleton (built by us), third-party (WordPress, Wix and the like), custom, or unknown."},"platform":{"type":"string","maxLength":60,"description":"For a third-party site, which platform, like wordpress or wix."}},"required":["url"],"additionalProperties":false}},{"key":"compliance.website.set_cadence","app":"compliance","title":"Set Accessibility Scan Schedule","description":"Choose how often a website is scanned for accessibility problems: weekly, monthly or off. Each scheduled scan costs tokens unless the Accessibility bundle covers it.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"compliance:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from List websites."},"cadence":{"type":"string","enum":["off","weekly","monthly"]}},"required":["siteId","cadence"],"additionalProperties":false}},{"key":"compliance.widget.update","app":"compliance","title":"Change the Accessibility Widget","description":"Change how the accessibility widget looks on a website: which corner it sits in and its colors. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"compliance:write","input":{"type":"object","properties":{"siteId":{"type":"string","format":"uuid","description":"The website's id, from List websites."},"position":{"type":"string","enum":["bottom-right","bottom-left"]},"primary":{"type":"string","pattern":"^#[0-9a-f]{3,8}$","description":"The button's main color, as hex."},"accent":{"type":"string","pattern":"^#[0-9a-f]{3,8}$","description":"The highlight color, as hex."}},"required":["siteId"],"additionalProperties":false}},{"key":"compliance.package.list","app":"compliance","title":"List Legal Packages","description":"List the legal document packages (privacy policy, terms, accessibility statement and more), what each costs in tokens, which documents each includes and which ones this organization already owns.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"compliance.template.get","app":"compliance","title":"Get a Legal Template's Questions","description":"Show the questions a legal document template asks (business name, contact email and so on), which ones are required, and whether this organization can generate it yet.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List legal packages."}},"required":["templateId"],"additionalProperties":false}},{"key":"compliance.document.list","app":"compliance","title":"List Legal Documents","description":"List the legal documents this organization has generated, latest version of each, newest first.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"compliance.document.get","app":"compliance","title":"Get a Legal Document","description":"Show one generated legal document's full text (Markdown, ready to paste into a website) and the answers it was made from.","kind":"read","risk":{},"access":{"role":"member"},"scope":"compliance:read","input":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid","description":"The document's id, from List legal documents."}},"required":["documentId"],"additionalProperties":false}},{"key":"compliance.package.buy","app":"compliance","title":"Buy a Legal Package","description":"Buy a legal document package for this organization, paid in tokens from the wallet. Buying one the organization already owns costs nothing and changes nothing.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"compliance:write","input":{"type":"object","properties":{"packageId":{"type":"string","format":"uuid","description":"The package's id, from List legal packages."}},"required":["packageId"],"additionalProperties":false}},{"key":"compliance.document.generate","app":"compliance","title":"Generate a Legal Document","description":"Fill in a legal document template with your answers and save the result as a new version. The wording is fixed by the template; only your answers change. The template must be in a package the organization owns.","kind":"write","risk":{},"access":{"role":"member"},"scope":"compliance:write","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List legal packages."},"siteId":{"type":"string","format":"uuid","description":"The website this document is for, from List websites. Leave out for one that covers the whole organization."},"answers":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":5000},{"type":"boolean"}]},"description":"Answers keyed by each question's key, from Get a legal template's questions. Yes/no questions take true or false."}},"required":["templateId","answers"],"additionalProperties":false}},{"key":"prospects.source.list","app":"prospects","title":"List Prospect Sources","description":"List the contact databases this organization can search (real estate agents, healthcare providers), the regions it may use, and each one's search filters with their choices.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"prospects.people.search","app":"prospects","title":"Search Prospects","description":"Search a contact database without spending anything. Results are anonymous: place, specialty or sales band, and whether an email or phone is on file, never names or contact details. Shows how many people match.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{"source":{"type":"string","enum":["mls","npi"],"description":"Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use."},"filters":{"type":"object","additionalProperties":{},"description":"Search filters by name, from List sources (each source lists its own filters, like state, city or specialty)."},"page":{"type":"integer","minimum":1,"maximum":1000}},"required":["source"],"additionalProperties":false}},{"key":"prospects.download.preview","app":"prospects","title":"Price a Prospect Download","description":"Before downloading, see what a download would cost: how many of the matching people you already own (free), how many would be charged, the price per person in tokens and your balance. Nothing is charged.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{"source":{"type":"string","enum":["mls","npi"],"description":"Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use."},"filters":{"type":"object","additionalProperties":{},"description":"Search filters by name, from List sources (each source lists its own filters, like state, city or specialty)."},"count":{"type":"integer","minimum":1,"maximum":5000,"description":"How many people you'd like to download."}},"required":["source","count"],"additionalProperties":false}},{"key":"prospects.download.start","app":"prospects","title":"Download Prospects","description":"Buy people matching a search and add them to this organization's contacts, tagged so you can find them. People you already own and people who asked not to be contacted are skipped for free; each new person costs tokens. Check the price first with Price a prospect download.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"prospects:write","input":{"type":"object","properties":{"source":{"type":"string","enum":["mls","npi"],"description":"Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use."},"filters":{"type":"object","additionalProperties":{},"description":"Search filters by name, from List sources (each source lists its own filters, like state, city or specialty)."},"count":{"type":"integer","minimum":1,"maximum":5000,"description":"How many people to download, at most."},"tag":{"type":"string","maxLength":60,"description":"An extra tag to put on everyone downloaded."}},"required":["source","count"],"additionalProperties":false}},{"key":"prospects.download.list","app":"prospects","title":"List Prospect Downloads","description":"List this organization's past downloads, newest first, with how many people each saved and what it cost.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":200}},"additionalProperties":false}},{"key":"prospects.download.get","app":"prospects","title":"Get a Prospect Download","description":"Show one download: its search, how many people were asked for, saved and skipped, its status and what it cost.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{"downloadId":{"type":"string","format":"uuid","description":"The download's id, from List prospect downloads."}},"required":["downloadId"],"additionalProperties":false}},{"key":"prospects.purchase.list","app":"prospects","title":"List Purchased Prospects","description":"List the people this organization has bought, newest first, with their contact details and whether a missing email or phone was looked up. To act on one person, look them up by their exact email address.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{"source":{"type":"string","enum":["mls","npi"],"description":"Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use."},"downloadId":{"type":"string","format":"uuid","description":"Only the people from one download."},"email":{"type":"string","format":"email","description":"Find one person by their exact email address."},"limit":{"type":"integer","minimum":1,"maximum":500},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},{"key":"prospects.contact.enrich_cost","app":"prospects","title":"Price of Finding Emails and Phones","description":"Show how many tokens one found email or one found phone number costs. Lookups that find nothing are free.","kind":"read","risk":{},"access":{"role":"member"},"scope":"prospects:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"prospects.contact.enrich","app":"prospects","title":"Find Missing Emails and Phones","description":"Look up missing email addresses, phone numbers or both for people in this organization's contacts. Each value found costs tokens; a lookup that finds nothing is free. A value is only filled in where the field is empty.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"prospects:write","input":{"type":"object","properties":{"contactIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200,"description":"The people to look up, by contact id, from List purchased prospects."},"fields":{"type":"array","items":{"type":"string","enum":["email","phone"]},"minItems":1,"maxItems":2,"description":"Which to look for; both when left out."}},"required":["contactIds"],"additionalProperties":false}},{"key":"prospects.partner_source.list","app":"prospects","title":"List Partner Prospect Sources","description":"Staff only: every partner, whether Prospects is turned on for it, and which contact databases its clients may search, limited to which regions.","kind":"read","risk":{},"access":{"role":"staff","capability":"prospects:operate"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"prospects.partner_source.save","app":"prospects","title":"Set a Partner's Prospect Source","description":"Staff only: turn a contact database on or off for one partner's clients, and limit it to regions (state codes like FL, TX for healthcare; region names for real estate). An empty list means everywhere. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"prospects:operate"},"scope":"operations:write","input":{"type":"object","properties":{"partnerId":{"type":"string","format":"uuid","description":"The partner's id, from List partner prospect sources."},"source":{"type":"string","enum":["mls","npi"],"description":"mls (real estate agents) or npi (healthcare providers)."},"enabled":{"type":"boolean"},"regions":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":200,"description":"Where its clients may search; everywhere when empty or left out."}},"required":["partnerId","source","enabled"],"additionalProperties":false}},{"key":"prospects.provider.list","app":"prospects","title":"List Lookup Providers","description":"Staff only: the services used, in order, to find missing emails and phones, and whether each one is on.","kind":"read","risk":{},"access":{"role":"staff","capability":"prospects:operate"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"prospects.provider.save","app":"prospects","title":"Set a Lookup Provider","description":"Staff only: turn a lookup service on or off and set its place in the order (lower goes first). Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"prospects:operate"},"scope":"operations:write","input":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z0-9-]{2,40}$","description":"The provider's key, from List lookup providers."},"position":{"type":"integer","minimum":0,"maximum":1000},"enabled":{"type":"boolean"}},"required":["key","position","enabled"],"additionalProperties":false}},{"key":"photos.project.list","app":"photos","title":"List photo projects","description":"List this organization's photo projects (one per listing), newest first, with whether each has been sent to the editors.","kind":"read","risk":{},"access":{"role":"member"},"scope":"photos:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"photos.project.get","app":"photos","title":"Get a photo project","description":"Show one photo project: its photos and, for each, the edits asked for with their status (waiting, delivered, accepted or sent back), token cost and any reason given.","kind":"read","risk":{},"access":{"role":"member"},"scope":"photos:read","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List photo projects."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.project.create","app":"photos","title":"Create a photo project","description":"Start a new photo project for a listing. Photos are added on the project page.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120,"description":"A name for the project, like the listing's street address."},"address":{"type":"string","maxLength":500,"description":"The property's address."}},"required":["name"],"additionalProperties":false}},{"key":"photos.project.update","app":"photos","title":"Update a photo project","description":"Change a project's name, address or notes for the editors. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List photo projects."},"name":{"type":"string","minLength":1,"maxLength":120},"address":{"type":"string","maxLength":500,"description":"Send an empty string to clear it."},"notes":{"type":"string","maxLength":4000,"description":"Instructions for the editors. Send an empty string to clear them."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.project.delete","app":"photos","title":"Delete a photo project","description":"Delete a photo project and hide its photos. Tokens held for edits that were not delivered are refunded.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List photo projects."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.project.submit","app":"photos","title":"Send a project to the editors","description":"Send a project's requested edits to the editing team. The tokens for every requested edit are set aside from the wallet now and spent as you accept each finished photo.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List photo projects."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.project.bulk_tag","app":"photos","title":"Ask for one edit on many photos","description":"Ask for the same edit on several photos in a project at once, before it is sent to the editors. Photos that already have that edit are skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List photo projects."},"photoIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":200,"description":"The photos' ids, from Get a photo project."},"edit":{"type":"string","enum":["declutter","virtual_staging","sky_replace","twilight"],"description":"declutter, virtual_staging, sky_replace or twilight."}},"required":["projectId","photoIds","edit"],"additionalProperties":false}},{"key":"photos.upload.delete","app":"photos","title":"Remove a photo","description":"Remove one photo from its project.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"photoId":{"type":"string","format":"uuid","description":"The photo's id, from Get a photo project."}},"required":["photoId"],"additionalProperties":false}},{"key":"photos.request.add","app":"photos","title":"Ask for an edit on a photo","description":"Ask for an edit on one photo (declutter, virtual staging, sky replacement or twilight), before its project is sent to the editors. The price is set now.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"photoId":{"type":"string","format":"uuid","description":"The photo's id, from Get a photo project."},"edit":{"type":"string","enum":["declutter","virtual_staging","sky_replace","twilight"],"description":"declutter, virtual_staging, sky_replace or twilight."}},"required":["photoId","edit"],"additionalProperties":false}},{"key":"photos.request.remove","app":"photos","title":"Remove an edit from a photo","description":"Take back an edit you asked for on a photo, before its project is sent to the editors.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a photo project."}},"required":["requestId"],"additionalProperties":false}},{"key":"photos.request.accept","app":"photos","title":"Accept a finished edit","description":"Accept a photo the editors delivered. The tokens set aside for that edit are spent. This can't be undone.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a photo project."}},"required":["requestId"],"additionalProperties":false}},{"key":"photos.request.reject","app":"photos","title":"Send a finished edit back","description":"Send a delivered photo back to the editors with what to fix. Nothing is charged; they deliver it again.","kind":"write","risk":{},"access":{"role":"member"},"scope":"photos:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a photo project."},"reason":{"type":"string","minLength":1,"maxLength":1000,"description":"What the editors should change."}},"required":["requestId","reason"],"additionalProperties":false}},{"key":"photos.request.history","app":"photos","title":"Get an edit's history","description":"Show what happened to one edit request, newest first: each delivery, acceptance, send-back with its reason, and reopening.","kind":"read","risk":{},"access":{"role":"member"},"scope":"photos:read","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a photo project."}},"required":["requestId"],"additionalProperties":false}},{"key":"photos.queue.list","app":"photos","title":"List the editing queue","description":"Staff only: every submitted project, from every customer, that still has edits waiting or sent back, oldest first, with how many are open.","kind":"read","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"photos.queue.get_project","app":"photos","title":"Get a project to edit","description":"Staff only: one submitted project with each photo's edits, who has claimed them, and links (valid for an hour) to download the originals. Logged to the staff audit.","kind":"read","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:read","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List the editing queue."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.queue.claim","app":"photos","title":"Claim an edit","description":"Staff only: take an edit request so no other editor works on it. Fails if someone already has it. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a project to edit."}},"required":["requestId"],"additionalProperties":false}},{"key":"photos.queue.release","app":"photos","title":"Release a claimed edit","description":"Staff only: give back an edit request you claimed so another editor can take it. Photos admins can release anyone's. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a project to edit."}},"required":["requestId"],"additionalProperties":false}},{"key":"photos.queue.deliver","app":"photos","title":"Deliver a finished edit","description":"Staff only: deliver the finished photo for an edit request from a public web address (JPEG, PNG, WebP or HEIC, up to 25 MB). The customer is emailed that it is ready. Logged to the staff audit.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:write","input":{"type":"object","properties":{"requestId":{"type":"string","format":"uuid","description":"The edit request's id, from Get a project to edit."},"fileUrl":{"type":"string","format":"uri","maxLength":2000,"description":"A public https address of the finished photo."}},"required":["requestId","fileUrl"],"additionalProperties":false}},{"key":"photos.project.reopen","app":"photos","title":"Reopen a submitted project","description":"Photos admins only: take a submitted project back from the editors so the customer can change it and send it again. Tokens set aside for edits not yet accepted go back to the customer's wallet. Logged to the staff audit.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:write","input":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"The project's id, from List the editing queue."}},"required":["projectId"],"additionalProperties":false}},{"key":"photos.default_pricing.get","app":"photos","title":"Get standard photo prices","description":"Photos admins only: the standard token price of each edit type and the per-project base fee, used wherever a partner hasn't set its own.","kind":"read","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"photos.default_pricing.update","app":"photos","title":"Change standard photo prices","description":"Photos admins only: change the standard per-project base fee or the token price of edit types, for every partner without its own price. Only the prices you send change; edits already asked for keep their price.","kind":"write","risk":{},"access":{"role":"staff","capability":"photos:edit"},"scope":"operations:write","input":{"type":"object","properties":{"baseTokenCost":{"type":"integer","minimum":0,"maximum":100000,"description":"The per-project base fee, in tokens."},"edits":{"type":"array","items":{"type":"object","properties":{"edit":{"type":"string","enum":["declutter","virtual_staging","sky_replace","twilight"],"description":"declutter, virtual_staging, sky_replace or twilight."},"tokens":{"type":"integer","minimum":0,"maximum":100000}},"required":["edit","tokens"],"additionalProperties":false},"maxItems":4,"description":"New prices per edit type, in tokens."}},"additionalProperties":false}},{"key":"photos.partner_pricing.get","app":"photos","title":"Get your partner's photo prices","description":"Partner admins: your own token price for each edit type and the per-project base fee, beside the standard price that applies where you haven't set one.","kind":"read","risk":{},"access":{"role":"partner_admin"},"scope":"photos:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"photos.partner_pricing.update","app":"photos","title":"Set your partner's photo prices","description":"Partner admins: set what your clients pay, in tokens, for each edit type or the per-project base fee. Send null for a price to go back to the standard one. Only the prices you send change; edits already asked for keep their price.","kind":"write","risk":{},"access":{"role":"partner_admin"},"scope":"photos:write","input":{"type":"object","properties":{"baseTokenCost":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}],"description":"Your per-project base fee, or null for the standard one."},"edits":{"type":"array","items":{"type":"object","properties":{"edit":{"type":"string","enum":["declutter","virtual_staging","sky_replace","twilight"],"description":"declutter, virtual_staging, sky_replace or twilight."},"tokens":{"anyOf":[{"type":"integer","minimum":0,"maximum":100000},{"type":"null"}]}},"required":["edit","tokens"],"additionalProperties":false},"maxItems":4,"description":"Your price per edit type, or null for the standard one."}},"additionalProperties":false}},{"key":"newsletters.list.list","app":"newsletters","title":"List Subscriber Lists","description":"List your newsletter's subscriber lists, newest first, with how many people are on each.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"newsletters.list.get","app":"newsletters","title":"Get a Subscriber List","description":"Show one subscriber list: its name, description and member count.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List subscriber lists."}},"required":["listId"],"additionalProperties":false}},{"key":"newsletters.list.create","app":"newsletters","title":"Create a Subscriber List","description":"Create a new subscriber list that campaigns and drips can send to.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["name"],"additionalProperties":false}},{"key":"newsletters.list.update","app":"newsletters","title":"Rename a Subscriber List","description":"Change a subscriber list's name or description. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List subscriber lists."},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["listId"],"additionalProperties":false}},{"key":"newsletters.list.add_subscribers","app":"newsletters","title":"Add Subscribers to a List","description":"Add existing subscribers to a list. People removed earlier are added back; ids that aren't yours are skipped.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List subscriber lists."},"subscriberIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Subscriber ids, from List subscribers."}},"required":["listId","subscriberIds"],"additionalProperties":false}},{"key":"newsletters.list.remove_subscribers","app":"newsletters","title":"Remove Subscribers from a List","description":"Take subscribers off a list so they no longer get its campaigns. They stay in your subscribers and can be added back.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List subscriber lists."},"subscriberIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"Subscriber ids, from List subscribers."}},"required":["listId","subscriberIds"],"additionalProperties":false}},{"key":"newsletters.subscriber.list","app":"newsletters","title":"List Subscribers","description":"List or search your newsletter subscribers, newest first, with their status (active, unsubscribed, bounced and so on). To act on one person, look them up by their exact email address.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["active","unsubscribed","bounced","complained","pending_confirmation"]},"search":{"type":"string","maxLength":100,"description":"Part of a name or email address."},"email":{"type":"string","format":"email","description":"Find one person by their exact email address."},"limit":{"type":"integer","minimum":1,"maximum":200},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},{"key":"newsletters.subscriber.get","app":"newsletters","title":"Get a Subscriber","description":"Show one subscriber: status, tags, extra details, where they came from and when they joined.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"subscriberId":{"type":"string","format":"uuid","description":"The subscriber's id, from List subscribers."}},"required":["subscriberId"],"additionalProperties":false}},{"key":"newsletters.subscriber.create","app":"newsletters","title":"Add a Subscriber","description":"Add one person to your subscribers. Only add people who agreed to get your emails. Addresses that bounced, complained or unsubscribed can't be added. Nothing is sent to them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"email":{"type":"string","format":"email"},"firstName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50,"description":"Labels for sorting subscribers; replaces the existing tags."},"customFields":{"type":"object","additionalProperties":{},"description":"Extra details to use in emails, such as {\"city\": \"Austin\"}; replaces the existing ones."}},"required":["email"],"additionalProperties":false}},{"key":"newsletters.subscriber.import","app":"newsletters","title":"Import Subscribers from a Spreadsheet","description":"Add up to 5,000 people from CSV text with an email column (first and last name optional). Duplicates and blocked addresses are skipped. With confirmation on, or over 500 new people, each new person gets one email asking them to confirm and stays inactive until they do.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":2000000,"description":"The spreadsheet as CSV text, with a header row."},"confirmFirst":{"type":"boolean","description":"Email each new person to confirm before they start getting newsletters."},"senderName":{"type":"string","maxLength":100,"description":"Who the confirmation email is from."},"replyTo":{"type":"string","format":"email","description":"Where replies to the confirmation email go."}},"required":["csv"],"additionalProperties":false}},{"key":"newsletters.subscriber.update","app":"newsletters","title":"Update a Subscriber","description":"Change a subscriber's name, tags, extra details or status. Only the fields you send change. Their email address can't be changed. Set the status to unsubscribed to stop all newsletters to them.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"subscriberId":{"type":"string","format":"uuid","description":"The subscriber's id, from List subscribers."},"firstName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"status":{"type":"string","enum":["active","unsubscribed","bounced","complained","pending_confirmation"]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50,"description":"Labels for sorting subscribers; replaces the existing tags."},"customFields":{"type":"object","additionalProperties":{},"description":"Extra details to use in emails, such as {\"city\": \"Austin\"}; replaces the existing ones."}},"required":["subscriberId"],"additionalProperties":false}},{"key":"newsletters.subscriber.delete","app":"newsletters","title":"Delete a Subscriber","description":"Remove a person from your subscribers so they get nothing more. Support can restore them if needed.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"subscriberId":{"type":"string","format":"uuid","description":"The subscriber's id, from List subscribers."}},"required":["subscriberId"],"additionalProperties":false}},{"key":"newsletters.campaign.list","app":"newsletters","title":"List Campaigns","description":"List your newsletter campaigns, newest first (up to 100), with status (draft, scheduled, waiting for approval, sent and so on), recipients and open and click counts.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["draft","scheduled","pending_agent_approval","pending_platform_approval","sending","sent","failed","cancelled"],"description":"Only campaigns in this status."}},"additionalProperties":false}},{"key":"newsletters.campaign.get","app":"newsletters","title":"Get a Campaign","description":"Show one campaign: subject, list, sender, content, schedule, status and results.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"newsletters.campaign.create","app":"newsletters","title":"Create a Draft Campaign","description":"Start a draft newsletter for a subscriber list, from a template or your own content. Nothing is sent until you send it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The subscriber list to send to, from List subscriber lists."},"subject":{"type":"string","minLength":1,"maxLength":300,"description":"The subject line. Optional when starting from a template that has one."},"templateId":{"type":"string","format":"uuid","description":"A template to copy the content (and subject) from, from List templates."},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"A stable id for the block, unique within the email."},"kind":{"type":"string","enum":["text","image","cta_button","divider","market_report","article_preview","video_card"],"description":"text = a paragraph (config.body), image (config.url, config.alt), cta_button (config.label, config.href), divider, or a live block filled in at send time."},"config":{"type":"object","additionalProperties":{},"description":"The block's settings, which depend on its kind."},"fallback":{"type":"string","enum":["skip","placeholder","fail"],"description":"For live blocks: what to do if their content can't be loaded."}},"required":["id","kind","config"],"additionalProperties":false},"minItems":1,"maxItems":100,"description":"The email's content, when not starting from a template."},"fromName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"The sender name people see."},"replyTo":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"description":"Where replies go."}},"required":["listId"],"additionalProperties":false}},{"key":"newsletters.campaign.schedule","app":"newsletters","title":"Schedule a Campaign","description":"Create a newsletter that goes out automatically at a future time to everyone active on the list. At that time it spends tokens (one per email by default) and may first wait for our review.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:send","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The subscriber list to send to, from List subscriber lists."},"subject":{"type":"string","minLength":1,"maxLength":300,"description":"The subject line. Optional when starting from a template that has one."},"templateId":{"type":"string","format":"uuid","description":"A template to copy the content (and subject) from, from List templates."},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"A stable id for the block, unique within the email."},"kind":{"type":"string","enum":["text","image","cta_button","divider","market_report","article_preview","video_card"],"description":"text = a paragraph (config.body), image (config.url, config.alt), cta_button (config.label, config.href), divider, or a live block filled in at send time."},"config":{"type":"object","additionalProperties":{},"description":"The block's settings, which depend on its kind."},"fallback":{"type":"string","enum":["skip","placeholder","fail"],"description":"For live blocks: what to do if their content can't be loaded."}},"required":["id","kind","config"],"additionalProperties":false},"minItems":1,"maxItems":100,"description":"The email's content, when not starting from a template."},"fromName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"The sender name people see."},"replyTo":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"description":"Where replies go."},"sendAt":{"type":"string","format":"date-time","description":"When to send, as an ISO date and time in the future."}},"required":["listId","sendAt"],"additionalProperties":false}},{"key":"newsletters.campaign.send","app":"newsletters","title":"Send a Campaign Now","description":"Send a draft campaign to everyone active on its list. It spends tokens (one per email by default). Your first two sends, very large sends, or sends after many bounces wait for our review first, and nothing is charged until then.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:send","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List campaigns."}},"required":["campaignId"],"additionalProperties":false}},{"key":"newsletters.template.list","app":"newsletters","title":"List Templates","description":"List your newsletter templates, most recently edited first, with subject line, content, schedule and whether each is active.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"newsletters.template.get","app":"newsletters","title":"Get a Template","description":"Show one newsletter template with its subject line, content blocks, schedule and default list.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."}},"required":["templateId"],"additionalProperties":false}},{"key":"newsletters.template.create","app":"newsletters","title":"Create a Template","description":"Create a reusable newsletter template. Without content it starts from a short sample you can edit.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"subjectLine":{"type":"string","maxLength":300},"defaultListId":{"anyOf":[{"type":"string","format":"uuid","description":"The list it usually goes to, from List subscriber lists."},{"type":"null"}],"description":"The list it usually goes to, from List subscriber lists."},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"A stable id for the block, unique within the email."},"kind":{"type":"string","enum":["text","image","cta_button","divider","market_report","article_preview","video_card"],"description":"text = a paragraph (config.body), image (config.url, config.alt), cta_button (config.label, config.href), divider, or a live block filled in at send time."},"config":{"type":"object","additionalProperties":{},"description":"The block's settings, which depend on its kind."},"fallback":{"type":"string","enum":["skip","placeholder","fail"],"description":"For live blocks: what to do if their content can't be loaded."}},"required":["id","kind","config"],"additionalProperties":false},"minItems":1,"maxItems":100,"description":"The email's content, in order."}},"required":["name"],"additionalProperties":false}},{"key":"newsletters.template.update","app":"newsletters","title":"Edit a Template","description":"Change a template's name, subject line, content, default list or repeating schedule, or turn it back on. Only the fields you send change, and every edit is kept in its history.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."},"name":{"type":"string","minLength":1,"maxLength":200},"subjectLine":{"type":"string","maxLength":300},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"A stable id for the block, unique within the email."},"kind":{"type":"string","enum":["text","image","cta_button","divider","market_report","article_preview","video_card"],"description":"text = a paragraph (config.body), image (config.url, config.alt), cta_button (config.label, config.href), divider, or a live block filled in at send time."},"config":{"type":"object","additionalProperties":{},"description":"The block's settings, which depend on its kind."},"fallback":{"type":"string","enum":["skip","placeholder","fail"],"description":"For live blocks: what to do if their content can't be loaded."}},"required":["id","kind","config"],"additionalProperties":false},"minItems":1,"maxItems":100,"description":"The email's content, in order."},"defaultListId":{"anyOf":[{"type":"string","format":"uuid","description":"The list it usually goes to."},{"type":"null"}],"description":"The list it usually goes to."},"schedule":{"anyOf":[{"type":"object","properties":{"cadence":{"type":"string","enum":["daily","weekly","monthly"]},"hour":{"type":"integer","minimum":0,"maximum":23,"description":"Hour of the day, 0-23, in the time zone."},"dayOfWeek":{"type":"integer","minimum":0,"maximum":6,"description":"For weekly: 0 = Sunday … 6 = Saturday."},"dayOfMonth":{"type":"integer","minimum":1,"maximum":31,"description":"For monthly: day of the month."},"timezone":{"type":"string","maxLength":64,"description":"Time zone, such as America/Chicago."}},"required":["cadence","hour"],"additionalProperties":false,"description":"When to prepare a new draft from this template for you to approve; null turns it off. Drafts are never sent without you."},{"type":"null"}],"description":"When to prepare a new draft from this template for you to approve; null turns it off. Drafts are never sent without you."},"active":{"type":"boolean","const":true,"description":"Turn a turned-off template back on."}},"required":["templateId"],"additionalProperties":false}},{"key":"newsletters.template.deactivate","app":"newsletters","title":"Turn Off a Template","description":"Turn off a template so it can't start new campaigns or drip steps. Campaigns already made from it keep their own copy.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."}},"required":["templateId"],"additionalProperties":false}},{"key":"newsletters.template.versions","app":"newsletters","title":"Show a Template's History","description":"List every saved version of a template, newest first, with who saved it and which fields changed.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."}},"required":["templateId"],"additionalProperties":false}},{"key":"newsletters.template.restore","app":"newsletters","title":"Restore an Earlier Template Version","description":"Put a template back the way it was in an earlier version. This is saved as a new version, so it can be undone.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."},"versionId":{"type":"string","format":"uuid","description":"The version's id, from Show a template's history."}},"required":["templateId","versionId"],"additionalProperties":false}},{"key":"newsletters.template.preview","app":"newsletters","title":"Preview an Email","description":"Build the finished email (HTML and plain text) from a template or from content blocks, with sample names and addresses. Nothing is sent or saved.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"The template's id, from List templates."},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":100,"description":"A stable id for the block, unique within the email."},"kind":{"type":"string","enum":["text","image","cta_button","divider","market_report","article_preview","video_card"],"description":"text = a paragraph (config.body), image (config.url, config.alt), cta_button (config.label, config.href), divider, or a live block filled in at send time."},"config":{"type":"object","additionalProperties":{},"description":"The block's settings, which depend on its kind."},"fallback":{"type":"string","enum":["skip","placeholder","fail"],"description":"For live blocks: what to do if their content can't be loaded."}},"required":["id","kind","config"],"additionalProperties":false},"minItems":1,"maxItems":100,"description":"The email's content, in order."}},"additionalProperties":false}},{"key":"newsletters.drip.list","app":"newsletters","title":"List Drips","description":"List your drips (automated email series), newest first, with their list, how people start them and whether each is active or paused.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"newsletters.drip.get","app":"newsletters","title":"Get a Drip","description":"Show one drip (automated email series): its name, list, how people start it and its status.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.create","app":"newsletters","title":"Create a Drip","description":"Create a drip, an automated series of emails people receive one after another once enrolled. Add its emails with Add a drip step.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"listId":{"anyOf":[{"type":"string","format":"uuid","description":"The subscriber list it belongs to, from List subscriber lists."},{"type":"null"}],"description":"The subscriber list it belongs to, from List subscriber lists."},"triggerKind":{"type":"string","enum":["manual","list_join","external_event"],"description":"How people start it: manual = you enroll them (the default), list_join = when they join the list, external_event = another tool starts it."},"triggerConfig":{"type":"object","additionalProperties":{},"description":"Settings for how people start the drip."}},"required":["name"],"additionalProperties":false}},{"key":"newsletters.drip.update","app":"newsletters","title":"Update a Drip","description":"Rename a drip or change its list or start settings. Only the fields you send change. To pause or resume it, use Pause a drip or Resume a drip.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."},"name":{"type":"string","minLength":1,"maxLength":200},"listId":{"anyOf":[{"type":"string","format":"uuid","description":"The subscriber list it belongs to."},{"type":"null"}],"description":"The subscriber list it belongs to."},"triggerConfig":{"type":"object","additionalProperties":{},"description":"Settings for how people start the drip."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.pause","app":"newsletters","title":"Pause a Drip","description":"Stop a drip from sending. Everyone enrolled stays where they are and picks up again when you resume it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.resume","app":"newsletters","title":"Resume a Drip","description":"Start a paused drip sending again. Enrolled people whose next email is due get it right away.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.delete","app":"newsletters","title":"Delete a Drip","description":"Delete a drip. It stops sending, and nobody enrolled gets its remaining emails.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.steps","app":"newsletters","title":"List a Drip's Steps","description":"List the emails in a drip, in order, with the template each one uses and how many hours it waits after the previous one.","kind":"read","risk":{},"access":{"role":"member"},"scope":"newsletters:read","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."}},"required":["dripId"],"additionalProperties":false}},{"key":"newsletters.drip.add_step","app":"newsletters","title":"Add a Drip Step","description":"Add an email to the end of a drip, using one of your templates, sent a number of hours after the previous one. People already enrolled will get it when they reach it.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."},"templateId":{"type":"string","format":"uuid","description":"The template for this email, from List templates."},"delayHours":{"type":"integer","minimum":0,"maximum":8760,"description":"Hours after the previous email (or after enrolling, for the first). Defaults to 0."}},"required":["dripId","templateId"],"additionalProperties":false}},{"key":"newsletters.drip.enroll","app":"newsletters","title":"Enroll Someone in a Drip","description":"Start one subscriber on a drip. They get its emails in order, starting with the first one when its wait time is up.","kind":"write","risk":{"emailsOthers":true},"access":{"role":"member"},"scope":"newsletters:write","input":{"type":"object","properties":{"dripId":{"type":"string","format":"uuid","description":"The drip's id, from List drips."},"subscriberId":{"type":"string","format":"uuid","description":"The subscriber's id, from List subscribers."}},"required":["dripId","subscriberId"],"additionalProperties":false}},{"key":"newsletters.approval.list","app":"newsletters","title":"List Newsletters Waiting for Approval","description":"Staff only: customer newsletters held for review before they go out, oldest first, with the customer and the reason they were held.","kind":"read","risk":{},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"newsletters.approval.approve","app":"newsletters","title":"Approve and Send a Held Newsletter","description":"Staff only: approve a customer's held newsletter and send it now to everyone active on its list. The customer's tokens pay for it. Logged to the staff audit.","kind":"write","risk":{"money":true,"emailsOthers":true},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List newsletters waiting for approval."}},"required":["campaignId"],"additionalProperties":false}},{"key":"newsletters.approval.reject","app":"newsletters","title":"Reject a Held Newsletter","description":"Staff only: cancel a customer's held newsletter instead of sending it. The customer sees the reason. Logged to the staff audit.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:write","input":{"type":"object","properties":{"campaignId":{"type":"string","format":"uuid","description":"The campaign's id, from List newsletters waiting for approval."},"reason":{"type":"string","maxLength":1000,"description":"Why, in words the customer will read."}},"required":["campaignId"],"additionalProperties":false}},{"key":"newsletters.limits.list","app":"newsletters","title":"List Customer Newsletter Limits","description":"Staff only: every customer's subscriber and monthly email limits, this month's usage and whether sending is suspended. Logged to the staff audit.","kind":"read","risk":{},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"newsletters.limits.update","app":"newsletters","title":"Change a Customer's Newsletter Limits","description":"Staff only: raise or lower a customer's subscriber limit or monthly email limit, and optionally lift a sending suspension. Only the fields you send change. Logged to the staff audit.","kind":"write","risk":{},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:write","input":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","description":"The customer organization's id, from List customer newsletter limits."},"subscriberCap":{"type":"integer","minimum":0,"maximum":1000000,"description":"Most active subscribers the customer may have."},"monthlyEmailCap":{"type":"integer","minimum":0,"maximum":1000000,"description":"Most emails the customer may send in 30 days."},"unsuspend":{"type":"boolean","const":true,"description":"Lift a sending suspension."}},"required":["orgId"],"additionalProperties":false}},{"key":"newsletters.abuse.check","app":"newsletters","title":"Run the Newsletter Abuse Check","description":"Staff only: check every customer's bounce and complaint rates now and suspend sending for any over the limits (this also runs every 15 minutes). Logged to the staff audit.","kind":"write","risk":{"destructive":true},"access":{"role":"staff","capability":"newsletters:approve"},"scope":"operations:write","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"recruiting.agent.search","app":"recruiting","title":"Search Agents","description":"Search real estate agents by name, place, brokerage and sales history. Free. Shows names, brokerages and production, and whether you've unlocked each one; contact details need an unlock.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{"q":{"type":"string","maxLength":200,"description":"Part of an agent's name."},"state":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter US state code, such as TX."},"city":{"type":"string","maxLength":100},"zip":{"type":"string","maxLength":10},"centerLat":{"type":"number","minimum":-90,"maximum":90,"description":"With centerLng and radiusMiles: search around a point."},"centerLng":{"type":"number","minimum":-180,"maximum":180},"radiusMiles":{"type":"number","exclusiveMinimum":0,"maximum":500},"officeInclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Only agents at these brokerages."},"officeExclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Leave out agents at these brokerages."},"totalUnitsMin":{"type":"number","minimum":0,"description":"Fewest total homes sold (all time)."},"totalUnitsMax":{"type":"number","minimum":0},"totalVolumeMin":{"type":"number","minimum":0,"description":"Lowest total sales volume in dollars (all time)."},"totalVolumeMax":{"type":"number","minimum":0},"listingPctMin":{"type":"number","minimum":0,"maximum":100,"description":"Lowest share of sales on the listing side, in percent."},"listingPctMax":{"type":"number","minimum":0,"maximum":100},"limit":{"type":"integer","minimum":1,"maximum":200},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},{"key":"recruiting.agent.unlock","app":"recruiting","title":"Unlock an Agent's Contact Details","description":"Reveal an agent's email, phones and address for your whole organization. Costs 10 tokens once; free if already unlocked or bought in Prospects.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"recruiting:unlock","input":{"type":"object","properties":{"mlsId":{"type":"string","minLength":1,"maxLength":64,"description":"The agent's MLS id, from Search agents."}},"required":["mlsId"],"additionalProperties":false}},{"key":"recruiting.agent.contact","app":"recruiting","title":"Show an Unlocked Agent's Contact Details","description":"Show the email, phones and address of an agent your organization already unlocked. Free.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{"mlsId":{"type":"string","minLength":1,"maxLength":64,"description":"The agent's MLS id, from Search agents."}},"required":["mlsId"],"additionalProperties":false}},{"key":"recruiting.agent.unlocked","app":"recruiting","title":"List Unlocked Agents","description":"List the agents your organization unlocked, with their contact details, 100 at a time; or just one list's agents (only the list's creator or an owner may). This is what the spreadsheet export contains.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:export","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"Only this list's agents, from List agent lists."},"page":{"type":"integer","minimum":1}},"additionalProperties":false}},{"key":"recruiting.list.list","app":"recruiting","title":"List Agent Lists","description":"List your organization's agent lists, most recently changed first, with how many agents are on each.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"recruiting.list.get","app":"recruiting","title":"Get an Agent List","description":"Show one agent list and its most recent 200 agents, with your notes and tags for each.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List agent lists."}},"required":["listId"],"additionalProperties":false}},{"key":"recruiting.list.create","app":"recruiting","title":"Create an Agent List","description":"Create a named list to collect unlocked agents in, such as top producers to call this month.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["name"],"additionalProperties":false}},{"key":"recruiting.list.update","app":"recruiting","title":"Rename an Agent List","description":"Change an agent list's name or description. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List agent lists."},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]}},"required":["listId"],"additionalProperties":false}},{"key":"recruiting.list.delete","app":"recruiting","title":"Delete an Agent List","description":"Delete an agent list. The agents on it stay unlocked; support can restore the list.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List agent lists."}},"required":["listId"],"additionalProperties":false}},{"key":"recruiting.list.add_agents","app":"recruiting","title":"Add Agents to a List","description":"Add unlocked agents to a list, with optional notes and tags. Free. Every agent must already be unlocked; if any aren't, nothing is added and you're told which.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List agent lists."},"mlsIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":1,"maxItems":1000,"description":"Agents' MLS ids."},"notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50}},"required":["listId","mlsIds"],"additionalProperties":false}},{"key":"recruiting.list.remove_agents","app":"recruiting","title":"Remove Agents from a List","description":"Take agents off a list. They stay unlocked and on your other lists.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"listId":{"type":"string","format":"uuid","description":"The list's id, from List agent lists."},"mlsIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":64},"minItems":1,"maxItems":1000,"description":"Agents' MLS ids."}},"required":["listId","mlsIds"],"additionalProperties":false}},{"key":"recruiting.saved_search.list","app":"recruiting","title":"List Saved Searches","description":"List your organization's saved agent searches, most recently changed first, with their filters.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"recruiting.saved_search.create","app":"recruiting","title":"Save a Search","description":"Save a set of agent search filters under a name so it can be run again later.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200},"filters":{"type":"object","properties":{"q":{"type":"string","maxLength":200,"description":"Part of an agent's name."},"state":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter US state code, such as TX."},"city":{"type":"string","maxLength":100},"zip":{"type":"string","maxLength":10},"centerLat":{"type":"number","minimum":-90,"maximum":90,"description":"With centerLng and radiusMiles: search around a point."},"centerLng":{"type":"number","minimum":-180,"maximum":180},"radiusMiles":{"type":"number","exclusiveMinimum":0,"maximum":500},"officeInclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Only agents at these brokerages."},"officeExclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Leave out agents at these brokerages."},"totalUnitsMin":{"type":"number","minimum":0,"description":"Fewest total homes sold (all time)."},"totalUnitsMax":{"type":"number","minimum":0},"totalVolumeMin":{"type":"number","minimum":0,"description":"Lowest total sales volume in dollars (all time)."},"totalVolumeMax":{"type":"number","minimum":0},"listingPctMin":{"type":"number","minimum":0,"maximum":100,"description":"Lowest share of sales on the listing side, in percent."},"listingPctMax":{"type":"number","minimum":0,"maximum":100},"limit":{"type":"integer","minimum":1,"maximum":200},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},"required":["name","filters"],"additionalProperties":false}},{"key":"recruiting.saved_search.update","app":"recruiting","title":"Update a Saved Search","description":"Rename a saved search or replace its filters. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"savedSearchId":{"type":"string","format":"uuid","description":"The saved search's id, from List saved searches."},"name":{"type":"string","minLength":1,"maxLength":200},"filters":{"type":"object","properties":{"q":{"type":"string","maxLength":200,"description":"Part of an agent's name."},"state":{"type":"string","minLength":2,"maxLength":2,"description":"Two-letter US state code, such as TX."},"city":{"type":"string","maxLength":100},"zip":{"type":"string","maxLength":10},"centerLat":{"type":"number","minimum":-90,"maximum":90,"description":"With centerLng and radiusMiles: search around a point."},"centerLng":{"type":"number","minimum":-180,"maximum":180},"radiusMiles":{"type":"number","exclusiveMinimum":0,"maximum":500},"officeInclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Only agents at these brokerages."},"officeExclude":{"type":"array","items":{"type":"string","maxLength":200},"maxItems":50,"description":"Leave out agents at these brokerages."},"totalUnitsMin":{"type":"number","minimum":0,"description":"Fewest total homes sold (all time)."},"totalUnitsMax":{"type":"number","minimum":0},"totalVolumeMin":{"type":"number","minimum":0,"description":"Lowest total sales volume in dollars (all time)."},"totalVolumeMax":{"type":"number","minimum":0},"listingPctMin":{"type":"number","minimum":0,"maximum":100,"description":"Lowest share of sales on the listing side, in percent."},"listingPctMax":{"type":"number","minimum":0,"maximum":100},"limit":{"type":"integer","minimum":1,"maximum":200},"offset":{"type":"integer","minimum":0}},"additionalProperties":false}},"required":["savedSearchId"],"additionalProperties":false}},{"key":"recruiting.saved_search.delete","app":"recruiting","title":"Delete a Saved Search","description":"Delete a saved search. Support can restore it if needed.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"savedSearchId":{"type":"string","format":"uuid","description":"The saved search's id, from List saved searches."}},"required":["savedSearchId"],"additionalProperties":false}},{"key":"recruiting.pipeline.list","app":"recruiting","title":"List Pipelines","description":"List your recruiting pipelines (boards that track agents from first contact to hire), newest first, with how many agents are in each.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"recruiting.pipeline.get","app":"recruiting","title":"Get a Pipeline","description":"Show one recruiting pipeline with its stages in order and the agents in it, with each one's stage, notes and tags.","kind":"read","risk":{},"access":{"role":"member"},"scope":"recruiting:read","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."}},"required":["pipelineId"],"additionalProperties":false}},{"key":"recruiting.pipeline.create","app":"recruiting","title":"Create a Pipeline","description":"Create a recruiting pipeline. It starts with six stages: sourced, contacted, interviewing, offer, hired and lost.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120}},"required":["name"],"additionalProperties":false}},{"key":"recruiting.pipeline.rename","app":"recruiting","title":"Rename a Pipeline","description":"Give a recruiting pipeline a new name.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."},"name":{"type":"string","minLength":1,"maxLength":120}},"required":["pipelineId","name"],"additionalProperties":false}},{"key":"recruiting.pipeline.delete","app":"recruiting","title":"Delete a Pipeline","description":"Delete a recruiting pipeline and its board. The agents in it stay unlocked.","kind":"write","risk":{"destructive":true},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."}},"required":["pipelineId"],"additionalProperties":false}},{"key":"recruiting.pipeline.add_stage","app":"recruiting","title":"Add a Pipeline Stage","description":"Add a custom stage to a pipeline, such as a second interview. By default it goes at the end.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."},"label":{"type":"string","minLength":1,"maxLength":80},"kind":{"type":"string","enum":["sourced","contacted","interviewing","offer","hired","lost"],"description":"Which default stage it is like, for grouping and color. Defaults to sourced."},"sortOrder":{"type":"integer","description":"Position on the board; lower numbers come first."}},"required":["pipelineId","label"],"additionalProperties":false}},{"key":"recruiting.pipeline.add_agent","app":"recruiting","title":"Add an Agent to a Pipeline","description":"Put an unlocked agent on a pipeline board, in the first stage unless you pick one. Costs 1 token; adding someone who's already there is free.","kind":"write","risk":{"money":true},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."},"mlsId":{"type":"string","minLength":1,"maxLength":64,"description":"The agent's MLS id, from Search agents."},"stageId":{"type":"string","format":"uuid","description":"The stage's id, from Get a pipeline."},"notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50}},"required":["pipelineId","mlsId"],"additionalProperties":false}},{"key":"recruiting.pipeline.update_agent","app":"recruiting","title":"Move or note an agent in a pipeline","description":"Move an agent to another stage, or change their notes, tags or the reason they were lost. Free. Only the fields you send change.","kind":"write","risk":{},"access":{"role":"member"},"scope":"recruiting:write","input":{"type":"object","properties":{"pipelineId":{"type":"string","format":"uuid","description":"The pipeline's id, from List pipelines."},"recruitId":{"type":"string","format":"uuid","description":"The agent's card id in this pipeline, from Get a pipeline."},"stageId":{"type":"string","format":"uuid","description":"The stage's id, from Get a pipeline."},"notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50},"lostReason":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]}},"required":["pipelineId","recruitId"],"additionalProperties":false}},{"key":"leads.lead.list","app":"leads","title":"List Leads","description":"List the leads your organization received from its covered ZIP codes, newest first (up to 100), with the person's details, tier, billing status and any dispute.","kind":"read","risk":{},"access":{"role":"member"},"scope":"leads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"leads.lead.get","app":"leads","title":"Get a Lead","description":"Show one lead your organization received: the person's details and request, ZIP, tier, billing status and any dispute.","kind":"read","risk":{},"access":{"role":"member"},"scope":"leads:read","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid","description":"The lead's id, from List leads."}},"required":["leadId"],"additionalProperties":false}},{"key":"leads.coverage.get","app":"leads","title":"Show Lead Coverage","description":"Show your organization's lead plan (tier, price per lead, monthly cap, billing period) and the ZIP codes it covers.","kind":"read","risk":{},"access":{"role":"member"},"scope":"leads:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"leads.dispute.file","app":"leads","title":"Dispute a Lead","description":"Ask for a lead's tokens back because it's bad: wrong contact details, outside your ZIP codes, a duplicate, spam, or something else. Allowed within 7 days of receiving it, once per lead. Our team reviews it.","kind":"write","risk":{},"access":{"role":"member"},"scope":"leads:write","input":{"type":"object","properties":{"leadId":{"type":"string","format":"uuid","description":"The lead's id, from List leads."},"reason":{"type":"string","enum":["bad_contact_info","wrong_zip","duplicate","spam","other"]},"detail":{"type":"string","maxLength":1000,"description":"What's wrong, in a sentence or two."}},"required":["leadId","reason"],"additionalProperties":false}},{"key":"leads.dispute.list","app":"leads","title":"List Disputes","description":"List disputes on your organization's leads, newest first, with their reason and whether they're pending, approved or rejected.","kind":"read","risk":{},"access":{"role":"member"},"scope":"leads:read","input":{"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","rejected","auto_refunded"]}},"additionalProperties":false}},{"key":"leads.dispute.get","app":"leads","title":"Get a Dispute","description":"Show one lead dispute: the reason, when it was filed, and the decision and note once it's resolved.","kind":"read","risk":{},"access":{"role":"member"},"scope":"leads:read","input":{"type":"object","properties":{"disputeId":{"type":"string","format":"uuid","description":"The dispute's id, from List disputes."}},"required":["disputeId"],"additionalProperties":false}},{"key":"leads.dispute.queue","app":"leads","title":"List Disputes Waiting for Review","description":"Staff only: open lead disputes across every customer, oldest first, with the lead, the agent who filed it and the customer. Logged to the staff audit.","kind":"read","risk":{},"access":{"role":"staff","capability":"leads:disputes"},"scope":"operations:read","input":{"type":"object","properties":{},"additionalProperties":false}},{"key":"leads.dispute.resolve","app":"leads","title":"Approve or Reject a Lead Dispute","description":"Staff only: decide an open lead dispute. Approving refunds the lead's tokens to the customer that paid for it; rejecting keeps the charge. You can't decide a dispute you filed. Logged to the staff audit.","kind":"write","risk":{"money":true},"access":{"role":"staff","capability":"leads:disputes"},"scope":"operations:write","input":{"type":"object","properties":{"disputeId":{"type":"string","format":"uuid","description":"The dispute's id, from List disputes."},"decision":{"type":"string","enum":["approved","rejected"]},"note":{"type":"string","maxLength":2000,"description":"Why, for the audit trail."}},"required":["disputeId","decision"],"additionalProperties":false}}],"unavailable":[]}