---
title: "Sign-up"
description: "Every operation in this group: what it accepts, what it returns and the errors it can answer with."
url: "https://nextmail.sh/docs/api/reference/sign-up"
area: "API"
category: "Reference"
---

# Sign-up

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

## Operations

An agent creates an account on Nextmail for a person, and the person supplies one thing: the six-digit code emailed to them. Neither call takes a credential, and the second one returns an API key, so a program goes from nothing to a working key in two requests. The account is the person's: it signs in with their address, gets the same free plan, free address and limits as any other, and they set a password from the welcome email. An address that already has an account is never signed in to this way, and the answer does not reveal that it has one.

### `POST /signups`

Start a sign-up

Takes no credential. Checks the address, then emails it a six-digit code that works once and runs out after 10 minutes, and answers with the `id` to finish with. Ask the person for the code, then call `POST /signups/{id}/verify`.

An address that cannot receive mail, or one on a disposable domain, is refused with `sign_up_address_refused` and nothing is sent. When the address already has an account, no code is sent: that person gets an email saying how to connect an agent to the account they have, and this call answers exactly as it would for a new address, so it never tells anyone who has an account.

One network may start 3 sign-ups an hour, counted together with sign-ups made in the apps, and one address 5 an hour. The next is a 429 `sign_up_rate_limited` with `Retry-After`.

- Sends no credential.

**Request body**

- `email` (`string`, required, 3 to 254 characters): The address the account signs in with. The six-digit code goes there, so it has to be an address the person reads.
- `name` (`string`, up to 80 characters): The name of the person the account is for. The address stands in when it is left out.
- `agent` (`string`, up to 60 characters): Who is asking, such as `Claude Code`. The emails name it, and the key it gets is named after it.
- `scopes` (`string[]`, at least one item, one of `"emails:send"`, `"emails:read"`, `"drafts:read"`, `"drafts:write"`, `"threads:read"`, `"threads:write"`, `"files:read"`, `"files:write"`, `"labels:read"`, `"labels:write"`, `"contacts:read"`, `"contacts:write"`, `"audiences:read"`, `"audiences:write"`, `"calendar:read"`, `"calendar:write"`, `"templates:read"`, `"templates:write"`, `"domains:read"`, `"domains:write"`, `"webhooks:read"`, `"webhooks:write"`, `"rules:read"`, `"rules:write"`, `"connections:read"`, `"members:read"`, `"members:write"`, `"roles:read"`, `"roles:write"`, `"settings:read"`, `"settings:write"`, `"keys:write"`, `"keys:read"`, `"keys:manage"`, `"forms:read"`, `"forms:write"`, `"knowledge:read"`, `"knowledge:write"`, `"automations:read"`, `"automations:write"`, `"tasks:read"`, `"tasks:write"`, `"connectors:read"`, `"connectors:use"`, `"connectors:write"`, `"billing:read"`, `"billing:write"`, `"account:read"`, `"account:write"`): What the key may do. Every scope when it is left out.

**Returns**

- `202` `SignUp`: The sign-up, waiting for its code.

**Errors**

- `400`: `malformed_json`.
- `422`: `sign_up_address_refused`, or `invalid_parameter` for a body the schema refuses, with `param` naming the field.
- `429`: `sign_up_rate_limited`.
- `503`: `sign_up_undeliverable`: the email could not be sent, and no sign-up is waiting.
- The errors every operation can return: `500`, described in the [error catalog](https://nextmail.sh/docs/api/errors).

Also available in: TypeScript [`signups.create()`](https://nextmail.sh/docs/sdk/reference/signups#create); Python [`signups.create()`](https://nextmail.sh/docs/python/reference/signups#create); Ruby [`signups.create`](https://nextmail.sh/docs/ruby/reference/signups#create); PHP [`signups->create`](https://nextmail.sh/docs/php/reference/signups#create); Go [`Signups.Create`](https://nextmail.sh/docs/go/reference/signups#create); Java [`signups().create`](https://nextmail.sh/docs/java/reference/signups#create); C# [`Signups.CreateAsync`](https://nextmail.sh/docs/csharp/reference/signups#create); CLI [`nextmail signups create`](https://nextmail.sh/docs/cli/reference/signups#signups-create).

### `POST /signups/{id}/verify`

Finish a sign-up

Takes no credential and returns one. Send the code the person read from their email. A right code creates the account, its workspace and its free address, and issues an API key that acts for the new owner, with every scope unless the sign-up asked for fewer. `apiKey.token` is shown here and nowhere else, so store it before anything else. The person gets a welcome email with a link to set a password, and sees the key under Settings, API keys, where they can narrow or remove it.

A sign-up takes 5 codes. A wrong one is a 400 `sign_up_code_invalid` whose message says how many tries are left, and the last wrong one cancels the sign-up with 429 `sign_up_locked`. A code that ran out, was used already, or belongs to no sign-up is a 400 `sign_up_code_expired`. One network may check 30 codes every 10 minutes across all sign-ups.

- Sends no credential.

**Path parameters**

- `id` (`string`, required): The `id` `POST /signups` answered with.

**Request body**

- `code` (`string`, required, pattern `^\d{6}$`): The six-digit code from the email the person received.

**Returns**

- `201` `SignUpAccount`: The account, its workspace and free address, and its key, shown only here.

**Errors**

- `400`: `sign_up_code_invalid`, `sign_up_code_expired` or `malformed_json`.
- `409`: `sign_up_address_taken`: the address got an account while the code was waiting.
- `422`: `invalid_parameter` for a code that is not six digits, with `param` naming it.
- `429`: `sign_up_locked`, or `sign_up_rate_limited` with `Retry-After`.
- The errors every operation can return: `500`, described in the [error catalog](https://nextmail.sh/docs/api/errors).

Also available in: TypeScript [`signups.verify()`](https://nextmail.sh/docs/sdk/reference/signups#verify); Python [`signups.verify()`](https://nextmail.sh/docs/python/reference/signups#verify); Ruby [`signups.verify`](https://nextmail.sh/docs/ruby/reference/signups#verify); PHP [`signups->verify`](https://nextmail.sh/docs/php/reference/signups#verify); Go [`Signups.Verify`](https://nextmail.sh/docs/go/reference/signups#verify); Java [`signups().verify`](https://nextmail.sh/docs/java/reference/signups#verify); C# [`Signups.VerifyAsync`](https://nextmail.sh/docs/csharp/reference/signups#verify); CLI [`nextmail signups verify`](https://nextmail.sh/docs/cli/reference/signups#signups-verify).

### Objects

#### `SignUp`

`object`

- `object` (`string`, required, one of `"sign_up"`)
- `id` (`string`, required): Finish the sign-up with this id.
- `sentTo` (`string`, required): The address the code went to, masked, to show the person where to look.
- `expiresAt` (`string`, required, format `date-time`): When the code runs out, 10 minutes after it was sent.

#### `SignUpAccount`

`object`

- `object` (`string`, required, one of `"sign_up_account"`)
- `id` (`string`, required): The id of the sign-up this finished.
- `userId` (`string`, required): The new account.
- `email` (`string`, required): The address the account signs in with.
- `name` (`string`, required): The name on the account.
- `workspaceId` (`string`, required): The workspace the account owns, and the key belongs to.
- `address` (`string`, required, nullable): The free address the account got, or null while none can be given out.
- `apiKey` (`SignUpApiKey`, required)

#### `SignUpApiKey`

`object`

- `object` (`string`, required, one of `"api_key"`)
- `id` (`string`, required)
- `name` (`string`, required): The agent that asked, or `Agent` when it gave no name.
- `scopes` (`string[]`, required): What the key may do.
- `token` (`string`, required): The secret, shown only in this answer. Send it as `Authorization: Bearer <token>`. It works until the person revokes it.
