---
title: "Create User"
method: POST
path: "/users"
tags: ["Public", "Registrations"]
---

# Create User

`POST /users`

## Request

- Base URL: `https://api.purplegrain.com/api/v1`
- URL: `https://api.purplegrain.com/api/v1/users`
- Auth: none declared

Email registration. Returns 204; a confirmation email follows. With the
optional top-level `property_draft` (the landing page's map, design
handoff 29) the property — and the business, when `owner_kind` is
`business` — is created in the same transaction as the account, its
ring saved and measured exactly as `updateFarmBoundary` would. An
invalid draft fails the whole request with 422 and nothing is created.

## Request body

- object
  - `user` object
    - `email` string, email
    - `mobile` string: Optional companion mobile (AU, any common format; normalized to E.164). Stored unverified; an SMS verification code is sent immediately (see /users/mobile-verifications). Phone-only accounts are created via /users/phone-sessions instead.
    - `password` string
    - `password_confirmation` string
    - `account_mode` 'grower' | 'contractor': Grower (hiring) vs Contractor (working); defaults to grower.
  - `property_draft` RegistrationPropertyDraft, nullable: The property a visitor mapped on the landing page before registering (design handoff 29). Created in the same transaction as the account — the business first when `owner_kind` is `business` (the new person its owner), then the property owned by the person or that business, named `name`, with `location.label` as its map label and `location.lng/lat` as its map point, then the ring saved exactly as `updateFarmBoundary` saves one (area measured server-side). An invalid draft fails the whole request with 422 and nothing is created; its errors point at `/data/attributes/property_draft.<field>`.
    - `name` string, required: Required.
    - `owner_kind` 'personal' | 'business': Defaults to personal.
    - `business_name` string, nullable: Required when `owner_kind` is business.
    - `location` SetupDraftLocation, nullable: The place the editor found for the property. `label` is required; `lng` and `lat` are both present or both absent. No other keys.
      - `label` string, required
      - `lng` number
      - `lat` number
    - `ring` array[], nullable: The corners, `[longitude, latitude]`, open or closed (first repeated last). Fewer than three distinct corners is not an error: the property is made without a boundary. Three or more must make a valid polygon (the boundary save's checks) enclosing less than 100,000 ha.
      - number[]
    - `area_ha` number, nullable: The client's own figure. Ignored; the area is measured from the ring.

## Response `204`

Created — the account, and with `property_draft` the property (and business) too.

## Other responses

- `403`: Forbidden — first-party only; refused to an API key or an assistant's token.
- `422`: Invalid account fields, or an invalid `property_draft` (errors point at `/data/attributes/property_draft.<field>`); nothing is created.

---

[API](https://skmtc.dev/purplegrain/apis/purple-grain-api.md) · [All operations](https://skmtc.dev/purplegrain/apis/purple-grain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/purplegrain/apis/purple-grain-api/revisions/4bedbc1c784c?raw)
