비트베이크

Building an Ultra-Fast SMS Authentication API with Bun & Elysia in 5 Minutes (Zero Paperwork)

2026-05-13T01:02:16.987Z

Close-up of a laptop screen displaying lines of code related to authentication and security, with a developer's hands on the keyboard in a modern, professional setting.

Building an Ultra-Fast SMS Authentication API with Bun & Elysia in 5 Minutes (Zero Paperwork)

1. The Bottleneck of SMS Verification in Modern Development

When you're building a startup MVP (Minimum Viable Product), launching an indie-hacker project, or scaling an e-commerce platform, verifying your users is non-negotiable. SMS authentication remains the gold standard for preventing spam, mitigating sybil attacks, and ensuring genuine user engagement.

However, the moment you attempt to integrate a traditional SMS API, you immediately hit a massive bureaucratic wall. Conventional SMS providers usually demand:

  • Extensive Paperwork: Business registration certificates, service usage proofs, and tedious legal documents.
  • Pre-Registered Caller IDs: You have to register a sending number and wait 3 to 5 business days for approval.
  • High Costs: Traditional providers charge anywhere from 30 to 50+ KRW per message, which scales poorly for bootstrapped startups.

For a solo developer or an agile team trying to validate an idea over the weekend, this barrier to entry is frustrating and drastically slows down your time-to-market.

2. The Solution Overview: Bun, Elysia, and EasyAuth

To bypass these archaic roadblocks, we are going to build a blazingly fast SMS authentication API in just 5 minutes. We'll leverage a modern, high-performance tech stack combined with a developer-first SMS service:

  1. Bun: The incredibly fast, all-in-one JavaScript runtime that serves as a drop-in replacement for Node.js.
  2. Elysia.js: A highly ergonomic, incredibly fast web framework built specifically for Bun, featuring end-to-end type safety.
  3. EasyAuth (이지어스): The ultimate developer-focused SMS Authentication API that requires zero paperwork.

EasyAuth is designed for speed. There is no need for business certificates, and you don't even need to pre-register a caller ID. It provides automatic sender numbers, and its API is distilled down to just two core endpoints: /send and /verify. Best of all, it costs only 15~25 KRW per message, making it up to 50% cheaper than traditional alternatives. You even get 10 free SMS credits upon signup to test your integration immediately.


3. Step-by-Step Implementation

Step 1: Initialize the Project Environment

First, ensure you have Bun installed on your system. If not, you can install it via curl (curl -fsSL https://bun.sh/install | bash).

Let's scaffold a new Elysia project. Open your terminal and run the following commands:

# Create a new project using the Elysia template
bun create elysia sms-auth-api
cd sms-auth-api

# Install Swagger for easy API testing and visualization
bun add @elysiajs/swagger

Step 2: Configure Environment Variables

Create an EasyAuth account. Once logged in, navigate to your dashboard to retrieve your API key. Create a .env file in the root of your new Bun project and store your credentials securely.

# .env
EASYAUTH_API_KEY=your_easyauth_api_key_here
PORT=3000

Step 3: Designing the API Endpoints

The architecture for our microservice is straightforward. We need a /send endpoint that clients will call to request an OTP (One-Time Password) to be sent to a specific phone number. Then, we need a /verify endpoint where the client submits the received code for validation.

Elysia makes this incredibly robust by offering out-of-the-box validation using t (powered by TypeBox). This ensures that if a client sends malformed data (like an invalid phone number format), the framework rejects the request before it even hits our business logic.


4. Complete Code Implementation

Below is the complete, production-ready code. Open src/index.ts and replace its contents with the following:

import { Elysia, t } from "elysia";
import { swagger } from "@elysiajs/swagger";

// EasyAuth API endpoint configuration
const EASYAUTH_API_URL = "https://api.easyauth.kr";
const API_KEY = process.env.EASYAUTH_API_KEY || "";

const app = new Elysia()
  // Automatically generate Swagger documentation (Access at http://localhost:3000/swagger)
  .use(swagger())
  
  // ---------------------------------------------------------
  // Endpoint 1: Send SMS Verification Code (/api/auth/send)
  // ---------------------------------------------------------
  .post(
    "/api/auth/send",
    async ({ body, set }) => {
      try {
        // Forward the request to EasyAuth's /send endpoint
        const response = await fetch(`${EASYAUTH_API_URL}/send`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${API_KEY}`
          },
          body: JSON.stringify({ phone: body.phone }),
        });

        const data = await response.json();

        // Handle upstream errors (e.g., insufficient balance, internal EasyAuth errors)
        if (!response.ok) {
          set.status = 400;
          return { success: false, message: data.message || "Failed to send SMS." };
        }

        return { success: true, message: "Verification code sent successfully." };
      } catch (error) {
        console.error("Send API Error:", error);
        set.status = 500;
        return { success: false, message: "Internal Server Error occurred." };
      }
    },
    {
      // Strict input validation using Elysia's 't' object
      body: t.Object({
        phone: t.String({ 
          pattern: "^010\\d{8}$", 
          error: "Invalid phone number format. Must be 11 digits starting with 010." 
        }),
      }),
    }
  )

  // ---------------------------------------------------------
  // Endpoint 2: Verify the Code (/api/auth/verify)
  // ---------------------------------------------------------
  .post(
    "/api/auth/verify",
    async ({ body, set }) => {
      try {
        // Forward the phone and code to EasyAuth's /verify endpoint
        const response = await fetch(`${EASYAUTH_API_URL}/verify`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${API_KEY}`
          },
          body: JSON.stringify({ phone: body.phone, code: body.code }),
        });

        const data = await response.json();

        // Handle incorrect codes or expired sessions
        if (!response.ok) {
          set.status = 400;
          return { success: false, message: data.message || "Invalid or expired verification code." };
        }

        return { success: true, message: "Phone number verified successfully." };
      } catch (error) {
        console.error("Verify API Error:", error);
        set.status = 500;
        return { success: false, message: "Internal Server Error occurred." };
      }
    },
    {
      // Validate that both phone and a 6-digit code are provided
      body: t.Object({
        phone: t.String(),
        code: t.String({ minLength: 6, maxLength: 6, error: "Code must be exactly 6 digits." }),
      }),
    }
  )
  .listen(process.env.PORT || 3000);

console.log(`🦊 SMS Auth API is running at http://${app.server?.hostname}:${app.server?.port}`);

Running and Testing the API

To start the development server, run:

bun run src/index.ts

Navigate to http://localhost:3000/swagger in your browser. Thanks to Elysia's swagger plugin, you will see an interactive API documentation page where you can immediately test sending and verifying SMS messages without writing a single line of frontend code.


5. Tips & Production Best Practices

While the code above works perfectly, bringing an SMS API to a production environment requires a few additional security measures to prevent abuse:

Implement Rate Limiting

SMS APIs cost money per invocation. Malicious actors could potentially write scripts to continuously hit your /send endpoint, draining your credits (a concept known as SMS toll fraud). To mitigate this, you should install @elysiajs/rate-limit:

bun add @elysiajs/rate-limit

And attach it to your application to restrict requests (e.g., max 3 requests per IP per minute).

Frontend Security & CORS

Ensure you restrict API access to only your authorized frontend domains. You can easily do this by incorporating the @elysiajs/cors plugin. Furthermore, consider implementing a CAPTCHA (like Google reCAPTCHA or Cloudflare Turnstile) on your frontend before allowing users to click the "Send SMS" button.

Robust Logging

Always implement logging to monitor SMS delivery success rates. In the case of EasyAuth, handling the responses gracefully and logging any 400 errors will help you debug user issues faster.


6. Conclusion: Why EasyAuth is the Ultimate Choice

Integrating SMS verification used to mean days of filling out paperwork, waiting for telecom approvals, and dealing with clunky legacy APIs. Today, by combining the raw speed of Bun and Elysia with the seamless developer experience of EasyAuth (이지어스), we successfully built a secure, fully functional SMS authentication microservice in under 5 minutes.

Whether you are an indie developer working on a side project, a freelancer delivering a client app, or a startup founder needing to launch an MVP quickly, EasyAuth is designed for you:

  • 🚫 Zero Paperwork: Forget business registrations and telecom proofs.
  • Instant Start: Integrate and test within 5 minutes of signing up.
  • 🤖 Auto Caller ID: No need to pre-register sending numbers.
  • 💸 Cost-Effective: At only 15~25 KRW per message, it's significantly cheaper than competitors.
  • 🎁 Free Trial: Get 10 free SMS credits immediately upon signup.

Stop wasting time on bureaucracy. Build fast, verify securely, and focus entirely on your core product with EasyAuth.

Start advertising on Bitbake

Contact Us

More Articles

2026-06-04T01:04:15.823Z

The 2026 E-Commerce New Product Launch Survival Formula: Dominating Platform Search Rankings in 7 Days via Reward-Based Trials and Purchase Verification

2026-06-04T01:04:15.800Z

2026 이커머스 신제품 론칭 생존 공식: 리워드형 체험단과 구매 인증으로 7일 만에 플랫폼 검색 랭킹 장악하기

2026-06-01T01:01:58.264Z

Surviving the 2026 Cookieless Era for B2C: Building Zero-Party Data with Reward-Based Quiz Marketing

2026-06-01T01:01:58.231Z

2026 쿠키리스 시대의 B2C 생존법: 리워드 기반 퀴즈 마케팅으로 제로파티 데이터 구축하기

Services

HomeFeedFAQCustomer Service

Inquiry

Bitbake

LAEM Studio | Business Registration No.: 542-40-01042

4th Floor, 402-J270, 16 Su-ro 116beon-gil, Wabu-eup, Namyangju-si, Gyeonggi-do

TwitterInstagramNaver Blog