Hydra is now in beta|Get started free|Follow our journey on X.com

Customer Auth API
On this page

Customer Auth

Customer authentication for storefronts built with Hydra. Customers register and log in with email and password. Hydra issues short-lived JWTs for API access and opaque refresh tokens for session continuity. This is separate from admin/merchant authentication.

Base URL: https://api.hydrajs.dev

Endpoints

Method Path Auth Description
POST /v1/auth/register Publishable Create customer account, return tokens
POST /v1/auth/login Publishable Email + password login
POST /v1/auth/token Publishable Refresh access token
POST /v1/auth/logout Publishable Invalidate refresh token
POST /v1/auth/forgot-password Publishable Request password reset
POST /v1/auth/reset-password Publishable Reset password with token

Publishable keys only

All auth endpoints require a publishable API key (pk_live_* or pk_test_*) via the X-API-Key header. Secret keys are not needed.

Prerequisite: store domain

Customer auth requires a domain to be set on the project (via PATCH /v1/store or the admin panel). Without it, all auth endpoints return 400 with "Store domain must be configured to use customer auth.". The domain is used for email verification links, password reset URLs, and other customer-facing emails. See Store API — Domain verification for setup.

Token strategy

Login and registration return an access token (JWT, 1 hour) and a refresh token (opaque, 30 days). The access token is sent as a Bearer token for authenticated requests to /v1/me. Refresh tokens are single-use with rotation — each refresh invalidates the old token and returns a new one.


Register

POST /v1/auth/register

Creates a new customer account with email and password. Returns access and refresh tokens along with the customer profile. The email must be unique within the project.

Request body

Field Type Required Description
email string Yes Email address (max 255 chars)
password string Yes Password (8-128 chars, must include uppercase, lowercase, and digit)
first_name string Yes First name (1-100 chars)
last_name string Yes Last name (1-100 chars)
phone string No Phone number (max 30 chars)
locale string No Preferred language (BCP 47, max 10 chars, e.g. en, es-419). Determines email language

Request

curl -X POST https://api.hydrajs.dev/v1/auth/register \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "password": "SecurePass1",
    "first_name": "Jane",
    "last_name": "Smith",
    "phone": "+1-555-0123"
  }'

Response 201

{
	"access_token": "eyJhbGciOiJIUzI1NiIs...",
	"refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
	"expires_in": 3600,
	"customer": {
		"id": "cus_abc123",
		"email": "jane@example.com",
		"first_name": "Jane",
		"last_name": "Smith",
		"phone": "+1-555-0123",
		"locale": null,
		"email_verified": false,
		"created_at": "2026-08-31T10:00:00Z",
		"updated_at": "2026-08-31T10:00:00Z"
	}
}

Login

POST /v1/auth/login

Authenticates a customer with email and password. Returns access and refresh tokens. Progressive lockout applies after repeated failures (5 failures: 1 min, 10: 5 min, 20+: 15 min).

Request body

Field Type Required Description
email string Yes Email address
password string Yes Password

Request

curl -X POST https://api.hydrajs.dev/v1/auth/login \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "password": "SecurePass1"
  }'

Response 200

{
	"access_token": "eyJhbGciOiJIUzI1NiIs...",
	"refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
	"expires_in": 3600,
	"customer": {
		"id": "cus_abc123",
		"email": "jane@example.com",
		"first_name": "Jane",
		"last_name": "Smith",
		"phone": "+1-555-0123",
		"locale": null,
		"email_verified": false,
		"created_at": "2026-08-31T10:00:00Z",
		"updated_at": "2026-08-31T10:00:00Z"
	}
}

Security

Returns 401 Unauthorized with "Invalid email or password." for both wrong email and wrong password (prevents email enumeration). Returns 429 Too Many Requests with Retry-After header when the account is temporarily locked.


Refresh token

POST /v1/auth/token

Exchanges a valid refresh token for new access and refresh tokens. The old refresh token is invalidated (single-use rotation). If a consumed token is submitted, all tokens in the session family are revoked as a theft countermeasure.

Request body

Field Type Required Description
refresh_token string Yes The refresh token from login or a previous refresh

Request

curl -X POST https://api.hydrajs.dev/v1/auth/token \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
  }'

Response 200

{
	"access_token": "eyJhbGciOiJIUzI1NiIs...",
	"refresh_token": "bmV3IHJlZnJlc2ggdG9r...",
	"expires_in": 3600
}

No customer object

The refresh response does not include the customer object. Use GET /v1/me to fetch the profile if needed.


Logout

POST /v1/auth/logout

Invalidates the provided refresh token. Idempotent — returns 204 even if the token was already invalidated or does not exist.

Request body

Field Type Required Description
refresh_token string Yes The refresh token to invalidate

Request

curl -X POST https://api.hydrajs.dev/v1/auth/logout \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
  }'

Response 204

No body.


Forgot password

POST /v1/auth/forgot-password

Generates a password reset token. Always returns a generic success message regardless of whether the email exists (prevents email enumeration). When the transactional email system is available, a reset link will be sent to the customer.

Request body

Field Type Required Description
email string Yes Email address (max 255 chars)

Request

curl -X POST https://api.hydrajs.dev/v1/auth/forgot-password \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com"
  }'

Response 200

{
	"message": "If an account exists, a reset link has been sent."
}

Reset password

POST /v1/auth/reset-password

Validates the reset token and sets a new password. The token is single-use and expires after 24 hours. All existing sessions for the customer are invalidated.

Request body

Field Type Required Description
token string Yes The reset token from the forgot-password flow
password string Yes New password (8-128 chars, must include uppercase, lowercase, and digit)

Request

curl -X POST https://api.hydrajs.dev/v1/auth/reset-password \
  -H "X-API-Key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "cmVzZXQgdG9rZW4gaGVyZQ...",
    "password": "NewSecurePass1"
  }'

Response 200

{
	"message": "Password has been reset successfully."
}

Token response object

Returned by register, login, refresh, and change-password endpoints.

Field Type Description
access_token string HS256 JWT valid for 1 hour
refresh_token string Opaque token valid for 30 days (single-use)
expires_in integer Access token TTL in seconds (3600)
customer object Customer profile (present on register and login only)

Auth customer object

Returned inside the token response on register and login.

Field Type Description
id string Customer ID (e.g. cus_abc123)
email string Email address
first_name string First name
last_name string Last name
phone string|null Phone number
locale string|null Preferred language (BCP 47, e.g. en, es-419)
email_verified boolean Whether the email has been verified
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp