Skip to main content

Installation

Install the EasyOTP SDK using npm or your preferred package manager:
npm install @easy-otp/sdk

Quick Start

import { EasyOTP } from '@easy-otp/sdk';

const client = new EasyOTP({
  apiKey: 'YOUR_API_KEY'
});

const result = await client.send({
  channel: 'sms',
  recipient: '+1234567890',
  message: 'Your verification code is: {code}'
});

console.log('Verification ID:', result.verification_id);

Initialization

Create a new EasyOTP client instance with your API key:
import { EasyOTP } from '@easy-otp/sdk';

const client = new EasyOTP({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://app.easyotp.dev/api/v1'
});

Configuration Options

apiKey
string
required
Your EasyOTP API key. Get it from your dashboard.
baseUrl
string
Base URL for the API. Defaults to https://app.easyotp.dev/api/v1.
Never expose your API key in client-side code. Always use the SDK from your backend server.

Methods

send()

Send a verification code via SMS, Email, or Voice.
const result = await client.send({
  channel: 'sms',
  recipient: '+1234567890',
  message: 'Your verification code is: {code}',
  expires_in: 300
});

Parameters

channel
string
required
Communication channel. Must be one of: sms, email, or voice
recipient
string
required
Recipient address:
  • For SMS/Voice: E.164 formatted phone number (e.g., +1234567890)
  • For Email: Valid email address (e.g., [email protected])
message
string
Custom message template. Use {code} as a placeholder for the verification code.Default: "Your verification code is: {code}"
subject
string
Email subject line (only used when channel is email)Default: "Your Verification Code"
expires_in
number
Code expiration time in seconds. Must be between 60 and 3600.Default: 300 (5 minutes)
code
string
Custom verification code. Must be a numeric string between 4-10 digits.If not provided, a code will be automatically generated.

Returns

success
boolean
Always true for successful requests
verification_id
string
Unique identifier for this verification. Use this when calling verify().
expires_at
string
ISO 8601 timestamp when the code expires
request_id
string
Unique request identifier for debugging

verify()

Verify a code that was previously sent.
const result = await client.verify({
  verification_id: '11f951d5-32d1-4b49-bdda-7da248e2615c',
  code: '123456'
});

Parameters

verification_id
string
required
The verification ID returned from the send() method
code
string
required
The verification code to check. Must be a numeric string between 4-10 digits.

Returns

success
boolean
Always true for successful requests (even if the code is invalid)
verified
boolean
true if the code was correct and not expired, false otherwise
message
string
Human-readable result message. Possible values:
  • "Code verified successfully"
  • "Invalid code"
  • "Code expired"
  • "Code already used"
request_id
string
Unique request identifier for debugging

Examples

Complete Verification Flow

import { EasyOTP } from '@easy-otp/sdk';

const client = new EasyOTP({
  apiKey: process.env.EASYOTP_API_KEY
});

async function verifyPhoneNumber(phoneNumber) {
  try {
    const sendResult = await client.send({
      channel: 'sms',
      recipient: phoneNumber,
      message: 'Your verification code is: {code}',
      expires_in: 300
    });
    
    console.log('Code sent! Verification ID:', sendResult.verification_id);
    
    return sendResult.verification_id;
  } catch (error) {
    console.error('Failed to send code:', error.message);
    throw error;
  }
}

async function checkVerificationCode(verificationId, code) {
  try {
    const verifyResult = await client.verify({
      verification_id: verificationId,
      code: code
    });
    
    if (verifyResult.verified) {
      console.log('Code verified successfully!');
      return true;
    } else {
      console.log('Verification failed:', verifyResult.message);
      return false;
    }
  } catch (error) {
    console.error('Failed to verify code:', error.message);
    throw error;
  }
}

const verificationId = await verifyPhoneNumber('+1234567890');
const isValid = await checkVerificationCode(verificationId, '123456');

Sending via Different Channels

const result = await client.send({
  channel: 'sms',
  recipient: '+1234567890',
  message: 'Your Acme Corp verification code is: {code}',
  expires_in: 300
});

Error Handling

The SDK throws errors for failed requests. Always wrap API calls in try-catch blocks:
import { EasyOTP } from '@easy-otp/sdk';

const client = new EasyOTP({
  apiKey: process.env.EASYOTP_API_KEY
});

try {
  const result = await client.send({
    channel: 'sms',
    recipient: '+1234567890',
    message: 'Your verification code is: {code}'
  });
  
  console.log('Success:', result.verification_id);
} catch (error) {
  if (error.status === 401) {
    console.error('Invalid API key');
  } else if (error.status === 402) {
    console.error('Insufficient credits');
  } else if (error.status === 429) {
    console.error('Rate limit exceeded:', error.retry_after);
  } else {
    console.error('Error:', error.message);
  }
}

Express.js Integration Example

import express from 'express';
import { EasyOTP } from '@easy-otp/sdk';

const app = express();
app.use(express.json());

const client = new EasyOTP({
  apiKey: process.env.EASYOTP_API_KEY
});

const sessions = new Map();

app.post('/api/send-code', async (req, res) => {
  try {
    const { phoneNumber } = req.body;
    
    const result = await client.send({
      channel: 'sms',
      recipient: phoneNumber,
      message: 'Your verification code is: {code}',
      expires_in: 300
    });
    
    const sessionId = generateSessionId();
    sessions.set(sessionId, {
      phoneNumber,
      verificationId: result.verification_id
    });
    
    res.json({ sessionId });
  } catch (error) {
    res.status(error.status || 500).json({
      error: error.message
    });
  }
});

app.post('/api/verify-code', async (req, res) => {
  try {
    const { sessionId, code } = req.body;
    const session = sessions.get(sessionId);
    
    if (!session) {
      return res.status(400).json({ error: 'Invalid session' });
    }
    
    const result = await client.verify({
      verification_id: session.verificationId,
      code: code
    });
    
    if (result.verified) {
      sessions.delete(sessionId);
      res.json({ success: true });
    } else {
      res.json({ success: false, message: result.message });
    }
  } catch (error) {
    res.status(error.status || 500).json({
      error: error.message
    });
  }
});

Error Handling

The SDK throws errors for failed API requests. Error objects include:
  • message: Human-readable error message
  • status: HTTP status code
  • request_id: Unique request identifier for debugging
  • retry_after: Seconds to wait before retrying (for rate limit errors)

Common Error Codes

Status CodeMeaningSolution
400Bad RequestCheck your request parameters
401UnauthorizedVerify your API key is correct
402Payment RequiredAdd credits to your account
403ForbiddenAPI key is disabled
404Not FoundVerification ID doesn’t exist
429Rate Limit ExceededWait for retry_after seconds
500Internal Server ErrorContact support with request_id

TypeScript Support

The SDK includes full TypeScript definitions. Import types as needed:
import { EasyOTP, SendOptions, VerifyOptions } from '@easy-otp/sdk';

const client = new EasyOTP({
  apiKey: process.env.EASYOTP_API_KEY!
});

const sendOptions: SendOptions = {
  channel: 'sms',
  recipient: '+1234567890',
  message: 'Your code is: {code}'
};

const result = await client.send(sendOptions);

Best Practices

Store API keys securely: Use environment variables and never commit them to version control.
Handle errors gracefully: Always wrap SDK calls in try-catch blocks and provide meaningful error messages to users.
Use appropriate expiration times:
  • SMS/Voice: 2-5 minutes
  • Email: 10-15 minutes
Keep verification IDs server-side: Never expose verification IDs in URLs or client-side code. Store them server-side associated with user sessions.
Rate limiting: The SDK automatically handles rate limit responses. Check for retry_after in error responses to inform users when they can retry.

Additional Resources