---
url: /api/auth.md
description: >-
  Authentication and account management API endpoints — register, login, refresh
  tokens, and manage your session.
---

# Authentication API

All endpoints are prefixed with `{BASE_PATH}` — default `/api`. Authentication endpoints are public (no JWT required), except where noted.

**Base URL:** `https://api.hule-do.com/api` (production)

## Token-based auth

Hule uses **JWT access tokens** (Bearer) for API authentication.

* **Access token:** short-lived (default 15 minutes). Sent in the `Authorization: Bearer <token>` header.
* **Refresh token:** long-lived (default 30 days). Used to obtain a new access token.
* Refresh tokens are single-use and rotated on every refresh. Reusing an old refresh token revokes all sessions for that user.

All authenticated endpoints return `401 Unauthorized` if the token is missing or expired.

***

## `POST /auth/register`

Create a signup request. A confirmation email is sent — the account is created only after confirmation.

**Request:**

```json
{
  "email": "user@example.com",
  "password": "securePassword123",
  "name": "Alex"
}
```

**Response:** `201` — no body (confirmation link sent to email).

***

## `POST /auth/register/confirm`

Confirm registration with the token from the email.

**Request:**

```json
{
  "token": "abc123..."
}
```

**Response:** `201`

```json
{
  "accessToken": "eyJhbG...",
  "refreshToken": "dGhpcyBp...",
  "user": {
    "id": "667f...",
    "email": "user@example.com",
    "name": "Alex"
  }
}
```

Account is created with `isEmailVerified: true`. A default workspace is created automatically.

***

## `POST /auth/login`

Login with email and password.

**Request:**

```json
{
  "email": "user@example.com",
  "password": "securePassword123"
}
```

**Response:** `200`

```json
{
  "accessToken": "eyJhbG...",
  "refreshToken": "dGhpcyBp...",
  "user": { "id": "...", "email": "...", "name": "..." }
}
```

***

## `POST /auth/login/code`

Request a one-time login code sent to your email. Works for any registered email — no password needed.

**Request:**

```json
{
  "email": "user@example.com"
}
```

**Response:** `200` — code sent to email (valid for 10 minutes, 5 attempts).

***

## `POST /auth/login/code/confirm`

Exchange the login code for tokens.

**Request:**

```json
{
  "email": "user@example.com",
  "code": "482913"
}
```

**Response:** `200`

```json
{
  "accessToken": "eyJhbG...",
  "refreshToken": "dGhpcyBp...",
  "user": { "id": "...", "email": "...", "name": "..." }
}
```

***

## `POST /auth/login/google`

Login or register with a Google ID token.

**Request:**

```json
{
  "idToken": "eyJhbGciOiJSUzI1NiIs..."
}
```

**Response:** `200`

```json
{
  "accessToken": "eyJhbG...",
  "refreshToken": "dGhpcyBp...",
  "user": { "id": "...", "email": "...", "name": "..." }
}
```

***

## `POST /auth/refresh`

Exchange a refresh token for a new access token and a new refresh token.

**Request:**

```json
{
  "refreshToken": "dGhpcyBp..."
}
```

**Response:** `200`

```json
{
  "accessToken": "eyJhbG...",
  "refreshToken": "bmV3IHJl..."
}
```

***

## `POST /auth/logout`

Revoke the current refresh token. Requires authentication (Bearer token).

**Headers:** `Authorization: Bearer <accessToken>`

**Request:**

```json
{
  "refreshToken": "dGhpcyBp..."
}
```

**Response:** `204 No Content`

***

## `POST /auth/password/reset/request`

Request a password reset email.

**Request:**

```json
{
  "email": "user@example.com"
}
```

**Response:** `200` — reset link sent to email.

***

## `POST /auth/password/reset/confirm`

Reset the password using the token from the email. All existing sessions are invalidated.

**Request:**

```json
{
  "token": "abc123...",
  "newPassword": "newSecurePassword456"
}
```

**Response:** `204 No Content`

***

## `POST /auth/email/change/request`

Request an email change. Requires authentication.

**Headers:** `Authorization: Bearer <accessToken>`

**Request:**

```json
{
  "newEmail": "newemail@example.com"
}
```

**Response:** `200` — confirmation link sent to new email.

***

## `POST /auth/email/change/confirm`

Confirm email change with the token.

**Request:**

```json
{
  "token": "abc123..."
}
```

**Response:** `204 No Content`

***

## `DELETE /auth/me`

Delete your account permanently. Requires authentication.

**Headers:** `Authorization: Bearer <accessToken>`

**Request:**

```json
{
  "password": "myPassword"
}
```

For passwordless accounts (Google/Telegram), send `"email": "user@example.com"` instead.

**Response:** `204 No Content`

***

## `GET /account/export`

Export all your data (GDPR Art. 20). Requires authentication. Rate-limited (heavier than normal reads).

**Headers:** `Authorization: Bearer <accessToken>`

**Response:** `200` — full JSON export of profile, owned workspaces, and notifications.

***

## Error responses

All endpoints return errors in a consistent format:

```json
{
  "error": "ValidationError",
  "issues": [
    { "path": "email", "message": "email must be a valid email address" }
  ]
}
```

Common HTTP status codes:

| Code | Meaning |
|------|---------|
| `400` | Bad request — invalid input |
| `401` | Unauthorised — missing or invalid token |
| `403` | Forbidden — insufficient permissions |
| `404` | Not found |
| `429` | Too many requests — rate limit exceeded |
| `500` | Internal server error |

## Related

* [API Examples](/api/examples) — full API usage walkthroughs.
* [Manage your account](/guides/manage-your-account) — sign-in and account settings in the app.
