Download OpenAPI specification:
Authentication API for Convilyn - AI-powered file conversion platform.
https://api.convilyn.com/api/v1https://pnz6t7y8jh.execute-api.ap-northeast-1.amazonaws.com/api/v1Most endpoints require a Bearer token in the Authorization header:
Authorization: Bearer <access_token>
Creates a new user account and sends verification email.
Important:
| email required | string <email> User email address (will be normalized to lowercase) |
| password required | string <password> [ 8 .. 128 ] characters Password must contain:
|
| fullName | string or null User's full name (optional) |
| newsletter | boolean Default: false Opt-in to marketing newsletter (persisted to user preferences) |
{- "email": "user@example.com",
- "password": "SecureP@ss123!",
- "fullName": "John Doe"
}{- "user": {
- "id": "d91c9ca9-03dc-4934-923c-a09487f7d727",
- "email": "user@example.com",
- "name": "John Doe",
- "emailVerified": false,
- "createdAt": "2026-01-13T10:00:00.000Z",
- "updatedAt": "2026-01-13T10:00:00.000Z"
}, - "message": "Account created successfully. Please check your email to verify your account before signing in.",
- "requiresVerification": true
}Authenticates user with email and password.
Requirements:
Security:
| email required | string <email> User email address |
| password required | string <password> User password |
{- "email": "user@example.com",
- "password": "SecureP@ss123!"
}{- "user": {
- "id": "d91c9ca9-03dc-4934-923c-a09487f7d727",
- "email": "user@example.com",
- "name": "John Doe",
- "emailVerified": true,
- "createdAt": "2026-01-12T15:21:20.583993Z",
- "updatedAt": "2026-01-12T15:23:56.731838Z"
}, - "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
- "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
- "expiresAt": "2026-01-12T15:36:23.153179Z"
}Revokes the refresh token for current session.
Note: Always returns success even if token is invalid (security best practice).
| refreshToken required | string JWT refresh token from signin or previous refresh |
{- "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}{- "message": "Logged out successfully",
- "success": true
}Revokes all refresh tokens for the authenticated user.
Use this when:
{- "message": "Logged out from 3 device(s)",
- "success": true
}Generate new access token and rotate refresh token.
Token Rotation (Security Feature):
Reuse Detection (Anti-Replay Attack):
Important: Always update stored refresh token after this call!
| refreshToken required | string JWT refresh token from signin or previous refresh |
{- "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}{- "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
- "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
- "expiresAt": "2026-01-13T10:30:00.000Z"
}Confirms user's email using verification token from email.
Token characteristics:
| token required | string Email verification token from email link |
{- "token": "dy0iNvNisdkWokl7s0yg-YlYTySxm9G6f4jH8FAK2vM"
}{- "message": "Email user@example.com verified successfully",
- "success": true
}Sends a new verification email.
Security (Anti-enumeration):
| email required | string <email> User email address |
{- "email": "user@example.com"
}{- "message": "Verification email sent to user@example.com",
- "success": true
}Sends password reset email with secure token.
Security (Anti-enumeration):
Token characteristics:
| email required | string <email> User email address |
{- "email": "user@example.com"
}{- "message": "If the email exists, a password reset link has been sent",
- "success": true
}Resets password using token from email.
Effects:
Important: User must sign in again after password reset.
| token required | string Password reset token from email link |
| newPassword required | string <password> [ 8 .. 128 ] characters New password (same requirements as signup) |
{- "token": "3ZEmvVgp7_Y59sUVQoR6KprN7KrdksiOQgS5PUC-Hsc",
- "newPassword": "NewSecureP@ss456!"
}{- "message": "Password reset successfully. Please sign in with your new password.",
- "success": true
}Changes password for currently logged-in user.
Requirements:
| currentPassword required | string <password> Current password |
| newPassword required | string <password> [ 8 .. 128 ] characters New password (same requirements as signup) |
{- "currentPassword": "OldP@ss123!",
- "newPassword": "NewP@ss456!"
}{- "message": "Password changed successfully",
- "success": true
}Returns profile data for the authenticated user.
{- "id": "d91c9ca9-03dc-4934-923c-a09487f7d727",
- "email": "user@example.com",
- "name": "John Doe",
- "emailVerified": true,
- "createdAt": "2026-01-12T15:21:20.583993Z",
- "updatedAt": "2026-01-12T15:23:56.731838Z"
}Update current user's profile information.
Requires authentication.
Allows users to update:
| displayName | string or null [ 1 .. 100 ] characters User's display name (full name) |
| locale | string or null <= 20 characters User's preferred locale (BCP 47 format) |
{- "displayName": "John Smith",
- "locale": "en"
}{- "id": "d91c9ca9-03dc-4934-923c-a09487f7d727",
- "email": "user@example.com",
- "name": "John Smith",
- "emailVerified": true,
- "createdAt": "2026-01-12T15:21:20.583993Z",
- "updatedAt": "2026-01-12T16:00:00.000Z"
}Permanently delete current user's account.
Requires authentication.
Effects:
{- "message": "Account deleted successfully",
- "success": true
}Returns the authenticated user's notification-channel toggles.
Missing keys fall back to defaults (newsletter=false, productUpdates=true, securityAlerts=true). The client always receives a complete view.
Requires authentication.
{- "newsletter": false,
- "productUpdates": true,
- "securityAlerts": true
}Partial update — only keys present in the body are written.
This is the canonical unsubscribe endpoint for the marketing
newsletter: send {"newsletter": false} to opt out.
Requires authentication.
| newsletter | boolean or null |
| productUpdates | boolean or null |
| securityAlerts | boolean or null |
{- "newsletter": false
}{- "newsletter": false,
- "productUpdates": true,
- "securityAlerts": true
}Third-party OAuth/OIDC sign-in (Google, GitHub).
Convilyn issues its own session — provider tokens never reach the browser. All flows use Authorization Code + PKCE (S256) + state.
Starts the Google OIDC sign-in flow.
The server generates a fresh state and PKCE
code_verifier, persists them under an
OAUTH_STATE#{state} item (TTL ≤ 10 min), and redirects
the user agent to Google's /o/oauth2/v2/auth endpoint
with code_challenge_method=S256.
Scopes: openid email profile (login only — incremental
authorization is used for any future Drive/Calendar work).
Caller: front-end triggers via plain navigation
(<a href> or window.location), NOT fetch, because the
response is a 302 to a cross-origin URL.
| redirect_to | string Default: "/" Example: redirect_to=/dashboard Same-origin path to land on after a successful
callback. Must start with a single |
{- "code": "AUTH_INVALID_REDIRECT",
- "message": "redirect_to must be a same-origin path"
}Starts the GitHub OAuth sign-in flow.
The server generates a fresh state and PKCE
code_verifier (S256 only — GitHub does not accept
plain), persists them under an OAUTH_STATE#{state} item
(TTL ≤ 10 min), and redirects to
https://github.com/login/oauth/authorize.
Scopes: read:user user:email — user:email is
required because GET /user does not return private
emails.
Caller: front-end triggers via plain navigation.
| redirect_to | string Default: "/" Example: redirect_to=/dashboard Same-origin path to land on after callback. |
{- "code": "AUTH_INVALID_REDIRECT",
- "message": "redirect_to must be a same-origin path"
}Receives Google's authorization-code redirect.
The server:
OAUTH_STATE#{state} item; rejects if
missing, expired, or already consumed (one-shot).code + code_verifier for tokens at
https://oauth2.googleapis.com/token.id_token (aud, iss, exp,
signature) against Google's published JWKs.OAuthAccount keyed by Google sub (NOT
email). If no Convilyn user is linked to that sub:id_token.email_verified is true and the email is
not present on any existing Convilyn user → create a
new Convilyn user and link.OAuthLinkingRequired (no automatic merge).access_token + HttpOnly refresh_token
cookies (same shape as /auth/signin) and redirects to
redirect_to.| code | string Authorization code from Google. Mutually exclusive with |
| state required | string Opaque state echoed back by Google. |
| error | string Set when the user denies consent or Google reports an error. |
| error_description | string |
Receives GitHub's authorization-code redirect.
The server:
OAUTH_STATE#{state} item; rejects if
missing, expired, or already consumed (one-shot).code + code_verifier for an access_token
at https://github.com/login/oauth/access_token.GET /user to obtain the GitHub id (the stable
identity key) and profile fields.GET /user/emails and selects the entry where
primary == true && verified == true. If no such entry
exists, returns 401 AUTH_OAUTH_TOKEN_INVALID.OAuthAccount keyed by GitHub id (NOT
email or login). Linking policy is identical to the
Google callback — a colliding email on an existing
email/password account returns 409 OAuthLinkingRequired.access_token + HttpOnly refresh_token
cookies and redirects to redirect_to.| code | string |
| state required | string |
| error | string |
| error_description | string |