Skip to main content
GET
/
verify
curl -X GET "http://localhost:8080/verify?type=signup&token=verification_token&redirect_to=https://yourapp.com/dashboard"
HTTP/1.1 303 See Other
Location: https://yourapp.com/dashboard#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&refresh_token=refresh_token_string&expires_in=3600&token_type=bearer
Verify email or phone confirmation via GET redirect. This endpoint is typically used in email verification links and redirects users to your application with authentication tokens.
This endpoint does not require authentication and is designed to be called from email links.
curl -X GET "http://localhost:8080/verify?type=signup&token=verification_token&redirect_to=https://yourapp.com/dashboard"

Query Parameters

type
string
required
The type of verification being performed.Options:
  • signup - Email/phone confirmation after registration
  • recovery - Password recovery verification
  • magiclink - Magic link authentication
  • invite - User invitation acceptance
  • email_change - Email change confirmation
token
string
required
The verification token sent via email or SMS.
redirect_to
string
URL to redirect to after successful verification. If not provided, uses default redirect URL.

Response

This endpoint returns a redirect response rather than JSON data.

Successful Verification

HTTP/1.1 303 See Other
Location: https://yourapp.com/dashboard#access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...&refresh_token=refresh_token_string&expires_in=3600&token_type=bearer
The redirect URL will include authentication tokens in the URL fragment:
ParameterDescription
access_tokenJWT access token for API authentication
refresh_tokenRefresh token for obtaining new access tokens
expires_inToken expiration time in seconds
token_typeToken type (always “bearer”)

Failed Verification

{
  "code": 400,
  "msg": "Invalid or expired token",
  "details": "The verification token is invalid or has expired"
}

Verification Types

Signup Verification

Confirms email or phone after user registration:
GET /verify?type=signup&token=abc123&redirect_to=https://yourapp.com/welcome

Password Recovery

Verifies password reset requests:
GET /verify?type=recovery&token=def456&redirect_to=https://yourapp.com/reset-password
Passwordless authentication via email:
GET /verify?type=magiclink&token=ghi789&redirect_to=https://yourapp.com/dashboard

Email Change

Confirms email address changes:
GET /verify?type=email_change&token=jkl012&redirect_to=https://yourapp.com/profile

User Invitation

Accepts user invitations:
GET /verify?type=invite&token=mno345&redirect_to=https://yourapp.com/setup

Handling Redirects in Your Application

Frontend Token Extraction

// Extract tokens from URL fragment after redirect
function extractTokensFromURL() {
  const hash = window.location.hash.substring(1);
  const params = new URLSearchParams(hash);
  
  return {
    access_token: params.get('access_token'),
    refresh_token: params.get('refresh_token'),
    expires_in: parseInt(params.get('expires_in')),
    token_type: params.get('token_type')
  };
}

// Use on your redirect page
if (window.location.hash.includes('access_token')) {
  const tokens = extractTokensFromURL();
  
  // Store tokens securely
  localStorage.setItem('access_token', tokens.access_token);
  localStorage.setItem('refresh_token', tokens.refresh_token);
  
  // Clean up URL
  window.history.replaceState({}, document.title, window.location.pathname);
  
  // Redirect to dashboard or show success message
  window.location.href = '/dashboard';
}

React Hook for Token Handling

import { useEffect } from 'react';
import { useRouter } from 'next/router';

function useAuthCallback() {
  const router = useRouter();

  useEffect(() => {
    // Check if we're on the callback page with tokens
    if (window.location.hash.includes('access_token')) {
      const hash = window.location.hash.substring(1);
      const params = new URLSearchParams(hash);
      
      const tokens = {
        access_token: params.get('access_token'),
        refresh_token: params.get('refresh_token'),
        expires_in: parseInt(params.get('expires_in'))
      };

      if (tokens.access_token) {
        // Store tokens and redirect
        localStorage.setItem('auth_tokens', JSON.stringify(tokens));
        
        // Clean URL and redirect
        window.history.replaceState({}, document.title, window.location.pathname);
        router.push('/dashboard');
      }
    }
  }, [router]);
}

// Use in your callback component
function AuthCallback() {
  useAuthCallback();
  
  return (
    <div>
      <h2>Verifying your account...</h2>
      <p>Please wait while we complete the verification process.</p>
    </div>
  );
}

Security Considerations

  • Token Expiration: Verification tokens have limited lifetime (typically 24 hours)
  • Single Use: Tokens can only be used once for security
  • HTTPS Required: Always use HTTPS in production to protect tokens
  • URL Fragments: Tokens are passed in URL fragments to prevent server-side logging

Error Handling

Handle verification errors gracefully in your application:
// Check for error parameters in URL
const urlParams = new URLSearchParams(window.location.search);
const error = urlParams.get('error');
const errorDescription = urlParams.get('error_description');

if (error) {
  switch (error) {
    case 'invalid_token':
      showError('The verification link is invalid or has expired. Please request a new one.');
      break;
    case 'expired_token':
      showError('The verification link has expired. Please request a new one.');
      break;
    default:
      showError('Verification failed. Please try again or contact support.');
  }
}

Development Testing

# Test signup verification
curl -X GET "http://localhost:8080/verify?type=signup&token=test_token&redirect_to=http://localhost:3000/callback"

# Test with invalid token
curl -X GET "http://localhost:8080/verify?type=signup&token=invalid_token"

Integration Testing

describe('Verification Endpoint', () => {
  test('should redirect with tokens on valid verification', async () => {
    const response = await request(app)
      .get('/verify')
      .query({
        type: 'signup',
        token: 'valid_test_token',
        redirect_to: 'http://localhost:3000/callback'
      })
      .expect(303);

    expect(response.headers.location).toContain('access_token=');
    expect(response.headers.location).toContain('refresh_token=');
  });

  test('should return error for invalid token', async () => {
    await request(app)
      .get('/verify')
      .query({
        type: 'signup',
        token: 'invalid_token'
      })
      .expect(400);
  });
});
I