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
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
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
// 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
Error Handling: All methods return promises and should be wrapped in try-catch blocks. Rate limiting (429) and delivery failures (403) are handled automatically with descriptive error messages.
Framework Examples
React Integration
React Example
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
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
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
# For server-side applications
AKEDLY_API_KEY=your_api_key_here
AKEDLY_PIPELINE_ID=your_pipeline_id_here
Security Note: Never expose your API keys in client-side code for production applications. Use server-side routes to handle authentication and only pass transaction IDs to the frontend.
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