ABDM Callback Debugging: Why Your Bridge URL Is Not Receiving Requests (Flowchart and Fixes, 2026)
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.

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.
| Milestone | Callbacks 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?
How do I register a bridge URL with the ABDM gateway?
How long does an ABDM bridge URL change take?
What callback paths does ABDM send requests to?
Is ABDM V3 discovery synchronous or asynchronous?
Does ABDM resend a callback my server missed?
How do I debug ABDM callbacks faster?


