Authentication
The BD Voucher API uses Bearer JWTs. Two schemes are registered in the OpenAPI document:
| Scheme | Login endpoint | Used by |
|---|---|---|
bearer-client | POST /api/v1/auth/sign-in | Storefront, mobile apps, partner integrations |
bearer-admin | POST /api/v1/admin/auth/login | Operations console |
Getting a client token
curl -X POST https://api.bdvoucher.com/api/v1/auth/sign-in \ -H 'Content-Type: application/json' \ -d '{"msisdn":"8801712345678","password":"••••"}'const res = await fetch('https://api.bdvoucher.com/api/v1/auth/sign-in', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ msisdn: '8801712345678', password: '••••' }),});const { data } = await res.json();// data.accessToken, data.refreshTokenResponse:
{ "success": true, "message": "Login successful", "data": { "accessToken": "eyJhbGciOiJIUzI1NiIs…", "refreshToken": "eyJhbGciOiJIUzI1NiIs…", "user": { "id": 42, "msisdn": "8801712345678", "name": "Jane Doe", "email": "jane@example.com" } }}Getting an admin token
curl -X POST https://admin-api.bdvoucher.com/api/v1/admin/auth/login \ -H 'Content-Type: application/json' \ -d '{"email":"admin@bdvoucher.com","password":"••••"}'Sending authenticated requests
Include the token in every subsequent request:
GET /api/v1/user/profile HTTP/1.1Host: api.bdvoucher.comAuthorization: Bearer eyJhbGciOiJIUzI1NiIs…Token lifecycle
- Access token — short-lived (typically 15–60 min). Send on every request.
- Refresh token — long-lived. Call
POST /api/v1/auth/refresh-tokenwith it to get a new access token without re-entering credentials.
POST /api/v1/auth/refresh-tokenContent-Type: application/json
{ "refreshToken": "eyJhbGciOiJIUzI1NiIs…" }New user registration
Registration uses a two-step OTP flow to verify the mobile number before creating the account.
Step 1 — Check if MSISDN is available
POST /api/v1/auth/user-existContent-Type: application/json
{ "msisdn": "8801712345678" }Returns { "exists": false } when the number is free to register.
Step 2 — Request an OTP
POST /api/v1/auth/send-otpContent-Type: application/json
{ "msisdn": "8801712345678" }Step 3 — Verify the OTP
POST /api/v1/auth/verify-otpContent-Type: application/json
{ "msisdn": "8801712345678", "otpCode": "123456" }Returns a short-lived otpToken to authorize the registration call.
Step 4 — Create the account
POST /api/v1/auth/registerContent-Type: application/json
{ "msisdn": "8801712345678", "otp_code": "123456", "name": "Jane Doe", "password": "••••"}Password management
| Action | Endpoint |
|---|---|
| Change password (authenticated) | POST /api/v1/auth/change-password |
| Request a password-reset OTP | POST /api/v1/auth/forgot-password |
| Reset with OTP | POST /api/v1/auth/reset-password |
401 vs 403
- 401 Unauthorized — missing, expired, or invalid token.
- 403 Forbidden — authenticated, but lacks the required role/permission.
See the full error reference for all errorCode values.