BaxVerify/Flutter SDK

Flutter SDK

Send and verify SMS OTP codes in Flutter iOS & Android apps

Installation

dependencies:
  baxcloud_verify_sdk: ^1.2.0
flutter pub get

Published on pub.dev. The SDK connects to BaxCloud automatically — only projectId and apiKey are required.

Quick Start

1import 'package:baxcloud_verify_sdk/baxcloud_verify_sdk.dart';
2
3final verify = BaxCloudVerifyClient(
4  config: BaxCloudVerifyConfig(
5    projectId: 'your-project-id',
6    apiKey: 'your-baxverify-api-key',
7    debug: true,
8  ),
9);
10
11// Send OTP
12final sent = await verify.sendOtp(
13  SendOtpOptions(
14    phone: '+14155552671',
15    purpose: BaxVerifyOtpPurpose.login,
16  ),
17);
18
19// Verify OTP — returns accessToken
20final result = await verify.verifyOtp(
21  VerifyOtpOptions(phone: '+14155552671', code: '123456'),
22);
23
24// Send proof to your backend or auth adapter
25final proof = result.externalAuth; // { id: phone, token: accessToken }

Configuration

OptionRequiredDescription
projectIdYesBaxCloud project ID
apiKeyYesAPI key with BaxVerify enabled
debugNoLog SDK activity

Production tip: proxy sendOtp / verifyOtp through your backend when possible so the API key is not embedded in the app. The accessToken flow works either way.

Verification access token

After verifyOtp, use result.accessToken with any backend. Validate on your server with @baxcloud/baxverify or the REST validate-token endpoint — not with a secret key in the mobile app.

1// Third-party auth envelope (Parse, custom adapters)
2final auth = result.externalAuth;
3// { 'id': '+14155552671', 'token': 'eyJhbG...' }
1// Exchange proof on your backend
2final result = await verify.verifyOtp(...);
3await http.post(
4  Uri.parse('https://your-api.com/auth/phone-login'),
5  headers: {'Content-Type': 'application/json'},
6  body: jsonEncode({
7    'phone': result.phone,
8    'baxverifyToken': result.accessToken,
9  }),
10);

Parse Server login

BaxVerify proves phone ownership; Parse Server creates the user session. Install @baxcloud/parse-server-baxverify on Parse Server (setup guide), then log in from Flutter:

dependencies:
  baxcloud_verify_sdk: ^1.2.0
  parse_server_sdk: ^6.0.0
1import 'package:parse_server_sdk/parse_server_sdk.dart';
2import 'package:baxcloud_verify_sdk/baxcloud_verify_sdk.dart';
3
4await Parse().initialize(
5  'YOUR_PARSE_APP_ID',
6  'https://your-parse-server.com/parse',
7  clientKey: 'YOUR_PARSE_CLIENT_KEY',
8);
9
10// 1. Send + verify OTP with BaxVerify
11final result = await verify.verifyOtp(
12  VerifyOtpOptions(phone: '+14155552671', code: userEnteredCode),
13);
14
15// 2. Log in to Parse with authData { id, token }
16final response = await ParseUser.logInWith(
17  'baxverify',
18  result.externalAuth!,
19);
20
21if (response.success) {
22  final user = response.result as ParseUser;
23  // user.sessionToken is your Parse session
24}
  1. Flutter: sendOtp → user enters SMS code
  2. Flutter: verifyOtpaccessToken
  3. Flutter: ParseUser.logInWith('baxverify', externalAuth)
  4. Parse Server: @baxcloud/parse-server-baxverify validates the token

Example in the package: example/parse_phone_login.dart on pub.dev.

API Methods

MethodDescription
sendOtpSend SMS verification code
verifyOtpVerify code; returns accessToken
validateVerificationTokenServer-side token validation
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.
1try {
2  await verify.sendOtp(SendOtpOptions(phone: '+14155552671', purpose: 'LOGIN'));
3} on BaxVerifyException catch (e) {
4  switch (e.code) {
5    case 'BAXVERIFY_FEATURE_DISABLED':
6      // e.helpUrl → enable BaxVerify in dashboard
7      break;
8    case 'BAXVERIFY_SENDER_NOT_CONFIGURED':
9      // e.helpUrl → BaxVerify Setup
10      break;
11    case 'BAXVERIFY_INSUFFICIENT_CREDITS':
12      // e.helpUrl → Billing
13      break;
14    default:
15      print('${e.statusCode} ${e.code}: ${e.message}');
16  }
17}