---
title: "Create an account: an unverified customer organization, its owner and a session. No credential; the website calls this from its servers"
method: POST
path: "/v1/auth/signup"
---

# Create an account: an unverified customer organization, its owner and a session. No credential; the website calls this from its servers

`POST /v1/auth/signup`

## Request

- Base URL: `https://api.evictionsapi.com`
- URL: `https://api.evictionsapi.com/v1/auth/signup`
- Auth: none required

## Request body

- object
  - `name` string, required
  - `organizationName` string
  - `email` string, email, required
  - `password` string, required
  - `heardFrom` 'chatgpt' | 'claude' | 'perplexity' | 'google' | 'ai_agent' | 'other'
  - `kind` 'owner' | 'property_manager' | 'both'

## Response `201`

The new session, user and organization. An `Idempotency-Key` header is ignored.

- object
  - `token` string, required: A session token (`ess_...`), shown here only. Send it as `Authorization: Bearer`.
  - `user` object, required
    - `id` string, required
    - `name` string, nullable, required
    - `email` string, required
    - `role` 'customer' | 'attorney' | 'platform_admin', required: The kind of account. The person's role in an organization is the top-level `role`.
    - `emailConfirmed` boolean, required: Whether the person confirmed this address (with the emailed link, or by signing in with Google). Nothing depends on it: an unconfirmed account works the same.
    - `hasPassword` boolean, required: Whether the account has a password (an account made with Google has none until one is set).
    - `googleLinked` boolean, required: Whether a Google account is linked, so the person can sign in with Google.
  - `organization` object, nullable, required: The organization this session acts for; null when the person belongs to none.
    - `id` string, required
    - `name` string, required
    - `verified` boolean, required
    - `kind` unknown, required
    - `contactEmail` string, nullable, required
    - `contactPhone` string, nullable, required
    - `contactAddress` string, nullable, required
    - `billingEmail` string, nullable, required
  - `role` unknown, required
  - `permissions` string[], required: What the person may change in that organization. Reading needs no permission. Empty without an organization.
  - `organizations` object[], required: Every organization the person belongs to, oldest membership first.
    - `id` string, required
    - `name` string, required
    - `kind` unknown, required
    - `role` 'owner' | 'member' | 'viewer' | 'custom', required
    - `caseEmails` 'all' | 'mine' | 'none', required: Which of the organization's case emails the person gets: all, only cases they opened, or none (`PATCH /v1/me/organizations/:id`).
  - `modes` object, required: The modes this server offers. `test` is always true.
    - `test` boolean, required
    - `live` boolean, required

## Other responses

- `400`: The request is invalid.
- `401`: Sign-in only: the email or password is incorrect (one fixed answer for both).
- `409`: Sign-up only: an account with that email already exists (`email_taken`).
- `413`: The request body is too large.
- `429`: Too many sign-up and sign-in attempts from this address: at most 10 every 10 minutes. Sign-in only: also after 5 wrong passwords for one account within 15 minutes, until the oldest of them is 15 minutes old, whatever password is sent; a successful sign-in clears the count. `Retry-After` gives the seconds to wait.
- `503`: `busy`: too many password checks are waiting. Nothing was created or changed. `Retry-After: 5` gives the seconds to wait; try again.

---

[API](https://skmtc.dev/evictionsapi/apis/evictions-api.md) · [All operations](https://skmtc.dev/evictionsapi/apis/evictions-api/llms.txt) · [OpenAPI document](https://skmtc.dev/evictionsapi/apis/evictions-api/revisions/28459213a1a3?raw)
