ABDMCallbacksDebugging

ABDM Callback Debugging: Why Your Bridge URL Is Not Receiving Requests (Flowchart and Fixes, 2026)

March 20, 202610 min readUpdated Sep 29, 2026
Written by
Gulshan Prajapati
Gulshan Prajapati

Software Development Expert

Writes about software development, scalable architecture, and practical problem-solving across modern digital products. Focuses on turning complex technical ideas into clear, real-world solutions.

ABDM Callback Debugging: Why Your Bridge URL Is Not Receiving Requests (Flowchart and Fixes, 2026)

If your ABDM bridge URL is not receiving callbacks, the cause is almost always one of six things: the bridge URL is not registered for this client ID, the change has not applied yet (it takes 5 to 15 minutes), the URL is not publicly reachable over HTTPS, the tunnel is silently dropping requests, your route does not match the path ABDM uses, or your handler does not answer with HTTP 202 fast enough. Check them in that order and the problem is found in minutes rather than days.

Callback problems are the biggest single theme developers raise about ABDM: in our review of 195 archived ABDM developer forum threads, 70 (36%) were about HIP linking and callbacks. This guide explains how ABDM callbacks work, walks through a debugging flowchart, and covers the V3 details that trip teams up after the callbacks do arrive. It is based on our own sandbox and production work on ABDM integrations. Updated September 2026.

How ABDM callbacks work

ABDM does not return results in API responses. When you call an ABDM API, the gateway answers 202 Accepted, and the real result arrives later as a POST to your bridge URL. When a patient acts in a PHR app (discovering records, linking, approving consent), ABDM also calls your bridge URL. Your server must therefore be publicly reachable over HTTPS, accept POSTs on ABDM's paths, and answer each one with 202 quickly.

MilestoneCallbacks your bridge URL receives
M1 (ABHA)Scan and Share profile from the facility QR
M2 (HIP)Link token, patient discovery, link init, link confirm, consent notification, health information request, ABHA deactivation
M3 (HIU)Consent request on-init, consent on-notify (granted, denied, revoked, expired), data request on-request, health information push to your data push URL

If you would rather have a team that has already solved these handle your integration, our ABDM integration services cover callback architecture through NHA testing.

Debugging flowchart: why the bridge URL is not receiving requests

1. Register the bridge URL for the right client ID

Register your public URL with the gateway, then read it back to confirm what ABDM holds:

# Register or update (sandbox base shown; production uses apis.abdm.gov.in)
curl -s -X PATCH https://dev.abdm.gov.in/api/hiecm/gateway/v3/bridge/url \
  -H "Authorization: Bearer $GATEWAY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://abdm.your-domain.example"}'

# Read back what the gateway has for your client ID
curl -s https://dev.abdm.gov.in/api/hiecm/gateway/v3/bridge-services \
  -H "Authorization: Bearer $GATEWAY_TOKEN"

The bridge URL is global per client ID. If a colleague's laptop, a staging server and your machine share one sandbox client ID, whichever registered last receives every callback, and everyone else sees nothing.

2. Wait for the change to apply

A 202 from the PATCH means accepted, not applied. In our testing the new URL took 5 to 15 minutes to start receiving callbacks. Testing immediately after a change is the most common false alarm.

3. Make sure the URL is publicly reachable over HTTPS

Call your own callback path from a machine outside your network. A valid TLS certificate is required. A corporate firewall, a missing DNS record or a VPN on the server all block callbacks. A VPN on your development machine can also block your outbound calls: in our testing a consumer VPN caused ABDM to answer 403.

4. Keep the tunnel stable and probe it

In development a tunnel is fine, but use one with a fixed domain so the URL does not change on restart:

ngrok http 3000 --domain=your-subdomain.ngrok-free.app

Tunnels fail quietly. A tunnel agent can show as online while losing requests, and a laptop that sleeps takes the tunnel with it. ABDM does not resend a lost consent notification, so a dropped callback can mean a grant you must request again. Before every test run, send a real-size POST through the tunnel to your callback path and confirm it arrives.

5. Match every path variant

We have seen ABDM callbacks arrive at more than one path shape for the same event. A route that only matches one prefix misses the others.

// Next.js catch-all: app/api/callbacks/v3/[[...path]]/route.ts
export async function POST(req: Request, { params }: { params: Promise<{ path?: string[] }> }) {
  const fullPath = ((await params).path ?? []).join('/')
  const requestId = req.headers.get('REQUEST-ID') ?? ''
  const body = await req.json()

  // Answer first, work later (on serverless, hand off to a job queue instead)
  queueMicrotask(() => handleCallback(fullPath, requestId, body))
  return new Response(null, { status: 202 })
}

function handleCallback(path: string, requestId: string, body: unknown) {
  if (path.endsWith('patient/care-context/discover')) return onDiscover(requestId, body)
  if (path.endsWith('link/care-context/init')) return onLinkInit(requestId, body)
  if (path.endsWith('request/hip/notify')) return onConsentNotify(requestId, body)
  // ...every other callback, plus a log line for anything unmatched
}

Match on the end of the path, not on a fixed prefix, and log every unmatched POST. Unmatched paths are how you discover a callback you did not know existed.

6. Return 202 fast, then do the work

Answer every callback with 202 immediately (we aim for well under 2 seconds) and do the matching, database work and outgoing calls in the background. A handler that times out or returns 500 looks to ABDM like a failed delivery, and slow acknowledgements are a common reason NHA test cases fail.

When callbacks arrive but the flow still fails

V3 discovery is asynchronous

In V1 and V2, discovery answered synchronously. In V3 your discover endpoint returns 202 with no records, and you send the result separately to on-discover. Returning the records in the first response means ABDM never receives them.

Echo the REQUEST-ID from the header

ABDM sends the request ID in the REQUEST-ID HTTP header. When you answer through an on-* API, the response.requestId in your body must equal that header value, or ABDM cannot correlate your answer with its request.

const abdmRequestId = req.headers.get('REQUEST-ID') ?? ''
// ...later, in the on-discover / on-init / on-confirm body:
const payload = { response: { requestId: abdmRequestId }, /* result fields */ }

Log every incoming POST

// middleware.ts: one line per callback, with path and REQUEST-ID
import { NextResponse, type NextRequest } from 'next/server'
export function middleware(req: NextRequest) {
  if (req.method === 'POST') {
    console.log(`[ABDM callback] ${req.nextUrl.pathname} request-id=${req.headers.get('REQUEST-ID')}`)
  }
  return NextResponse.next()
}

Keep the REQUEST-ID of every call and callback. It is the first thing ABDM sandbox support asks for.

ABDM callback checklist

  • Bridge URL registered (202) and read back from bridge-services for the right client ID
  • Waited 15 minutes after the last change
  • Only one environment uses this client ID
  • Public HTTPS with a valid certificate, reachable from outside your network
  • Stable tunnel with a fixed domain, probed with a real-size POST before each run
  • Catch-all route for /v3/, /api/v3/ and /api/callbacks/v3/
  • Every callback answered with 202 immediately; work done in the background
  • Discovery answers asynchronously through on-discover
  • REQUEST-ID from the header echoed as response.requestId
  • Every POST logged with path and REQUEST-ID

How we run ABDM callbacks on our integrations

On our ABDM integrations, callbacks are treated as the product, not plumbing:

  • A watchdog probes the tunnel every minute during sandbox testing, so a dead tunnel is found before a test run, not after it.
  • The bridge URL of a shared client ID is switched deliberately, and everyone who depends on it is told before the switch.
  • Every unmatched callback path is logged with its REQUEST-ID, so new callbacks are found early.

For the flows these callbacks drive, see our ABDM HIP reference architecture and ABDM HIU reference architecture. For other errors, read 25 common ABDM errors and fixes, and for the full path from sandbox to go-live, the ABDM integration step-by-step guide. The V3 changes behind the async discovery are in our ABDM V3 migration guide.

Still stuck with a bridge URL that will not receive requests? Talk to our ABDM team and we will trace it with you.

Ready to scale?

Talk to our healthcare engineering team about building, integrating, and shipping faster.

Frequently Asked Questions

Why is my ABDM bridge URL not receiving callback requests?

Check six things in order: the bridge URL is registered for this client ID, 5 to 15 minutes have passed since the change, the URL is publicly reachable over HTTPS, the tunnel is not dropping requests, your route matches every callback path variant, and your handler answers with HTTP 202 quickly.

How do I register a bridge URL with the ABDM gateway?

Send a PATCH to /api/hiecm/gateway/v3/bridge/url on the gateway with your gateway token and the public HTTPS URL, then read it back from /api/hiecm/gateway/v3/bridge-services. The URL applies to the whole client ID and takes 5 to 15 minutes to take effect.

How long does an ABDM bridge URL change take?

In our testing, 5 to 15 minutes. The PATCH returns 202 immediately, but callbacks keep going to the old URL until the change applies, so wait before testing.

What callback paths does ABDM send requests to?

ABDM calls your bridge URL for link tokens, patient discovery, link init and confirm, consent notifications, health information requests and Scan and Share, among others. The same callback can arrive with different path prefixes such as /v3/, /api/v3/ and /api/callbacks/v3/, so use a catch-all route that matches on the end of the path.

Is ABDM V3 discovery synchronous or asynchronous?

Asynchronous. Your discover endpoint returns 202 with no records, and you send the matched care contexts separately to on-discover, echoing the REQUEST-ID header as response.requestId.

Does ABDM resend a callback my server missed?

Do not rely on it. In our testing ABDM did not resend a lost consent notification, so that consent had to be requested again. Keep your endpoint and tunnel healthy and log every incoming callback.

How do I debug ABDM callbacks faster?

Log every incoming POST with its path and REQUEST-ID, probe your tunnel with a real-size request before each test, use a single environment per client ID, and follow the debugging flowchart in this guide from registration to the 202 response.
Share