Kulcare Docs
DeveloperPatients

ABDM (Ayushman Bharat Digital Mission) Integration

This document provides comprehensive coverage of the ABDM integration in Kulcare API Backend, enabling seamless connectivity with India's national digital health ecosystem.

Overview

The ABDM integration enables Kulcare to participate in India's unified digital health infrastructure through:

  • ABHA (Ayushman Bharat Health Account) creation and management
  • Health Information Provider (HIP) functionality for sharing patient data
  • Health Information User (HIU) functionality for requesting patient data
  • FHIR-compliant data exchange
  • Care Context Linking for patient record management
  • Consent Management for secure data sharing

Key Features

  • Multi-modal ABHA registration (Aadhaar, Mobile)
  • Patient-initiated and HIP-initiated linking
  • Secure consent-based data sharing
  • FHIR R4 compliant health records
  • Real-time webhook handling
  • Comprehensive audit trails

Architecture

The ABDM integration follows the application's parts-based architecture:

parts/abdm/
├── controllers/          # API controllers for different ABDM services
│   └── abdm/
│       ├── abha/        # ABHA registration and authentication
│       ├── hip/         # Health Information Provider endpoints
│       └── hiu/         # Health Information User endpoints
├── models/              # Data models and business logic
├── services/            # External API service integrations
├── interactors/         # Business logic orchestration
├── serializers/         # JSON response formatters
├── policies/            # Authorization policies
├── migrate/             # Database migrations
└── routes.rb           # Route definitions

Service Components

  1. ABHA Services: Handle user registration, authentication, and profile management
  2. HIP Services: Manage care context linking and data sharing as a provider
  3. HIU Services: Handle consent requests and data retrieval as a user
  4. Gateway Services: Manage authentication tokens and API communication
  5. FHIR Services: Convert Kulcare data to FHIR-compliant formats

Data Models

Core Models

AbdmGatewayToken

Manages authentication tokens for ABDM Gateway communication.

# Table: abdm_gateway_tokens
class AbdmGatewayToken < ApplicationRecord
  # Columns:
  # access_token: string         - JWT access token
  # expires_at: integer         - Token expiration timestamp
  # refresh_token: string       - JWT refresh token
  # refresh_expires_at: integer - Refresh token expiration
  
  def is_valid?
    expires_at > Time.current.to_i
  end
  
  def self.current_token
    token = first
    return nil unless token&.is_valid?
    token.access_token
  end
end

AbdmService

Represents registered ABDM services for clinics.

# Table: abdm_services
class AbdmService < ApplicationRecord
  belongs_to :clinic
  
  # Columns:
  # clinic_id: integer          - Associated clinic
  # service_type: string        - HIP, HIU, or both
  # service_id: string         - ABDM service identifier
  # active: boolean            - Service status
  
  enum service_type: { hip: 'HIP', hiu: 'HIU', both: 'BOTH' }
  
  scope :active, -> { where(active: true) }
end

AbdmCareContext

Manages care context linking between patients and health records.

# Table: abdm_care_contexts
class AbdmCareContext < ApplicationRecord
  belongs_to :clinic
  belongs_to :clinic_patient
  belongs_to :care_context, polymorphic: true
  
  # Columns:
  # clinic_id: integer              - Associated clinic
  # clinic_patient_id: integer      - Patient reference
  # abdm_reference: string          - ABDM care context reference
  # abdm_display: string           - Display name for care context
  # care_context_id: integer       - Related care context (Careplan, etc.)
  # care_context_type: string      - Type of care context
  # status: string                 - Linking status (PENDING, LINKED, etc.)
  # patient_notified: boolean      - Patient notification status
  # fhir_record: jsonb            - FHIR representation of the record
  
  enum status: {
    pending: 'PENDING',
    linked: 'LINKED',
    unlinked: 'UNLINKED',
    expired: 'EXPIRED'
  }
  
  def fhir_bundle
    return fhir_record if fhir_record.present?
    care_context&.fhir_careplan
  end
end

AbdmRequest

Tracks all ABDM API requests for audit and debugging.

# Table: abdm_requests
class AbdmRequest < ApplicationRecord
  belongs_to :clinic
  
  # Columns:
  # request_id: string          - Unique request identifier
  # clinic_id: integer         - Associated clinic
  # request_type: string       - Type of request
  # payload: jsonb             - Request payload
  # response: jsonb            - Response data
  # status: string             - Request status
  # created_at: datetime       - Request timestamp
  
  enum status: {
    pending: 'PENDING',
    success: 'SUCCESS',
    failed: 'FAILED',
    timeout: 'TIMEOUT'
  }
  
  scope :recent, -> { order(created_at: :desc) }
  scope :by_type, ->(type) { where(request_type: type) }
end

Linking Models

HipLinkRequest

Manages HIP-initiated linking requests.

# Table: hip_link_requests
class HipLinkRequest < ApplicationRecord
  belongs_to :clinic
  belongs_to :clinic_patient
  
  # Columns:
  # clinic_id: integer         - Associated clinic
  # clinic_patient_id: integer - Patient reference
  # request_id: string         - ABDM request ID
  # status: string            - Request status
  # modes: jsonb              - Available authentication modes
  # link_token: string        - Generated link token
  # expires_at: datetime      - Token expiration
  
  enum status: {
    initiated: 'INITIATED',
    auth_required: 'AUTH_REQUIRED',
    completed: 'COMPLETED',
    failed: 'FAILED'
  }
  
  def expired?
    expires_at < Time.current
  end
end

HipConsent

Tracks consent artifacts and permissions.

# Table: hip_consents
class HipConsent < ApplicationRecord
  belongs_to :clinic
  belongs_to :clinic_patient
  
  # Columns:
  # consent_id: string         - ABDM consent identifier
  # clinic_id: integer        - Associated clinic
  # clinic_patient_id: integer - Patient reference
  # status: string            - Consent status
  # consent_detail: jsonb     - Consent artifact details
  # granted_at: datetime      - When consent was granted
  # expires_at: datetime      - When consent expires
  
  enum status: {
    requested: 'REQUESTED',
    granted: 'GRANTED',
    denied: 'DENIED',
    expired: 'EXPIRED',
    revoked: 'REVOKED'
  }
  
  scope :active, -> { where(status: 'GRANTED').where('expires_at > ?', Time.current) }
  
  def active?
    granted? && expires_at > Time.current
  end
end

HiuConsentRequest

Manages HIU consent requests for data access.

# Table: hiu_consent_requests
class HiuConsentRequest < ApplicationRecord
  belongs_to :clinic
  belongs_to :doctor
  belongs_to :clinic_patient
  
  # Columns:
  # clinic_id: integer         - Requesting clinic
  # doctor_id: integer        - Requesting doctor
  # clinic_patient_id: integer - Target patient
  # health_id: string         - Patient's ABHA ID
  # purpose_code: string      - Purpose of data request
  # hi_types: jsonb           - Types of health information requested
  # start_ts: datetime        - Data request start date
  # end_ts: datetime          - Data request end date
  # expire_at: datetime       - Consent expiration
  # status: string            - Request status
  # consent_request_id: string - ABDM consent request ID
  # data_fetch_status: string - Data retrieval status
  
  enum status: {
    initiated: 'INITIATED',
    pending: 'PENDING',
    granted: 'GRANTED',
    denied: 'DENIED',
    expired: 'EXPIRED'
  }
  
  enum data_fetch_status: {
    not_started: 'NOT_STARTED',
    in_progress: 'IN_PROGRESS',
    completed: 'COMPLETED',
    failed: 'FAILED'
  }
end

API Endpoints

ABHA Registration & Authentication

Aadhaar-based Registration

POST /abdm/abha/auth/aadhaar_signup/send_otp
POST /abdm/abha/auth/aadhaar_signup/verify_otp
POST /abdm/abha/auth/aadhaar_signup/send_mobile_otp
POST /abdm/abha/auth/aadhaar_signup/verify_mobile_otp
POST /abdm/abha/auth/aadhaar_signup/create_abha_address
POST /abdm/abha/auth/aadhaar_signup

Example: Send Aadhaar OTP

curl -X POST https://api.kulcare.com/abdm/abha/auth/aadhaar_signup/send_otp \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "aadhaar_number": "123456789012"
  }'

Response:

{
  "success": true,
  "message": "OTP sent successfully",
  "data": {
    "transaction_id": "txn_abc123",
    "expires_in": 300
  }
}

Mobile-based Authentication

POST /abdm/abha/auth/mobile/send_otp
POST /abdm/abha/auth/mobile/verify_otp

ABHA Login

POST /abdm/abha/mobile/login/send_otp
POST /abdm/abha/mobile/login/verify_otp
POST /abdm/abha/mobile/login

HIP (Health Information Provider) Endpoints

Care Context Linking

POST /abdm/hip/links/fetch_modes
GET  /abdm/hip/links/auth_modes
POST /abdm/hip/links/auth_init
POST /abdm/hip/links/auth_confirm
POST /abdm/hip/links/link_token_generate
POST /abdm/hip/links/add_contexts
POST /abdm/hip/links/notify_patient
POST /abdm/hip/links/check_token

Example: Generate Link Token

curl -X POST https://api.kulcare.com/abdm/hip/links/link_token_generate \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_reference": "patient_123",
    "care_contexts": [
      {
        "reference": "careplan_456",
        "display": "Diabetes Management Plan"
      }
    ]
  }'

HIU (Health Information User) Endpoints

POST /abdm/hiu/consent_requests
GET  /abdm/hiu/consent_requests
GET  /abdm/hiu/consent_requests/:id

Example: Create Consent Request

curl -X POST https://api.kulcare.com/abdm/hiu/consent_requests \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_health_id": "patient@abdm",
    "purpose_code": "CAREMGT",
    "hi_types": ["Prescription", "DiagnosticReport"],
    "date_range": {
      "from": "2024-01-01",
      "to": "2024-12-31"
    },
    "data_expire_at": "2025-06-30"
  }'

Webhook Endpoints

ABDM Gateway sends callbacks to these endpoints:

HIP Linking Webhooks

POST /abdm/v0.5/users/auth/on-fetch-modes
POST /abdm/v0.5/users/auth/on-init
POST /abdm/v0.5/users/auth/on-confirm
POST /abdm/api/v3/hip/token/on-generate-token
POST /abdm/v0.5/users/auth/notify
POST /abdm/v1.0/patients/profile/share
POST /abdm/v0.5/links/link/on-add-contexts
POST /abdm/v0.5/patients/sms/on-notify

Patient Linking Webhooks

POST /abdm/v0.5/care-contexts/discover
POST /abdm/v0.5/links/link/init
POST /abdm/v0.5/links/link/confirm
POST /abdm/v0.5/consents/hip/notify
POST /abdm/v0.5/consent-requests/on-init
POST /abdm/v0.5/consents/hiu/notify
POST /abdm/v0.5/consents/on-fetch

Data Transfer Webhooks

POST /abdm/v0.5/health-information/hip/request
POST /abdm/v0.5/health-information/hiu/on-request
POST /abdm/hiu/data/notification

FHIR Implementation

Kulcare implements FHIR R4 standards for health data exchange.

Supported FHIR Resources

Core Resources

  • Bundle: Container for all resources
  • Composition: Document structure and metadata
  • Patient: Patient demographics and identifiers
  • Practitioner: Healthcare provider information
  • Organization: Healthcare facility details
  • Encounter: Clinical encounter information

Clinical Resources

  • Condition: Diagnosis and health problems
  • MedicationRequest: Prescribed medications
  • Observation: Clinical observations and measurements
  • Appointment: Follow-up appointments
  • CarePlan: Treatment plans and care coordination

FHIR Bundle Structure

# Example FHIR Bundle generation
def fhir_careplan
  FhirBundle.new(
    resourceType: 'Bundle',
    id: Util.encode_id(id),
    type: 'document',
    timestamp: created_at.iso8601,
    entry: [
      fhir_composition_entry,
      fhir_patient_entry,
      fhir_practitioner_entry,
      fhir_organisation_entry,
      fhir_encounter_entry,
      *fhir_condition_entries,
      *fhir_medication_entries
    ]
  )
end

Data Mapping

Kulcare EntityFHIR ResourceMapping Notes
ClinicPatientPatientDemographics and identifiers
DoctorPractitionerHealthcare provider details
ClinicOrganizationHealthcare facility
AppointmentEncounterClinical encounter
CareplanComplaintConditionDiagnosis and problems
CareplanMedicineMedicationRequestPrescriptions
CareplanCompositionDocument structure

Example FHIR Patient Resource

{
  "resourceType": "Patient",
  "id": "patient_123",
  "identifier": [
    {
      "use": "usual",
      "system": "https://healthid.ndhm.gov.in",
      "value": "patient@abdm"
    }
  ],
  "name": [
    {
      "use": "official",
      "text": "John Doe",
      "given": ["John"],
      "family": "Doe"
    }
  ],
  "telecom": [
    {
      "system": "phone",
      "value": "+91-9999999999",
      "use": "mobile"
    }
  ],
  "gender": "male",
  "birthDate": "1990-01-01",
  "address": [
    {
      "use": "home",
      "text": "123 Main Street, Mumbai, Maharashtra, India",
      "city": "Mumbai",
      "state": "Maharashtra",
      "country": "IN"
    }
  ]
}

Authentication Flows

ABHA Registration Flow

Aadhaar-based Registration

  1. Send Aadhaar OTP: Initiate registration with Aadhaar number
  2. Verify Aadhaar OTP: Confirm Aadhaar authentication
  3. Send Mobile OTP: Verify mobile number
  4. Verify Mobile OTP: Confirm mobile authentication
  5. Suggest Address: Get ABHA address suggestions
  6. Create ABHA Address: Finalize ABHA creation
  7. Complete Registration: Receive ABHA credentials

Mobile-based Registration

  1. Send Mobile OTP: Initiate with mobile number
  2. Verify Mobile OTP: Complete mobile verification
  3. Create Profile: Complete ABHA profile setup

Login Flow

Mobile Login

  1. Send Login OTP: Request OTP for existing ABHA
  2. Verify Login OTP: Authenticate user
  3. Receive Tokens: Get access and refresh tokens

Care Context Linking

HIP-Initiated Linking

  1. Fetch Authentication Modes: Get available auth methods
  2. Initialize Authentication: Start auth process
  3. Confirm Authentication: Complete patient verification
  4. Generate Link Token: Create secure linking token
  5. Add Care Contexts: Link patient records
  6. Notify Patient: Inform patient of successful linking

Patient-Initiated Linking

  1. Discover Care Contexts: Patient searches for records
  2. Initialize Linking: Patient initiates link request
  3. Confirm Linking: Complete the linking process

Implementation Example

# Generate link token for patient
class GenerateLinkToken
  def self.call(clinic:, patient:, care_contexts:)
    # Create link request
    link_request = HipLinkRequest.create!(
      clinic: clinic,
      clinic_patient: patient,
      request_id: SecureRandom.uuid,
      status: 'initiated'
    )
    
    # Generate secure token
    token = SecureRandom.base64(32)
    link_request.update!(
      link_token: token,
      expires_at: 1.hour.from_now
    )
    
    # Create care contexts
    care_contexts.each do |context_data|
      AbdmCareContext.create!(
        clinic: clinic,
        clinic_patient: patient,
        abdm_reference: context_data[:reference],
        abdm_display: context_data[:display],
        care_context: context_data[:resource],
        status: 'pending'
      )
    end
    
    # Send to ABDM Gateway
    AbdmGateway::TokenService.notify_token_generation(
      link_request.request_id,
      token
    )
    
    link_request
  end
end
  1. Create Consent Request: Request permission to access data
  2. Wait for Approval: Patient approves through PHR app
  3. Receive Consent Artifact: Get approved consent details
  4. Request Data: Fetch health information from HIP
  5. Process Data: Handle received FHIR data

HIP Data Sharing Flow

  1. Receive Consent: Process consent artifact
  2. Prepare Data: Convert records to FHIR format
  3. Encrypt & Share: Securely transmit data
  4. Audit: Log all data sharing activities

Implementation Example

# Create HIU consent request
class CreateConsentRequest
  def self.call(clinic:, doctor:, patient:, purpose:, hi_types:, date_range:)
    consent_request = HiuConsentRequest.create!(
      clinic: clinic,
      doctor: doctor,
      clinic_patient: patient,
      health_id: patient.health_id,
      purpose_code: purpose,
      hi_types: hi_types,
      start_ts: date_range[:from],
      end_ts: date_range[:to],
      expire_at: 6.months.from_now,
      status: 'initiated'
    )
    
    # Send to ABDM Gateway
    response = AbdmGateway::ConsentService.create_request(
      consent_request.consent_request_id,
      {
        patient: { id: patient.health_id },
        hiu: { id: clinic.abdm_service.service_id },
        requester: {
          name: doctor.full_name,
          identifier: doctor.registration_number
        },
        purpose: { code: purpose },
        hiTypes: hi_types,
        permission: {
          accessMode: 'VIEW',
          dateRange: date_range,
          dataEraseAt: 1.year.from_now,
          frequency: { unit: 'HOUR', value: 1 }
        }
      }
    )
    
    if response.success?
      consent_request.update!(
        consent_request_id: response.data['consentRequestId'],
        status: 'pending'
      )
    else
      consent_request.update!(status: 'failed')
    end
    
    consent_request
  end
end

Security & Privacy

Data Protection

  1. Encryption: All sensitive data encrypted at rest and in transit
  2. Token Security: JWT tokens securely stored and transmitted
  3. Audit Trails: Complete logging of all ABDM operations
  4. Access Control: Role-based access to ABDM functions

Privacy Compliance

  1. Consent Management: Explicit consent for all data sharing
  2. Data Minimization: Only share necessary health information
  3. Right to Withdraw: Support consent withdrawal
  4. Data Retention: Proper data retention and deletion policies

ABDM Compliance

  1. FHIR Standards: Full compliance with FHIR R4
  2. ABDM Protocols: Adherence to ABDM integration guidelines
  3. Security Standards: Implementation of ABDM security requirements
  4. Audit Requirements: Meeting ABDM audit and logging standards

Error Handling

Common Error Scenarios

  1. Authentication Failures: Invalid OTP, expired tokens
  2. Authorization Errors: Insufficient permissions
  3. Network Issues: Gateway timeouts, connectivity problems
  4. Data Validation: Invalid FHIR data, missing required fields
  5. Consent Issues: Expired consent, insufficient permissions

Error Response Format

{
  "success": false,
  "message": "Detailed error message",
  "error_code": "ABDM_ERROR_CODE",
  "errors": {
    "field": ["Specific field errors"]
  }
}

Error Recovery Strategies

  1. Retry Logic: Automatic retry for transient failures
  2. Token Refresh: Automatic token renewal
  3. Fallback Mechanisms: Alternative flows for critical operations
  4. User Feedback: Clear error messages for user action

Monitoring & Debugging

Key Metrics

  1. Token Refresh Rate: Frequency of token renewals
  2. Webhook Success Rate: Percentage of successful webhook processing
  3. Care Context Linking Rate: Success rate of linking operations
  4. Data Sharing Volume: Amount of health data shared
  5. Error Rates: Frequency and types of errors

Debug Commands

Check ABDM Service Status

clinic = Clinic.find(clinic_id)
abdm_service = clinic.abdm_services.first
puts "Service Type: #{abdm_service.service_type}"
puts "Service ID: #{abdm_service.service_id}"

Validate FHIR Data

careplan = Careplan.find(careplan_id)
fhir_bundle = careplan.fhir_careplan
puts "FHIR Bundle: #{fhir_bundle.to_json}"

Check Request History

requests = AbdmRequest.where(clinic_id: clinic_id)
                     .order(created_at: :desc)
                     .limit(5)
requests.each do |req|
  puts "Type: #{req.request_type}, Status: #{req.status}"
end

Health Check Endpoint

# GET /abdm/health
def health_check
  {
    gateway_token: AbdmGatewayToken.first&.is_valid?,
    recent_webhooks: AbdmWebhook.where('created_at > ?', 1.hour.ago).count,
    active_consents: HipConsent.where(status: 'GRANTED').count,
    pending_links: AbdmCareContext.where(status: 'PENDING').count
  }
end

Integration Best Practices

For Mobile Applications

  1. Token Storage: Securely store ABHA tokens using encrypted storage
  2. Token Refresh: Implement automatic token refresh mechanism
  3. Error Handling: Graceful handling of network and API errors
  4. User Experience: Clear feedback for ABDM operations
  5. Privacy: Ensure user consent before any data sharing
  6. Offline Support: Cache essential data for offline access

For Backend Integration

  1. Webhook Reliability: Implement retry mechanisms for webhook processing
  2. Data Validation: Validate all FHIR data before sharing
  3. Consent Verification: Always verify consent before data access
  4. Audit Logging: Log all ABDM operations for compliance
  5. Error Monitoring: Monitor and alert on ABDM integration failures

On this page