Menu

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/me

The 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_workspaces

The 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_domains

List domains, with filters and paging.

projectIdqueryuuidoptional
registrarAccountIdqueryuuidoptional
statusquery"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_domain

Add a domain to a project under a registrar account.

domainNamebodystringrequired· Max 253 characters.
projectIdbodyuuidrequired
registrarAccountIdbodyuuidrequired
statusbody"Active" | "Expired" | "Transferred" | "Unknown"optional· Optional; worked out from expiryDate when left out. "Transferred" archives the domain.
autoRenewbodybooleanoptionaldefault false
expiryDatebodydate (YYYY-MM-DD) | nulloptional
notesbodystringoptional· 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_domains

Add 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.
projectIdbodyuuidrequired
registrarAccountIdbodyuuidrequired
statusbody"Active" | "Expired" | "Transferred" | "Unknown"optional
autoRenewbodybooleanoptional
expiryDatebodydate (YYYY-MM-DD) | nulloptional
notesbodystringoptional· Max 2000 characters.
archivedbodybooleanoptional
archivedNotebodystring | nulloptional
GET/domains/lookuplookup_domains

Look 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_domains

Add 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) | nulloptional
GET/domains/expiringdomains_expiring_soon

Domains 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_domain

Get one domain by id or by its exact name, e.g. /domains/example.com.

domainpathuuid or domain namerequired
PATCH/domains/{id}update_domain

Update a domain. Only the fields you send change.

idpathuuidrequired
domainNamebodystringoptional· Max 253 characters.
statusbody"Active" | "Expired" | "Transferred" | "Unknown"optional· Optional; follows expiryDate when that changes. "Transferred" archives the domain.
autoRenewbodybooleanoptional
expiryDatebodydate (YYYY-MM-DD) | nulloptional
notesbodystringoptional· Free-text notes, max 2000 characters. Empty string clears it.
projectIdbodyuuidoptional
registrarAccountIdbodyuuidoptional
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.
DELETE/domains/{id}delete_domain

Delete a domain. Owners only; Editors archive instead.

idpathuuidrequired

Projects

Group domains by client, brand or experiment, inside a workspace.

GET/projectslist_projects

List 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_project

Create a project in a workspace.

namebodystringrequired· Max 100 characters.
descriptionbodystringoptional· Optional description, max 500 characters
workspaceIdbodyuuidoptional· Workspace id from list_workspaces. Defaults to the first workspace you own.
PATCH/projects/{id}update_project

Rename a project or change its description.

idpathuuidrequired
namebodystringoptional· Max 100 characters.
descriptionbodystringoptional· Optional description, max 500 characters
DELETE/projects/{id}delete_project

Delete a project and all its domains. Owner only. Add ?confirm=true to proceed.

idpathuuidrequired
confirmquerybooleanoptionaldefault 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_registrars

List your registrars with their account counts.

workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.
POST/registrarsadd_registrar

Add 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_registrar

Update a registrar's name or URL.

idpathuuidrequired
namebodystringoptional· Max 100 characters.
urlbodystringoptional· Registrar website, e.g. namecheap.com; max 500 characters.
DELETE/registrars/{id}delete_registrar

Delete a registrar with its accounts and their domains. Add ?confirm=true to proceed.

idpathuuidrequired
confirmquerybooleanoptionaldefault 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_accounts

List your registrar accounts, optionally for one registrar.

registrarIdqueryuuidoptional
workspaceIdqueryuuidoptional· Workspace id from list_workspaces. Leave out to cover every workspace you can see.
POST/registrar-accountsadd_registrar_account

Add an account under one of your registrars.

registrarIdbodyuuidrequired
displayNamebodystringrequired· 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_account

Update a registrar account.

idpathuuidrequired
displayNamebodystringoptional· 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.
isActivebodybooleanoptional
DELETE/registrar-accounts/{id}delete_registrar_account

Delete a registrar account and its domains. Add ?confirm=true to proceed.

idpathuuidrequired
confirmquerybooleanoptionaldefault 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_logs

Recent registrar sync results across your accounts.

limitqueryintegeroptionaldefault 20· Max 100.
registrarAccountIdqueryuuidoptional

Monitoring

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_monitored

Every 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_domains

Start 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_monitoring

Stop 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_changes

What 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_report

Everything 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_availability

Whether 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_readiness

Whether 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.