---
title: "Log in"
method: POST
path: "/auth/login"
---

# Log in

`POST /auth/login`

## Request

- Base URL: `https://app.yoping.me/api/v1`
- URL: `https://app.yoping.me/api/v1/auth/login`
- Auth: none required

Verifies credentials, rotates and sets the `yp_session` cookie, and returns the same bootstrap payload as GET /me. Wrong password, unknown email, and a temporarily locked account all return the same 401. Limited to 10 attempts per IP per minute, plus a progressive per-account lock.

## Request body

- LoginRequest
  - `email` string, email, required
  - `password` string, required

## Response `200`

Either fully logged in (password alone was sufficient; the session cookie is set and the /me bootstrap payload is returned) or, for an account with TOTP enrolled, phase 1 only — no cookie is set yet, and the response instead carries a `totp_token` to submit to POST /auth/login/totp along with a 6-digit code or recovery code.

- union
  - object: Uniform success envelope: the payload is always under `data`.
    - `data` Me, required: The SPA bootstrap payload, returned by GET /me and POST /auth/login.
      - `user` object, required
        - `id` string, required
        - `email` string, email, required
        - `email_verified` boolean, required
        - `totp_enabled` boolean, required: Whether two-factor authentication (TOTP) is enrolled and confirmed for this account.
        - `created_at` string, date-time, required
      - `account` object, required
        - `id` string, required
        - `name` string, required
        - `plan` 'free' | 'pro' | 'team', required
        - `status` string, required
        - `deleted_at` string, date-time, nullable, required: Set while the account is in its deletion grace window.
      - `limits` object, required: The plan's enforced caps.
        - `max_monitors` integer, required
        - `min_interval_seconds` integer, required
        - `max_regions` integer, required: Regions per monitor; the effective cap is min(max_regions, active fleet size).
        - `allowed_channel_types` string[], required
        - `result_retention_days` integer, required
        - `mcp_history_days` integer, required: MCP history window in days; 0 means unlimited.
        - `mcp_queries_per_day` integer, required
        - `max_alert_after_seconds` integer, required: Per-monitor DOWN-alert delay cap in seconds; 0 means the knob is not available on this plan.
        - `max_region_alert_after_seconds` integer, required: Per-monitor region-degradation alert delay cap in seconds; 0 means the knob is not available on this plan.
      - `usage` object, required
        - `monitors` integer, required: Current monitor count.
      - `regions` string[], required: Active region codes; resolve display names via GET /regions.
      - `billing` object, required: Billing summary. When `configured` is false (billing disabled on this deployment) every other field is its zero value and the dashboard hides billing UI. Subscription fields are null until the account has a subscription.
        - `configured` boolean, required
        - `has_subscription` boolean, required
        - `status` string, nullable, required: Paddle subscription status verbatim (e.g. trialing, active, past_due, canceled).
        - `plan` 'pro' | 'team' | 'null', nullable, required
        - `interval` 'monthly' | 'annual' | 'null', nullable, required
        - `current_period_end` string, date-time, nullable, required
        - `trial_end` string, date-time, nullable, required
        - `cancel_at_period_end` boolean, required
        - `trial_available` boolean, required: True when the account has never had a subscription; the first checkout gets a 14-day trial.
        - `can_manage` boolean, required: True when a billing customer exists, so POST /billing/portal will succeed.
      - `recovery_codes_remaining` integer: Count of unused two-factor recovery codes. Present only when totp_enabled is true.
  - object: Uniform success envelope: the payload is always under `data`.
    - `data` TotpRequired, required: Phase-1 login response for an account with TOTP enrolled: credentials were valid but no session cookie is set yet. Submit `totp_token` plus a code to POST /auth/login/totp to finish logging in.
      - `totp_required` true, required
      - `totp_token` string, required: Single-use, expires 5 minutes after phase 1. Pass to POST /auth/login/totp as `totp_token`.

## Other responses

- `400`: Invalid input (code `validation_failed`): malformed JSON, a missing or out-of-range field, bad pagination parameters, or a rejected token.
- `401`: Not authenticated (code `unauthorized`): missing, invalid, or expired session; invalid login credentials; or a Bearer token, which this surface rejects.
- `403`: Forbidden. Code `forbidden` for a cross-origin (CSRF) request blocked by origin validation or for API-key management attempted without a browser session; `account_suspended` when a suspended account attempts a mutation; `account_deleted` when an account in its deletion grace window calls a non-exempt route.
- `429`: Too many requests (code `rate_limited`). A global per-IP budget of 300 requests/minute (burst 60) applies to every endpoint; login, signup, and test alerts have tighter dedicated limits.

---

[API](https://skmtc.dev/yoping/apis/yopingme-api.md) · [All operations](https://skmtc.dev/yoping/apis/yopingme-api/llms.txt) · [OpenAPI document](https://skmtc.dev/yoping/apis/yopingme-api/revisions/76d8deb40173?raw)
