Mailocity signup API

version 1.5.0 OpenAPI spec (YAML)

No authentication. Both endpoints answer only what the SaaS administrator has opened with PATCH /v1/settings (freeSignup, paidSignup), the plans marked signup, and the shared domains marked signup (see api/openapi.yaml). Bodies must be application/json.

A free signup is active at once. A paid signup (solo or team plan) is created pending: it cannot sign in or receive mail until billing sets the tenant to active through PATCH /v1/tenants/{tenantId}.

Limits: 30 attempts per source address per hour, and signupsPerIpPerHour successful signups. Reserved names answer like taken ones.

Joining a team. /api/join/{slug} serves a team's join page at /join/{slug}: people become members of an existing team on its signup domain while the team has opened its signup (team_signup in its plan), or with one of its invitation links (?invite=). The team sets this up with /v1/tenants/{tenantId}/team-settings and /team-invites. The same limits apply. See docs/kb/team-admin.md.

Through Zappocity. While single sign-on is on, accounts are made with a Zappocity account: GET /api/signup/identity says so (required), the page sends the browser to startUrl to sign in to zappo.city (or create the account there, with a confirmed email), and POST /api/signup and POST /api/join/{slug} then take no password: the mailbox has none of its own and is linked to that Zappocity account, which signs in to it. Without that sign-in (kept 30 minutes, for one account) they answer 403 with zappocityRequired and startUrl. A signup through Zappocity needs no verification code or captcha: the confirmed Zappocity account stands for them.

General

GET /api/captcha

The captcha a public form needs

For purpose signup, join (team join pages), reset (password reset requests) or signin (webmail). An empty provider means none is needed. For pow, find a nonce such that SHA-256(salt ":" nonce) starts with difficulty zero bits and send "salt.expires.difficulty.signature.nonce" as captcha; each answer works once, for ten minutes. For turnstile and hcaptcha, render the provider's widget with siteKey and send its token. Signups whose address fails the platform's checks are held for approval or refused (403).

ParameterInType
purpose *querystring
Responses
  • 200 The challenge.
    {
      "difficulty": 17,
      "expires": 1791460800,
      "provider": "pow",
      "salt": "Zq3...",
      "signature": "9b1c..."
    }
  • 400 Unknown purpose.
GET /api/join/{slug}

What a team's join and sign-in pages show

404 for an unknown or suspended team, and for one with nothing to show (no title, message or colour, signup closed and no valid invitation). domain is set only when joining is possible. Webmail's sign-in page uses title, message and accent at /mail?team={slug}.

ParameterInType
slug *pathstring
invitequerystring
Responses
  • 200 The team page.
    {
      "accent": "#1a73e8",
      "domain": "acme.com",
      "inviteValid": true,
      "message": "Use your work name.",
      "name": "Acme",
      "signupOpen": false,
      "slug": "acme",
      "title": "Join Acme"
    }
  • 404 No such team page.
POST /api/join/{slug}

Become a member of a team

Makes a member account localPart@ the team's signup domain, within its seats. Needs open signup or a valid invite, which is used up by one join. The team's welcome message (or the platform's) is sent.

ParameterInType
slug *pathstring
Request
{
  "displayName": "Amy",
  "invite": "tQ2x...",
  "localPart": "amy",
  "password": "correct horse battery"
}
Responses
  • 201 Joined.
    {
      "accountId": "3d05579f-ed2b-40c4-a5a7-5a3717b216ec",
      "address": "amy@acme.com",
      "tenantId": "9b1c..."
    }
  • 403 Signup is closed, the invitation is not valid, or, while single sign-on is on, no Zappocity sign-in (zappocityRequired, startUrl).
  • 404 No such team.
  • 409 The address is taken or reserved
  • 422 A value is not valid.
  • 429 Too many signups from this network.
POST /api/signup

Create an account on a shared domain

Responses
  • 201 Created. The new tenant has one owner account.
  • 400 Not a valid JSON object.
  • 403 Signups are not open for that plan or domain; the invitation is used, expired, cancelled or not accepted now; or, while single sign-on is on, no Zappocity sign-in (zappocityRequired, startUrl).
  • 409 The address is taken or reserved.
  • 415 Not application/json.
  • 422 A value is not valid.
  • 429 Too many signups or attempts from this source address.
POST /api/signup/code

Send a signup verification code

A 6-digit code, valid 15 minutes, by email to an address at another provider (not a domain hosted here) or by text message to a mobile number with its country code. Asks for the signup captcha. At most 5 codes an hour from one network and 3 to one address or number; a number verifies at most phoneLimit accounts in 30 days.

Request
{
  "captcha": "...",
  "method": "sms",
  "to": "+1 415 555 0100"
}
Responses
  • 201 Sent; pass id with the code to POST /api/signup.
    {
      "id": "6f1c2e8a-3b5d-4c7e-9f10-2a3b4c5d6e7f",
      "method": "sms",
      "to": "+14155550100"
    }
  • 403 The captcha is missing or wrong, or the number has verified as many accounts as it may.
  • 422 Not offered this way, or not a valid address or number (or an address hosted here).
  • 429 Too many codes for now.
  • 503 The code could not be sent.
GET /api/signup/identity

Whether accounts are made through Zappocity, and as whom

ParameterInType
nextquerystringThe page to come back to (/signup or /join/{slug}, with its query).
Responses
  • 200 required is true while single sign-on is on; then startUrl signs in to Zappocity and comes back to next, and email and name are there once this browser has.
    {
      "email": "amy@example.com",
      "name": "Amy",
      "required": true,
      "startUrl": "/api/signup/sso/start?next=%2Fsignup"
    }
GET /api/signup/invitations/{code}

What an invitation link offers

For the signup page: the invitation's plan and the shared domains to choose from. Used, expired, cancelled and unknown links, and all links while the platform does not accept invitations, get the same 404.

ParameterInType
code *pathstring
Responses
  • 200 The invitation can be used.
  • 404 The invitation cannot be used.
GET /api/signup/options

What the signup page may offer

Plans and domains are empty unless at least one kind of signup is open.

Responses
  • 200 Open signups, plans and domains.
GET /api/signup/sso/callback

Where Zappocity sends the browser back

ParameterInType
codequerystring
statequerystring
Responses
  • 302 To next, signed in for a signup for 30 minutes; or to next#sso-error=... (expired, unverified, unavailable).
GET /api/signup/sso/start

Sign in to Zappocity (or create the account there) for a signup

ParameterInType
nextquerystring
Responses
  • 302 To Zappocity; or straight to next while single sign-on is off.