Node.js SDK

The Akedly Node.js SDK provides a simple JavaScript wrapper around our authentication API, compatible with both server-side Node.js applications and frontend frameworks.

Installation

Installation

BASH
npm install akedly

Requirements

  • Node.js 14 or higher
  • Akedly account with API key and pipeline ID

Quick Start

Import and configure the SDK with your credentials from the Akedly dashboard:

Setup

JS
/lib/akedly.js
import akedly from "akedly";

// Configure with your credentials
akedly.setAPIKey("YOUR_API_KEY");
akedly.setPipelineID("YOUR_PIPELINE_ID");

Authentication Flow

The SDK simplifies the 3-step authentication process into easy-to-use methods:

Step 1 & 2 Combined: Create and activate a transaction in one call Step 3: Verify the user's OTP input

Complete Flow

JS
// Step 1 & 2: Create and activate transaction
async function sendOTP() {
  try {
    const transaction = await akedly.createTransaction(
      "user@example.com", 
      "+201234567890"
    );
    
    const activatedTransaction = await akedly.activateTransaction(
      transaction.data._id
    );
    
    // Save the transaction object ID for verification
    return activatedTransaction.data._id;
  } catch (error) {
    console.error("Failed to send OTP:", error);
  }
}

// Step 3: Verify OTP
async function verifyUserOTP(userOTP, transactionObjectID) {
  try {
    const result = await akedly.verifyOTP(userOTP, transactionObjectID);
    
    if (result.status === "success") {
      console.log("User authenticated successfully!");
      return true;
    }
  } catch (error) {
    console.error("OTP verification failed:", error);
    return false;
  }
}

API Methods

  • Name
    setAPIKey(apiKey)
    Type
    function
    Description

    Configure your Akedly API key from the dashboard

  • Name
    setPipelineID(pipelineID)
    Type
    function
    Description

    Set your pipeline ID for the authentication flow

  • Name
    createTransaction(email, phoneNumber)
    Type
    async function
    Description

    Create a new authentication transaction. Returns transaction object with _id

  • Name
    activateTransaction(transactionID)
    Type
    async function
    Description

    Activate transaction and send OTP. Returns activated transaction with object ID

  • Name
    verifyOTP(otp, transactionObjectID)
    Type
    async function
    Description

    Verify user's OTP input. Returns verification result

Framework Examples

React Integration

React Example

JS
components/OTPAuth.jsx
import { useState } from 'react';
import akedly from 'akedly';

// Configure Akedly (do this once in your app)
akedly.setAPIKey(process.env.REACT_APP_AKEDLY_API_KEY);
akedly.setPipelineID(process.env.REACT_APP_AKEDLY_PIPELINE_ID);

function OTPAuth({ user, onSuccess }) {
  const [transactionId, setTransactionId] = useState(null);
  const [otp, setOtp] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const sendOTP = async () => {
    setLoading(true);
    setError(null);
    
    try {
      const transaction = await akedly.createTransaction(
        user.email, 
        user.phone
      );
      const activated = await akedly.activateTransaction(transaction.data._id);
      setTransactionId(activated.data._id);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const verifyOTP = async () => {
    setLoading(true);
    setError(null);
    
    try {
      const result = await akedly.verifyOTP(otp, transactionId);
      if (result.status === 'success') {
        onSuccess(result);
      } else {
        setError('Invalid OTP. Please try again.');
      }
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="max-w-md mx-auto">
      {!transactionId ? (
        <div>
          <p>Send OTP to {user.phone}</p>
          <button 
            onClick={sendOTP} 
            disabled={loading}
            className="btn-primary"
          >
            {loading ? 'Sending...' : 'Send OTP'}
          </button>
        </div>
      ) : (
        <div>
          <input
            type="text"
            value={otp}
            onChange={(e) => setOtp(e.target.value)}
            placeholder="Enter 6-digit OTP"
            maxLength={6}
            className="input"
          />
          <button 
            onClick={verifyOTP} 
            disabled={loading || otp.length < 6}
            className="btn-primary"
          >
            {loading ? 'Verifying...' : 'Verify OTP'}
          </button>
        </div>
      )}
      
      {error && (
        <div className="error-message">{error}</div>
      )}
    </div>
  );
}

export default OTPAuth;

Express.js Server

Express.js Example

JS
routes/auth.js
const express = require('express');
const akedly = require('akedly');

const router = express.Router();

// Configure Akedly
akedly.setAPIKey(process.env.AKEDLY_API_KEY);
akedly.setPipelineID(process.env.AKEDLY_PIPELINE_ID);

// Send OTP endpoint
router.post('/send-otp', async (req, res) => {
  try {
    const { email, phone } = req.body;
    
    // Validate input
    if (!phone) {
      return res.status(400).json({ error: 'Phone number is required' });
    }
    
    const transaction = await akedly.createTransaction(email, phone);
    const activated = await akedly.activateTransaction(transaction.data._id);
    
    res.json({ 
      success: true, 
      transactionId: activated.data._id,
      message: 'OTP sent successfully'
    });
  } catch (error) {
    console.error('OTP send error:', error);
    res.status(500).json({ 
      error: error.message || 'Failed to send OTP' 
    });
  }
});

// Verify OTP endpoint
router.post('/verify-otp', async (req, res) => {
  try {
    const { otp, transactionId } = req.body;
    
    // Validate input
    if (!otp || !transactionId) {
      return res.status(400).json({ 
        error: 'OTP and transaction ID are required' 
      });
    }
    
    const result = await akedly.verifyOTP(otp, transactionId);
    
    if (result.status === 'success') {
      // Here you can create JWT token, session, etc.
      res.json({ 
        success: true, 
        message: 'OTP verified successfully',
        // Add your auth token here
        // token: generateJWT(userId)
      });
    } else {
      res.status(400).json({ 
        error: 'Invalid OTP. Please try again.' 
      });
    }
  } catch (error) {
    console.error('OTP verification error:', error);
    res.status(500).json({ 
      error: error.message || 'Failed to verify OTP' 
    });
  }
});

module.exports = router;

Next.js API Routes

Next.js Example

JS
pages/api/auth/
import akedly from 'akedly';

// Configure Akedly
akedly.setAPIKey(process.env.AKEDLY_API_KEY);
akedly.setPipelineID(process.env.AKEDLY_PIPELINE_ID);

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const { email, phone } = req.body;
    
    const transaction = await akedly.createTransaction(email, phone);
    const activated = await akedly.activateTransaction(transaction.data._id);
    
    res.status(200).json({ 
      success: true, 
      transactionId: activated.data._id 
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

Environment Variables

Environment Setup

ENV
# For server-side applications
AKEDLY_API_KEY=your_api_key_here
AKEDLY_PIPELINE_ID=your_pipeline_id_here

Troubleshooting

Common Issues

  • Name
    Rate Limiting (429)
    Type
    error
    Description

    User hit the 60-second rate limit. Display a countdown timer and allow retry after the specified time.

  • Name
    Invalid Credentials (401)
    Type
    error
    Description

    Check your API key and pipeline ID. Ensure they're correctly set from your Akedly dashboard.

  • Name
    OTP Delivery Failed (403)
    Type
    error
    Description

    The phone number may be invalid or the pipeline configuration needs to be updated.

  • Name
    Network Errors
    Type
    error
    Description

    Wrap all API calls in try-catch blocks and implement proper error handling with user-friendly messages.

Best Practices

  • Server-side Configuration: Always configure API keys on the server side for security
  • Error Handling: Implement comprehensive error handling for all authentication flows
  • User Experience: Show loading states and clear error messages to users
  • Rate Limiting: Handle rate limits gracefully with countdown timers
  • Transaction Storage: Store transaction IDs securely and associate them with user sessions

Was this page helpful?