Everything an automated client needs to work with NeatMail, at stable URLs: an OpenAPI description, OAuth 2.0 discovery documents, the exact mailbox scopes NeatMail requests, and Markdown versions of every page on this site.
Machine-readable files
/llms.txt— llms.txt site index: every product, tool, guide and comparison page with a summary./openapi.json— OpenAPI 3.1 description of this site's HTTP surface and its OAuth security schemes./.well-known/api-catalog— RFC 9727 API Catalog: links to the OpenAPI description, developer docs and status endpoint./.well-known/oauth-authorization-server— RFC 8414 authorization server metadata (redirects to the issuer that publishes it)./.well-known/openid-configuration— OpenID Connect discovery document (redirects to the issuer that publishes it)./sitemap.xml— Every indexable URL with its last-modified date./robots.txt— Crawler rules, including explicit allowances for AI crawlers.
Markdown content negotiation
Every page in the sitemap serves two representations from the same URL. Send Accept: text/markdown and you get Markdown; send anything else and you get HTML. Responses carry Vary: Accept, so a cache cannot hand one audience the other’s bytes.
curl -sI -H "Accept: text/markdown" https://www.neatmail.app/pricingAn Accept header that no representation satisfies gets 406 Not Acceptable with a plain-text list of what is available, and a URL that does not exist gets a real 404 whose body is a short Markdown map of the site.
OAuth 2.0
NeatMail’s authorization server is https://clerk.neatmail.app. It publishes standard discovery documents:
- RFC 8414 authorization server metadata:
https://clerk.neatmail.app/.well-known/oauth-authorization-server - OpenID Connect discovery:
https://clerk.neatmail.app/.well-known/openid-configuration - Both are reachable from this origin at
/.well-known/oauth-authorization-serverand/.well-known/openid-configuration, which redirect to the issuer that publishes them.
- Authorization:
https://clerk.neatmail.app/oauth/authorize - Token:
https://clerk.neatmail.app/oauth/token - Revocation:
https://clerk.neatmail.app/oauth/token/revoke - UserInfo:
https://clerk.neatmail.app/oauth/userinfo - JWKS:
https://clerk.neatmail.app/.well-known/jwks.json
Grant types: authorization_code, refresh_token. PKCE method: S256. Third-party client registration is not open yet — write to help@send.neatmail.app if you need one.
Scopes issued by NeatMail
| Scope | What NeatMail does with it |
|---|---|
openid | Issue an ID token identifying the signed-in NeatMail user. |
profile | Read the display name and avatar shown in the NeatMail app. |
email | Read the verified email address the NeatMail account is keyed on. |
offline_access | Issue a refresh token so background workers can keep processing a mailbox between sessions. |
public_metadata | Read account metadata that the NeatMail app exposes to its own front end. |
private_metadata | Read server-only account metadata such as plan and entitlement flags. |
Delegated mailbox scopes
NeatMail never holds your mail password. It asks you to grant a narrow, revocable set of scopes to your own provider.
Google (Gmail)
| Scope | What NeatMail does with it |
|---|---|
openid | Issue an ID token identifying the connected Google account. |
https://www.googleapis.com/auth/userinfo.email | Read the verified email address the NeatMail account is keyed on. |
https://www.googleapis.com/auth/userinfo.profile | Read the display name and avatar shown in the NeatMail app. |
https://www.googleapis.com/auth/gmail.readonly | Read message and thread data to classify incoming mail, detect promises, and assemble the context a draft reply is written from. |
https://www.googleapis.com/auth/gmail.labels | Create and maintain the NeatMail label set (including the single 'Follow up' label). |
https://www.googleapis.com/auth/gmail.modify | Apply and remove those labels on messages, auto-archive mail that matches your archive rules, and move mail to Trash when you ask. |
https://www.googleapis.com/auth/gmail.compose | Create draft replies and follow-ups in your mailbox, send a draft when you approve it (in the app or from Telegram), and send the unsubscribe requests you trigger. Nothing is sent without an action from you. |
https://www.googleapis.com/auth/calendar.readonly | Read free/busy blocks and upcoming events, so a draft can check whether a time proposed in an email is actually free, offer times you are available, and resolve a deadline that names an event rather than a date. Read-only: NeatMail never creates or edits events. |
Revoke at myaccount.google.com/permissions.
Microsoft (Outlook / Graph)
| Scope | What NeatMail does with it |
|---|---|
openid | Issue an ID token identifying the connected Microsoft account. |
email | Read the account's primary email address. |
profile | Read the display name shown in the NeatMail app. |
offline_access | Issue a refresh token so background workers can keep processing the mailbox. |
User.Read | Read the signed-in user's basic Microsoft profile. |
Mail.ReadWrite | Read mail for classification and drafting, apply NeatMail categories and folders, create draft replies, and send the drafts and unsubscribe requests you approve. |
MailboxSettings.ReadWrite | Requested on the Microsoft consent screen, but NeatMail currently makes no mailbox-settings call — no code path reads or writes your time zone or automatic replies. It is a candidate for removal from the consent screen. |
Calendars.Read | Read free/busy blocks and upcoming events, so a draft can check whether a time proposed in an email is actually free, offer times you are available, and resolve a deadline that names an event rather than a date. Read-only: NeatMail never creates or edits events. |
Revoke at myaccount.microsoft.com/permissions.
Versioning and deprecation
The API is versioned in the URL path: /api/v1. The version is part of the address, so a URL in a log line or a tool call is never ambiguous about which contract it used.
Within a version, changes are additive only — new endpoints, new optional fields, new error codes. A breaking change means a new version path; the old one keeps working while it is deprecated.
When a path is deprecated it keeps answering and starts sending three signals:
| Signal | Specification | Meaning |
|---|---|---|
Deprecation | RFC 9745 | When the deprecation was announced, as an sf-date. |
Sunset | RFC 8594 | The earliest date the path may stop working. |
Link; rel="successor-version" | RFC 5829 | The versioned path to move to. |
There will be at least 6 months between the Deprecation date and the Sunset date.
Currently deprecated:
| Path | Use instead | Sunset |
|---|---|---|
/api/geo | /api/v1/geo | 2027-08-23 |
Errors
Every failure under /api — and every error returned to a client that asked for JSON — is an RFC 9457 application/problem+json document. Branch on code: it is stable API surface, unlike title or the status alone.
{
"type": "https://www.neatmail.app/developers#error-not-found",
"title": "Resource not found",
"status": 404,
"detail": "No endpoint at /api/v1/nope.",
"instance": "/api/v1/nope",
"code": "not_found",
"resolution": "Check the path against https://www.neatmail.app/sitemap.xml (pages) or https://www.neatmail.app/openapi.json (endpoints).",
"documentation": "https://www.neatmail.app/developers#errors"
}| Code | Status | Meaning | What to do |
|---|---|---|---|
not_found | 404 | Resource not found | Check the path against https://www.neatmail.app/sitemap.xml (pages) or https://www.neatmail.app/openapi.json (endpoints). |
not_acceptable | 406 | No acceptable representation | Retry with an Accept header this resource can satisfy — text/html or text/markdown for pages, application/json for API endpoints. |
method_not_allowed | 405 | Method not allowed | Retry with a method listed in the Allow response header. |
unsupported_api_version | 404 | Unsupported API version | Only /api/v1 exists. See the versioning policy at https://www.neatmail.app/developers#versioning. |
internal_error | 500 | Internal server error | The request was not processed. Retry with backoff; if it persists, report it to help@send.neatmail.app. |
Endpoints callable without a NeatMail session
GET https://www.neatmail.app/api/v1— Index of the v1 API: every operation, with the versioning and error policy.GET https://www.neatmail.app/api/v1/geo— Two-letter country code for the caller, used to pick a pricing currency.GET https://dashboard.neatmail.app/api/health— Liveness and dependency status for the NeatMail application.
https://www.neatmail.app/api/v1 also serves a machine-readable index of version v1: its operations, the deprecation list, and the versioning and error policies.
There is no general-purpose NeatMail developer API yet: everything else under https://dashboard.neatmail.app/api is first-party and requires an authenticated session. There is no public webhook API and no hosted MCP server; when either ships it will be listed here and in llms.txt.
Source and self-hosting
NeatMail is source-available under the Elastic License 2.0 at GitHub. Self-hosting is free for personal and commercial use; reselling a hosted version or building a competing SaaS is restricted. A self-hosted deployment needs Google Cloud credentials, an OpenAI API key, PostgreSQL and Redis.
Contact
help@send.neatmail.app — developer, OAuth and integration questions.