> ## Documentation Index
> Fetch the complete documentation index at: https://doc.playsmart.api.dolly.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /auth/register — Create a new player account

> Register a new PlaySmart player with email, password, and device ID. Returns JWT access and refresh tokens along with the user profile object.

Calling this endpoint creates a new player account and immediately returns a JWT access token and refresh token. You do not need to make a separate login call after registration — your client can start making authenticated requests with the tokens returned here.

## Endpoint

```text theme={null}
POST /auth/register
```

No authentication is required.

## Request body

<ParamField body="email" type="string" required>
  The player's email address. Must be a valid email format. Used as the unique account identifier.
</ParamField>

<ParamField body="password" type="string" required>
  The player's password. Minimum 8 characters.
</ParamField>

<ParamField body="deviceId" type="string" required>
  A unique identifier for the player's device. This value is stored as the player's `auth_user_id` and becomes the `sub` claim in all issued JWTs.
</ParamField>

## Example request

```bash theme={null}
curl -X POST https://playsmart-gateway-1w8ko864.uc.gateway.dev/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "player@example.com",
    "password": "s3cur3pass",
    "deviceId": "device-abc-123"
  }'
```

## Response

### 201 Created

<ResponseField name="access_token" type="string">
  A signed JWT bearer token. Include this in the `Authorization: Bearer` header on every authenticated request. Expires in 30 days.
</ResponseField>

<ResponseField name="refresh_token" type="string">
  A signed JWT refresh token. Use this to obtain a new access token when the current one expires. Expires in 180 days.
</ResponseField>

<ResponseField name="user" type="object">
  <Expandable title="properties">
    <ResponseField name="id" type="string">
      The player's unique identifier. Matches the `deviceId` supplied at registration and the `sub` claim in the JWT.
    </ResponseField>

    <ResponseField name="email" type="string">
      The player's email address.
    </ResponseField>

    <ResponseField name="pseudo" type="string">
      The player's display name. Empty string on a freshly created account.
    </ResponseField>

    <ResponseField name="total_games_completed" type="number">
      Total games the player has completed. Always `0` on registration.
    </ResponseField>
  </Expandable>
</ResponseField>

```json theme={null}
{
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": "device-abc-123",
      "email": "player@example.com",
      "pseudo": "",
      "total_games_completed": 0
    }
  }
}
```

## Error responses

| HTTP status       | Code          | Message                    | Meaning                                                                         |
| ----------------- | ------------- | -------------------------- | ------------------------------------------------------------------------------- |
| `400 BAD_REQUEST` | `BAD_REQUEST` | `invalid_payload`          | The request body failed validation. Check `details` for field-level errors.     |
| `409 CONFLICT`    | `CONFLICT`    | `email_already_registered` | An account with this email already exists. Direct the player to log in instead. |

```json theme={null}
{
  "error": {
    "code": "CONFLICT",
    "message": "email_already_registered"
  }
}
```
