BaxVerify/Node.js SDK

Node.js SDK

Server-side SMS OTP verification for Express, NestJS, Next.js API routes, and any Node.js backend

Installation

npm install @baxcloud/baxverify
# or
pnpm add @baxcloud/baxverify

Requires Node.js 18+. The client connects to BaxCloud automatically — only projectId and apiKey are required.

Quick Start

1import { BaxCloudVerifyClient } from '@baxcloud/baxverify';
2
3const verify = new BaxCloudVerifyClient({
4  projectId: process.env.BAXCLOUD_PROJECT_ID!,
5  apiKey: process.env.BAXCLOUD_API_KEY!,
6});
7
8// Send OTP from your API route
9await verify.sendOtp({ phone: '+14155552671', purpose: 'LOGIN' });
10
11// Verify code — returns accessToken (JWT proof)
12const result = await verify.verifyOtp({
13  phone: '+14155552671',
14  code: '123456',
15});
16
17// Validate token when client exchanges it for your session
18const proof = await verify.validateVerificationToken({
19  token: result.accessToken,
20});
21console.log('Verified:', proof.phone);

Phone login pattern

Keep your BaxCloud API key on the server. Mobile or web clients call your API; your API calls BaxVerify. After OTP success, return the accessToken to the client or exchange it immediately for your own session JWT.

1// POST /auth/phone-login — client sends BaxVerify proof
2app.post('/auth/phone-login', async (req, res) => {
3  const proof = await verify.validateVerificationToken({
4    token: req.body.accessToken,
5  });
6
7  // Create your session (JWT, cookie, database session, etc.)
8  const session = await createUserSession(proof.phone);
9  res.json({ sessionToken: session.token });
10});

Works with any auth stack — custom JWT, session cookies, Parse Server custom auth, Firebase custom tokens pattern, etc.

Parse Server

For Parse phone login, use the dedicated adapter @baxcloud/parse-server-baxverify — not a copy-paste auth file. Mobile clients call ParseUser.logInWith('baxverify', externalAuth) after BaxVerify OTP.

npm install @baxcloud/parse-server-baxverify

Full setup: Parse Server SDK guide · Flutter client

Configuration

OptionRequiredDescription
projectIdYesBaxCloud project ID
apiKeyYesAPI key with BaxVerify enabled
timeoutNoRequest timeout in ms (default 30000)
debugNoLog requests to console
1// externalAuth for Parse or other auth adapters
2const auth = BaxCloudVerifyClient.externalAuthFromVerifyResult(result);
3// { id: '+14155552671', token: 'eyJhbG...' }

API Methods

MethodDescription
sendOtpSend SMS verification code
verifyOtpVerify code; returns accessToken
validateVerificationTokenValidate proof JWT (single-use by default)
getStatsSent / verified / failed counts
listLogsPaginated delivery logs

Error codes

Failed BaxVerify API calls return a structured JSON envelope. Use error.code for programmatic handling and error.details.helpUrl to link users to the right dashboard page.

{
  "success": false,
  "error": {
    "code": "BAXVERIFY_FEATURE_DISABLED",
    "message": "BaxVerify is not enabled for this project. Enable it under Project → Features.",
    "details": {
      "projectId": "your-project-id",
      "helpUrl": "https://baxcloud.tech/dashboard/projects/your-project-id?tab=features",
      "docsUrl": "https://baxcloud.tech/docs/baxverify"
    }
  },
  "timestamp": "2026-06-06T12:00:00.000Z",
  "path": "/v1/auth/sms/send"
}
CodeHTTPMessageWhat to do
BAXVERIFY_FEATURE_DISABLED403BaxVerify is not enabled for this project.Enable BaxVerify under Project → Features (details.helpUrl).
BAXVERIFY_PLAN_NOT_INCLUDED403Your plan does not include BaxVerify.Upgrade your subscription (details.helpUrl → Billing).
BAXVERIFY_API_KEY_SCOPE403API key lacks BaxVerify scope.Create or edit an API key with BaxVerify enabled.
BAXVERIFY_SENDER_NOT_CONFIGURED400No SMS sender configured.Rent a phone number and/or register a Sender ID in BaxVerify Setup (details.helpUrl).
BAXVERIFY_INSUFFICIENT_CREDITS400Insufficient credits for SMS delivery.Add credits in Billing before sending (details.helpUrl).
BAXVERIFY_VERIFY_FEE_CREDITS400Insufficient credits for the verification fee.Add credits in Billing (details.helpUrl).
BAXVERIFY_NO_SUBSCRIPTION400No active subscription for this project.Subscribe or restore billing for the project.
BAXVERIFY_RATE_LIMIT429Rate limit exceeded.Wait before sending or verifying another code.
BAXVERIFY_OTP_EXPIRED400Code expired or not found.Call send again to request a new code.
BAXVERIFY_OTP_INVALID400Invalid verification code.Ask the user to re-enter the code from SMS.
BAXVERIFY_OTP_MAX_ATTEMPTS429Too many failed attempts.Request a new code via send.
BAXVERIFY_INVALID_PHONE400Phone number is not valid.Use full international format with country code (e.g. +14155552671).
BAXVERIFY_SMS_SEND_FAILED400Failed to send SMS.Check sender setup, destination number, and provider status.
BAXVERIFY_TOKEN_INVALID401Verification token is invalid or expired.User must verify OTP again to obtain a new accessToken.
BAXVERIFY_TOKEN_CONSUMED401Verification token already used.Tokens are single-use when consume: true — verify OTP again.
BAXVERIFY_PROJECT_INACTIVE403Project is not active.Reactivate the project in the dashboard.
BAXVERIFY_PROJECT_HEADER_REQUIRED400X-Project-Id header is required.Send X-Project-Id with every request.
BAXVERIFY_API_KEY_PROJECT_MISMATCH403API key does not belong to this project.Use an API key created for the same project as X-Project-Id.
1import { BaxVerifyError } from '@baxcloud/baxverify';
2
3try {
4  await verify.sendOtp({ phone: '+14155552671', purpose: 'LOGIN' });
5} catch (err) {
6  if (err instanceof BaxVerifyError) {
7    switch (err.code) {
8      case 'BAXVERIFY_FEATURE_DISABLED':
9        // err.details?.helpUrl → enable in dashboard
10        break;
11      case 'BAXVERIFY_SENDER_NOT_CONFIGURED':
12        // err.details?.helpUrl → BaxVerify Setup
13        break;
14      case 'BAXVERIFY_INSUFFICIENT_CREDITS':
15        // err.details?.helpUrl → Billing
16        break;
17      default:
18        console.error(err.statusCode, err.code, err.message);
19    }
20  }
21}