Every action in Lawyer Rebrand
Everything you can look up or change in Lawyer Rebrand, product by product. The in-app assistant, the MCP server and the API all run these same actions, so what you can do in one you can do in the others. Actions marked Changes data change your account; the assistant always asks you to confirm them first.
Running an action
Send the inputs as JSON to the product that owns the action, with a personal access token that holds the action's scope. Add X-RS-Org: <organization id> to act in an organization other than your active one.
curl -X POST https://chatbots.lawyerrebrand.com/api/v1/actions/chatbots.bot.create \
-H "Authorization: Bearer <your token>" \
-H "Content-Type: application/json" \
-d '{ ... }'
→ { "ok": true, "result": { ... } }
→ { "ok": false, "error": { "code": "...", "message": "..." } }The full list as JSON: https://core.lawyerrebrand.com/v1/actions.
Chatbots
List Chatbots
ReadsList the chatbots in your organization with their status (draft, live or paused).
chatbots.bot.list · scope chatbots:read · Any member
Get a Chatbot's Settings
ReadsShow one chatbot's settings: greeting, instructions, lead email, fallback, allowed websites and status.
chatbots.bot.get · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string |
Create a Chatbot
Changes dataCreate 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.
chatbots.bot.create · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
purpose | "sales" | "scheduling" | "support" | "recruiting" | "generic" | What the chatbot is for. Defaults to generic. |
greeting | string | The first message visitors see. Leave out to use the suggested greeting. |
instructions | string | How the chatbot should behave. Leave out to use the suggested instructions. |
Update a Chatbot
Changes dataChange 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.
chatbots.bot.update · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
name | string | |
purpose | "sales" | "scheduling" | "support" | "recruiting" | "generic" | |
greeting | any | The first message visitors see. Supports **bold**. |
instructions | any | How the chatbot should behave and what to avoid. |
knowledge | any | Notes the chatbot always knows. |
notifyEmail | any | Where new leads and handoffs are emailed. |
dailyMessageCap | any | |
status | "draft" | "live" | "paused" | |
fallbackMode | "handoff" | "contact" | handoff = take the visitor's details; contact = send them to your phone or contact page. |
contactUrl | any | |
contactPhone | any | |
knowledgeOnly | boolean | Answer only from the notes and sources. |
allowedDomains | string[] | Websites the chatbot may run on, like yourbusiness.com. |
Make a New Preview Link
Changes dataDeletesReplace 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.
chatbots.bot.new_preview_link · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string |
Delete a Chatbot
Changes dataDeletesDelete a chatbot. It stops answering on every website it is installed on and disappears from your list. Its leads and conversations are kept.
chatbots.bot.delete · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string |
List a Chatbot's Version History
ReadsList 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.
chatbots.version.list · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
kind | "settings" | "knowledge" | Only settings versions or only knowledge versions. Leave out for both. |
limit | integer | How many to return (default 50). |
Restore an Earlier Version
Changes dataPut 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.
chatbots.version.restore · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
versionId (required) | string | The id from the version history. |
List a Chatbot's Knowledge Sources
ReadsList 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.
chatbots.source.list · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string |
Read a Knowledge Source
ReadsShow the text the chatbot learned from one knowledge source (the first 20,000 characters, and whether there is more).
chatbots.source.get · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
sourceId (required) | string |
Add a web page to a chatbot's knowledge
Changes dataRead 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.
chatbots.source.add_page · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
url (required) | string | The full page address, starting with https:// |
Import a whole website into a chatbot's knowledge
Changes dataRead 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.
chatbots.source.crawl_site · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
url (required) | string | The site's address, starting with https:// |
exclude | string[] | Paths to skip, like "/blog/*" or "/team/jane". A * matches anything. Kept and reused when the source is refreshed. |
Add a file to a chatbot's knowledge
Changes dataAdd 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.
chatbots.source.upload_file · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
botId (required) | string | |
name | string | The file name shown in the source list. Required with content; taken from the address otherwise. |
content | string | The file's text. HTML is cleaned to plain text when the name ends in .html. |
url | string | The address of a file to download, starting with https:// |
Remove a Knowledge Source
Changes dataDeletesRemove 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.
chatbots.source.remove · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
sourceId (required) | string |
Refresh a Knowledge Source
Changes dataRead 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.
chatbots.source.refresh · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
sourceId (required) | string |
List Chatbot Leads
ReadsList 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).
chatbots.lead.list · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
botId | string | Only this chatbot's leads. |
status | "new" | "contacted" | "won" | "lost" | |
limit | integer | How many to return (default 100). |
Set a Lead's Status
Changes dataMove a chatbot lead along: new, contacted, won or lost.
chatbots.lead.set_status · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
status (required) | "new" | "contacted" | "won" | "lost" |
List Handoff Requests
ReadsList 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.
chatbots.handoff.list · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "open" | "resolved" | "all" | Defaults to open. |
botId | string | Only this chatbot's requests. |
limit | integer | How many to return (default 100). |
Read a Handoff Request
ReadsShow one handoff request with the visitor's details and the conversation that led to it.
chatbots.handoff.get · scope chatbots:read · Any member
| Input | Type | Notes |
|---|---|---|
handoffId (required) | string |
Resolve a Handoff Request
Changes dataMark a handoff request as dealt with, so it leaves your open list.
chatbots.handoff.resolve · scope chatbots:write · Any member
| Input | Type | Notes |
|---|---|---|
handoffId (required) | string |
Resolve a handoff request for a client (staff)
Changes dataFor 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.
chatbots.handoff.staff_resolve · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
handoffId (required) | string | |
note | string | Why or how it was resolved. |
Reputation
List Surveys
ReadsList your satisfaction surveys with their status (active, draft or archived), scale and which one is the default.
reputation.survey.list · scope reputation:read · Any member
Get a Survey
ReadsShow one survey in full: its question, labels, thank-you wording for each kind of answer, extra questions, email and text wording, and its look.
reputation.survey.get · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Create a Survey
Changes dataCreate a new survey styled with your brand. Your first survey becomes the default one that invitations use.
reputation.survey.create · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
name | string | |
metric | "nps" | "csat5" | "csat10" | The rating scale: nps = 0 to 10 likelihood to recommend; csat5 = 1 to 5 stars; csat10 = 1 to 10. |
preset | "classic" | "luxe" | "clinical" | "warm" | "minimal" | A starting look: classic, luxe, clinical, warm or minimal. |
Update a Survey
Changes dataChange 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}.
reputation.survey.update · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
name | string | |
metric | "nps" | "csat5" | "csat10" | The rating scale: nps = 0 to 10 likelihood to recommend; csat5 = 1 to 5 stars; csat10 = 1 to 10. |
alertAtOrBelow | integer | Scores at or below this send a same-day alert to your alert emails. |
content | object | 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 | object | Look to change: preset, background, surface, text, muted, accent, accentText, border (hex colors), headingFont, bodyFont, radius, buttonStyle, layout, logoUrl, headerImageUrl, headingCaps. |
Activate a Survey
Changes dataMake an archived or draft survey active again, so invitations can use it.
reputation.survey.activate · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Archive a Survey
Changes dataDeletesArchive a survey so no new invitations use it. Surveys already sent can still be answered. The default survey can't be archived.
reputation.survey.archive · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Make a Survey the Default
Changes dataMake this survey the default one that invitations, CSV uploads and connected systems use when no survey is named.
reputation.survey.make_default · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Copy a Survey
Changes dataMake an active copy of a survey, with the same wording and look, to edit separately.
reputation.survey.duplicate · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Delete a Survey
Changes dataDeletesDelete a survey and cancel its invitations that haven't gone out yet. Its responses are kept. The default survey can't be deleted.
reputation.survey.delete · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
Email Yourself a Test Survey
Changes dataEmail 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.
reputation.survey.send_test · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
surveyId (required) | string | The survey's id, from List surveys. |
List Survey Invitations
ReadsList the 100 most recent survey invitations with their status (scheduled, sent, answered, skipped, failed or canceled), channel and when they go out.
reputation.invitation.list · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "scheduled" | "sending" | "sent" | "opened" | "responded" | "failed" | "skipped" | "canceled" |
Send a Survey to One Person
Changes dataSpends moneyEmails other peopleSurvey 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.
reputation.invitation.send · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
email | string | |
phone | string | A mobile number. Texts go only to people who agreed to receive them. |
firstName | string | |
lastName | string | |
smsConsent | boolean | true only if this person agreed to receive texts. |
visitAt | string | When the visit was, in your time zone, like 2026-10-16T14:30. |
surveyId | string | Which survey. Defaults to your default survey. |
locationId | string | |
providerId | string | |
channel | "auto" | "email" | "sms" | auto = email when there is one, otherwise text. |
sendNow | boolean | Send right away (inside sending hours) instead of waiting the usual delay. |
Send Surveys from a CSV
Changes dataSpends moneyEmails other peopleSchedule 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.
reputation.invitation.import · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
csv (required) | string | The CSV file's contents, header row first. |
surveyId | string | Which survey. Defaults to your default survey. |
locationId | string | The location for rows that don't name one. |
smsConsent | boolean | true only if everyone in the file agreed to receive texts. |
Send Due Surveys Now
Changes dataSpends moneyEmails other peopleSend 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.
reputation.invitation.send_due · scope reputation:write · Any member
Cancel a Scheduled Survey
Changes dataDeletesCancel a survey that hasn't gone out yet. One that was already sent can't be canceled.
reputation.invitation.cancel · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
invitationId (required) | string | The invitation's id, from List survey invitations. |
Report a Visit
Changes dataSpends moneyEmails other peopleReport 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.
reputation.visit.report · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
externalId | string | |
firstName | string | |
lastName | string | |
email | string | |
phone | string | |
smsConsent | boolean | |
visitAt | string | |
location | string | |
provider | string | |
survey | string | |
sendNow | boolean |
Get the Satisfaction Summary
ReadsShow 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.
reputation.summary.get · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
days | 7 | 30 | 90 | 365 | The period, in days. Defaults to 90. |
List Responses
ReadsList 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.
reputation.response.list · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
since | string | Only responses on or after this date or time (ISO 8601). |
before | string | Only responses before this date or time (ISO 8601). |
limit | integer | |
segment | "promoter" | "passive" | "detractor" | promoter = happy, passive = neutral, detractor = unhappy. |
followupOpen | boolean | true = only responses still waiting on a follow-up. |
Get a Response
ReadsShow one survey response with its follow-up status and your team's notes on it. Contact details are not included.
reputation.response.get · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
responseId (required) | string | The response's id, from List responses. |
Set a Response's Follow-Up
Changes dataOpen a follow-up on a response, mark it resolved, or clear it, with an optional note that is added to the response's history.
reputation.response.set_follow_up · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
responseId (required) | string | The response's id, from List responses. |
status (required) | "open" | "resolved" | "none" | open = needs a follow-up; resolved = done; none = no follow-up needed. |
note | string |
Add a Note to a Response
Changes dataAdd an internal note to a survey response, visible to your team only.
reputation.response.add_note · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
responseId (required) | string | The response's id, from List responses. |
body (required) | string |
Delete a Response
Changes dataDeletesDelete a survey response. It no longer shows in any list, count, export or report.
reputation.response.delete · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
responseId (required) | string | The response's id, from List responses. |
List Reviews
ReadsList the public reviews in your reviews inbox, newest first, with their rating, text and reply status. Shows up to 200.
reputation.review.list · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
filter | "unreplied" | "low" | unreplied = no posted reply yet; low = 3 stars or fewer. |
platform | "google" | "yelp" | "healthgrades" | "facebook" | "zocdoc" | "vitals" | "webmd" | "realself" | "zillow" | "bbb" | "other" | Where the review was posted: google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other. |
Add a Review
Changes dataAdd a public review to your reviews inbox by hand, with its rating, text, author and link.
reputation.review.add · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
platform | "google" | "yelp" | "healthgrades" | "facebook" | "zocdoc" | "vitals" | "webmd" | "realself" | "zillow" | "bbb" | "other" | Where the review was posted: google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other. |
rating | integer | Star rating, 1 to 5. |
body | string | The review's text. |
authorName | string | |
reviewUrl | string | Link to the review, starting with https:// |
postedAt | string | When it was posted (a date or ISO 8601 time). Defaults to now. |
locationId | string | Which of your locations it is about, from List locations. |
Import Reviews from a CSV
Changes dataImport 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.
reputation.review.import · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
csv (required) | string | The CSV file's contents, header row first. |
platform | "google" | "yelp" | "healthgrades" | "facebook" | "zocdoc" | "vitals" | "webmd" | "realself" | "zillow" | "bbb" | "other" | The platform for rows without a platform column. Defaults to google. |
Save a Review Reply
Changes dataSave 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.
reputation.review.reply · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
reviewId (required) | string | The review's id, from List reviews. |
replyBody (required) | string | |
posted | boolean | true = you have posted this reply on the review site. |
Remove a Review
Changes dataDeletesRemove a review from your reviews inbox. It stays on the review site; this only removes it from your list.
reputation.review.delete · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
reviewId (required) | string | The review's id, from List reviews. |
List Contacts
ReadsList 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.
reputation.contact.list · scope reputation:read · Any member
| Input | Type | Notes |
|---|---|---|
search | string | Part of a name, email or phone number. |
email | string | Find one person by their exact email address. |
page | integer |
Stop Surveys to a Person
Changes dataDeletesStop sending surveys to one person and cancel any of theirs that haven't gone out yet.
reputation.contact.unsubscribe · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
contactId (required) | string | The person's id, from List contacts. |
Resume Surveys to a Person
Changes dataTurn surveys back on for someone whose surveys were stopped. Only do this if they asked for it.
reputation.contact.resubscribe · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
contactId (required) | string | The person's id, from List contacts. |
Delete a Contact
Changes dataDeletesDelete a person from your contacts and cancel their surveys that haven't gone out yet. Their past responses are kept.
reputation.contact.delete · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
contactId (required) | string | The person's id, from List contacts. |
Get Reputation Settings
ReadsShow 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.
reputation.settings.get · scope reputation:read · Any member
Update Reputation Settings
Changes dataChange your general Reputation settings. Only the fields you send change. Healthcare mode keeps names, providers and visit details out of every email.
reputation.settings.update · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
fromName | any | The practice or business name patients see as the sender. |
replyTo | any | Where replies to survey emails go. |
timezone | string | An IANA time zone, like America/New_York. |
healthcareMode | boolean | |
sendDelayMinutes | integer | How long after a visit the survey goes out. |
quietStart | integer | Hour (0 to 23) when the sending window opens. |
quietEnd | integer | Hour (1 to 24) when the sending window closes; must be after quietStart. |
reminderEnabled | boolean | Send one reminder to people who haven't answered. |
reminderAfterDays | integer | |
minDaysBetween | integer | The fewest days between two surveys to the same person. |
alertEmails | string[] | Who is emailed the same day a low score comes in. |
Set the Sending Address
Changes dataSet 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.
reputation.settings.set_sender · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
fromEmail (required) | any |
Set a Custom Survey Domain
Changes dataUse 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.
reputation.settings.set_domain · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
customDomain (required) | any |
List Locations
ReadsList your office locations, which surveys, providers, review links and reports can be tied to.
reputation.location.list · scope reputation:read · Any member
Add a Location
Changes dataAdd an office location, so responses and review links can be tied to it.
reputation.location.add · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
address | string | |
phone | string |
Remove a Location
Changes dataDeletesRemove a location and hide its review links. Its past responses keep their history.
reputation.location.remove · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
locationId (required) | string | The location's id, from List locations. |
List Providers
ReadsList the providers (doctors, staff or agents) that surveys and reports can be tied to.
reputation.provider.list · scope reputation:read · Any member
Add a Provider
Changes dataAdd a provider, optionally at one of your locations, so responses can be tied to them.
reputation.provider.add · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
title | string | Like MD, DDS or Hygienist. |
locationId | string | The location's id, from List locations. |
Remove a Provider
Changes dataDeletesRemove a provider from your list. Their past responses keep their history.
reputation.provider.remove · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
providerId (required) | string | The provider's id, from List providers. |
List Review Links
ReadsList the public review links (Google, Yelp and others) offered to everyone who answers a survey, and whether each is shown.
reputation.review_site.list · scope reputation:read · Any member
Add a Review Link
Changes dataAdd 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.
reputation.review_site.add · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
platform | "google" | "yelp" | "healthgrades" | "facebook" | "zocdoc" | "vitals" | "webmd" | "realself" | "zillow" | "bbb" | "other" | google, yelp, healthgrades, facebook, zocdoc, vitals, webmd, realself, zillow, bbb or other. |
url (required) | string | The full https:// link to your review page, or a Google Place ID. |
label | string | Button text. Defaults to Review us on <platform>. |
locationId | string | Show it only for surveys from this location. |
Show or Hide a Review Link
Changes dataShow or hide one review link on the thank-you pages without deleting it.
reputation.review_site.set_active · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
reviewSiteId (required) | string | The review link's id, from List review links. |
active (required) | boolean |
Delete a Review Link
Changes dataDeletesDelete a review link for good. To take it off the thank-you pages for now, hide it instead.
reputation.review_site.remove · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
reviewSiteId (required) | string | The review link's id, from List review links. |
List Connection Keys
ReadsList the keys your booking or records systems use to report visits, with when each was last used. The keys themselves are never shown again.
reputation.api_key.list · scope reputation:read · Any member
Create a Connection Key
Changes dataCreate 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.
reputation.api_key.create · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
name | string | What will use it, like Front desk scheduler. |
Revoke a Connection Key
Changes dataDeletesRevoke a connection key. Anything using it stops working immediately.
reputation.api_key.revoke · scope reputation:write · Any member
| Input | Type | Notes |
|---|---|---|
keyId (required) | string | The key's id, from List connection keys. |
List Pending Customer Setup
ReadsStaff only: customer survey domains and sending addresses waiting on our team to finish setting up, oldest first.
reputation.setup.list · scope operations:read · Platform staff
Recheck a Customer's Domain
Changes dataStaff only: check a customer's custom survey domain or sending address again and record the result. Logged to the staff audit.
reputation.setup.recheck · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The customer organization's id, from List pending customer setup. |
kind (required) | "survey" | "sender" | survey = the custom survey domain; sender = the sending address. |
Mark a Sending Address Verified
Changes dataStaff 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.
reputation.setup.mark_sender_verified · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The customer organization's id, from List pending customer setup. |
Paid Ads
List Ad Campaigns
ReadsList 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.
ads.campaign.list · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
days | 7 | 30 | 90 | Results over the last 7, 30 or 90 days. Default 30. |
platform | "openai" | "google" | "microsoft" | |
status | "enabled" | "paused" | "removed" | |
accountId | string | Only campaigns in this ad account. |
familyId | string | Only campaigns in this family (a source campaign and its clones). |
Get an Ad Campaign
ReadsShow one ad campaign with its targeting, ad groups, ads and keywords, and its daily results over the last 7, 30 or 90 days.
ads.campaign.get · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
days | 7 | 30 | 90 | Results over the last 7, 30 or 90 days. Default 30. |
Pause an Ad Campaign
Changes dataPause 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.
ads.campaign.pause · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Resume an Ad Campaign
Changes dataSpends moneyResume 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.
ads.campaign.resume · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Change a Campaign's Daily Budget
Changes dataSpends moneyChange 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.
ads.campaign.set_budget · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
dailyBudget (required) | number | The new daily budget in the ad account's currency, like 25 or 42.50. |
Clone Campaigns into Drafts
Changes dataMake 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.
ads.campaign.clone · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignIds (required) | string[] | |
platform (required) | "google" | "microsoft" | Where the clones will go. |
accountId | any | The ad account the clones will be created in. Can be chosen later on each draft. |
recipeId | any | A saved recipe whose budget, bidding and targeting rules to apply. |
List Clone Drafts
ReadsList 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.
ads.draft.list · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "draft" | "awaiting_approval" | "approved" | "creating" | "created" | "failed" | "discarded" | |
limit | integer |
Get a Clone Draft
ReadsShow one clone draft in full: name, budget, bidding, targeting, ad groups with ads and keywords, its problems, and what still blocks approving it.
ads.draft.get · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string |
Edit a Clone Draft
Changes dataChange 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.
ads.draft.update · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string | |
accountId | any | The ad account the campaign will be created in; null clears it. |
spec | object |
Rewrite a Draft with AI
Changes dataSpends moneyHave 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.
ads.draft.rewrite · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string | |
requestId (required) | string | A new id (4 to 64 letters, digits, - or _) for each deliberate rewrite. Sending the same id again never charges twice. |
Rewrite Several Drafts with AI
Changes dataSpends moneyHave 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.
ads.draft.rewrite_many · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftIds (required) | string[] | |
requestId (required) | string | A new id (4 to 64 letters, digits, - or _) for each deliberate rewrite. Sending the same id again never charges twice. |
Approve a Clone Draft
Changes dataApprove 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.
ads.draft.approve · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string |
Approve Several Clone Drafts
Changes dataApprove 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.
ads.draft.approve_many · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftIds (required) | string[] |
Create a Campaign from a Draft
Changes dataSpends moneyCreate 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.
ads.draft.create · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string |
Create Campaigns from Several Drafts
Changes dataSpends moneyCreate 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.
ads.draft.create_many · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftIds (required) | string[] |
Discard a Clone Draft
Changes dataDeletesDiscard a draft that hasn't been created. Nothing on any ad platform changes.
ads.draft.discard · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
draftId (required) | string |
List Clone Recipes
ReadsList the saved clone recipes: reusable budget, bidding, naming and targeting rules applied when campaigns are cloned from one platform to another.
ads.recipe.list · scope ads:read · Any member
Get a Clone Recipe
ReadsShow one saved clone recipe with every rule it applies.
ads.recipe.get · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
recipeId (required) | string |
Save a Clone Recipe
Changes dataCreate 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.
ads.recipe.save · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
recipeId | string | Leave out to create a new recipe. |
name | string | |
fromPlatform | "openai" | "google" | "microsoft" | "meta" | "tiktok" | "linkedin" | |
toPlatform | "openai" | "google" | "microsoft" | "meta" | "tiktok" | "linkedin" | |
settings | object |
Delete a Clone Recipe
Changes dataDeletesDelete a saved clone recipe. Drafts already made with it keep their settings.
ads.recipe.delete · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
recipeId (required) | string |
List Campaign Families
ReadsList 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).
ads.family.list · scope ads:read · Any member
Get a Campaign Family
ReadsShow one campaign family: its members, its off or ask setting per kind of change, and its open and recent proposed changes.
ads.family.get · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
familyId (required) | string |
Set How a Family Shares Changes
Changes dataFor 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.
ads.family.set_sync · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
familyId (required) | string | |
kind (required) | "copy" | "keywords" | "status" | "budget" | |
mode (required) | "off" | "ask" |
Pause Every Campaign in a Family
Changes dataPause 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.
ads.family.pause_all · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
familyId (required) | string |
Resume Every Campaign in a Family
Changes dataSpends moneyResume 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.
ads.family.resume_all · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
familyId (required) | string |
Remove a Campaign from Its Family
Changes dataTake 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.
ads.family.remove_member · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
List Proposed Changes
ReadsList changes proposed between family members, newest first, each with a plain-English summary. Shows open ones unless another status is asked for.
ads.proposal.list · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "open" | "approved" | "rejected" | "applied" | "failed" | |
familyId | string | |
limit | integer |
Approve a Proposed Change
Changes dataSpends moneyApprove 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.
ads.proposal.approve · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
proposalId (required) | string |
Reject a Proposed Change
Changes dataReject one open proposed change. Nothing is applied to any campaign.
ads.proposal.reject · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
proposalId (required) | string |
List Ad Accounts
ReadsList 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.
ads.account.list · scope ads:read · Any member
Add Sample Ad Accounts
Changes dataAdd 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.
ads.account.add_samples · scope ads:write · Any member
Add a ChatGPT Ads Account
Changes dataAdd a ChatGPT ads account, kept up to date by importing its Ads Manager exports. Owners and admins only.
ads.account.add_chatgpt · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
accountId (required) | string | The account id shown in ChatGPT Ads Manager. |
currency | string | Three-letter currency code. Default USD. |
Sync an Ad Account Now
Changes dataRead 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.
ads.account.sync · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string |
Disconnect an Ad Account
Changes dataDeletesDisconnect an ad account from Paid Ads. Its campaigns stay in the history and nothing on the platform changes. Owners and admins only.
ads.account.disconnect · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string |
Preview a ChatGPT Ads Export
ReadsRead a ChatGPT Ads Manager CSV export and show the campaigns and days of results it contains, with any warnings, without saving anything.
ads.account.preview_csv · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
csv (required) | string | The CSV file exported from ChatGPT Ads Manager, as text. |
Import a ChatGPT Ads Export
Changes dataImport a ChatGPT Ads Manager CSV export into a ChatGPT ads account: its campaigns and daily results. Preview it first to check what it contains.
ads.account.import_csv · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
csv (required) | string | The CSV file exported from ChatGPT Ads Manager, as text. |
defaultDay | string | The day (YYYY-MM-DD) for results when the file has no date column. |
Get the Linked Editing Sheet
ReadsShow the spreadsheet linked for editing drafts (if any), when it was last synced, and its recent syncs with their status.
ads.sheet.get · scope ads:read · Any member
Get a Sheet Sync
ReadsShow 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.
ads.sheet.get_run · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
runId (required) | string |
Link the Sample Editing Sheet
Changes dataLink the built-in sample spreadsheet, to try editing drafts from a sheet before linking your own Google Sheet. Owners and admins only.
ads.sheet.link_sample · scope ads:write · Any member
Sync the Editing Sheet
Changes dataRead 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.
ads.sheet.sync · scope ads:write · Any member
Apply a sheet sync to the drafts
Changes dataApply 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.
ads.sheet.apply_run · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
runId (required) | string |
Discard a Sheet Sync
Changes dataDeletesThrow away a sheet sync without applying it. No draft changes.
ads.sheet.discard_run · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
runId (required) | string |
Unlink the Editing Sheet
Changes dataDeletesUnlink the spreadsheet used for editing drafts and forget its access. Drafts stay as they are. Owners and admins only.
ads.sheet.unlink · scope ads:write · Any member
Get the Ads Report
ReadsThe 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.
ads.report.get · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
days | 7 | 30 | 90 | A rolling range: the last 7, 30 or 90 days as of each view. Default 30. |
from | string | Fixed range start (YYYY-MM-DD); send with to. |
to | string | Fixed range end (YYYY-MM-DD). |
Get the Setup Checklist
ReadsThe 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.
ads.onboarding.get · scope ads:read · Any member
List Report Links
ReadsList the read-only report links made for this organization, with each link's address, range, expiry and views. Owners and admins only.
ads.report_link.list · scope ads:read · Any member
Make a Report Link
Changes dataMake 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.
ads.report_link.create · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
label | string | A name for the link, like March review. |
days | 7 | 30 | 90 | A rolling range: the last 7, 30 or 90 days as of each view. Default 30. |
from | string | Fixed range start (YYYY-MM-DD); send with to. |
to | string | Fixed range end (YYYY-MM-DD). |
expiresInDays | integer | How long the link works, 1 to 90 days. Default 30. |
Revoke a Report Link
Changes dataDeletesRevoke a report link. It stops working right away. Owners and admins only.
ads.report_link.revoke · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
linkId (required) | string |
Get Paid Ads Settings
ReadsShow 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.
ads.settings.get · scope ads:read · Any member
Change Paid Ads Settings
Changes dataChange 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.
ads.settings.update · scope ads:write · Any member
| Input | Type | Notes |
|---|---|---|
maxDailyBudget | any | US dollars per day across every platform, like 500; null removes the limit. |
noConversionDays | integer | Alert when a campaign has no conversions over this many days. |
noConversionSpend | number | Only once it has spent at least this much (US dollars) in that window. |
Read the Change Log
ReadsThe Paid Ads change log, newest first: who changed what and when, with before and after, for campaigns, drafts, proposed changes, accounts and settings.
ads.change.list · scope ads:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId | string | |
limit | integer |
List Drafts Waiting on Staff
ReadsStaff: 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.
ads.ops_draft.list · scope operations:read · Platform staff
Approve or send back a client's draft
Changes dataStaff: 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.
ads.ops_draft.decide · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client's organization. |
draftId (required) | string | |
decision (required) | "approve" | "return" |
List Every Client's Ad Accounts
ReadsStaff: every organization's connected ad accounts, failing ones first, with the client's name, status and last sync.
ads.ops_account.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
failingOnly | boolean |
Sync a Client's Ad Account
Changes dataStaff: re-run the sync for one client's ad account now. Only reads from the platform.
ads.ops_account.sync · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client's organization. |
accountId (required) | string |
List Onboarded Clients
ReadsStaff: the client organizations onboarded to Paid Ads, with their contact, status (onboarding, active or archived) and partner.
ads.ops_client.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
includeArchived | boolean |
Get a Client's Onboarding
ReadsStaff: one client's onboarding: contact, status, the ad platforms on its checklist with their ids and link steps, and where each stands.
ads.ops_client.get · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client's organization. |
Onboard a New Client
Changes dataEmails other peopleStaff: 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.
ads.ops_client.add · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
partnerId (required) | string | The partner the client belongs to. |
name (required) | string | |
contactName | string | |
contactEmail | string | |
accountIds | object | Ad account ids per platform key (google, microsoft, openai, ...), several separated by commas. |
invite | boolean | Invite the contact to the organization. |
sendEmail | boolean | Email the invitation (otherwise the link is returned to send yourself). |
Start Onboarding an Existing Organization
Changes dataStaff: make an organization that already exists a Paid Ads client being onboarded. Nothing is created and no one is invited.
ads.ops_client.onboard_existing · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
name | string |
Check a Clients CSV
ReadsStaff: check a CSV of clients and show what each row would do, with any problems, without importing anything.
ads.ops_client.check_csv · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
csv (required) | string | The clients CSV as text: a name column, optional contact and one column per ad platform. |
Import Clients from a CSV
Changes dataEmails other peopleStaff: 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.
ads.ops_client.import_csv · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
partnerId (required) | string | |
csv (required) | string | The clients CSV as text: a name column, optional contact and one column per ad platform. |
invite | boolean | |
sendEmail | boolean |
Save a Client's Contact
Changes dataStaff: save the contact name and email for a client being onboarded. Only the fields you send change.
ads.ops_client.save_contact · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
contactName | string | |
contactEmail | string |
Set a Client's Status
Changes dataDeletesStaff: mark a client onboarding, active, or archived (archived clients are hidden from the client list).
ads.ops_client.set_status · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
status (required) | "onboarding" | "active" | "archived" |
Add a platform to a client's checklist
Changes dataStaff: add an ad platform the client uses, with its account id, to the client's setup checklist.
ads.ops_client.add_platform · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
platform (required) | string | Platform key, like google, microsoft or openai. |
accountId | string |
Remove a platform from a client's checklist
Changes dataDeletesStaff: remove one ad platform from a client's setup checklist. Connected ad accounts are not touched.
ads.ops_client.remove_platform · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
platformId (required) | string | The checklist entry's id. |
Record a Manager-Link Step by Hand
Changes dataStaff: 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.
ads.ops_client.record_link_step · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
platformId (required) | string | |
step (required) | "requested" | "accepted" | "reset" |
Invite Someone to a Client's Organization
Changes dataEmails other peopleStaff: 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).
ads.ops_client.invite · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
email (required) | string | |
role | "owner" | "member" | |
sendEmail | boolean |
Send a Manager-Account Link Request
Changes dataEmails other peopleStaff: 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.
ads.ops_client.send_link_request · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client's organization. |
platformId (required) | string | The client's checklist entry for that platform. |
managerId (required) | string | The agency's manager account. |
customerNumber | string | Microsoft only: the client's customer number, when needed. |
Check a Manager-Account Link
Changes dataStaff: ask the ad platform whether the client accepted the manager-account link request. Run from the agency's organization.
ads.ops_client.check_link · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
platformId (required) | string | |
managerId (required) | string |
Add a client's ad accounts through a manager
Changes dataStaff: 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.
ads.ops_client.add_accounts · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
managerId (required) | string |
List a Client's Report Links
ReadsStaff: the read-only report links made for one client's organization.
ads.ops_report_link.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string |
Make a report link for a client
Changes dataStaff: 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).
ads.ops_report_link.create · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
label | string | A name for the link, like March review. |
days | 7 | 30 | 90 | A rolling range: the last 7, 30 or 90 days as of each view. Default 30. |
from | string | Fixed range start (YYYY-MM-DD); send with to. |
to | string | Fixed range end (YYYY-MM-DD). |
expiresInDays | integer | How long the link works, 1 to 90 days. Default 30. |
Revoke a Client's Report Link
Changes dataDeletesStaff: revoke one of a client's report links. It stops working right away.
ads.ops_report_link.revoke · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | |
linkId (required) | string |
List the Agency's Manager Accounts
ReadsStaff: the Google Ads manager and Microsoft agency accounts connected in your current organization (the agency), with their status. Sign-ins are never shown.
ads.ops_manager.list · scope operations:read · Platform staff
Disconnect a Manager Account
Changes dataDeletesStaff: disconnect one of the agency's manager accounts. Client ad accounts already added keep working until their own sign-in is removed.
ads.ops_manager.disconnect · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
managerId (required) | string |
Websites
Add a Website to My Websites
Changes dataAdd a website address to My Websites so it can be audited or have work requested on it. Adding one you archived brings it back.
websites.website.add · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
url (required) | string | The website address, like example.com. |
label | string | A short name, like Main practice site. |
Archive a Website
Changes dataDeletesRemove a website from My Websites. Its audits and past requests are kept, and adding the address again restores it.
websites.website.archive · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
websiteId (required) | string | The website's id, from websites.website.list. |
List My Websites
ReadsList the websites your organization manages (My Websites), with how many open Client Work requests and audits each one has.
websites.website.list · scope websites:read · Any member
Rename a Website
Changes dataChange the label shown for one of My Websites. Send an empty label to clear it.
websites.website.rename · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
websiteId (required) | string | The website's id, from websites.website.list. |
label (required) | string |
Archive a Built Site
Changes dataDeletesArchive a built site so it no longer appears as active. Its history and saved versions are kept.
websites.site.archive · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
Create a Site from a Template
Changes dataStart 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.
websites.site.create · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
kind (required) | "website" | "landing_page" | "listing_site" | |
templateSlug (required) | string | A template slug from websites.template.list. |
templateVariant | string | One of the template's variant keys; defaults to its first. |
name (required) | string | |
slug | string | Short address name, like 'jane-smith'. Defaults to the name, simplified. |
Get a Built Site
ReadsShow one built site in full: name, address slug, settings, every page and its blocks, status and addresses.
websites.site.get · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
List Built Sites
ReadsList the sites built with the website builder in your organization, with status (draft, published, archived) and addresses.
websites.site.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
kind | "website" | "landing_page" | "listing_site" | |
status | "draft" | "published" | "archived" | "expired" |
List Site Templates
ReadsList the starter templates a new site can be built from, with their kinds and design variants.
websites.template.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
kind | "website" | "landing_page" | "listing_site" |
List a Site's Published Versions
ReadsList a site's publish history, newest first: when each version went live, who published it, and what changed.
websites.site_version.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
Publish a Site
Changes dataSpends moneyPublish a site so visitors see its current pages, and save this version to its history. Each publish spends tokens from your balance.
websites.site.publish · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
Restore a Published Version
Changes dataSpends moneyBring 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.
websites.site_version.restore · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
publishId (required) | string | The version's id, from websites.site_version.list. |
mode (required) | "draft" | "publish" |
Unpublish a Site
Changes dataDeletesTake a published site offline and return it to draft. Publishing it again later spends tokens again.
websites.site.unpublish · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
Edit a Built Site
Changes dataChange 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.
websites.site.update · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
name | string | |
slug | string | |
config | object | Site settings: brand colors, fonts, navigation and search details. |
pages | object[] | The full list of pages, each with its path, title and blocks. Read the site first and send back the edited list. |
Add a Custom Domain
Changes dataSpends moneyConnect 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.
websites.domain.add · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
domain (required) | string | A bare domain like example.com, without https:// or a path. |
Check a Domain's Setup
Changes dataLook 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.
websites.domain.check · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
domain (required) | string | A bare domain like example.com, without https:// or a path. |
List a Site's Domains
ReadsList 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.
websites.domain.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
Make a Domain the Main Address
Changes dataMake a verified, live domain the site's main address. The domain must already show as active.
websites.domain.make_primary · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
domain (required) | string | A bare domain like example.com, without https:// or a path. |
Remove a Domain from a Site
Changes dataDeletesDisconnect a domain from a site. Visitors to that address stop seeing the site.
websites.domain.remove · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The site's id, from websites.site.list. |
domain (required) | string | A bare domain like example.com, without https:// or a path. |
Add Items to a Request
Changes dataAdd one or more items of work to one of your requests, each with the page it applies to if you know it.
websites.request_item.add · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
items (required) | object[] |
Approve Finished Work and Pay
Changes dataSpends moneyEmails other peopleApprove 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.
websites.request.approve_completion · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
Approve the List of Work
Changes dataSpends moneyEmails other peopleApprove 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.
websites.request.approve_scope · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
Attach a File to a Request
Changes dataUpload a file, such as a photo or a document, to one of your requests or to one item of it.
websites.request.attach_file · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
itemId | any | The item's id, from websites.request.get. |
filename (required) | string | |
contentType | string | Like image/png or application/pdf. |
contentBase64 (required) | string | The file's contents, base64-encoded. At most 4 MB. |
Cancel a Request
Changes dataDeletesCancel one of your open requests. Nothing more is done on it and nothing is billed for it.
websites.request.cancel · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
Send a Message on a Request
Changes dataEmails other peoplePost a message on one of your requests, or on one item of it. The team and the other people following the request are emailed.
websites.request.comment · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
itemId | any | The item's id, from websites.request.get. |
body (required) | string |
Request Fixes from an Audit
Changes dataEmails other peopleOpen 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.
websites.request.create_from_audit · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
title (required) | string | |
auditRunId | any | The audit report's id. |
siteId | any | The audited website, from websites.website.list. |
items | string[] | The findings to fix, one per item. |
Open a Client Work Request
Changes dataEmails other peopleAsk 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.
websites.request.create · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
title (required) | string | |
service | "website" | "google_business" | "social" | "content_seo" | "other" | What kind of work: website, google_business (Google Business Profile), social, content_seo or other. |
siteId | any | For website work: one of My Websites (websites.website.list). |
items | object[] |
Decline an Item
Changes dataTurn down one proposed item of work on your request so it is left out of the approved list.
websites.request_item.decline · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
itemId (required) | string | The item's id, from websites.request.get. |
Get a Client Work Request
ReadsShow 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.
websites.request.get · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
List Client Work Requests
ReadsList your organization's Client Work requests (website, Google Business Profile, social, content and other work), newest first, with their status.
websites.request.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
includeClosed | boolean | Also list completed, closed and canceled requests. |
Mute or Unmute a Request
Changes dataStop, or start again, getting emails about one request. Your other requests are not affected.
websites.request.mute · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | |
mute (required) | boolean |
Reopen a Request for Follow-Up
Changes dataEmails other peopleStart a follow-up request linked to a completed one, keeping the original and its history. Everyone following it is emailed.
websites.request.reopen · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
Send Finished Work Back for Changes
Changes dataEmails other peopleInstead of approving finished work, say what still needs doing. The request goes back to in progress at no charge and the team is emailed.
websites.request.request_changes · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
reason (required) | string |
Say which page an item is for
Changes dataRecord the page or place on your site an item of work applies to, like a full address or 'the footer'.
websites.request_item.set_page · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.request.list. |
itemId (required) | string | The item's id, from websites.request.get. |
targetUrl (required) | any |
Assign a Request
Changes dataEmails other peopleStaff: make a team member the owner of a request. They are emailed.
websites.ops_request.assign · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
assigneeId (required) | string | The team member's user id. |
Open a Request for a Client
Changes dataEmails other peopleStaff: 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.
websites.ops_request.create · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client organization, from websites.ops_client.list. |
title (required) | string | |
service | "website" | "google_business" | "social" | "content_seo" | "other" | |
siteId | any | For website work: one of the client's websites. |
items | object[] | |
auditRunId | any | When converting audit findings: the audit report's id. |
remediationId | any | When converting a fix-it request from an audit: its id, so it is marked as converted. |
Get a Request (Staff View)
ReadsStaff: show one Client Work request with its items, the whole thread including team-only notes, and attached files.
websites.ops_request.get · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
Find a Client Organization
ReadsStaff: list client organizations work can be opened for, with their partner, optionally filtered by name.
websites.ops_client.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
query | string | Part of the organization or partner name. |
List the Client Work Queue
ReadsStaff: list Client Work requests across every client, oldest first, with each client and partner name.
websites.ops_request.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
includeClosed | boolean | Also list completed, closed and canceled requests. |
Send the list to the client for approval
Changes dataEmails other peopleStaff: send a request's finished list of items to the client and ask them to approve it. The client is emailed.
websites.ops_request.send_scope · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
Set a request's priority or due date
Changes dataStaff: change a request's priority (low, normal, high) or due date. Send a null due date to clear it.
websites.ops_request.set_details · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
priority | "low" | "normal" | "high" | |
dueAt | any | A date like 2026-11-01. |
Add an item to a client's request
Changes dataEmails other peopleStaff: 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.
websites.ops_request_item.add · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
description (required) | string | |
targetUrl | any | |
kind | "hourly" | "flat" | hourly (default) or flat, a fixed price. |
estHours | any | |
flatTokens | any | For a fixed-price item: its price in tokens. |
Attach a file to a request (staff)
Changes dataStaff: upload a file to a client's request or to one item of it.
websites.ops_request.attach_file · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
itemId | any | The item's id, from websites.ops_request.get. |
filename (required) | string | |
contentType | string | Like image/png or application/pdf. |
contentBase64 (required) | string | The file's contents, base64-encoded. At most 4 MB. |
Post on a Request (Staff)
Changes dataEmails other peopleStaff: 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.
websites.ops_request.comment · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
itemId | any | The item's id, from websites.ops_request.get. |
body (required) | string | |
internal | boolean | true = team-only note (no email); false (default) = a reply the client sees. |
Reopen a Request (Staff)
Changes dataEmails other peopleStaff: start a follow-up request linked to a completed one. Everyone following it, including the client, is emailed.
websites.ops_request.reopen · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
Update an Item (Staff)
Changes dataStaff: change an item's status, estimated hours, actual hours worked or the page it applies to. Only the fields you send change.
websites.ops_request_item.update · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
itemId (required) | string | The item's id, from websites.ops_request.get. |
status | "proposed" | "approved" | "in_progress" | "done" | "declined" | |
estHours | any | |
actualHours | any | Hours actually worked; billed when the client approves completion. |
targetUrl | any |
Start Work on a Request
Changes dataStaff: start work on a request whose list the client approved. It moves to in progress.
websites.ops_request.start_work · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
Submit Finished Work to the Client
Changes dataEmails other peopleStaff: tell the client the work is done and ask them to check and approve it. The client is emailed.
websites.ops_request.submit_for_review · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from websites.ops_request.list. |
Get My Email Settings
ReadsShow 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.
websites.notification_settings.get · scope websites:read · Any member
List My Notifications
ReadsList your recent Client Work notifications, newest first, with which ones are unread.
websites.notification.list · scope websites:read · Any member
| Input | Type | Notes |
|---|---|---|
limit | integer |
Mark Notifications Read
Changes dataMark one notification as read, or all of your unread notifications when no id is given.
websites.notification.mark_read · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
notificationId | string |
Change My Email Settings
Changes dataChange 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.
websites.notification_settings.update · scope websites:write · Any member
| Input | Type | Notes |
|---|---|---|
mode | "immediate" | "digest" | "off" | |
events | object | 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. |
Audit
List Audit Types and Prices
ReadsList 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.
audit.category.list · scope audit:read · Any member
List Audits
ReadsList your organization's 50 most recent website audits with their type, status and when they finished.
audit.run.list · scope audit:read · Any member
| Input | Type | Notes |
|---|---|---|
category | "accessibility" | "performance" | "seo" | "aeo" | accessibility, performance, seo (search) or aeo (how AI chatbots see the site). |
siteId | string | Only audits of this website, from audit.site.list. |
Get an Audit's Results
ReadsShow one audit: whether it is queued, running, finished or failed, and each check's score and summary once it is done.
audit.run.get · scope audit:read · Any member
| Input | Type | Notes |
|---|---|---|
runId (required) | string | The audit's id, from audit.run.list or audit.run.start. |
Run a Website Audit
Changes dataSpends moneyStart 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.
audit.run.start · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
url (required) | string | The full address to audit, starting with https:// |
category (required) | "accessibility" | "performance" | "seo" | "aeo" | accessibility, performance, seo (search) or aeo (how AI chatbots see the site). |
depth | "scan" | "deep" | deep checks more pages and costs twice as much, where available. |
siteId | string | Link the audit to one of your websites, from audit.site.list. |
List Audited Websites
ReadsList the websites your organization audits, with their labels.
audit.site.list · scope audit:read · Any member
Get a Website's Audit Schedule
ReadsShow which audits run automatically for one website, how often (weekly or monthly), and when each runs next.
audit.site.get_schedules · scope audit:read · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from audit.site.list. |
Add a Website to Audit
Changes dataAdd a website to your organization so it can be audited and scheduled. Adding an address you deleted brings it back.
audit.site.add · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
url (required) | string | The website's address, starting with https:// |
label (required) | string | A short name, like Main practice site. |
Schedule Recurring Audits
Changes dataSpends moneyTurn 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.
audit.site.set_schedules · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from audit.site.list. |
schedules (required) | object[] |
Delete an Audited Website
Changes dataDeletesRemove a website from your audited websites and stop its scheduled audits. Past reports are kept and it can be restored.
audit.site.delete · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from audit.site.list. |
Restore a Deleted Website
Changes dataBring back a website you deleted from your audited websites.
audit.site.restore · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from audit.site.list. |
Ask Us to Fix a Website
Changes dataEmails other peopleAsk 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.
audit.remediation.request · scope audit:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId | string | One of your websites, from audit.site.list. Or send url instead. |
url | string | The website's address, when it isn't one of your websites yet. |
phone | string | |
message | string | Anything the team should know. |
List Fix-It Requests (Staff)
ReadsStaff: list requests to fix websites from every partner, newest first, with contact details and status. Open ones by default.
audit.ops_remediation.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
status | "new" | "contacted" | "quoted" | "won" | "lost" | |
includeClosed | boolean | Also list won and lost requests. |
Update a Fix-It Request's Status (Staff)
Changes dataStaff: move a request to fix a website along the pipeline: new, contacted, quoted, won or lost.
audit.ops_remediation.set_status · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | |
status (required) | "new" | "contacted" | "quoted" | "won" | "lost" |
Cold Email
List Cold Email Campaigns
ReadsList 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.
coldemail.campaign.list · scope coldemail:read · Any member
Get a Campaign
ReadsShow 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.
coldemail.campaign.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Create a Campaign
Changes dataCreate a new cold email campaign as a draft. Nothing sends until it has steps, inboxes and recipients and you launch it.
coldemail.campaign.create · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string |
Change a Campaign's Settings
Changes dataChange 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.
coldemail.campaign.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
name | string | |
timezone | string | Time zone of the sending window, like America/Chicago. |
sendHourStart | integer | First hour emails may go out (0 to 23). |
sendHourEnd | integer | Hour sending stops, not included; 24 means through midnight. |
sendDays | integer[] | Days of the week to send: 1 is Monday, 7 is Sunday. |
stopOnReply | boolean | Stop the sequence for a person once they reply. |
dailyCap | any | Most emails the campaign sends a day; null for no cap. |
useLeadTimezone | boolean | Use each recipient's own time zone for the sending window. |
trackOpens | boolean | |
trackClicks | boolean | |
stopOnClick | boolean | Stop the sequence for a person once they click a link. |
minGapMinutes | any | Minimum minutes between two emails from the same inbox. |
maxNewPerDay | any | Most new recipients started each day. |
inboxIds | string[] | Inboxes that send this campaign (replaces the current list). |
groupIds | string[] | Inbox groups that send this campaign (replaces the current list). |
Launch or Resume a Campaign
Changes dataSpends moneyEmails other peopleStart 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.
coldemail.campaign.launch · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Pause a Campaign
Changes dataStop an active campaign from sending. Recipients keep their place, so resuming carries on where it left off.
coldemail.campaign.pause · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Complete or Archive a Campaign
Changes dataDeletesMark a campaign completed or archived. It stops sending for good; its results stay.
coldemail.campaign.end · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
status (required) | "completed" | "archived" |
Turn Test Mode on or Off
Changes dataEmails other peopleWhile 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.
coldemail.campaign.set_test_mode · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
on (required) | boolean |
Delete a Campaign
Changes dataDeletesDelete a campaign with its steps, recipients and results. This can't be undone; archiving keeps the results.
coldemail.campaign.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Add a Follow-Up Campaign
Changes dataCreate 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.
coldemail.campaign.create_follow_up · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign whose replies start the follow-up. |
triggerCategory (required) | "interested" | "meeting_request" | "information_request" | "not_interested" | "wrong_person" | "out_of_office" | "other" | The reply category that starts it for a person. |
name | string |
Add a Sequence Step
Changes dataAdd 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.
coldemail.step.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
stepOrder | integer | Position in the sequence, starting at 1. |
waitDays | integer | Days to wait after the previous step (0 for the first). |
subject | any | 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 (required) | string | The email text. Supports {{first_name}}, {{company}} and other recipient fields, {{first_name|there}} for a fallback, and {a|b} to vary wording. |
weight | integer | How often this version is chosen against the step's other versions; 0 pauses it. |
Edit a Sequence Step
Changes dataChange 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.
coldemail.step.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
stepId (required) | string | |
stepOrder | integer | |
waitDays | integer | |
subject | any | |
body | string | |
weight | integer |
Remove a Sequence Step
Changes dataDeletesRemove one step (and its other versions) from a campaign's sequence. The sequence history keeps the old version so it can be restored.
coldemail.step.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
stepId (required) | string |
Add an A/B version to a step
Changes dataAdd another version (B, C and so on) of a step to test against the original. Each recipient gets one version, chosen by weight.
coldemail.step_version.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
stepId (required) | string | |
subject | any | |
body (required) | string | The email text. Supports {{first_name}}, {{company}} and other recipient fields, {{first_name|there}} for a fallback, and {a|b} to vary wording. |
weight | integer |
Edit an A/B version
Changes dataChange version B, C and so on of a step. Only the fields you send change. Weight 0 pauses that version.
coldemail.step_version.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
stepId (required) | string | |
label (required) | string | Which version: B, C and so on (the step itself is version A). |
subject | any | |
body | string | |
weight | integer |
Remove an A/B version
Changes dataDeletesRemove one extra version (B, C and so on) of a step. The sequence history keeps it so it can be restored.
coldemail.step_version.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
versionId (required) | string | The version's id, from the campaign's steps. |
Write a Sequence with AI
Changes dataSpends moneyWrite 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.
coldemail.sequence.write_ai · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
audience (required) | string | Who you're writing to. |
offer (required) | string | What you're offering them. |
goal | string | What a good reply looks like; defaults to agreeing to a short call. |
tone | "friendly" | "direct" | "formal" | |
steps | integer | How many emails, 1 to 5 (default 3). |
abTest | boolean | Also write a B version of each email. |
replace | boolean | Replace the current steps (only before anything has been sent). |
requestId | string | Any unique text; repeating a request with the same value never charges twice. |
List a Sequence's Saved Versions
ReadsList the saved versions of a campaign's sequence, newest first, with what changed in each and who changed it.
coldemail.sequence.history · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string |
Restore an Earlier Sequence
Changes dataPut 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.
coldemail.sequence.restore · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
versionId (required) | string | From the sequence history. |
List a Campaign's Recipients
ReadsList the people in a campaign with their status, reply category and current step. Page with the next value returned.
coldemail.recipient.list · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
limit | integer | |
after | string | The next value from the previous page. |
status | string | Only people in this status, like active, replied or bounced. |
category | string | Only people whose reply has this category, like interested. |
Add Recipients to a Campaign
Changes dataEmails other peopleAdd 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.
coldemail.recipient.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
recipients (required) | object[] | |
skipGeneric | boolean | Skip generic addresses like info@ or office@ (default yes). |
skipNoMail | boolean | Skip addresses whose domain can't receive mail (default yes). |
skipOtherCampaigns | boolean | Skip people already in another campaign (default no). |
tags | string[] | Tags added to everyone's contact. |
Import Recipients from a CSV
Changes dataEmails other peopleAdd 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.
coldemail.recipient.import_csv · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | |
csv (required) | string | |
mapping | array | One entry per column, in order: a known field (email, first_name, company…), a custom field, or skip. |
skipGeneric | boolean | Skip generic addresses like info@ (default yes). |
skipNoMail | boolean | Skip addresses whose domain can't receive mail (default yes). |
skipOtherCampaigns | boolean | Skip people already in another campaign (default no). |
tags | string[] |
List Inboxes
ReadsList 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.
coldemail.inbox.list · scope coldemail:read · Any member
Get an Inbox
ReadsShow one inbox in full, including its latest DNS check, blocklist check and inbox placement tests. Passwords and keys are never shown.
coldemail.inbox.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Connect an Inbox
Changes dataConnect 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.
coldemail.inbox.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
transport (required) | "smtp" | "sendgrid" | smtp = your own mailbox; sendgrid = send through SendGrid. |
fromEmail (required) | string | |
fromName | string | |
dailyLimit | integer | Most emails a day (default 40; at most 500 for a mailbox). |
warmupEnabled | boolean | Warm the mailbox up: start small and build its sending reputation. |
smtpHost | string | |
smtpPort | integer | |
smtpUsername | string | |
smtpPassword | string | For Gmail or Outlook, an app password. |
imapHost | string | To read replies; leave empty to set it up later. |
imapPort | integer | |
imapUsername | string | |
imapPassword | string | |
sendgridApiKey | string | Your own SendGrid key (starts with SG.). Leave empty to use the account your provider supplies, if any. |
Change an Inbox's Daily Limit
Changes dataChange 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.
coldemail.inbox.set_daily_limit · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string | |
dailyLimit (required) | integer |
Set a SendGrid Inbox's Key
Changes dataAdd or replace the SendGrid API key a SendGrid inbox sends with, and connect its delivery reports. The key is stored encrypted.
coldemail.inbox.set_sendgrid_key · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string | |
sendgridApiKey (required) | string |
Set how an inbox's replies are read
Changes dataChoose 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.
coldemail.inbox.set_reply_settings · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string | |
mode (required) | "imap" | "parse" | "none" | |
imapHost | string | |
imapPort | integer | |
imapUsername | string | |
imapPassword | string | Leave empty to keep the saved one. |
replyDomain | string | For parse: a subdomain like reply.yourdomain.com. |
Remove an Inbox
Changes dataDeletesDisconnect and remove an inbox. Campaigns stop sending from it.
coldemail.inbox.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Send a Test Email to Yourself
Changes dataSend 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.
coldemail.inbox.send_test · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Check an Inbox's DNS
Changes dataCheck 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.
coldemail.inbox.check_dns · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Check an Inbox's Domains Against Blocklists
Changes dataCheck the inbox's sending, reply and tracking domains against the main domain blocklists now. The result is saved on the inbox.
coldemail.inbox.check_blocklists · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Run an Inbox Placement Test
Changes dataSpends moneySend 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.
coldemail.inbox.placement_test · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string | |
requestId | string | Any unique text; repeating a request with the same value never charges twice. |
Resume a Paused Inbox
Changes dataEmails other peopleTurn 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.
coldemail.inbox.resume · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
inboxId (required) | string |
Create or Change an Inbox Group
Changes dataCreate 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.
coldemail.inbox_group.save · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
groupId | string | |
name | string | Required for a new group. |
inboxIds | string[] | The inboxes in the group (replaces the current list). |
Delete an Inbox Group
Changes dataDeletesDelete an inbox group. Campaigns that used it keep their individually chosen inboxes.
coldemail.inbox_group.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
groupId (required) | string |
Get Cold Email Settings
ReadsShow 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.
coldemail.settings.get · scope coldemail:read · Any member
Set Your Business Mailing Address
Changes dataSet the physical mailing address that the law requires at the bottom of every commercial email. Nothing sends until it is set.
coldemail.settings.set_postal_address · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
address (required) | string |
Add a Test Recipient
Changes dataAdd an address that campaigns in test mode send to. In test mode, only these addresses are emailed.
coldemail.test_recipient.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
email (required) | string |
Remove a Test Recipient
Changes dataDeletesStop sending test-mode emails to an address.
coldemail.test_recipient.remove · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
email (required) | string |
List the Blocklist
ReadsList 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).
coldemail.blocklist.list · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
search | string | |
limit | integer | |
before | string | The next value from the previous page. |
Block Addresses or Domains
Changes dataAdd email addresses or whole domains (like competitor.com) to your do-not-mail list. No campaign emails them again.
coldemail.blocklist.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
entries (required) | string[] | |
note | string |
Unblock an Address or Domain
Changes dataDeletesRemove 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.
coldemail.blocklist.remove · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
entryId (required) | string | From the blocklist. |
Update the Company Profile
Changes dataChange 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.
coldemail.profile.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
about | any | |
offer | any | |
faq | any | |
signature | any | |
bookingUrl | any | Your scheduling page, starting with https://. |
Create a New Booking Webhook
Changes dataDeletesCreate 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.
coldemail.booking_link.reset · scope coldemail:write · Any member
Add a Sending Domain
Changes dataAdd 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.
coldemail.sending_domain.add · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
domain (required) | string | Just the part after the @, like yourcompany.com. |
Check a Sending Domain
Changes dataLook 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.
coldemail.sending_domain.check · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
domainId (required) | string |
Remove a Sending Domain
Changes dataDeletesRemove a sending domain. Inboxes sending from it through a shared delivery account stop until it is verified again.
coldemail.sending_domain.remove · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
domainId (required) | string |
Set a Custom Tracking Domain
Changes dataUse 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.
coldemail.tracking_domain.set · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
domain (required) | string |
Check the Tracking Domain
Changes dataLook up the tracking domain's CNAME record now. DNS changes can take up to an hour to appear.
coldemail.tracking_domain.check · scope coldemail:write · Any member
Remove the Tracking Domain
Changes dataDeletesStop using your custom tracking domain. Tracked links go back to the standard address.
coldemail.tracking_domain.remove · scope coldemail:write · Any member
List Replies
ReadsList 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.
coldemail.reply.list · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
limit | integer | |
since | string | Only replies after this time. |
before | string | The next value from the previous page. |
category | "interested" | "meeting_request" | "information_request" | "not_interested" | "do_not_contact" | "out_of_office" | "wrong_person" | "bounce" | "other" | "meeting_booked" | |
campaignId | string | |
includeAutomatic | boolean | Include out-of-office replies and bounce notices. |
Get a Conversation
ReadsShow one recipient's whole conversation: every email sent and received, team notes, any saved reply draft, and whether it is snoozed or archived.
coldemail.conversation.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | The recipient's id, from a reply or a campaign's recipients. |
Set a Reply's Category
Changes dataEmails other peopleCorrect 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.
coldemail.reply.set_category · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
messageId (required) | string | The reply's id. |
category (required) | "interested" | "meeting_request" | "information_request" | "not_interested" | "do_not_contact" | "out_of_office" | "wrong_person" | "bounce" | "other" | "meeting_booked" |
Reply to a Recipient
Changes dataEmails other peopleSend 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.
coldemail.conversation.send_reply · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
body (required) | string |
Draft a Reply with AI
Changes dataSpends moneyWrite 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.
coldemail.conversation.draft_reply · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
requestId | string | Any unique text; repeating a request with the same value never charges twice. |
Discard a Saved Reply Draft
Changes dataThrow away the reply draft saved on a conversation.
coldemail.conversation.discard_draft · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string |
Snooze a Conversation
Changes dataHide a conversation from the inbox until a set time. It comes back then, or sooner if they write again.
coldemail.conversation.snooze · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
until (required) | "tomorrow" | "3days" | "week" | "date" | |
date | string | When until is date: the date and time it comes back. |
Archive, Unarchive or Mark Unread
Changes dataArchive a conversation, move it back to the inbox, end a snooze, or mark its latest reply unread.
coldemail.conversation.set_state · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
op (required) | "archive" | "unarchive" | "unsnooze" | "unread" |
Add a Team Note
Changes dataAdd a private note to a conversation. Only your team sees it; it is never sent.
coldemail.conversation.add_note · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
body (required) | string |
Tag the Person in a Conversation
Changes dataAdd or remove tags on the contact behind a conversation, so you can find or import them later.
coldemail.conversation.tag · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | |
tags (required) | string[] | |
op | "add" | "remove" |
Update Several Conversations
Changes dataEmails other peopleMark 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).
coldemail.conversation.bulk_update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
leadIds (required) | string[] | |
op (required) | "read" | "archive" | "unarchive" | "category" | |
category | "interested" | "meeting_request" | "information_request" | "not_interested" | "do_not_contact" | "out_of_office" | "wrong_person" | "bounce" | "other" | "meeting_booked" | When op is category: the category to set. |
List Contacts
ReadsList 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.
coldemail.contact.list · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
tag | string | |
search | string | |
limit | integer | |
offset | integer |
Mark Contacts Do Not Contact
Changes dataDeletesMark 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.
coldemail.contact.mark_do_not_contact · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
contactIds (required) | string[] |
Clear Do Not Contact
Changes dataUndo a mistaken do-not-contact mark on up to 200 contacts. No campaign restarts; add them to a campaign again to reach them.
coldemail.contact.clear_do_not_contact · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
contactIds (required) | string[] |
List Client Report Links
ReadsList the private, read-only report links you share with clients, the campaigns each shows, and when each was last viewed.
coldemail.client_report.list · scope coldemail:read · Any member
Create a Client Report Link
Changes dataCreate 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.
coldemail.client_report.create · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | Usually the client's name. |
campaignIds (required) | string[] | |
showReplies | boolean | Also show replies. |
Change a Client Report Link
Changes dataChange which campaigns a client report shows, or whether it shows replies. Only the fields you send change.
coldemail.client_report.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
reportId (required) | string | |
campaignIds | string[] | |
showReplies | boolean |
Revoke a Client Report Link
Changes dataDeletesStop a client report link working, at once and for good.
coldemail.client_report.revoke · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
reportId (required) | string |
List LinkedIn Accounts
ReadsList the LinkedIn profiles your team works outreach from, with their daily and weekly invitation limits and status.
coldemail.linkedin_account.list · scope coldemail:read · Any member
Get a LinkedIn Account
ReadsShow one LinkedIn account's settings, its campaigns (with the connection note and follow-up messages) and how many people are in each stage.
coldemail.linkedin_account.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string |
List People on a LinkedIn Account
ReadsList the people on a LinkedIn account, newest first, optionally only those in one stage (queued, invited, accepted, replied and so on).
coldemail.linkedin_person.list · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
status | "queued" | "invited" | "accepted" | "replied" | "not_interested" | "do_not_contact" | "withdrawn" | "skipped" | "completed" | |
limit | integer |
Get Today's LinkedIn Queue
ReadsShow 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.
coldemail.linkedin_queue.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string |
Add a LinkedIn Account
Changes dataAdd a LinkedIn profile to work outreach from. Nothing is sent automatically: your team sends each invitation and message by hand from the daily queue.
coldemail.linkedin_account.create · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
label (required) | string | Usually the name of the person whose profile it is. |
timezone | string | The profile owner's time zone, like America/Chicago. |
profileUrl | any | |
status | "active" | "paused" | "restricted" | |
dailyInviteLimit | integer | |
weeklyInviteLimit | integer | |
dailyMessageLimit | integer | |
withdrawAfterDays | integer | Withdraw an invitation nobody accepted after this many days. |
voiceNotes | any | How this person writes, for AI-personalized notes. |
Change a LinkedIn Account
Changes dataChange a LinkedIn account's name, limits, time zone, status or writing voice. Only the fields you send change.
coldemail.linkedin_account.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
label | string | |
timezone | string | The profile owner's time zone, like America/Chicago. |
profileUrl | any | |
status | "active" | "paused" | "restricted" | |
dailyInviteLimit | integer | |
weeklyInviteLimit | integer | |
dailyMessageLimit | integer | |
withdrawAfterDays | integer | Withdraw an invitation nobody accepted after this many days. |
voiceNotes | any | How this person writes, for AI-personalized notes. |
Remove a LinkedIn Account
Changes dataDeletesRemove a LinkedIn account and its queue from your organization.
coldemail.linkedin_account.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string |
Create a LinkedIn Campaign
Changes dataCreate 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.
coldemail.linkedin_campaign.create · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
name (required) | string |
Get a LinkedIn Campaign
ReadsShow one LinkedIn campaign: its status, connection note, follow-up messages and whether notes are personalized with AI.
coldemail.linkedin_campaign.get · scope coldemail:read · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
campaignId (required) | string |
Change a LinkedIn Campaign
Changes dataChange 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.
coldemail.linkedin_campaign.update · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
campaignId (required) | string | |
name | string | |
status | "draft" | "active" | "paused" | "completed" | |
connectionNote | string | Supports {{first_name}}, {{company}}, {{headline}} and {{first_name|there}} for a fallback. |
personalizeWithAi | boolean | Offer an AI-personalized note for each person (1 token each, only when used). |
followups | object[] | Messages after someone accepts, in order (replaces the current list). Supports {{first_name}}, {{company}}, {{headline}} and {{first_name|there}} for a fallback. |
Remove a LinkedIn Campaign
Changes dataDeletesRemove a LinkedIn campaign. Its people leave the daily queue.
coldemail.linkedin_campaign.delete · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
campaignId (required) | string |
Import People into a LinkedIn Campaign
Changes dataAdd 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.
coldemail.linkedin_campaign.import_csv · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
campaignId (required) | string | |
csv (required) | string |
Import tagged contacts into a LinkedIn campaign
Changes dataAdd 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.
coldemail.linkedin_campaign.import_contacts · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
campaignId (required) | string | |
tag (required) | string |
Record an invitation or message as sent
Changes dataRecord 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.
coldemail.linkedin_queue.mark_sent · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
kind (required) | "invite" | "followup" | |
step | integer | For a follow-up: which one, as shown in the queue (0 is the first). |
Skip a Person
Changes dataTake a person waiting for an invitation off the queue without inviting them.
coldemail.linkedin_queue.skip · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
Save a Person's LinkedIn Profile Link
Changes dataSave the profile link for a person who was imported without one, so they move onto the invitation list. Their contact gets the link too.
coldemail.linkedin_queue.save_profile_link · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
profileUrl (required) | string | Like https://www.linkedin.com/in/their-name. |
Set aside a person who can't be found
Changes dataSet aside a person without a profile link whom nobody could find on LinkedIn.
coldemail.linkedin_queue.not_found · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
Record a New Connection
Changes dataRecord that a person accepted the invitation (or was already connected). Their first follow-up message is scheduled.
coldemail.linkedin_queue.mark_connected · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
Record Many New Connections
Changes dataPaste the names or profile links of people who accepted, one per line, and they are matched to pending invitations and recorded as connected.
coldemail.linkedin_queue.mark_accepted_bulk · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
accepted (required) | string |
Record a Withdrawn Invitation
Changes dataRecord that someone on your team withdrew a person's unanswered invitation on LinkedIn.
coldemail.linkedin_queue.mark_withdrawn · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
Stop Follow-Ups to a Person
Changes dataStop any further follow-up messages to a connection.
coldemail.linkedin_queue.stop_followups · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
Log a LinkedIn Reply
Changes dataEmails other peopleLog 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.
coldemail.linkedin_queue.log_reply · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
reply (required) | string | |
category | "auto" | "interested" | "meeting_request" | "information_request" | "not_interested" | "do_not_contact" | "out_of_office" | "wrong_person" | "other" |
Personalize a Connection Note with AI
Changes dataSpends moneyWrite 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.
coldemail.linkedin_queue.personalize_note · scope coldemail:write · Any member
| Input | Type | Notes |
|---|---|---|
accountId (required) | string | |
personId (required) | string | From the queue or the account's people. |
requestId | string | Any unique text; repeating a request with the same value never charges twice. |
Allow or stop a client using our sending account
Changes dataPlatform 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.
coldemail.ops.set_platform_sending · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client organization. |
enabled (required) | boolean | |
note | string |
Mark a Client's Sending Domain Verified
Changes dataPlatform 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.
coldemail.ops.verify_sending_domain · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The client organization. |
domain (required) | string | |
note (required) | string |
video
List Video Profiles
ReadsList 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.
video.profile.list · scope video:read · Any member
Get a Video Profile
ReadsShow one video profile's settings: its voice, avatar, language, captions and who it is shared with.
video.profile.get · scope video:read · Any member
| Input | Type | Notes |
|---|---|---|
profileId (required) | string | The profile's id, from List video profiles. |
Video Profile Options
ReadsList 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.
video.profile.options · scope video:read · Any member
Create a Video Profile
Changes dataCreate 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.
video.profile.create · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
voiceProvider (required) | "generic" | "elevenlabs" | generic = one of our standard voices; elevenlabs = a cloned voice (ours, set up by concierge, or from your connected ElevenLabs account). |
voiceId (required) | string | The voice's id, from Video profile options. |
avatarProvider | "none" | "heygen_stock" | "heygen" | none = voice only; heygen_stock = one of our stock spokespeople; heygen = your custom avatar. |
avatarId | string | The avatar's id, from Video profile options. Empty when avatarProvider is none. |
language | string | Language code, like en or es. |
captionMode | "none" | "burned" | "sidecar" | "both" | none = no captions; burned = captions drawn into the video; sidecar = a separate caption file; both. |
scope | string | "personal" for just you, or the id of an organization you own to share the profile with its members. |
Update a Video Profile
Changes dataChange 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.
video.profile.update · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
profileId (required) | string | The profile's id, from List video profiles. |
name | string | |
voiceProvider | "generic" | "elevenlabs" | generic = one of our standard voices; elevenlabs = a cloned voice (ours, set up by concierge, or from your connected ElevenLabs account). |
voiceId | string | The voice's id, from Video profile options. |
avatarProvider | "none" | "heygen_stock" | "heygen" | none = voice only; heygen_stock = one of our stock spokespeople; heygen = your custom avatar. |
avatarId | string | The avatar's id, from Video profile options. Empty when avatarProvider is none. |
language | string | Language code, like en or es. |
captionMode | "none" | "burned" | "sidecar" | "both" | none = no captions; burned = captions drawn into the video; sidecar = a separate caption file; both. |
scope | string | "personal" for just you, or the id of an organization you own to share the profile with its members. |
Delete a Video Profile
Changes dataDeletesDelete a video profile. Automations that use it will need another profile before they can run.
video.profile.delete · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
profileId (required) | string | The profile's id, from List video profiles. |
Set Your Default Video Profile
Changes dataMake a video profile your default, so new videos and automations start with it selected.
video.profile.set_default · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
profileId (required) | string | The profile's id, from List video profiles. |
List Market Areas
ReadsList 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.
video.area.list · scope video:read · Any member
Add a Market Area
Changes dataAdd a city, ZIP code or neighborhood you want market report videos for. The label is what you see in lists, like Austin, TX 78704.
video.area.create · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
type (required) | "city" | "zip" | "neighborhood" | |
value (required) | string | The city name, five-digit ZIP code or neighborhood name. |
label (required) | string | How the area is shown in lists. |
boundaryId | string | A market-data boundary id, when you have one. Leave out otherwise. |
Remove a Market Area
Changes dataDeletesRemove one of your market areas. Videos already made for it are kept.
video.area.delete · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
areaId (required) | string | The area's id, from List market areas. |
List Automations
ReadsList this organization's automations: recurring market report videos, each with an area, template, video profile, schedule and whether it is active or paused.
video.automation.list · scope video:read · Any member
Get an Automation
ReadsShow one automation's settings, schedule, when it last ran and when it runs next.
video.automation.get · scope video:read · Any member
| Input | Type | Notes |
|---|---|---|
automationId (required) | string | The automation's id, from List automations. |
List Video Templates
ReadsList the video templates for each kind of video (for example the market report templates an automation can use), with their ids.
video.template.list · scope video:read · Any member
| Input | Type | Notes |
|---|---|---|
contentType | string | Only templates for this kind of video, like market_report. Kinds come from List video types. |
Create an Automation
Changes dataSpends moneySet 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.
video.automation.create · scope video:render · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
areaId (required) | string | One of your areas, from List market areas. |
templateId (required) | string | A market report template, from List video templates. |
videoProfileId (required) | string | The voice and avatar to use, from List video profiles. |
cadence (required) | "monthly" | "manual" | |
enableDistribution | boolean | Post each finished video to your connected social accounts. |
Pause an Automation
Changes dataPause an automation so it stops making videos until you resume it. Only the person who set it up can pause it.
video.automation.pause · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
automationId (required) | string | The automation's id, from List automations. |
Resume an Automation
Changes dataResume 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.
video.automation.resume · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
automationId (required) | string | The automation's id, from List automations. |
Delete an Automation
Changes dataDeletesDelete an automation so it never runs again. Videos it already made are kept. Only the person who set it up can delete it.
video.automation.delete · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
automationId (required) | string | The automation's id, from List automations. |
Run an Automation Now
Changes dataSpends moneyMake 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.
video.automation.run_now · scope video:render · Any member
| Input | Type | Notes |
|---|---|---|
automationId (required) | string | The automation's id, from List automations. |
List Video Types
ReadsList 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.
video.content_type.list · scope video:read · Any member
List Videos
ReadsList 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.
video.job.list · scope video:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "queued" | "fetching_data" | "scripting" | "awaiting_recording" | "synthesizing_voice" | "rendering_avatar" | "composing" | "distributing" | "completed" | "failed" | "refunded" | |
limit | integer |
Get a Video
ReadsShow one video's status, its progress through each step, why it failed if it did, and the link to the finished video.
video.job.get · scope video:read · Any member
| Input | Type | Notes |
|---|---|---|
videoId (required) | string | The video's id, from List videos. |
Make a New Listing Video
Changes dataSpends moneyMake 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.
video.video.create_new_listing · scope video:render · Any member
| Input | Type | Notes |
|---|---|---|
propertyAddress (required) | string | |
listingPriceUsd (required) | integer | |
beds (required) | integer | |
baths (required) | number | |
sqft (required) | integer | |
photoUrls (required) | string[] | Public https links to the listing photos, in order. |
mlsId | string | The listing's MLS number, if any. |
videoProfileId (required) | string | The voice and avatar to use, from List video profiles. |
Make a Just-Sold Video
Changes dataSpends moneyMake 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.
video.video.create_transaction_closed · scope video:render · Any member
| Input | Type | Notes |
|---|---|---|
propertyAddress (required) | string | |
soldPriceUsd (required) | integer | |
listedPriceUsd | integer | |
daysOnMarket | integer | |
buyerName | string | Only if the buyer agreed to be named. |
sellerName | string | Only if the seller agreed to be named. |
beds | integer | |
baths | number | |
sqft | integer | |
photoUrls | string[] | Public https links to photos of the home. |
videoProfileId (required) | string | The voice and avatar to use, from List video profiles. |
Make a Video
Changes dataSpends moneyMake 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.
video.video.create · scope video:render · Any member
| Input | Type | Notes |
|---|---|---|
contentTypeKey (required) | string | The kind of video, from List video types. |
videoProfileId (required) | string | The voice and avatar to use, from List video profiles. |
subject (required) | object | The details this kind of video needs, as listed by List video types. |
List Video Connections
ReadsShow 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.
video.connection.list · scope video:read · Any member
Connect ElevenLabs
Changes dataConnect 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.
video.connection.connect_elevenlabs · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
apiKey (required) | string | The API key from your account with that vendor. |
Connect HeyGen
Changes dataConnect 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.
video.connection.connect_heygen · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
apiKey (required) | string | The API key from your account with that vendor. |
Connect Metricool
Changes dataConnect 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.
video.connection.connect_metricool · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
apiKey (required) | string | The API key from your account with that vendor. |
userId | string | Your Metricool user id, if your account has more than one. |
Disconnect a Video Vendor Account
Changes dataDeletesDisconnect 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.
video.connection.disconnect · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
vendor (required) | "elevenlabs" | "heygen" | "metricool" |
Ask for Concierge Setup
Changes dataEmails other peopleAsk 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.
video.concierge.request · scope video:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | Your name. |
email (required) | string | Where our team should reply. |
topic (required) | "voice_clone" | "avatar" | "social_publishing" | "other" | |
message (required) | string | What you'd like set up (at least 10 characters). |
List Concierge Requests (Staff)
ReadsFor platform staff: list customers' concierge requests for voice clones, custom avatars and social publishing, newest first. Open requests by default.
video.concierge.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
status | "open" | "closed" | "all" |
Mark a Concierge Request Fulfilled (Staff)
Changes dataEmails other peopleFor 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.
video.concierge.fulfill · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The request's id, from List concierge requests. |
agentId (required) | string | The customer's user id (agent_id on the request). |
kind (required) | "voice" | "avatar" | |
vendor (required) | "elevenlabs" | "heygen" | |
externalId (required) | string | The voice or avatar id on our ElevenLabs or HeyGen account. |
name (required) | string | What the customer will see it called. |
tier | string | |
previewUrl | string | |
scope (required) | string | "personal" for the customer alone, or an organization id to share it with that organization. |
autoCreateProfile (required) | boolean | Also create a starter video profile that uses it. |
content
List Articles
ReadsList 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.
content.article.list · scope content:read · Any member
| Input | Type | Notes |
|---|---|---|
limit | integer | |
offset | integer | |
status | "queued" | "fetched" | "failed" | "skipped" | fetched = ready to use (the default). |
Read an Article
ReadsShow one article from your content library in full, with its title, summary, body text and original link.
content.article.get · scope content:read · Any member
| Input | Type | Notes |
|---|---|---|
articleId (required) | string | The article's id, from List articles. |
Get Your Marketing Profile
ReadsShow 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.
content.profile.get · scope content:read · Any member
Update Your Marketing Profile
Changes dataChange 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.
content.profile.update · scope content:write · Any member
| Input | Type | Notes |
|---|---|---|
brokerage | any | |
license_number | any | |
service_area | any | Where you work, like Austin and Round Rock, TX. |
specialties | string[] | |
logo_url | any | A public link to your logo image. |
headshot_url | any | A public link to your headshot. |
brand_colors | string[] | Like #1a73e8. |
voice_clone_id | any | The id of your cloned voice, if you have one. |
cta_phone | any | |
cta_website | any | |
cta_calendar_url | any | Where people book time with you. |
cta_keyword | any | The word people comment or text to get your lead magnet. |
cta_lead_magnet | any | What you offer in exchange, like a free home valuation. |
List an Article's Scripts (Staff)
ReadsFor 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.
content.script.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
articleId (required) | string | The article's id. |
Generate a Script (Staff)
Changes dataSpends moneyFor 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.
content.script.generate · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
articleId (required) | string | The article's id, from List articles. |
format (required) | "video_youtube_long" | "video_tiktok_short" | "video_reels_short" | "text_rewrite" | "text_summary" | |
force | boolean | Write a new one even if this format already has a script (spends tokens again). |
Send a Script to Video (Staff)
Changes dataFor 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.
content.script.send_to_video · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
transformationId (required) | string | The script's id, from List an article's scripts. |
Send a post to a website (staff)
Changes dataFor 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.
content.script.send_to_website · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
transformationId (required) | string | The script's id, from List an article's scripts. |
siteId (required) | string | The website's id in Websites. |
slug | string | The post's web address ending. Websites may adjust it. |
heroImageUrl | string | |
tags | string[] | |
publish | boolean | Publish right away instead of saving a draft. |
core
Get Your Account
ReadsShow your sign-in email and your personal brand: the name, headshot and voice notes used on things made for you.
core.account.get · scope core:read · Any member
Change Your Sign-In Email
Changes dataEmails other peopleStart 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.
core.account.request_email_change · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
newEmail (required) | string | The new email address to sign in with. |
Delete Your Account
Changes dataDeletesDelete 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.
core.account.delete · scope core:write · Any member
Save Your Personal Brand
Changes dataChange 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.
core.account.save_brand · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
agentName | any | Your name as shown on your materials. Send an empty value to clear it. |
headshotUrl | any | A web address of your headshot image. Send null to clear it. |
agentVoiceNotes | any | Notes on how you like to sound. Send an empty value to clear it. |
List Your API Tokens
ReadsList 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.
core.token.list · scope core:read · Any member
Create an API Token
Changes dataCreate 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.
core.token.create · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | A name to recognize the token by later. |
scopes (required) | string[] | What the token may do, like wallet:read or orgs:write. |
dailyTokenCap | any | Most tokens this key may spend in a day. |
monthlyTokenCap | any | Most tokens this key may spend in a month. |
expiresAt | any | When the token stops working (ISO 8601). Leave out for no expiry. |
Revoke an API Token
Changes dataDeletesRevoke one of your API tokens. Anything still using it stops working at once. This can't be undone; create a new token instead.
core.token.revoke · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
tokenId (required) | string | The token's id, from List your API tokens. |
List Your Organizations
ReadsList 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.
core.organization.list · scope orgs:read · Any member
Get the Active Organization
ReadsShow the active organization's name, its brand (business name, website, logos, colors, fonts, voice) and your role in it.
core.organization.get · scope orgs:read · Any member
Create an Organization
Changes dataCreate 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.
core.organization.create · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | The business or workspace name. |
Rename the Organization
Changes dataGive the active organization a new name. Owners only.
core.organization.rename · scope orgs:write · Organization owners
| Input | Type | Notes |
|---|---|---|
name (required) | string |
Delete the Organization
Changes dataDeletesDelete (archive) the active organization. Owners only. Refused while it has an active subscription, or if it is your only organization. Support can restore it.
core.organization.archive · scope orgs:write · Organization owners
Switch the Active Organization
Changes dataMake another of your organizations the active one, in every product. Everything after this applies to that organization.
core.organization.switch · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
orgId (required) | string | The organization's id, from List your organizations. |
Save the Organization's Brand
Changes dataChange 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.
core.organization.save_brand · scope orgs:write · Organization owners
| Input | Type | Notes |
|---|---|---|
businessName | any | The business name shown on materials. Send an empty value to clear it. |
brokerage | any | The display name, when it differs from the business name. Send an empty value to clear it. |
website | any | The business website. Send null to clear it. |
logoUrl | any | Web address of the logo image. Send null to clear it. |
darkLogoUrl | any | Web address of a logo for dark backgrounds. Send null to clear it. |
faviconUrl | any | Web address of the small browser-tab icon. Send null to clear it. |
primaryColor | any | The main brand color, as a hex color like #1A73E8. Send null to clear it. |
secondaryColor | any | The second brand color, as a hex color like #1A73E8. Send null to clear it. |
fontHeading | any | Font for headings. Send an empty value to clear it. |
fontBody | any | Font for body text. Send an empty value to clear it. |
voiceGuidelines | any | How the business sounds in writing. Send an empty value to clear it. |
List the Organization's Members
ReadsList the people with a role in the active organization (owner, admin or member), with their user ids and email addresses.
core.organization.list_members · scope orgs:read · Any member
| Input | Type | Notes |
|---|---|---|
email | string | Only the person with exactly this email address. Use it to find someone when addresses are shown masked. |
Make Someone an Owner
Changes dataMake an existing member of the active organization an owner. Owners can rename or delete it, manage billing and change other owners. Owners only.
core.organization.promote_owner · scope orgs:write · Organization owners
| Input | Type | Notes |
|---|---|---|
userId (required) | string | The person's user id, from List members or List teams. |
Remove Someone's Owner Role
Changes dataChange an owner of the active organization back to an admin. The last remaining owner can't be changed. Owners only.
core.organization.demote_owner · scope orgs:write · Organization owners
| Input | Type | Notes |
|---|---|---|
userId (required) | string | The person's user id, from List members or List teams. |
List Teams
ReadsList the active organization's teams, each with its members, their user ids, email addresses and team roles.
core.team.list · scope orgs:read · Any member
List Pending Invitations
ReadsList invitations to the active organization's teams that haven't been accepted yet, with who was invited, to which team and when each expires.
core.team.list_invitations · scope orgs:read · Any member
| Input | Type | Notes |
|---|---|---|
email | string | Only the person with exactly this email address. Use it to find someone when addresses are shown masked. |
Create a Team
Changes dataCreate a team in the active organization, with you as its owner. Organization owners only.
core.team.create · scope orgs:write · Organization owners
| Input | Type | Notes |
|---|---|---|
name (required) | string |
Invite Someone to a Team
Changes dataEmails other peopleInvite 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.
core.team.invite · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
teamId (required) | string | The team's id, from List teams. |
email (required) | string | The email address to invite. |
role | "member" | "owner" | Their role on the team. A team owner can invite others and edit the team's brand. |
Resend an Invitation
Changes dataEmails other peopleEmail a pending team invitation again, with the same link and a fresh 14-day expiry. Organization owners and the team's owners only.
core.team.resend_invite · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
invitationId (required) | string | The invitation's id, from List pending invitations. |
Save a Team's Brand
Changes dataChange 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.
core.team.save_brand · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
businessName | any | The business name shown on materials. Send an empty value to clear it. |
brokerage | any | The display name, when it differs from the business name. Send an empty value to clear it. |
website | any | The business website. Send null to clear it. |
logoUrl | any | Web address of the logo image. Send null to clear it. |
darkLogoUrl | any | Web address of a logo for dark backgrounds. Send null to clear it. |
faviconUrl | any | Web address of the small browser-tab icon. Send null to clear it. |
primaryColor | any | The main brand color, as a hex color like #1A73E8. Send null to clear it. |
secondaryColor | any | The second brand color, as a hex color like #1A73E8. Send null to clear it. |
fontHeading | any | Font for headings. Send an empty value to clear it. |
fontBody | any | Font for body text. Send an empty value to clear it. |
voiceGuidelines | any | How the business sounds in writing. Send an empty value to clear it. |
teamId (required) | string | The team's id, from List teams. |
Remove Someone from a Team
Changes dataDeletesTake a person off one of the active organization's teams. Organization owners and the team's owners can remove anyone; anyone can remove themselves.
core.team.remove_member · scope orgs:write · Any member
| Input | Type | Notes |
|---|---|---|
teamId (required) | string | The team's id, from List teams. |
userId (required) | string | The person's user id, from List members or List teams. |
List Webhooks
ReadsList the addresses the active organization sends event notifications to, the events each receives and whether it is on.
core.webhook.list · scope webhooks:read · Any member
Add a Webhook
Changes dataSend 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.
core.webhook.add · scope webhooks:write · Any member
| Input | Type | Notes |
|---|---|---|
url (required) | string | A full https:// address on the public internet. |
events (required) | string[] | Which events to send. |
Remove a Webhook
Changes dataDeletesStop sending events to one of the active organization's webhook addresses. Owners and admins only.
core.webhook.remove · scope webhooks:write · Any member
| Input | Type | Notes |
|---|---|---|
id (required) | string | The webhook's id, from List webhooks. |
Send a Test Event
Changes dataSend a signed test event to one of the active organization's webhooks and report what it answered. Owners and admins only.
core.webhook.test · scope webhooks:write · Any member
| Input | Type | Notes |
|---|---|---|
id (required) | string | The webhook's id, from List webhooks. |
Get the Token Balance
ReadsShow the active organization's token balance: tokens from the plan, purchased tokens, and tokens held for work in progress.
core.billing.get_balance · scope wallet:read · Any member
List Token History
ReadsList the active organization's token history, newest first: purchases, plan grants, spending and refunds.
core.billing.list_ledger · scope wallet:read · Any member
| Input | Type | Notes |
|---|---|---|
limit | integer | How many entries to return. |
Get the Plan and Subscriptions
ReadsShow the active organization's plan, its subscription status and billing period, and its recurring bundles.
core.billing.get_plan · scope wallet:read · Any member
List What Can Be Bought
ReadsList the token packs, plans and bundles the active organization can buy, at the prices it would pay, and whether online checkout is available.
core.billing.list_options · scope wallet:read · Any member
Buy a Token Pack
Changes dataSpends moneyStart 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.
core.billing.buy_tokens · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
packKey (required) | string | The pack's key, from List what can be bought. |
Buy a Custom Number of Tokens
Changes dataSpends moneyStart 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.
core.billing.buy_custom_tokens · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
tokens (required) | integer | How many tokens to buy. |
Subscribe to a Bundle
Changes dataSpends moneyStart 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.
core.billing.buy_bundle · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
bundleKey (required) | string | The bundle's key, from List what can be bought. |
siteId | string | The website the bundle is for, when it covers one site. |
siteUrl | string | That website's address. |
Cancel a Bundle Subscription
Changes dataSpends moneyDeletesCancel 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.
core.billing.cancel_bundle · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
orgBundleId (required) | string | The subscription's id, from Get the plan and subscriptions. |
Subscribe to a Plan
Changes dataSpends moneyStart 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.
core.billing.start_subscription · scope core:write · Any member
| Input | Type | Notes |
|---|---|---|
planKey (required) | string | The plan's key, from List what can be bought. |
List Assistant Escalations
ReadsList requests customers escalated from the assistant to a person, newest first: who asked, the summary, the reason and where each stands.
core.escalation.list · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
status | "open" | "acknowledged" | "resolved" | Only escalations in this state. |
limit | integer |
Acknowledge an Escalation
Changes dataMark an assistant escalation as being worked on, so other staff know someone has it.
core.escalation.acknowledge · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
id (required) | string | The escalation's id, from List escalations. |
Resolve an Escalation
Changes dataClose an assistant escalation, with an optional note on how it was resolved for other staff.
core.escalation.resolve · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
id (required) | string | The escalation's id, from List escalations. |
note | string | How it was resolved, for other staff. |
Reply to an Escalation by Email
Changes dataEmails other peopleEmail 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.
core.escalation.reply · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
id (required) | string | The escalation's id, from List escalations. |
message (required) | string | The reply, as plain text. |
mailings
List Mail Pieces
ReadsList the postcards, cards, gifts and kits a mail campaign can send, with the id to use when choosing what goes out in a month.
mailings.piece.list · scope mailings:read · Any member
List Campaign Templates
ReadsList the ready-made yearly mail programs a campaign can start from, with what each one sends in each month.
mailings.template.list · scope mailings:read · Any member
List Mail Campaigns
ReadsList this organization's mail campaigns, newest first, with each one's status (draft, active, paused or canceled).
mailings.campaign.list · scope mailings:read · Any member
Get a Mail Campaign
ReadsShow one mail campaign: its status, what it sends in each month with the message printed on it, and which recipients are enrolled.
mailings.campaign.get · scope mailings:read · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
List Upcoming Mailings
ReadsList what your active campaigns will mail over the next months: which piece goes out, in which month, to how many recipients.
mailings.order.list · scope mailings:read · Any member
| Input | Type | Notes |
|---|---|---|
months | integer | How many months ahead to look; 6 if left out. |
Start a Mail Campaign
Changes dataCreate 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.
mailings.campaign.start · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
templateId | string | The template to copy, from List campaign templates. Leave out for a blank campaign. |
Set a Month's Mailing
Changes dataChoose 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.
mailings.campaign.set_month · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
month (required) | integer | 1 for January through 12 for December. |
pieceId (required) | any | The piece to mail that month, from List mail pieces; null for no mailing that month. |
message | any | The message printed on the piece. Leave out to keep the current one. |
Activate a Mail Campaign
Changes dataSpends moneyTurn 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.
mailings.campaign.activate · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
Pause a Mail Campaign
Changes dataPause a campaign so nothing more is mailed until it is activated again. Its schedule and recipients are kept.
mailings.campaign.pause · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
Cancel a Mail Campaign
Changes dataDeletesCancel a campaign for good: no more mail goes out from it. Use pause instead to stop it for a while.
mailings.campaign.cancel · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
Set a Campaign's Recipients
Changes dataReplace 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.
mailings.campaign.set_recipients · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List mail campaigns. |
recipientIds (required) | string[] | Every recipient who should get this campaign's mail, from List recipients. |
List Recipients
ReadsList 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.
mailings.recipient.list · scope mailings:read · Any member
| Input | Type | Notes |
|---|---|---|
search | string | Part of a name, street, city or ZIP code. |
name | string | Find people by their exact full name. |
page | integer |
Add a Recipient
Changes dataAdd a person and their mailing address to this organization's mailing list, so campaigns can mail to them.
mailings.recipient.add · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
address1 (required) | string | Street address. |
address2 | any | Apartment, suite or unit. |
city (required) | string | |
state (required) | string | |
postalCode (required) | string | ZIP code. |
Remove a Recipient
Changes dataDeletesRemove a person from this organization's mailing list.
mailings.recipient.remove · scope mailings:write · Any member
| Input | Type | Notes |
|---|---|---|
recipientId (required) | string | The person's id, from List recipients. |
List This Month's Mailing Runs
ReadsStaff 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.
mailings.run.list · scope operations:read · Platform staff
Mark a Mailing Run Sent
Changes dataStaff 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.
mailings.run.mark_sent · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
campaignId (required) | string | The campaign's id, from List this month's mailing runs. |
year (required) | integer | |
month (required) | integer | |
pieceId (required) | string | The piece that was ordered, from List this month's mailing runs. |
vendorOrderRef | string | The order number, for staff records only. |
compliance
List Websites
ReadsList this organization's websites with how often each is scanned for accessibility, its latest accessibility score and whether the accessibility widget is installed.
compliance.website.list · scope compliance:read · Any member
Get a Website
ReadsShow 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.
compliance.website.get · scope compliance:read · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from List websites. |
Add a Website
Changes dataAdd 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.
compliance.website.add · scope compliance:write · Any member
| Input | Type | Notes |
|---|---|---|
url (required) | string | The website's address, like https://example.com. |
label | string | A short name to show instead of the address. |
origin | "lovable" | "skeleton" | "third-party" | "custom" | "unknown" | How the site was built: lovable, skeleton (built by us), third-party (WordPress, Wix and the like), custom, or unknown. |
platform | string | For a third-party site, which platform, like wordpress or wix. |
Set Accessibility Scan Schedule
Changes dataSpends moneyChoose how often a website is scanned for accessibility problems: weekly, monthly or off. Each scheduled scan costs tokens unless the Accessibility bundle covers it.
compliance.website.set_cadence · scope compliance:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from List websites. |
cadence (required) | "off" | "weekly" | "monthly" |
Change the Accessibility Widget
Changes dataChange how the accessibility widget looks on a website: which corner it sits in and its colors. Only the fields you send change.
compliance.widget.update · scope compliance:write · Any member
| Input | Type | Notes |
|---|---|---|
siteId (required) | string | The website's id, from List websites. |
position | "bottom-right" | "bottom-left" | |
primary | string | The button's main color, as hex. |
accent | string | The highlight color, as hex. |
List Legal Packages
ReadsList 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.
compliance.package.list · scope compliance:read · Any member
Get a Legal Template's Questions
ReadsShow 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.
compliance.template.get · scope compliance:read · Any member
| Input | Type | Notes |
|---|---|---|
templateId (required) | string | The template's id, from List legal packages. |
List Legal Documents
ReadsList the legal documents this organization has generated, latest version of each, newest first.
compliance.document.list · scope compliance:read · Any member
Get a Legal Document
ReadsShow one generated legal document's full text (Markdown, ready to paste into a website) and the answers it was made from.
compliance.document.get · scope compliance:read · Any member
| Input | Type | Notes |
|---|---|---|
documentId (required) | string | The document's id, from List legal documents. |
Buy a Legal Package
Changes dataSpends moneyBuy a legal document package for this organization, paid in tokens from the wallet. Buying one the organization already owns costs nothing and changes nothing.
compliance.package.buy · scope compliance:write · Any member
| Input | Type | Notes |
|---|---|---|
packageId (required) | string | The package's id, from List legal packages. |
Generate a Legal Document
Changes dataFill 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.
compliance.document.generate · scope compliance:write · Any member
| Input | Type | Notes |
|---|---|---|
templateId (required) | string | The template's id, from List legal packages. |
siteId | string | The website this document is for, from List websites. Leave out for one that covers the whole organization. |
answers (required) | object | Answers keyed by each question's key, from Get a legal template's questions. Yes/no questions take true or false. |
prospects
List Prospect Sources
ReadsList 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.
prospects.source.list · scope prospects:read · Any member
Search Prospects
ReadsSearch 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.
prospects.people.search · scope prospects:read · Any member
| Input | Type | Notes |
|---|---|---|
source (required) | "mls" | "npi" | Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use. |
filters | object | Search filters by name, from List sources (each source lists its own filters, like state, city or specialty). |
page | integer |
Price a Prospect Download
ReadsBefore 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.
prospects.download.preview · scope prospects:read · Any member
| Input | Type | Notes |
|---|---|---|
source (required) | "mls" | "npi" | Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use. |
filters | object | Search filters by name, from List sources (each source lists its own filters, like state, city or specialty). |
count (required) | integer | How many people you'd like to download. |
Download Prospects
Changes dataSpends moneyBuy 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.
prospects.download.start · scope prospects:write · Any member
| Input | Type | Notes |
|---|---|---|
source (required) | "mls" | "npi" | Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use. |
filters | object | Search filters by name, from List sources (each source lists its own filters, like state, city or specialty). |
count (required) | integer | How many people to download, at most. |
tag | string | An extra tag to put on everyone downloaded. |
List Prospect Downloads
ReadsList this organization's past downloads, newest first, with how many people each saved and what it cost.
prospects.download.list · scope prospects:read · Any member
| Input | Type | Notes |
|---|---|---|
limit | integer |
Get a Prospect Download
ReadsShow one download: its search, how many people were asked for, saved and skipped, its status and what it cost.
prospects.download.get · scope prospects:read · Any member
| Input | Type | Notes |
|---|---|---|
downloadId (required) | string | The download's id, from List prospect downloads. |
List Purchased Prospects
ReadsList 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.
prospects.purchase.list · scope prospects:read · Any member
| Input | Type | Notes |
|---|---|---|
source | "mls" | "npi" | Which database: mls (real estate agents) or npi (healthcare providers). List sources shows which ones you can use. |
downloadId | string | Only the people from one download. |
email | string | Find one person by their exact email address. |
limit | integer | |
offset | integer |
Price of Finding Emails and Phones
ReadsShow how many tokens one found email or one found phone number costs. Lookups that find nothing are free.
prospects.contact.enrich_cost · scope prospects:read · Any member
Find Missing Emails and Phones
Changes dataSpends moneyLook 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.
prospects.contact.enrich · scope prospects:write · Any member
| Input | Type | Notes |
|---|---|---|
contactIds (required) | string[] | The people to look up, by contact id, from List purchased prospects. |
fields | string[] | Which to look for; both when left out. |
List Partner Prospect Sources
ReadsStaff only: every partner, whether Prospects is turned on for it, and which contact databases its clients may search, limited to which regions.
prospects.partner_source.list · scope operations:read · Platform staff
Set a Partner's Prospect Source
Changes dataStaff 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.
prospects.partner_source.save · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
partnerId (required) | string | The partner's id, from List partner prospect sources. |
source (required) | "mls" | "npi" | mls (real estate agents) or npi (healthcare providers). |
enabled (required) | boolean | |
regions | string[] | Where its clients may search; everywhere when empty or left out. |
List Lookup Providers
ReadsStaff only: the services used, in order, to find missing emails and phones, and whether each one is on.
prospects.provider.list · scope operations:read · Platform staff
Set a Lookup Provider
Changes dataStaff only: turn a lookup service on or off and set its place in the order (lower goes first). Logged to the staff audit.
prospects.provider.save · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
key (required) | string | The provider's key, from List lookup providers. |
position (required) | integer | |
enabled (required) | boolean |
photos
List photo projects
ReadsList this organization's photo projects (one per listing), newest first, with whether each has been sent to the editors.
photos.project.list · scope photos:read · Any member
Get a photo project
ReadsShow 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.
photos.project.get · scope photos:read · Any member
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List photo projects. |
Create a photo project
Changes dataStart a new photo project for a listing. Photos are added on the project page.
photos.project.create · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | A name for the project, like the listing's street address. |
address | string | The property's address. |
Update a photo project
Changes dataChange a project's name, address or notes for the editors. Only the fields you send change.
photos.project.update · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List photo projects. |
name | string | |
address | string | Send an empty string to clear it. |
notes | string | Instructions for the editors. Send an empty string to clear them. |
Delete a photo project
Changes dataDeletesDelete a photo project and hide its photos. Tokens held for edits that were not delivered are refunded.
photos.project.delete · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List photo projects. |
Send a project to the editors
Changes dataSpends moneySend 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.
photos.project.submit · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List photo projects. |
Ask for one edit on many photos
Changes dataAsk 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.
photos.project.bulk_tag · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List photo projects. |
photoIds (required) | string[] | The photos' ids, from Get a photo project. |
edit (required) | "declutter" | "virtual_staging" | "sky_replace" | "twilight" | declutter, virtual_staging, sky_replace or twilight. |
Remove a photo
Changes dataDeletesRemove one photo from its project.
photos.upload.delete · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
photoId (required) | string | The photo's id, from Get a photo project. |
Ask for an edit on a photo
Changes dataAsk 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.
photos.request.add · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
photoId (required) | string | The photo's id, from Get a photo project. |
edit (required) | "declutter" | "virtual_staging" | "sky_replace" | "twilight" | declutter, virtual_staging, sky_replace or twilight. |
Remove an edit from a photo
Changes dataTake back an edit you asked for on a photo, before its project is sent to the editors.
photos.request.remove · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a photo project. |
Accept a finished edit
Changes dataSpends moneyAccept a photo the editors delivered. The tokens set aside for that edit are spent. This can't be undone.
photos.request.accept · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a photo project. |
Send a finished edit back
Changes dataSend a delivered photo back to the editors with what to fix. Nothing is charged; they deliver it again.
photos.request.reject · scope photos:write · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a photo project. |
reason (required) | string | What the editors should change. |
Get an edit's history
ReadsShow what happened to one edit request, newest first: each delivery, acceptance, send-back with its reason, and reopening.
photos.request.history · scope photos:read · Any member
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a photo project. |
List the editing queue
ReadsStaff only: every submitted project, from every customer, that still has edits waiting or sent back, oldest first, with how many are open.
photos.queue.list · scope operations:read · Platform staff
Get a project to edit
ReadsStaff 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.
photos.queue.get_project · scope operations:read · Platform staff
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List the editing queue. |
Claim an edit
Changes dataStaff only: take an edit request so no other editor works on it. Fails if someone already has it. Logged to the staff audit.
photos.queue.claim · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a project to edit. |
Release a claimed edit
Changes dataStaff 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.
photos.queue.release · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a project to edit. |
Deliver a finished edit
Changes dataEmails other peopleStaff 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.
photos.queue.deliver · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
requestId (required) | string | The edit request's id, from Get a project to edit. |
fileUrl (required) | string | A public https address of the finished photo. |
Reopen a submitted project
Changes dataDeletesPhotos 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.
photos.project.reopen · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
projectId (required) | string | The project's id, from List the editing queue. |
Get standard photo prices
ReadsPhotos 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.
photos.default_pricing.get · scope operations:read · Platform staff
Change standard photo prices
Changes dataPhotos 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.
photos.default_pricing.update · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
baseTokenCost | integer | The per-project base fee, in tokens. |
edits | object[] | New prices per edit type, in tokens. |
Get your partner's photo prices
ReadsPartner 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.
photos.partner_pricing.get · scope photos:read · Partner admins
Set your partner's photo prices
Changes dataPartner 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.
photos.partner_pricing.update · scope photos:write · Partner admins
| Input | Type | Notes |
|---|---|---|
baseTokenCost | any | Your per-project base fee, or null for the standard one. |
edits | object[] | Your price per edit type, or null for the standard one. |
recruiting
Search Agents
ReadsSearch 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.
recruiting.agent.search · scope recruiting:read · Any member
| Input | Type | Notes |
|---|---|---|
q | string | Part of an agent's name. |
state | string | Two-letter US state code, such as TX. |
city | string | |
zip | string | |
centerLat | number | With centerLng and radiusMiles: search around a point. |
centerLng | number | |
radiusMiles | number | |
officeInclude | string[] | Only agents at these brokerages. |
officeExclude | string[] | Leave out agents at these brokerages. |
totalUnitsMin | number | Fewest total homes sold (all time). |
totalUnitsMax | number | |
totalVolumeMin | number | Lowest total sales volume in dollars (all time). |
totalVolumeMax | number | |
listingPctMin | number | Lowest share of sales on the listing side, in percent. |
listingPctMax | number | |
limit | integer | |
offset | integer |
Unlock an Agent's Contact Details
Changes dataSpends moneyReveal an agent's email, phones and address for your whole organization. Costs 10 tokens once; free if already unlocked or bought in Prospects.
recruiting.agent.unlock · scope recruiting:unlock · Any member
| Input | Type | Notes |
|---|---|---|
mlsId (required) | string | The agent's MLS id, from Search agents. |
Show an Unlocked Agent's Contact Details
ReadsShow the email, phones and address of an agent your organization already unlocked. Free.
recruiting.agent.contact · scope recruiting:read · Any member
| Input | Type | Notes |
|---|---|---|
mlsId (required) | string | The agent's MLS id, from Search agents. |
List Unlocked Agents
ReadsList 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.
recruiting.agent.unlocked · scope recruiting:export · Any member
| Input | Type | Notes |
|---|---|---|
listId | string | Only this list's agents, from List agent lists. |
page | integer |
List Agent Lists
ReadsList your organization's agent lists, most recently changed first, with how many agents are on each.
recruiting.list.list · scope recruiting:read · Any member
Get an Agent List
ReadsShow one agent list and its most recent 200 agents, with your notes and tags for each.
recruiting.list.get · scope recruiting:read · Any member
| Input | Type | Notes |
|---|---|---|
listId (required) | string | The list's id, from List agent lists. |
Create an Agent List
Changes dataCreate a named list to collect unlocked agents in, such as top producers to call this month.
recruiting.list.create · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
description | any |
Rename an Agent List
Changes dataChange an agent list's name or description. Only the fields you send change.
recruiting.list.update · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
listId (required) | string | The list's id, from List agent lists. |
name | string | |
description | any |
Delete an Agent List
Changes dataDeletesDelete an agent list. The agents on it stay unlocked; support can restore the list.
recruiting.list.delete · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
listId (required) | string | The list's id, from List agent lists. |
Add Agents to a List
Changes dataAdd 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.
recruiting.list.add_agents · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
listId (required) | string | The list's id, from List agent lists. |
mlsIds (required) | string[] | Agents' MLS ids. |
notes | any | |
tags | string[] |
Remove Agents from a List
Changes dataDeletesTake agents off a list. They stay unlocked and on your other lists.
recruiting.list.remove_agents · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
listId (required) | string | The list's id, from List agent lists. |
mlsIds (required) | string[] | Agents' MLS ids. |
List Saved Searches
ReadsList your organization's saved agent searches, most recently changed first, with their filters.
recruiting.saved_search.list · scope recruiting:read · Any member
Save a Search
Changes dataSave a set of agent search filters under a name so it can be run again later.
recruiting.saved_search.create · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string | |
filters (required) | object |
Update a Saved Search
Changes dataRename a saved search or replace its filters. Only the fields you send change.
recruiting.saved_search.update · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
savedSearchId (required) | string | The saved search's id, from List saved searches. |
name | string | |
filters | object |
Delete a Saved Search
Changes dataDeletesDelete a saved search. Support can restore it if needed.
recruiting.saved_search.delete · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
savedSearchId (required) | string | The saved search's id, from List saved searches. |
List Pipelines
ReadsList your recruiting pipelines (boards that track agents from first contact to hire), newest first, with how many agents are in each.
recruiting.pipeline.list · scope recruiting:read · Any member
Get a Pipeline
ReadsShow one recruiting pipeline with its stages in order and the agents in it, with each one's stage, notes and tags.
recruiting.pipeline.get · scope recruiting:read · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
Create a Pipeline
Changes dataCreate a recruiting pipeline. It starts with six stages: sourced, contacted, interviewing, offer, hired and lost.
recruiting.pipeline.create · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
name (required) | string |
Rename a Pipeline
Changes dataGive a recruiting pipeline a new name.
recruiting.pipeline.rename · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
name (required) | string |
Delete a Pipeline
Changes dataDeletesDelete a recruiting pipeline and its board. The agents in it stay unlocked.
recruiting.pipeline.delete · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
Add a Pipeline Stage
Changes dataAdd a custom stage to a pipeline, such as a second interview. By default it goes at the end.
recruiting.pipeline.add_stage · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
label (required) | string | |
kind | "sourced" | "contacted" | "interviewing" | "offer" | "hired" | "lost" | Which default stage it is like, for grouping and color. Defaults to sourced. |
sortOrder | integer | Position on the board; lower numbers come first. |
Add an Agent to a Pipeline
Changes dataSpends moneyPut 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.
recruiting.pipeline.add_agent · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
mlsId (required) | string | The agent's MLS id, from Search agents. |
stageId | string | The stage's id, from Get a pipeline. |
notes | any | |
tags | string[] |
Move or note an agent in a pipeline
Changes dataMove an agent to another stage, or change their notes, tags or the reason they were lost. Free. Only the fields you send change.
recruiting.pipeline.update_agent · scope recruiting:write · Any member
| Input | Type | Notes |
|---|---|---|
pipelineId (required) | string | The pipeline's id, from List pipelines. |
recruitId (required) | string | The agent's card id in this pipeline, from Get a pipeline. |
stageId | string | The stage's id, from Get a pipeline. |
notes | any | |
tags | string[] | |
lostReason | any |
leads
List Leads
ReadsList 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.
leads.lead.list · scope leads:read · Any member
Get a Lead
ReadsShow one lead your organization received: the person's details and request, ZIP, tier, billing status and any dispute.
leads.lead.get · scope leads:read · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | The lead's id, from List leads. |
Show Lead Coverage
ReadsShow your organization's lead plan (tier, price per lead, monthly cap, billing period) and the ZIP codes it covers.
leads.coverage.get · scope leads:read · Any member
Dispute a Lead
Changes dataAsk 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.
leads.dispute.file · scope leads:write · Any member
| Input | Type | Notes |
|---|---|---|
leadId (required) | string | The lead's id, from List leads. |
reason (required) | "bad_contact_info" | "wrong_zip" | "duplicate" | "spam" | "other" | |
detail | string | What's wrong, in a sentence or two. |
List Disputes
ReadsList disputes on your organization's leads, newest first, with their reason and whether they're pending, approved or rejected.
leads.dispute.list · scope leads:read · Any member
| Input | Type | Notes |
|---|---|---|
status | "pending" | "approved" | "rejected" | "auto_refunded" |
Get a Dispute
ReadsShow one lead dispute: the reason, when it was filed, and the decision and note once it's resolved.
leads.dispute.get · scope leads:read · Any member
| Input | Type | Notes |
|---|---|---|
disputeId (required) | string | The dispute's id, from List disputes. |
List Disputes Waiting for Review
ReadsStaff 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.
leads.dispute.queue · scope operations:read · Platform staff
Approve or Reject a Lead Dispute
Changes dataSpends moneyStaff 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.
leads.dispute.resolve · scope operations:write · Platform staff
| Input | Type | Notes |
|---|---|---|
disputeId (required) | string | The dispute's id, from List disputes. |
decision (required) | "approved" | "rejected" | |
note | string | Why, for the audit trail. |