Turalogin

The fully hosted passwordless service.

No email infrastructure. No token management. No verification logic.Turalogin handles it all. just two API calls from your backend.

Or copy the AI prompt to scaffold auth instantly

Set Up with AI in Seconds

Copy this prompt to Cursor, Claude, ChatGPT, or any AI coding assistant to instantly scaffold Turalogin authentication in your app.

Add Turalogin email authentication to my app using V2 API. Here's how it works: 1. My backend calls Turalogin API to start auth (sends email to user) 2. User receives email with BOTH a clickable one-time login link AND a 6-digit code 3. User chooses: Click link (instant) OR enter code manually (if link doesn't work) 4. My backend verifies the token/code with Turalogin API (server-side only) 5. On success, I create my own session/cookie - Turalogin never touches my frontend API Details (V2 - Recommended): - Base URL: https://api.turalogin.com/api/v2 - IMPORTANT: Every API request MUST include the Authorization header: Authorization: Bearer <TURALOGIN_API_KEY> Security Notes: - All /auth/verify endpoints MUST be called server-side only (never from browser) - Your TURALOGIN_API_KEY must never be exposed to the client V2 Endpoints: POST /auth/start Body: { email: string, method?: 'ota' | 'otp', // Optional, defaults to 'ota' redirectUrl?: string, // Required for ota method appName?: string // Optional: Override app name in emails (max 128 chars, for multi-brand apps) } Returns: { token, method, message, expiresAt } - method='ota' (One Time Authentication): Email contains clickable link + 6-digit code - Link format: {redirectUrl}?token={token} - User can click link OR enter the 6-digit code - method='otp': Email contains ONLY 6-digit code (no link) - For pure OTP flow without links POST /auth/verify/link Body: { token: string // From URL query parameter (?token=...) } Returns: { success, jwt, user: { email } } - Use this when user clicks the one-time login link - Extract token from URL query parameter - Returns JWT in the "jwt" field (V2 uses email as JWT subject) - V2 does not return expiresIn - you manage your own session duration POST /auth/verify/code Body: { token: string, // From /auth/start response code: string // 6-digit code from email } Returns: { success, jwt, user: { email } } - Use this when user enters the 6-digit code manually - Requires BOTH token (from /auth/start) AND code (from user input) - Returns JWT in the "jwt" field (V2 uses email as JWT subject) - V2 does not return expiresIn - you manage your own session duration Error Responses: - 400: Missing or invalid parameters (includes helpful hints) - 401: Invalid, expired, already-used token/session, or wrong verification code - 500: Server error (retry with exponential backoff) Session Constraints: - One-time login links and OTP codes expire after 15 minutes - Each link/code can only be used once (single-use) - After verification, create your own session - Turalogin does not manage sessions Domain/User Restriction (Your Responsibility): Turalogin verifies ANY email address. If your app needs access control: - Domain restriction: Validate email domain BEFORE calling /auth/start - Email allowlist: Check against your user database BEFORE calling /auth/start - Example: const domain = email.split("@")[1]?.toLowerCase(); if (!ALLOWED_DOMAINS.includes(domain)) return 403; - This validation MUST be server-side (in your API route), never client-side only - Turalogin handles email verification - domain/user restriction is your responsibility Authentication Methods: - **ota** (default - One Time Authentication): Email contains clickable link + 6-digit code. User chooses which to use. - **otp**: Email contains ONLY 6-digit code (no link). Pure OTP flow. Per-Request Branding (appName): - Pass optional appName in /auth/start to override the dashboard-configured app name in emails - Useful for multi-brand apps sharing a single API key (e.g. multiple domains, white-label) - Email subject/body will say "Sign in to {appName}" instead of the dashboard name - Omitting appName falls back to dashboard name (fully backward compatible) V2 vs V1: V2 uses clearer naming and separate endpoints: - token (not sessionId) - jwt (not token in response) - redirectUrl (not validationUrl) - /verify/link and /verify/code (not single /verify endpoint) Environment Variables: - TURALOGIN_API_KEY: Your API key from the dashboard - TURALOGIN_REDIRECT_URL: The URL where authentication links redirect to (required for ota method) - Development: http://localhost:3000/auth/verify - Production: https://myapp.com/auth/verify Example fetch call to start authentication (V2): const response = await fetch('https://api.turalogin.com/api/v2/auth/start', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.TURALOGIN_API_KEY}` }, body: JSON.stringify({ email, method: 'ota', // 'ota' (link + code) or 'otp' (code only) redirectUrl: process.env.TURALOGIN_REDIRECT_URL, // required for ota appName: 'My Brand' // optional: override app name in emails (for multi-brand apps) }) }); const { token } = await response.json(); // IMPORTANT: Store this token - you'll need it for code verification Please create: 1. Auth endpoint to start authentication: - Calls Turalogin /api/v2/auth/start with email, method, and redirectUrl - Returns the token to your frontend/confirmation page - Example: redirect to /check-email?token=${token}&email=${email} 2. Auth verification endpoints that handle TWO authentication paths: Path A - One Time Login Link, akaMagic Link (automatic): - Extract token from URL query param: ?token=xyz - Call /api/v2/auth/verify/link with { token } - Receives: { jwt, user } Path B - 6-Digit Code (manual): - User enters the 6-digit code from email - Get the token from your confirmation page (URL param, state, or hidden field) - Call /api/v2/auth/verify/code with { token: tokenFromStep1, code: userEnteredCode } - Receives: { jwt, user } - CRITICAL: You must pass BOTH token (from step 1) AND code (from user input) 3. Login page/form with email input 4. Confirmation page after email submission: - Display: "Check your email for a login link from Turalogin.com" - Display: "Or enter the 6-digit code from the email below:" - Include a code input field (6 digits, numeric) - Store the token from step 1 (pass via URL param, React state, or form hidden field) - When user enters code, call your verification endpoint with { token, code } 5. Use proper error handling for all error cases (400, 401, 500) and loading states 6. Set up environment variables for both TURALOGIN_API_KEY and TURALOGIN_REDIRECT_URL IMPORTANT - Domain Restriction (Your Responsibility): Turalogin will send a magic link to ANY valid email address. If you need to restrict access to specific email domains (e.g., internal tools, team dashboards, B2B apps), you MUST validate the domain in your backend BEFORE calling /auth/start. Example domain restriction pattern: const domain = email.split("@")[1]?.toLowerCase(); const ALLOWED_DOMAINS = ["yourcompany.com", "partner.com"]; if (!ALLOWED_DOMAINS.includes(domain)) { return Response.json({ error: "Unauthorized domain" }, { status: 403 }); } This validation must be server-side (in your API route), never client-side only. Turalogin handles email verification - domain/user restriction is your responsibility. V2 Key Concepts: - token: Returned by /auth/start, used for verification (both paths) - jwt: Returned by /auth/verify/link or /auth/verify/code (this is your authentication JWT) - code: The 6-digit number in the email (optional alternative to clicking link) - appName: Optional per-request override of the email display name (for multi-brand/white-label apps) V2 Endpoints: - Start: POST /api/v2/auth/start → returns { token } - Verify link: POST /api/v2/auth/verify/link → accepts { token } → returns { jwt, user } - Verify code: POST /api/v2/auth/verify/code → accepts { token, code } → returns { jwt, user } V2 is clearer than V1 because it uses separate endpoints for link and code verification.

Need a framework-specific prompt? View all AI prompts →

Try It Live

See how Turalogin works in action. When you request a magic link, the email contains both a clickable button and a 6-digit code. Users choose their preferred method.

What Users Receive

Sign in to Your App

Your App

Sign In

Or use this code:

123456

Two Ways to Sign In

One-Click Button

Click the button → Instant authentication. Fast and effortless.

6-Digit Code

Copy and paste the code. Works when links don't render or switching devices.

This flexibility means your users always have a way to sign in

Links blocked by email client? Use the code. On mobile? Click the button. It just works.

MCP Server for AI Assistants

Use the Turalogin MCP server so Cursor and Claude can integrate auth directly. The assistant calls our API instead of just suggesting code.

The Problem

Auth is time consuming to build. Email deliverability, link expiry, token security. it's a rabbit hole.

Hosted auth sidesteps this but adds redirects, login pages you don't control, and tokens exposed to the browser.

The Solution

Turalogin sends login links from our trusted domain. Your backend verifies. You create the session. That's it.

Users never leave your site
Frontend never touches tokens
Backend makes two API calls total

How It Works

1

Backend calls /auth/start with user's email

2

User gets email with login button AND 6-digit code

3

User chooses: Click button (instant) or enter code (manual)

4

Backend calls /auth/verify server-side

5

You create your session. Turalogin is done

Two endpoints. No redirects. No token leakage.

Invite Users Too

Beyond login, Turalogin V2 lets you invite users with the same link and code flow. Custom expiry, metadata, batch sending, status tracking.

V2 Invite Endpoint

Send branded invite emails with a magic link and 6-digit code. Same verification flow as login.

Custom Expiry

Set expiresIn from 1 minute to 7 days. Default 24 hours.

Metadata Pass-Through

Attach JSON metadata to invites. Stored and returned on verification. No extra lookups.

Batch Invites

Send up to 50 invites in a single API call. Each gets individual success/failure tracking.

Status Check

Query any invite by token to see if it's pending, used, or expired. Great for admin dashboards.

Same Security Model

Server-to-server verification, one-time use tokens, automatic expiry. No shortcuts.

Quick Example

POST /api/v2/auth/invite
{
  "email": "newuser@company.com",
  "message": "Welcome to the team!",
  "redirectUrl": "https://app.com/accept-invite",
  "expiresIn": 604800,
  "appName": "My App",
  "metadata": { "role": "editor", "team": "design" },
  "cc": ["admin@company.com"]
}

Returns a token. Verify via /verify/link or /verify/code. Response includes metadata.

What Your Users See

Professional, mobile-friendly emails sent from our trusted domain. Your app name is displayed prominently. users know exactly where they're signing in.

Sign in to Your App
From: Turalogin <auth@mail.turalogin.com>

Your App Name

powered by Turalogin

Click the button below to sign in to your account. This link expires in 15 minutes.

Sign in to Your App

Or use this verification code:

123456

If you didn't request this email, you can safely ignore it.

Emails come from auth@mail.turalogin.com with full SPF/DKIM/DMARC . no spam folder issues.

Why Hosted

Email deliverability is hard. Token security is tricky. Building auth infrastructure takes weeks. Turalogin handles all of it so you don't have to.

Email Deliverability Solved

SPF, DKIM, DMARC. all configured. Your login emails land in inboxes, not spam.

Secure by Default

Tokens never touch the browser. Links expire. Verification is server-to-server only.

Two API Calls

Start auth. Verify token. That's the entire integration. Works on localhost immediately.

You Own Everything Else

Create your own sessions and cookies. Turalogin verifies identity and gets out of the way.

Any Backend, Same Pattern

POST to start. POST to verify. That's it. If your stack can make HTTP requests, you're ready.

Next.js, Express, Django, Rails, Go, PHP. same two endpoints.

Works Everywhere

Next.js
Node.js
Bun/Deno
Python
Ruby
Java
Go
PHP
.NET
Serverless

Dashboard

Create apps, generate API keys, rotate secrets. Each app gets isolated tokens. no cross-app leakage.

This site runs on Turalogin. You'll experience the flow firsthand.

Security Model

Tokens never touch browsers. Login links expire in 15 minutes and work once. Verification is server-to-server only.

Simple doesn't mean insecure. This is auth with a small attack surface.

Built For

Teams shipping multiple apps
Devs tired of auth boilerplate
Apps that need session control

Auth that disappears into infrastructure. Boring in the best way.

Get Started

Sign up, grab your API key, and integrate. You'll use the same login link flow your users will.

How Turalogin Compares

Many auth services exist, but they solve different problems. Here's how Turalogin fits into the landscape.

Closest Matches Conceptually

Clerk

Supports magic links and email-first auth, but it is frontend-heavy. Expects UI components or SDKs in the client and manages sessions unless you work around it.

Strong product, but more opinionated than Turalogin's design.

Auth0

Supports passwordless email links and backend verification. However, it is complex, expensive at scale, and deeply involved in frontend redirects and hosted pages.

Requires careful configuration to avoid frontend coupling.

Supabase Auth

Supports magic links and server-side verification. Closer to Turalogin's flow, but bundled with a full backend platform and database.

Not a focused auth-only service.

Lightweight and Developer-Centric

Magic

Popularized passwordless email auth. Relies on client-side SDKs and cryptographic keys in the browser.

Almost the opposite of Turalogin's backend-only trust boundary.

Stytch

One of the closest commercial comparisons. Supports magic links, backend verification, and session handoff.

Still expects frontend participation and has broader scope than Turalogin's intentionally narrow design.

Open Source Adjacent Patterns

NextAuth (Auth.js)

Supports email magic links and backend verification, but it is a library, not a hosted auth service.

Turalogin resembles extracting just the email provider piece and turning it into a standalone API.

Ory Kratos

Supports passwordless login flows with backend APIs. Powerful but heavy, self-hosted, and complex.

Far more complex than what Turalogin aims to be.

What Makes Turalogin Distinct

Turalogin's model is closer to “email identity verification as a service” than full authentication. It doesn't manage users, sessions, UI, or cookies. It verifies control of an email address and hands that fact back to the backend. That puts it closer to Stripe-style APIs than traditional auth platforms.

In short, services exist in the same category, but none are as narrow, backend-only, and frontend-agnostic by default. That simplicity is the differentiator.