Authentication
All authenticated endpoints require a JWT bearer token. This section covers registration, login, token refresh, and API key management.
Register
Create a new tenant account.
POST /auth/register
Request
{
"email": "owner@yodybrand.vn",
"password": "secure_password_min_8_chars",
"brand_name": "Yody",
"country": "VN"
}
Response
{
"tenantId": "ulid_tenant_id",
"email": "owner@yodybrand.vn",
"accessToken": "jwt_token_15min_expiry",
"refreshToken": "jwt_token_7day_expiry",
"expiresIn": 900
}
Error Cases
- 400 — Email invalid, password too short, brand_name empty
- 409 — Email already registered
Login
Authenticate with email and password.
POST /auth/login
Request
{
"email": "owner@yodybrand.vn",
"password": "secure_password_min_8_chars"
}
Response
{
"accessToken": "jwt_token_15min_expiry",
"refreshToken": "jwt_token_7day_expiry",
"expiresIn": 900
}
Error Cases
- 400 — Missing email or password
- 401 — Invalid credentials
Refresh Token
Get a new access token using your refresh token (valid for 7 days).
POST /auth/refresh
Request
{
"refreshToken": "jwt_refresh_token"
}
Response
{
"accessToken": "new_jwt_token_15min_expiry",
"expiresIn": 900
}
Error Cases
- 400 — Missing refreshToken
- 401 — Refresh token expired or invalid
Get Current User
Retrieve the authenticated tenant's profile.
GET /auth/me
Response
{
"tenantId": "ulid_tenant_id",
"email": "owner@yodybrand.vn",
"brand_name": "Yody",
"country": "VN",
"createdAt": "2026-03-12T00:00:00Z"
}
API Keys
List API Keys
GET /api/tenants/me/api-keys
Response
{
"data": [
{
"id": "key_ulid",
"name": "Production API Key",
"lastUsedAt": "2026-03-12T12:00:00Z",
"createdAt": "2026-03-01T00:00:00Z"
}
]
}
Create API Key
POST /api/tenants/me/api-keys
Request
{
"name": "Production API Key"
}
Response
{
"id": "key_ulid",
"name": "Production API Key",
"key": "dolly_sk_xxxxxxxxxxxxx_ONLY_SHOWN_ONCE",
"createdAt": "2026-03-12T00:00:00Z"
}
⚠️ Important: The key field is only returned once. Store it securely. You cannot retrieve it again.
Delete API Key
DELETE /api/tenants/me/api-keys/:keyId
Response
{
"success": true,
"message": "API key deleted"
}
Token Expiry & Refresh Cycle
- Access token: 15 minutes
- Refresh token: 7 days
- API key: No expiry (revoke via DELETE)
When your access token expires:
- Store the refresh token securely (httpOnly cookie recommended)
- Call
/auth/refreshto get a new access token - Catch 401 errors and refresh automatically
Error Responses
| Error | HTTP | Cause | Action |
|---|---|---|---|
INVALID_REQUEST | 400 | Missing required fields | Check request schema |
UNAUTHORIZED | 401 | Invalid credentials or expired token | Refresh token or re-login |
FORBIDDEN | 403 | Accessing another tenant's resources | Verify tenant context |
CONFLICT | 409 | Email already registered | Try login instead |
INTERNAL_ERROR | 500 | Server error | Retry with backoff |