API reference
Paths are relative to https://lemon.domains/api/v1. Send Authorization: Bearer YOUR_TOKEN on every request. Each endpoint runs the MCP tool named beside it, so the tool reference describes the same behaviour.
Account
Who the token belongs to.
GET/meThe account and token making the request. Handy for checking a token works.
No parameters.
Workspaces
A workspace holds projects, registrars and domains, shared with the people its Owners invite. Roles: Owner, Editor, Viewer.
GET/workspaceslist_workspacesThe workspaces you belong to, with your role and access in each.
No parameters.
Domains
Every domain belongs to a project and a registrar account.
GET/domainslist_domainsList domains, with filters and paging.
projectIdqueryuuidoptionalregistrarAccountIdqueryuuidoptionalstatusquery"Active" | "Expired" | "Transferred" | "Unknown"optional· Older filter, worked out from the expiry date: Active (today or later), Expired (past), Unknown (no date). "Transferred" returns archived domains. Prefer displayStatus.displayStatusquery"Active" | "Expiring soon" | "Expired" | "Unknown" | "Not at registrar" | "Archived"optional· Status as the app shows it. "Archived" returns archived domains; other values leave them out.archivedquery"exclude" | "include" | "only"optionaldefault "exclude"· Archived domains: "exclude" (default) leaves them out, "include" adds them, "only" returns just them.searchquerystringoptional· Case-insensitive substring match against the domain name. % and _ match literally.expiringWithinDaysqueryintegeroptional· Only return domains expiring within this many days. Already-expired domains are excluded unless includeExpired is true; max 3650.includeExpiredquerybooleanoptionaldefault false· When expiringWithinDays is set, also include domains whose expiry date is already in the past.workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.timezonequerystringoptional· IANA time zone used to decide what 'today' is, e.g. Australia/Sydney. Defaults to your account time zone, else UTC; max 64 characters.fieldsquery"summary" | "full"optionaldefault "summary"· summary (default) returns lean rows; full adds notes, ids, dateLastChecked, and timestamps.limitqueryintegeroptionaldefault 25· Max rows to return (default 25, max 500).offsetqueryintegeroptionaldefault 0· Rows to skip, for pagination; max 9007199254740991.POST/domainsadd_domainAdd a domain to a project under a registrar account.
domainNamebodystringrequired· Max 253 characters.projectIdbodyuuidrequiredregistrarAccountIdbodyuuidrequiredstatusbody"Active" | "Expired" | "Transferred" | "Unknown"optional· Optional; worked out from expiryDate when left out. "Transferred" archives the domain.autoRenewbodybooleanoptionaldefault falseexpiryDatebodydate (YYYY-MM-DD) | nulloptionalnotesbodystringoptional· Free-text notes, max 2000 characters.archivedbodybooleanoptional· true archives the domain (no longer tracked, e.g. transferred to another company); false unarchives it.archivedNotebodystring | nulloptional· Why the domain was archived, max 500 characters. Kept only while archived.POST/domains/bulkbulk_add_domainsAdd up to 200 domains in one request. A bad entry never fails the batch.
domainsbodyarray of objectsrequired· Max 200 items.Each item in domains:
domainNamebodystringrequired· Max 253 characters.projectIdbodyuuidrequiredregistrarAccountIdbodyuuidrequiredstatusbody"Active" | "Expired" | "Transferred" | "Unknown"optionalautoRenewbodybooleanoptionalexpiryDatebodydate (YYYY-MM-DD) | nulloptionalnotesbodystringoptional· Max 2000 characters.archivedbodybooleanoptionalarchivedNotebodystring | nulloptionalGET/domains/lookuplookup_domainsLook domains up in the public registry: registrar, expiry, and whether each is already in your account. Pass ?domains=a.com,b.com.
domainsquerystring[]required· Max 25 items.POST/domains/quick-addquick_add_domainsAdd domains by registrar name. Projects and registrar accounts are found or created for you.
domainsbodyarray of objectsrequired· Max 1000 items.projectIdbodyuuidoptional· Defaults to your first project, created if you have none.workspaceIdbodyuuidoptional· Workspace id from list_workspaces. Defaults to the first workspace you own.Each item in domains:
domainNamebodystringrequired· Max 253 characters.registrarbodystringrequired· Registrar slug from lookup_domains (e.g. namecheap), or the registrar's name; max 200 characters.expiryDatebodydate (YYYY-MM-DD) | nulloptionalGET/domains/expiringdomains_expiring_soonDomains that expire within a number of days, soonest first.
withinDaysqueryintegeroptionaldefault 30· Max 3650.limitqueryintegeroptionaldefault 100· Max 500.includeExpiredquerybooleanoptionaldefault false· Also include domains whose expiry date is already in the past (overdue).workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.timezonequerystringoptional· IANA time zone used to decide what 'today' is, e.g. Australia/Sydney. Defaults to your account time zone, else UTC; max 64 characters.GET/domains/{domain}get_domainGet one domain by id or by its exact name, e.g. /domains/example.com.
domainpathuuid or domain namerequiredPATCH/domains/{id}update_domainUpdate a domain. Only the fields you send change.
idpathuuidrequireddomainNamebodystringoptional· Max 253 characters.statusbody"Active" | "Expired" | "Transferred" | "Unknown"optional· Optional; follows expiryDate when that changes. "Transferred" archives the domain.autoRenewbodybooleanoptionalexpiryDatebodydate (YYYY-MM-DD) | nulloptionalnotesbodystringoptional· Free-text notes, max 2000 characters. Empty string clears it.projectIdbodyuuidoptionalregistrarAccountIdbodyuuidoptionalarchivedbodybooleanoptional· true archives the domain (no longer tracked, e.g. transferred to another company); false unarchives it.archivedNotebodystring | nulloptional· Why the domain was archived, max 500 characters. Kept only while archived.DELETE/domains/{id}delete_domainDelete a domain. Owners only; Editors archive instead.
idpathuuidrequiredProjects
Group domains by client, brand or experiment, inside a workspace.
GET/projectslist_projectsList the projects you can see, with your role in each.
workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.POST/projectsadd_projectCreate a project in a workspace.
namebodystringrequired· Max 100 characters.descriptionbodystringoptional· Optional description, max 500 charactersworkspaceIdbodyuuidoptional· Workspace id from list_workspaces. Defaults to the first workspace you own.PATCH/projects/{id}update_projectRename a project or change its description.
idpathuuidrequirednamebodystringoptional· Max 100 characters.descriptionbodystringoptional· Optional description, max 500 charactersDELETE/projects/{id}delete_projectDelete a project and all its domains. Owner only. Add ?confirm=true to proceed.
idpathuuidrequiredconfirmquerybooleanoptionaldefault false· Set to true to delete. Without it nothing is deleted and you get a 409 confirmation_required error whose willDelete shows what would go.Registrars
Registrar platforms you use, such as Porkbun or Namecheap.
GET/registrarslist_registrarsList your registrars with their account counts.
workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.POST/registrarsadd_registrarAdd a registrar, such as Namecheap or Porkbun.
namebodystringrequired· Max 100 characters.urlbodystringoptional· Registrar website, e.g. namecheap.com; max 500 characters.workspaceIdbodyuuidoptional· Workspace id from list_workspaces. Defaults to the first workspace you own.PATCH/registrars/{id}update_registrarUpdate a registrar's name or URL.
idpathuuidrequirednamebodystringoptional· Max 100 characters.urlbodystringoptional· Registrar website, e.g. namecheap.com; max 500 characters.DELETE/registrars/{id}delete_registrarDelete a registrar with its accounts and their domains. Add ?confirm=true to proceed.
idpathuuidrequiredconfirmquerybooleanoptionaldefault false· Set to true to delete. Without it nothing is deleted and you get a 409 confirmation_required error whose willDelete shows what would go.Registrar accounts
Logins under a registrar. Registrar API credentials are set in the app, never through the API.
GET/registrar-accountslist_registrar_accountsList your registrar accounts, optionally for one registrar.
registrarIdqueryuuidoptionalworkspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.POST/registrar-accountsadd_registrar_accountAdd an account under one of your registrars.
registrarIdbodyuuidrequireddisplayNamebodystringrequired· Max 200 characters.accountUsernamebodystringrequired· Max 100 characters.contactEmailbodystringoptional· Contact email for the account; max 254 characters.domainListUrlbodystringoptional· URL of the registrar's domain-list page; max 1000 characters.PATCH/registrar-accounts/{id}update_registrar_accountUpdate a registrar account.
idpathuuidrequireddisplayNamebodystringoptional· Max 200 characters.accountUsernamebodystringoptional· Max 100 characters.contactEmailbodystring | string | nulloptional· Contact email for the account. Pass "" or null to clear it.domainListUrlbodystringoptional· URL of the registrar's domain-list page; max 1000 characters.isActivebodybooleanoptionalDELETE/registrar-accounts/{id}delete_registrar_accountDelete a registrar account and its domains. Add ?confirm=true to proceed.
idpathuuidrequiredconfirmquerybooleanoptionaldefault false· Set to true to delete. Without it nothing is deleted and you get a 409 confirmation_required error whose willDelete shows what would go.Sync
Results of registrar syncs.
GET/sync/logsrecent_sync_logsRecent registrar sync results across your accounts.
limitqueryintegeroptionaldefault 20· Max 100.registrarAccountIdqueryuuidoptionalMonitoring
Watch any domain, yours or not, and see what changed in its public records. Each workspace can watch up to 1,000 domains besides its own.
GET/monitoringlist_monitoredEvery monitored domain in a workspace, yours and watched, with its latest change.
workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.POST/monitoringmonitor_domainsStart watching domains you don't own, up to 1,000 per workspace.
domainsbodystring[]required· Domains to watch, e.g. example.com; max 1000 items.workspaceIdbodyuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.DELETE/monitoringstop_monitoringStop watching a domain. Pass ?domain=example.com.
domainquerystringrequired· The watched domain, e.g. example.com; max 253 characters.workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.GET/monitoring/changeslist_changesWhat changed on monitored domains, newest first, with filters for domain, kind and date.
domainquerystringoptional· Only this domain; max 253 characters.kindquery"registrar" | "transfer_lock" | "nameservers" | "expired" | "available" | "expiry" | "statuses" | "dnssec" | "email_provider" | "hosting" | "ssl" | "website" | "parked"optional· Only this kind of change.sincequerystringoptional· ISO date or time; only changes found after it; max 40 characters.limitqueryintegeroptionaldefault 100· Max changes to return (default 100, max 500).workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.Domain intelligence
Look up any domain on the internet. Each account gets 200 reports, 2,000 availability checks and 200 transfer checks a day.
GET/reportdomain_reportEverything about one domain: registration, locks, status codes, DNS, website, certificate, email, history, transfer readiness and issues. Pass ?domain=example.com.
domainquerystringrequired· A registered domain, e.g. example.com; max 253 characters.freshquerybooleanoptionaldefault false· true skips the 10-minute cache and looks everything up again.POST/availabilitycheck_availabilityWhether up to 50 names are free to register: full domains, or words combined with extensions: available, taken (with registrar and expiry), dropping soon or unknown.
domainsbodystring[]optional· Full domains to check, e.g. example.com; max 50 items.wordsbodystring[]optional· Names without an extension, combined with every entry in tlds; max 50 items.tldsbodystring[]optional· Extensions for words, without the dot. Default ["com"]; max 30 items.prefixesbodystring[]optional· Also try each word with these in front, e.g. ["get", "try"]; max 10 items.suffixesbodystring[]optional· Also try each word with these after it, e.g. ["hq", "app"]; max 10 items.pluralbodybooleanoptional· Also try the plural of each word (party -> parties).hacksbodybooleanoptional· Also try domain hacks, where the end of the word becomes the extension (quillbase -> quillba.se).GET/transfertransfer_readinessWhether a domain can move to another registrar today, and how. Pass ?domain=example.com.
domainquerystringrequired· A registered domain, e.g. example.com; max 253 characters.