Convilyn Auth API (1.0.0)

Download OpenAPI specification:

Convilyn Support: support@convilyn.com

Authentication API for Convilyn - AI-powered file conversion platform.

Base URL

  • Production: https://api.convilyn.com/api/v1
  • Development: https://pnz6t7y8jh.execute-api.ap-northeast-1.amazonaws.com/api/v1

Authentication

Most endpoints require a Bearer token in the Authorization header:

Authorization: Bearer <access_token>

Token Lifecycle

  • Access Token: 15 minutes
  • Refresh Token: 7 days
  • Email Verification Token: 24 hours
  • Password Reset Token: 30 minutes

Security Features

  • HMAC-SHA256 token hashing (tokens never stored in plaintext)
  • Refresh token rotation (each refresh generates new tokens)
  • Reuse detection (old rotated token triggers all-session revocation)
  • Account lockout (5 failed attempts = 15 min lock)
  • Anti-enumeration patterns (sensitive endpoints always return success)

Authentication

User signup, signin, and logout

Register new user

Creates a new user account and sends verification email.

Important:

  • User does NOT receive tokens immediately after signup
  • Email verification is REQUIRED before signin
  • Verification email is sent automatically
  • User must verify email then signin separately
Request Body schema: application/json
required
email
required
string <email>

User email address (will be normalized to lowercase)

password
required
string <password> [ 8 .. 128 ] characters

Password must contain:

  • At least 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one digit
  • At least one special character (!@#$%^&*(),.?":{}|<>)
fullName
string or null

User's full name (optional)

newsletter
boolean
Default: false

Opt-in to marketing newsletter (persisted to user preferences)

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "SecureP@ss123!",
  • "fullName": "John Doe"
}

Response samples

Content type
application/json
{
  • "user": {
    },
  • "message": "Account created successfully. Please check your email to verify your account before signing in.",
  • "requiresVerification": true
}

Sign in user

Authenticates user with email and password.

Requirements:

  • Email must be verified (403 if not)
  • Account must not be locked (423 if locked)
  • Account must not be disabled (403 if disabled)

Security:

  • 5 failed attempts triggers 15-minute account lock
  • Lock expires automatically after duration
Request Body schema: application/json
required
email
required
string <email>

User email address

password
required
string <password>

User password

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "SecureP@ss123!"
}

Response samples

Content type
application/json
{
  • "user": {
    },
  • "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "expiresAt": "2026-01-12T15:36:23.153179Z"
}

Logout from current device

Revokes the refresh token for current session.

Note: Always returns success even if token is invalid (security best practice).

Request Body schema: application/json
required
refreshToken
required
string

JWT refresh token from signin or previous refresh

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response samples

Content type
application/json
{
  • "message": "Logged out successfully",
  • "success": true
}

Logout from all devices

Revokes all refresh tokens for the authenticated user.

Use this when:

  • User suspects account compromise
  • User wants to sign out everywhere
  • After password change (optional)
Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "message": "Logged out from 3 device(s)",
  • "success": true
}

Token

Token refresh and rotation

Refresh access token (with rotation)

Generate new access token and rotate refresh token.

Token Rotation (Security Feature):

  • Each refresh generates a NEW refresh token
  • Old refresh token is invalidated immediately
  • Client MUST store and use the new refresh token

Reuse Detection (Anti-Replay Attack):

  • If an old/rotated token is reused, it indicates a potential token theft
  • ALL user sessions are immediately revoked
  • User must re-authenticate on all devices

Important: Always update stored refresh token after this call!

Request Body schema: application/json
required
refreshToken
required
string

JWT refresh token from signin or previous refresh

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response samples

Content type
application/json
{
  • "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  • "expiresAt": "2026-01-13T10:30:00.000Z"
}

Email Verification

Email verification endpoints

Verify email address

Confirms user's email using verification token from email.

Token characteristics:

  • One-time use only
  • Expires after 24 hours
  • Previous tokens are invalidated when new one is requested
Request Body schema: application/json
required
token
required
string

Email verification token from email link

Responses

Request samples

Content type
application/json
{
  • "token": "dy0iNvNisdkWokl7s0yg-YlYTySxm9G6f4jH8FAK2vM"
}

Response samples

Content type
application/json
{
  • "message": "Email user@example.com verified successfully",
  • "success": true
}

Resend verification email

Sends a new verification email.

Security (Anti-enumeration):

  • Always returns success message regardless of whether email exists
  • This prevents attackers from discovering valid email addresses
  • Check server logs for actual delivery status
Request Body schema: application/json
required
email
required
string <email>

User email address

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com"
}

Response samples

Content type
application/json
Example
{
  • "message": "Verification email sent to user@example.com",
  • "success": true
}

Password

Password reset and change

Request password reset

Sends password reset email with secure token.

Security (Anti-enumeration):

  • Always returns success regardless of whether email exists
  • This prevents attackers from discovering valid email addresses

Token characteristics:

  • Expires after 30 minutes
  • One-time use only
  • Previous reset tokens are invalidated
Request Body schema: application/json
required
email
required
string <email>

User email address

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com"
}

Response samples

Content type
application/json
{
  • "message": "If the email exists, a password reset link has been sent",
  • "success": true
}

Reset password with token

Resets password using token from email.

Effects:

  • Updates password
  • Revokes ALL refresh tokens (logout from all devices)
  • Sends confirmation email

Important: User must sign in again after password reset.

Request Body schema: application/json
required
token
required
string

Password reset token from email link

newPassword
required
string <password> [ 8 .. 128 ] characters

New password (same requirements as signup)

Responses

Request samples

Content type
application/json
{
  • "token": "3ZEmvVgp7_Y59sUVQoR6KprN7KrdksiOQgS5PUC-Hsc",
  • "newPassword": "NewSecureP@ss456!"
}

Response samples

Content type
application/json
{
  • "message": "Password reset successfully. Please sign in with your new password.",
  • "success": true
}

Change password (authenticated)

Changes password for currently logged-in user.

Requirements:

  • Must be authenticated
  • Current password must be correct
  • New password must meet strength requirements
Authorizations:
BearerAuth
Request Body schema: application/json
required
currentPassword
required
string <password>

Current password

newPassword
required
string <password> [ 8 .. 128 ] characters

New password (same requirements as signup)

Responses

Request samples

Content type
application/json
{
  • "currentPassword": "OldP@ss123!",
  • "newPassword": "NewP@ss456!"
}

Response samples

Content type
application/json
{
  • "message": "Password changed successfully",
  • "success": true
}

User

User information

Get current user info

Returns profile data for the authenticated user.

Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "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 user profile

Update current user's profile information.

Requires authentication.

Allows users to update:

  • Display name (full_name)
  • Preferred locale
Authorizations:
BearerAuth
Request Body schema: application/json
required
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)

Responses

Request samples

Content type
application/json
{
  • "displayName": "John Smith",
  • "locale": "en"
}

Response samples

Content type
application/json
{
  • "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"
}

Delete user account

Permanently delete current user's account.

Requires authentication.

Effects:

  • Soft deletes user account
  • Revokes all refresh tokens
  • Clears refresh token cookie
  • Logs out from all devices
Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "message": "Account deleted successfully",
  • "success": true
}

Get notification preferences

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.

Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "newsletter": false,
  • "productUpdates": true,
  • "securityAlerts": true
}

Update notification preferences

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.

Authorizations:
BearerAuth
Request Body schema: application/json
required
newsletter
boolean or null
productUpdates
boolean or null
securityAlerts
boolean or null

Responses

Request samples

Content type
application/json
{
  • "newsletter": false
}

Response samples

Content type
application/json
{
  • "newsletter": false,
  • "productUpdates": true,
  • "securityAlerts": true
}

OAuth

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.

Begin Google sign-in

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.

query Parameters
redirect_to
string
Default: "/"
Example: redirect_to=/dashboard

Same-origin path to land on after a successful callback. Must start with a single /. Defaults to the site root.

Responses

Response samples

Content type
application/json
{
  • "code": "AUTH_INVALID_REDIRECT",
  • "message": "redirect_to must be a same-origin path"
}

Begin GitHub sign-in

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:emailuser:email is required because GET /user does not return private emails.

Caller: front-end triggers via plain navigation.

query Parameters
redirect_to
string
Default: "/"
Example: redirect_to=/dashboard

Same-origin path to land on after callback.

Responses

Response samples

Content type
application/json
{
  • "code": "AUTH_INVALID_REDIRECT",
  • "message": "redirect_to must be a same-origin path"
}

Google sign-in callback

Receives Google's authorization-code redirect.

The server:

  1. Looks up the OAUTH_STATE#{state} item; rejects if missing, expired, or already consumed (one-shot).
  2. Exchanges code + code_verifier for tokens at https://oauth2.googleapis.com/token.
  3. Verifies the returned id_token (aud, iss, exp, signature) against Google's published JWKs.
  4. Upserts an OAuthAccount keyed by Google sub (NOT email). If no Convilyn user is linked to that sub:
    • If id_token.email_verified is true and the email is not present on any existing Convilyn user → create a new Convilyn user and link.
    • If the email matches an existing email/password account that is NOT already linked to Google → return 409 OAuthLinkingRequired (no automatic merge).
  5. Issues Convilyn access_token + HttpOnly refresh_token cookies (same shape as /auth/signin) and redirects to redirect_to.
query Parameters
code
string

Authorization code from Google. Mutually exclusive with error.

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

Responses

GitHub sign-in callback

Receives GitHub's authorization-code redirect.

The server:

  1. Looks up the OAUTH_STATE#{state} item; rejects if missing, expired, or already consumed (one-shot).
  2. Exchanges code + code_verifier for an access_token at https://github.com/login/oauth/access_token.
  3. Calls GET /user to obtain the GitHub id (the stable identity key) and profile fields.
  4. Calls GET /user/emails and selects the entry where primary == true && verified == true. If no such entry exists, returns 401 AUTH_OAUTH_TOKEN_INVALID.
  5. Upserts an 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.
  6. Issues Convilyn access_token + HttpOnly refresh_token cookies and redirects to redirect_to.
query Parameters
code
string
state
required
string
error
string
error_description
string

Responses