NeatMail Developer Resources

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

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

An 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:

  • 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

ScopeWhat NeatMail does with it
openidIssue an ID token identifying the signed-in NeatMail user.
profileRead the display name and avatar shown in the NeatMail app.
emailRead the verified email address the NeatMail account is keyed on.
offline_accessIssue a refresh token so background workers can keep processing a mailbox between sessions.
public_metadataRead account metadata that the NeatMail app exposes to its own front end.
private_metadataRead 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)

ScopeWhat NeatMail does with it
openidIssue an ID token identifying the connected Google account.
https://www.googleapis.com/auth/userinfo.emailRead the verified email address the NeatMail account is keyed on.
https://www.googleapis.com/auth/userinfo.profileRead the display name and avatar shown in the NeatMail app.
https://www.googleapis.com/auth/gmail.readonlyRead 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.labelsCreate and maintain the NeatMail label set (including the single 'Follow up' label).
https://www.googleapis.com/auth/gmail.modifyApply 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.composeCreate 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.readonlyRead 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)

ScopeWhat NeatMail does with it
openidIssue an ID token identifying the connected Microsoft account.
emailRead the account's primary email address.
profileRead the display name shown in the NeatMail app.
offline_accessIssue a refresh token so background workers can keep processing the mailbox.
User.ReadRead the signed-in user's basic Microsoft profile.
Mail.ReadWriteRead mail for classification and drafting, apply NeatMail categories and folders, create draft replies, and send the drafts and unsubscribe requests you approve.
MailboxSettings.ReadWriteRequested 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.ReadRead 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:

SignalSpecificationMeaning
DeprecationRFC 9745When the deprecation was announced, as an sf-date.
SunsetRFC 8594The earliest date the path may stop working.
Link; rel="successor-version"RFC 5829The versioned path to move to.

There will be at least 6 months between the Deprecation date and the Sunset date.

Currently deprecated:

PathUse insteadSunset
/api/geo/api/v1/geo2027-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"
}
CodeStatusMeaningWhat to do
not_found404Resource not foundCheck the path against https://www.neatmail.app/sitemap.xml (pages) or https://www.neatmail.app/openapi.json (endpoints).
not_acceptable406No acceptable representationRetry with an Accept header this resource can satisfy — text/html or text/markdown for pages, application/json for API endpoints.
method_not_allowed405Method not allowedRetry with a method listed in the Allow response header.
unsupported_api_version404Unsupported API versionOnly /api/v1 exists. See the versioning policy at https://www.neatmail.app/developers#versioning.
internal_error500Internal server errorThe 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.