# Create User

**POST** `/users`

Base URL: `https://live.savewithsail.com/api/v1`

Creates a Sail user mapped to your internal identity. Required for the server-to-server pattern. Optional for token-scoped integrations, where a user can be created implicitly at token exchange.

## Authorization

- PartnerKey (http, bearer)

## Body

Content type: `application/json`

- `external_user_id` (string, required)
  Your internal identifier for this user.
- `email` (string<email>)
  The user's email address.
- `first_name` (string)
  The user's first name.
- `last_name` (string)
  The user's last name.
- `phone` (string)
  The user's phone number.
- `address` (object)
  The user's mailing address.
  - `street` (string)
    Street address.
  - `city` (string)
    City.
  - `state` (string)
    State or region.
  - `zip` (string)
    Postal code.
  - `country` (string)
    ISO 3166-1 alpha-2 country code.

Example:

```json
{
  "external_user_id": "string",
  "email": "user@example.com",
  "first_name": "string",
  "last_name": "string",
  "phone": "+1 415-555-0122",
  "address": {
    "street": "string",
    "city": "string",
    "state": "string",
    "zip": "string",
    "country": "US"
  }
}
```

## Responses

### 201

User created. No credential is returned. PII access uses ephemeral tokens minted on demand.

- `id` (string)
  The Sail user id.
- `external_user_id` (string)
  Echo of the `external_user_id` supplied at creation.
- `status` ("active" | "inactive")
  Whether the user is active or inactive.
- `created_at` (string<date-time>)
  When the user was created.

Example:

```json
{
  "id": "usr_abc123",
  "external_user_id": "string",
  "status": "active",
  "created_at": "1970-01-01T00:00:00.000Z"
}
```

### default

Standard error envelope covering 400, 401, 403, 404, 429, and 500.

- `error` (object)
  The error detail.
  - `code` (string)
    Machine-readable code, e.g. `not_found`, `token_scope_mismatch`, `product_not_enabled`, `insufficient_key_scope`, `insufficient_token_scope`, `user_token_required`, `user_token_expired`, `invalid_user_token`, `invalid_key_configuration`, `connection_not_reconnectable`, `rate_limited`.
  - `message` (string)
    Human-readable error message. May change, so match on `error.code` instead.
  - `param` (string)
    The request field that caused the error, when applicable. Null otherwise.

Example:

```json
{
  "error": {
    "code": "string",
    "message": "string",
    "param": "string"
  }
}
```