DEV Community

Dishant Singh for DishIs Technologies

Posted on • Edited on

Build Your Own Temp Mail Website in Minutes with This Open-Source Project!

Most disposable email services are black boxes. You use the website, the emails appear, you have no idea what is running underneath and no way to customize anything.

FreeCustom.Email is different — there is an open-source project you can deploy as your own temp mail website, and a full API behind it that you can build on top of however you want. This post shows you exactly how to get your own instance running, how to hook into the API for custom functionality, and what you can build from there.


What You Are Actually Building

The open-source project gives you a complete, deployable temp mail frontend that connects to the FreeCustom.Email API. You get:

  • A working temp mail website with your own branding and domain
  • Full control over the UI — change anything you want
  • The same underlying email infrastructure (real SMTP, real delivery, real OTP extraction)
  • Access to the REST API for any custom features you want to add

You are not reinventing the email infrastructure. You are building a custom interface on top of infrastructure that already works.


Option 1: Use the Open-Source Frontend

FreeCustom.Email provides an open-source project you can clone and deploy. It is a complete temp mail UI that connects to the API.

The full guide with deployment instructions lives at freecustom.email/blog/build-your-own-temp-mail-website.

The basic flow:

# Clone the project
git clone https://github.com/DishIs/temp-mail
cd temp-mail

# Install dependencies
npm install

# Add your API key
cp .env.example .env.local
# Edit .env.local and set FCE_API_KEY=fce_your_key_here
Enter fullscreen mode Exit fullscreen mode

Get your API key by running fce login (install the CLI first) or from the dashboard.

# Start dev server
npm run dev
Enter fullscreen mode Exit fullscreen mode

You now have a running temp mail website at localhost:3000. Deploy it anywhere that runs Next.js — Vercel, Railway, Fly.io, your own VPS.


Option 2: Build From Scratch With the API

If you want more control, the REST API is straightforward. Here is a minimal temp mail app in about 60 lines of JavaScript:

// Simple temp mail app — no framework needed
const FCE_KEY = process.env.FCE_API_KEY;
const BASE = 'https://api2.freecustom.email/v1';

const headers = {
  'Authorization': `Bearer ${FCE_KEY}`,
  'Content-Type': 'application/json',
};

// 1. Create a random inbox
async function createInbox() {
  const res = await fetch(`${BASE}/inboxes`, {
    method: 'POST',
    headers,
    body: JSON.stringify({ inbox: `user-${Date.now()}@ditmail.info` }),
  });
  const { data } = await res.json();
  return data.inbox;
}

// 2. List messages
async function getMessages(inbox) {
  const res = await fetch(`${BASE}/inboxes/${inbox}/messages`, { headers });
  const { data } = await res.json();
  return data ?? [];
}

// 3. Get a single message
async function getMessage(inbox, id) {
  const res = await fetch(`${BASE}/inboxes/${inbox}/messages/${id}`, { headers });
  const { data } = await res.json();
  return data;
}

// 4. Extract OTP (Growth plan+)
async function getOtp(inbox) {
  const res = await fetch(`${BASE}/inboxes/${inbox}/otp`, { headers });
  const { data } = await res.json();
  return data?.otp;
}

// 5. Delete inbox when done
async function deleteInbox(inbox) {
  await fetch(`${BASE}/inboxes/${inbox}`, { method: 'DELETE', headers });
}
Enter fullscreen mode Exit fullscreen mode

That is the full API surface for a basic temp mail app. Five functions covering the whole lifecycle.


Adding Real-Time Email with WebSocket

Polling getMessages() works but feels slow. On Startup plan+, you can push emails to the browser the moment they arrive using the WebSocket endpoint:

// Client-side — connect to the real-time stream
function watchInbox(inbox, onEmail) {
  const ws = new WebSocket(
    `wss://api2.freecustom.email/v1/ws?inbox=${inbox}&api_key=${FCE_KEY}`
  );

  ws.onmessage = (event) => {
    const email = JSON.parse(event.data);
    onEmail(email);
  };

  ws.onclose = () => {
    // Auto-reconnect after 2 seconds
    setTimeout(() => watchInbox(inbox, onEmail), 2000);
  };

  return ws;
}

// Usage
const ws = watchInbox('user@ditmail.info', (email) => {
  console.log('New email:', email.subject);
  renderEmailInUI(email);
});
Enter fullscreen mode Exit fullscreen mode

Emails appear in under 200ms. No polling loop, no refresh button, no delay.


A Minimal React Component

Here is a self-contained React component that gives you a working temp mail UI:

import { useState, useEffect, useCallback } from 'react';

const FCE_BASE = 'https://api2.freecustom.email/v1';
const headers = { 'Authorization': `Bearer ${process.env.NEXT_PUBLIC_FCE_KEY}` };

export function TempMailWidget() {
  const [inbox, setInbox]     = useState<string | null>(null);
  const [messages, setMessages] = useState<any[]>([]);
  const [selected, setSelected] = useState<any | null>(null);
  const [loading, setLoading]  = useState(false);

  // Create inbox on mount
  useEffect(() => {
    const addr = `user-${Date.now()}@ditmail.info`;
    fetch(`${FCE_BASE}/inboxes`, {
      method: 'POST',
      headers: { ...headers, 'Content-Type': 'application/json' },
      body: JSON.stringify({ inbox: addr }),
    }).then(() => setInbox(addr));
  }, []);

  // Real-time WebSocket
  useEffect(() => {
    if (!inbox) return;
    const ws = new WebSocket(
      `wss://api2.freecustom.email/v1/ws?inbox=${inbox}&api_key=${process.env.NEXT_PUBLIC_FCE_KEY}`
    );
    ws.onmessage = (e) => {
      const msg = JSON.parse(e.data);
      setMessages(prev => [msg, ...prev]);
    };
    return () => ws.close();
  }, [inbox]);

  const openMessage = useCallback(async (id: string) => {
    setLoading(true);
    const res = await fetch(`${FCE_BASE}/inboxes/${inbox}/messages/${id}`, { headers });
    const { data } = await res.json();
    setSelected(data);
    setLoading(false);
  }, [inbox]);

  if (!inbox) return <p>Creating inbox…</p>;

  return (
    <div className="temp-mail">
      <div className="inbox-header">
        <code>{inbox}</code>
        <button onClick={() => navigator.clipboard.writeText(inbox)}>Copy</button>
      </div>

      {messages.length === 0 ? (
        <p className="waiting">Waiting for emails…</p>
      ) : (
        <ul className="message-list">
          {messages.map(msg => (
            <li key={msg.id} onClick={() => openMessage(msg.id)}>
              <strong>{msg.from?.name ?? msg.from?.address}</strong>
              <span>{msg.subject}</span>
            </li>
          ))}
        </ul>
      )}

      {selected && (
        <div className="message-body">
          <h3>{selected.subject}</h3>
          <p className="from">From: {selected.from?.address}</p>
          <div dangerouslySetInnerHTML={{ __html: selected.html ?? selected.text }} />
        </div>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Style it however you want. The core logic is about 60 lines.


Adding OTP Auto-Extraction to Your UI

This is the feature that users love most. When an email arrives that contains a verification code, surface it immediately:

async function checkForOtp(inbox: string): Promise<string | null> {
  const res = await fetch(
    `https://api2.freecustom.email/v1/inboxes/${inbox}/otp`,
    { headers }
  );
  const { success, data } = await res.json();
  return success ? data?.otp ?? null : null;
}

// In your email display component
const otp = await checkForOtp(inbox);
if (otp) {
  return (
    <div className="otp-banner">
      <span>Verification code:</span>
      <strong>{otp}</strong>
      <button onClick={() => navigator.clipboard.writeText(otp)}>Copy</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The API handles all OTP parsing — numeric codes, alphanumeric tokens, magic links. You just display whatever it returns. OTP extraction is available on Growth plan+.


CLI for Development and Testing

While building, the fce CLI is useful for quickly testing your inboxes without needing to use your UI:

# Install
curl -fsSL freecustom.email/install.sh | sh
fce login

# Watch any inbox in real time
fce watch user-1234567890@ditmail.info

# Check if OTP arrived
fce otp user-1234567890@ditmail.info
Enter fullscreen mode Exit fullscreen mode
────────────────────────────────────────────────
  OTP
────────────────────────────────────────────────

  OTP   ·  212342
  From  ·  noreply@someservice.com
  Subj  ·  Your verification code
  Time  ·  20:19:54
Enter fullscreen mode Exit fullscreen mode

The CLI is MIT-licensed and open source: github.com/DishIs/fce-cli


What You Can Build on Top of This

Once you have the basic UI running, the API opens up a lot of directions:

Custom domain inboxes — on Growth plan, users can receive emails at user@yourdomain.com instead of the default FCE domains. Great for white-labelling.

Saved inboxes — let logged-in users register and keep specific addresses rather than getting a random one every session.

Notification webhooks — call your own endpoint when emails arrive by combining WebSocket with your backend.

Team inboxes — a shared inbox address multiple people on a team can watch, useful for staging environment alerts.

API access for power users — expose the FCE API to your own users with your own rate limits and billing, acting as a reseller layer.

The full-stack guide covers the monetization and multi-tenant patterns in detail if you want to go that route.


The Full API Reference

The complete API is documented at freecustom.email/api/docs and there is an interactive playground at freecustom.email/api/playground. The OpenAPI spec is at freecustom.email/openapi.yaml if you want to generate a client in another language.

The endpoints you will use most:

POST   /v1/inboxes                              Create inbox
GET    /v1/inboxes                              List inboxes
DELETE /v1/inboxes/{inbox}                      Remove inbox
GET    /v1/inboxes/{inbox}/messages             List messages
GET    /v1/inboxes/{inbox}/messages/{id}        Get message
GET    /v1/inboxes/{inbox}/otp                  Extract OTP
WSS    /v1/ws?inbox={inbox}&api_key={key}       Real-time stream
GET    /v1/domains                              Available domains
Enter fullscreen mode Exit fullscreen mode

Auth is Authorization: Bearer fce_your_key on every request.


Pricing

The API is free to start — 5,000 requests per month with no credit card. Paid plans add higher limits, WebSocket delivery, and OTP extraction.

Plan Price Req/month WebSocket OTP extraction
Free $0 5,000
Developer $7/mo 100,000
Startup $19/mo 500,000
Growth $49/mo 2,000,000

Full details: freecustom.email/api/pricing


Links


If you build something with this — a custom UI, a niche tool on top of the API, a white-labelled instance — I would genuinely like to see it. Drop a link in the comments.

Top comments (0)