{"_id":"@akhilesharora/abdm-abha-sdk","_rev":"2-bb58665d018cc2f35a6d36766394c66b","name":"@akhilesharora/abdm-abha-sdk","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@akhilesharora/abdm-abha-sdk","version":"1.0.0","keywords":["abha","abdm","ayushman-bharat","health-id","india","healthcare","ndhm","health-account","aadhaar","kyc","hip","hiu","digital-health"],"author":{"name":"Akhilesh Arora","email":"akhildawra@gmail.com"},"license":"MIT","_id":"@akhilesharora/abdm-abha-sdk@1.0.0","maintainers":[{"name":"akhilesharora","email":"akhildawra@gmail.com"}],"homepage":"https://github.com/akhilesharora/abdm-abha-sdk#readme","bugs":{"url":"https://github.com/akhilesharora/abdm-abha-sdk/issues"},"dist":{"shasum":"61b85223ff4647e829184bf5333d7cfa6a04dbd4","tarball":"https://registry.npmjs.org/@akhilesharora/abdm-abha-sdk/-/abdm-abha-sdk-1.0.0.tgz","fileCount":7,"integrity":"sha512-KZd06+vrvjwhVDepuBcZbwMtfMNRRCPhJVb5INnY8kUgWdRDDvXWSozpi9DhbyoqBfjjCDjAVVI5wweQMBV8RQ==","signatures":[{"sig":"MEUCIFE8HEgg9OcCez9FEANB+TauOp7sJgMk9pUqsNFj7X0BAiEAifXaag8ktrnFyzaMlvfx0LyuhCUhD2pmYeHJxNUf14U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":101448},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","engines":{"node":">=16.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"d09255dc250b2051a88bb100eb1b08e73fc48a72","scripts":{"dev":"tsup src/index.ts --format cjs,esm --dts --watch","lint":"eslint src/","test":"vitest run","build":"tsup src/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"akhilesharora","email":"akhildawra@gmail.com"},"repository":{"url":"git+https://github.com/akhilesharora/abdm-abha-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"ABDM ABHA (Ayushman Bharat Health Account) SDK for Node.js - V3 API integration for Indian healthcare systems","directories":{},"_nodeVersion":"20.19.3","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^1.0.0","typescript":"^5.0.0","@types/node":"^20.0.0"},"peerDependencies":{},"_npmOperationalInternal":{"tmp":"tmp/abdm-abha-sdk_1.0.0_1770676854720_0.8448023916296914","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@akhilesharora/abdm-abha-sdk","version":"1.1.0","description":"ABDM ABHA (Ayushman Bharat Health Account) SDK for Node.js - V3 API integration for Indian healthcare systems","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup src/index.ts --format cjs,esm --dts --clean","dev":"tsup src/index.ts --format cjs,esm --dts --watch","lint":"eslint src/","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"keywords":["abha","abdm","ayushman-bharat","health-id","india","healthcare","ndhm","health-account","aadhaar","kyc","hip","hiu","digital-health"],"author":{"name":"Akhilesh Arora","email":"akhildawra@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/akhilesharora/abdm-abha-sdk.git"},"homepage":"https://github.com/akhilesharora/abdm-abha-sdk#readme","bugs":{"url":"https://github.com/akhilesharora/abdm-abha-sdk/issues"},"engines":{"node":">=16.0.0"},"devDependencies":{"@types/node":"^20.0.0","tsup":"^8.0.0","typescript":"^5.0.0","vitest":"^1.0.0"},"peerDependencies":{},"dependencies":{},"_id":"@akhilesharora/abdm-abha-sdk@1.1.0","gitHead":"dc3105c91d9aec757c01382fd5da767c3ca76f86","_nodeVersion":"20.19.3","_npmVersion":"10.8.2","dist":{"integrity":"sha512-lif/oOkjg+FIivNpu6icZE8I6UiNX/CXRf/3DQLsFT8FRdkdblwrMDl0OVRnxyR624QrsbLYOMWwqfD33zEqWw==","shasum":"cb09754f5c1447bf9bc1ffff9dc19f2eab194f6a","tarball":"https://registry.npmjs.org/@akhilesharora/abdm-abha-sdk/-/abdm-abha-sdk-1.1.0.tgz","fileCount":7,"unpackedSize":109297,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCID34Yc7YEs/ubClKI/8j1VexuHxcK19J+CZqasnHle0gAiEA+U2GeGqHvH5+Khm4HHSkOVRt4qniuF05uUDbweKsqVc="}]},"_npmUser":{"name":"akhilesharora","email":"akhildawra@gmail.com"},"directories":{},"maintainers":[{"name":"akhilesharora","email":"akhildawra@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/abdm-abha-sdk_1.1.0_1770677713048_0.799671345977127"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-09T22:40:54.574Z","modified":"2026-02-09T22:55:13.337Z","1.0.0":"2026-02-09T22:40:54.871Z","1.1.0":"2026-02-09T22:55:13.192Z"},"bugs":{"url":"https://github.com/akhilesharora/abdm-abha-sdk/issues"},"author":{"name":"Akhilesh Arora","email":"akhildawra@gmail.com"},"license":"MIT","homepage":"https://github.com/akhilesharora/abdm-abha-sdk#readme","keywords":["abha","abdm","ayushman-bharat","health-id","india","healthcare","ndhm","health-account","aadhaar","kyc","hip","hiu","digital-health"],"repository":{"type":"git","url":"git+https://github.com/akhilesharora/abdm-abha-sdk.git"},"description":"ABDM ABHA (Ayushman Bharat Health Account) SDK for Node.js - V3 API integration for Indian healthcare systems","maintainers":[{"name":"akhilesharora","email":"akhildawra@gmail.com"}],"readme":"# ABDM ABHA SDK\n\n> **Unofficial Version** - This SDK is not affiliated with or endorsed by ABDM/NHA.\n\nABDM (Ayushman Bharat Digital Mission) ABHA integration SDK for Node.js applications.\n\nBased on **ABHA V3 APIs SOP V1.2** (October 2024) - [Official Documentation](https://abdm.gov.in/publications).\n\n[![npm version](https://badge.fury.io/js/%40akhilesharora%2Fabdm-abha-sdk.svg)](https://www.npmjs.com/package/@akhilesharora/abdm-abha-sdk)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Features\n\n- **Complete V3 API Types** - Full TypeScript definitions for all ABHA V3 APIs\n- **Validation Utilities** - Validate ABHA numbers, addresses, mobile numbers, Aadhaar\n- **Format Helpers** - Format and parse ABHA identifiers\n- **Constants** - All API endpoints, scopes, error codes\n- **Zero Dependencies** - Lightweight, no external dependencies\n- **Tree Shakeable** - Import only what you need\n\n## Installation\n\n```bash\nnpm install @akhilesharora/abdm-abha-sdk\n```\n\n```bash\nyarn add @akhilesharora/abdm-abha-sdk\n```\n\n```bash\npnpm add @akhilesharora/abdm-abha-sdk\n```\n\n## Quick Start\n\n### Validate ABHA Number\n\n```typescript\nimport { isValidABHANumber, formatABHANumber, maskABHANumber } from '@akhilesharora/abdm-abha-sdk'\n\n// Validate format\nisValidABHANumber('91-1234-5678-9012')  // true\nisValidABHANumber('1234567890123')      // false (wrong format)\n\n// Format raw digits\nformatABHANumber('91123456789012')      // '91-1234-5678-9012'\n\n// Mask for display\nmaskABHANumber('91-1234-5678-9012')     // 'XX-XXXX-XXXX-9012'\n```\n\n### Validate ABHA Address\n\n```typescript\nimport { isValidABHAAddress, formatABHAAddress, parseABHAAddress } from '@akhilesharora/abdm-abha-sdk'\n\n// Validate\nisValidABHAAddress('john.doe@abdm')     // true (production)\nisValidABHAAddress('test_user@sbx')     // true (sandbox)\nisValidABHAAddress('john@gmail.com')    // false\n\n// Format\nformatABHAAddress('JohnDoe', 'production')  // 'johndoe@abdm'\nformatABHAAddress('TestUser', 'sandbox')    // 'testuser@sbx'\n\n// Parse\nparseABHAAddress('john.doe@abdm')       // { username: 'john.doe', domain: 'abdm' }\n```\n\n### Validate Mobile & Aadhaar\n\n```typescript\nimport { isValidMobile, isValidAadhaar, maskMobile, maskAadhaar } from '@akhilesharora/abdm-abha-sdk'\n\n// Mobile (Indian 10-digit)\nisValidMobile('9876543210')     // true\nmaskMobile('9876543210')        // 'XXXXXX3210'\n\n// Aadhaar (12-digit)\nisValidAadhaar('123456789012')  // true\nmaskAadhaar('123456789012')     // 'XXXXXXXX9012'\n```\n\n## Complete Integration Example\n\nHere's a full working example showing how to integrate ABHA login in your application:\n\n```typescript\nimport crypto from 'crypto'\nimport {\n  ABDM_BASE_URLS,\n  ABDM_SESSION_URLS,\n  API_ENDPOINTS,\n  SCOPES,\n  LOGIN_HINTS,\n  OTP_SYSTEMS,\n  HEADERS,\n  isValidABHANumber,\n  formatABHAName,\n} from '@akhilesharora/abdm-abha-sdk'\nimport type {\n  ABHAProfile,\n  OTPGenerateRequest,\n  OTPVerifyRequest,\n  OTPGenerateResponse,\n  OTPVerifyResponse,\n} from '@akhilesharora/abdm-abha-sdk'\n\n// ============================================================================\n// CONFIGURATION - Replace with your sandbox/production credentials\n// ============================================================================\nconst config = {\n  clientId: 'YOUR_CLIENT_ID',\n  clientSecret: 'YOUR_CLIENT_SECRET',\n  environment: 'sandbox' as const,\n}\n\nconst BASE_URL = ABDM_BASE_URLS[config.environment]\nconst SESSION_URL = ABDM_SESSION_URLS[config.environment]\n\n// ============================================================================\n// HELPER: Generate required headers\n// ============================================================================\nfunction getHeaders(accessToken: string, userToken?: string) {\n  const headers: Record<string, string> = {\n    'Content-Type': 'application/json',\n    [HEADERS.REQUEST_ID]: crypto.randomUUID(),\n    [HEADERS.TIMESTAMP]: new Date().toISOString(),\n    [HEADERS.AUTHORIZATION]: `Bearer ${accessToken}`,\n  }\n  if (userToken) {\n    headers[HEADERS.X_TOKEN] = `Bearer ${userToken}`\n  }\n  return headers\n}\n\n// ============================================================================\n// STEP 1: Get Session Token (call once, cache for 30 min)\n// ============================================================================\nasync function getSessionToken(): Promise<string> {\n  const response = await fetch(SESSION_URL, {\n    method: 'POST',\n    headers: { 'Content-Type': 'application/json' },\n    body: JSON.stringify({\n      clientId: config.clientId,\n      clientSecret: config.clientSecret,\n      grantType: 'client_credentials',\n    }),\n  })\n  const data = await response.json()\n  return data.accessToken  // Valid for 1800 seconds (30 min)\n}\n\n// ============================================================================\n// STEP 2: Get RSA Public Key for encryption\n// ============================================================================\nasync function getPublicKey(accessToken: string): Promise<string> {\n  const response = await fetch(`${BASE_URL}${API_ENDPOINTS.PUBLIC_KEY}`, {\n    headers: getHeaders(accessToken),\n  })\n  const data = await response.json()\n  return data.publicKey  // PEM format RSA public key\n}\n\n// ============================================================================\n// STEP 3: RSA Encrypt sensitive data (ABHA number, OTP, etc.)\n// ============================================================================\nfunction rsaEncrypt(data: string, publicKeyPem: string): string {\n  const buffer = Buffer.from(data, 'utf8')\n  const encrypted = crypto.publicEncrypt(\n    {\n      key: publicKeyPem,\n      padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,\n      oaepHash: 'sha1',  // ABDM requires SHA-1 for OAEP\n    },\n    buffer\n  )\n  return encrypted.toString('base64')\n}\n\n// ============================================================================\n// STEP 4: Request OTP\n// ============================================================================\nasync function requestOTP(\n  accessToken: string,\n  publicKey: string,\n  abhaNumber: string\n): Promise<{ txnId: string; message: string }> {\n  // Validate before sending\n  if (!isValidABHANumber(abhaNumber)) {\n    throw new Error('Invalid ABHA number format. Expected: XX-XXXX-XXXX-XXXX')\n  }\n\n  const request: OTPGenerateRequest = {\n    scope: [SCOPES.ABHA_LOGIN, SCOPES.MOBILE_VERIFY],\n    loginHint: LOGIN_HINTS.ABHA_NUMBER,\n    loginId: rsaEncrypt(abhaNumber.replace(/-/g, ''), publicKey),  // Encrypt without dashes\n    otpSystem: OTP_SYSTEMS.ABDM,\n  }\n\n  const response = await fetch(`${BASE_URL}${API_ENDPOINTS.LOGIN_REQUEST_OTP}`, {\n    method: 'POST',\n    headers: getHeaders(accessToken),\n    body: JSON.stringify(request),\n  })\n\n  const data: OTPGenerateResponse = await response.json()\n  return { txnId: data.txnId, message: data.message }\n}\n\n// ============================================================================\n// STEP 5: Verify OTP and get profile\n// ============================================================================\nasync function verifyOTP(\n  accessToken: string,\n  publicKey: string,\n  txnId: string,\n  otp: string\n): Promise<{ profile: ABHAProfile; tokens: { token: string; refreshToken: string } }> {\n  const request: OTPVerifyRequest = {\n    scope: [SCOPES.ABHA_LOGIN, SCOPES.MOBILE_VERIFY],\n    authData: {\n      authMethods: ['otp'],\n      otp: {\n        txnId,\n        otpValue: rsaEncrypt(otp, publicKey),\n      },\n    },\n  }\n\n  const response = await fetch(`${BASE_URL}${API_ENDPOINTS.LOGIN_VERIFY}`, {\n    method: 'POST',\n    headers: getHeaders(accessToken),\n    body: JSON.stringify(request),\n  })\n\n  const data: OTPVerifyResponse = await response.json()\n  return {\n    profile: data.ABHAProfile,\n    tokens: {\n      token: data.tokens.token,           // User token for profile APIs\n      refreshToken: data.tokens.refreshToken,\n    },\n  }\n}\n\n// ============================================================================\n// USAGE EXAMPLE\n// ============================================================================\nasync function loginWithABHA(abhaNumber: string, otp: string) {\n  // 1. Get session token (cache this!)\n  const accessToken = await getSessionToken()\n\n  // 2. Get public key (cache for a few hours)\n  const publicKey = await getPublicKey(accessToken)\n\n  // 3. Request OTP\n  const { txnId } = await requestOTP(accessToken, publicKey, abhaNumber)\n  console.log('OTP sent! Transaction ID:', txnId)\n\n  // 4. User enters OTP, then verify\n  const { profile, tokens } = await verifyOTP(accessToken, publicKey, txnId, otp)\n\n  // 5. Use the profile\n  console.log('Welcome,', formatABHAName(profile))\n  console.log('ABHA Number:', profile.ABHANumber)\n  console.log('ABHA Address:', profile.preferredAbhaAddress)\n  console.log('KYC Verified:', profile.kycVerified)\n\n  // Store tokens.token for subsequent API calls\n  return { profile, userToken: tokens.token }\n}\n\n// Example call (in your API route or service)\n// await loginWithABHA('91-1234-5678-9012', '123456')\n```\n\n### Key Points\n\n1. **Session Token**: Call once, cache for 30 minutes. Used in all API calls.\n2. **Public Key**: Fetch once per session. Used to encrypt all sensitive data.\n3. **Encryption**: ALL sensitive data (ABHA, mobile, Aadhaar, OTP) must be RSA encrypted.\n4. **Headers**: Every request needs `REQUEST-ID` (UUID) and `TIMESTAMP` (ISO 8601).\n5. **User Token**: After login, use `X-token` header for profile APIs.\n\n### Express.js Route Example\n\n```typescript\nimport express from 'express'\nimport { isValidABHANumber, isValidOTP } from '@akhilesharora/abdm-abha-sdk'\n\nconst router = express.Router()\n\n// POST /api/abha/request-otp\nrouter.post('/request-otp', async (req, res) => {\n  const { abhaNumber } = req.body\n\n  if (!isValidABHANumber(abhaNumber)) {\n    return res.status(400).json({ error: 'Invalid ABHA number format' })\n  }\n\n  const { txnId } = await requestOTP(accessToken, publicKey, abhaNumber)\n  res.json({ txnId, message: 'OTP sent to registered mobile' })\n})\n\n// POST /api/abha/verify-otp\nrouter.post('/verify-otp', async (req, res) => {\n  const { txnId, otp } = req.body\n\n  if (!isValidOTP(otp)) {\n    return res.status(400).json({ error: 'OTP must be 6 digits' })\n  }\n\n  const { profile, tokens } = await verifyOTP(accessToken, publicKey, txnId, otp)\n  res.json({ profile, token: tokens.token })\n})\n```\n\n## API Reference\n\n### Types\n\n```typescript\nimport type {\n  ABHAProfile,\n  ABHATokens,\n  ABHASession,\n  OTPGenerateRequest,\n  OTPVerifyResponse,\n  MobileLoginResponse,\n  ABHAAccountSummary,\n} from '@akhilesharora/abdm-abha-sdk'\n```\n\n### Constants\n\n```typescript\nimport {\n  ABDM_BASE_URLS,\n  ABDM_SESSION_URLS,\n  API_ENDPOINTS,\n  SCOPES,\n  LOGIN_HINTS,\n  OTP_SYSTEMS,\n  ERROR_CODES,\n} from '@akhilesharora/abdm-abha-sdk'\n\n// Base URLs\nABDM_BASE_URLS.sandbox      // 'https://abhasbx.abdm.gov.in/abha/api'\nABDM_BASE_URLS.production   // 'https://abha.abdm.gov.in/api/abha'\n\n// Scopes\nSCOPES.ABHA_ENROL           // 'abha-enrol'\nSCOPES.ABHA_LOGIN           // 'abha-login'\nSCOPES.MOBILE_VERIFY        // 'mobile-verify'\n\n// Login Hints\nLOGIN_HINTS.ABHA_NUMBER     // 'abha-number'\nLOGIN_HINTS.MOBILE          // 'mobile'\nLOGIN_HINTS.AADHAAR         // 'aadhaar'\n\n// OTP Systems\nOTP_SYSTEMS.AADHAAR         // 'aadhaar' (OTP to Aadhaar-linked mobile)\nOTP_SYSTEMS.ABDM            // 'abdm' (OTP to ABHA-linked mobile)\n```\n\n### Validation Functions\n\n| Function | Description |\n|----------|-------------|\n| `isValidABHANumber(value)` | Validate XX-XXXX-XXXX-XXXX format |\n| `isValidABHAAddress(value)` | Validate username@abdm format |\n| `isValidMobile(value)` | Validate 10-digit Indian mobile |\n| `isValidAadhaar(value)` | Validate 12-digit Aadhaar |\n| `isValidOTP(value)` | Validate 6-digit OTP |\n| `isValidPinCode(value)` | Validate 6-digit PIN code |\n\n### Format Functions\n\n| Function | Description |\n|----------|-------------|\n| `formatABHANumber(digits)` | Format 14 digits to XX-XXXX-XXXX-XXXX |\n| `formatABHAAddress(username, env)` | Create username@abdm or @sbx |\n| `formatMobile(mobile)` | Format as 98765 43210 |\n| `formatAadhaar(aadhaar)` | Format as 1234 5678 9012 |\n| `formatABHAName(profile)` | Combine first/middle/last name |\n\n### Mask Functions\n\n| Function | Description |\n|----------|-------------|\n| `maskABHANumber(value)` | XX-XXXX-XXXX-1234 |\n| `maskMobile(value)` | XXXXXX3210 |\n| `maskAadhaar(value)` | XXXXXXXX9012 |\n\n### Gender Helpers\n\n```typescript\nimport { toABHAGender, fromABHAGender, getGenderDisplay } from '@akhilesharora/abdm-abha-sdk'\n\ntoABHAGender('MALE')        // 'M'\nfromABHAGender('M')         // 'MALE'\ngetGenderDisplay('M')       // 'Male'\n```\n\n### Date Helpers\n\n```typescript\nimport { parseABHADate, toABHADate, calculateAge } from '@akhilesharora/abdm-abha-sdk'\n\nparseABHADate('26-11-1989')  // Date object\ntoABHADate(new Date())       // '10-02-2026'\ncalculateAge('26-11-1989')   // 36\n```\n\n## API Endpoints\n\n### Base URLs\n\n| Environment | URL |\n|-------------|-----|\n| Sandbox | `https://abhasbx.abdm.gov.in/abha/api` |\n| Production | `https://abha.abdm.gov.in/api/abha` |\n| Session (Sandbox) | `https://dev.abdm.gov.in/api/hiecm/gateway/v3/sessions` |\n| PHR (Sandbox) | `https://abhasbx.abdm.gov.in/abha/api/v3/phr/web` |\n\n### Key Endpoints\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/v3/profile/public/certificate` | GET | Get RSA public key |\n| `/v3/enrollment/request/otp` | POST | Generate OTP for enrollment |\n| `/v3/enrollment/enrol/byAadhar` | POST | Create ABHA via Aadhaar |\n| `/v3/profile/login/request/otp` | POST | Generate OTP for login |\n| `/v3/profile/login/verify` | POST | Verify OTP and get profile |\n| `/v3/profile/account` | GET | Get ABHA profile |\n| `/v3/profile/account/qrCode` | GET | Generate QR code |\n| `/v3/profile/account/abha-card` | GET | Get ABHA card |\n\n## Typical Flows\n\n### Login via ABHA OTP (Recommended for HIP)\n\n```typescript\nimport { API_ENDPOINTS, SCOPES, LOGIN_HINTS, OTP_SYSTEMS } from '@akhilesharora/abdm-abha-sdk'\nimport type { OTPGenerateRequest, OTPVerifyRequest, OTPVerifyResponse } from '@akhilesharora/abdm-abha-sdk'\n\n// Step 1: Generate OTP\nconst otpRequest: OTPGenerateRequest = {\n  scope: [SCOPES.ABHA_LOGIN, SCOPES.MOBILE_VERIFY],\n  loginHint: LOGIN_HINTS.ABHA_NUMBER,\n  loginId: encryptedABHANumber,  // RSA encrypted\n  otpSystem: OTP_SYSTEMS.ABDM,\n}\n\n// POST to API_ENDPOINTS.LOGIN_REQUEST_OTP\n\n// Step 2: Verify OTP\nconst verifyRequest: OTPVerifyRequest = {\n  scope: [SCOPES.ABHA_LOGIN, SCOPES.MOBILE_VERIFY],\n  authData: {\n    authMethods: ['otp'],\n    otp: {\n      txnId: txnIdFromStep1,\n      otpValue: encryptedOTP,  // RSA encrypted\n    },\n  },\n}\n\n// POST to API_ENDPOINTS.LOGIN_VERIFY\n// Response includes tokens + ABHAProfile\n```\n\n### Mobile Login (Multiple Accounts)\n\nWhen logging in via mobile number, the response includes an `accounts` array since multiple ABHAs can be linked to one mobile:\n\n```typescript\nimport type { MobileLoginResponse, ABHAAccountSummary } from '@akhilesharora/abdm-abha-sdk'\n\n// Response structure\nconst response: MobileLoginResponse = {\n  tokens: { ... },\n  accounts: [\n    {\n      ABHANumber: '91-4819-7073-XXXX',\n      preferredAbhaAddress: 'user@sbx',\n      name: 'John Doe',\n      status: 'ACTIVE',\n      profilePhoto: '...',  // Base64\n    },\n    // ... more accounts\n  ],\n}\n```\n\n## Required Headers\n\nAll V3 APIs require these headers:\n\n| Header | Description |\n|--------|-------------|\n| `REQUEST-ID` | UUID for tracking |\n| `TIMESTAMP` | ISO 8601 timestamp |\n| `Authorization` | `Bearer {accessToken}` from session API |\n| `X-token` | `Bearer {userToken}` (for profile APIs after login) |\n\n## Encryption\n\nAll sensitive data (Aadhaar, Mobile, OTP, Password) must be RSA encrypted using the public key from `/v3/profile/public/certificate`.\n\n```typescript\nimport { ENCRYPTION } from '@akhilesharora/abdm-abha-sdk'\n\n// Algorithm: RSA/ECB/OAEPWithSHA-1AndMGF1Padding\nconsole.log(ENCRYPTION.ALGORITHM)\n```\n\n## Error Handling\n\n```typescript\nimport { ERROR_CODES } from '@akhilesharora/abdm-abha-sdk'\n\n// Common error codes\nERROR_CODES.INVALID_ABHA_NUMBER    // 'ABHA_INVALID_NUMBER'\nERROR_CODES.OTP_EXPIRED            // 'ABHA_OTP_EXPIRED'\nERROR_CODES.PROFILE_NOT_FOUND      // 'ABHA_PROFILE_NOT_FOUND'\nERROR_CODES.SESSION_EXPIRED        // 'ABHA_SESSION_EXPIRED'\n```\n\n## ABHAProfile Structure\n\n```typescript\ninterface ABHAProfile {\n  // Identity\n  ABHANumber: string        // '91-1601-4548-XXXX'\n  phrAddress?: string[]     // ['user@sbx']\n  preferredAbhaAddress?: string\n\n  // Name (from Aadhaar KYC)\n  firstName: string\n  middleName?: string\n  lastName: string\n\n  // Demographics\n  dob: string               // 'DD-MM-YYYY'\n  gender: 'M' | 'F' | 'O'\n  mobile: string            // Masked: '******1670'\n  email?: string\n\n  // Address (from Aadhaar)\n  address?: string\n  stateName?: string\n  districtName?: string\n  pinCode?: string\n\n  // Status\n  abhaType: 'STANDARD' | 'CHILD'\n  abhaStatus: 'ACTIVE' | 'INACTIVE' | 'DELETED' | 'DEACTIVATED'\n\n  // Verification\n  kycVerified?: boolean\n  verificationStatus?: string\n  verificationType?: string\n  authMethods?: string[]\n\n  // Photo\n  photo?: string            // Base64 JPEG\n}\n```\n\n## Requirements\n\n- Node.js >= 16.0.0\n- TypeScript >= 5.0 (for TypeScript users)\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting a pull request.\n\n## Resources\n\n- [ABHA V3 APIs SOP V1.2 (PDF)](https://sandboxcms.abdm.gov.in/uploads/ABDM_ABHA_V3_AP_Is_SOP_V1_1_4_faef8099bd.pdf) - Official API documentation\n- [ABDM Sandbox](https://sandbox.abdm.gov.in/)\n- [ABDM Developer Portal](https://developers.abdm.gov.in/)\n- [ABHA V3 APIs SOP](https://abdm.gov.in/publications)\n\n## Author\n\n**Akhilesh Arora**\n- Email: akhildawra@gmail.com\n- GitHub: [@akhilesharora](https://github.com/akhilesharora)\n","readmeFilename":"README.md"}