Back to BlogIndustry Guides

Building an HCP Portal: Registration, Verification and Content Gating

Rupak Amin

Founder & Lead Engineer, RAITHub

14 min read

An HCP portal is a gated website where healthcare professionals sign up, are checked against a professional register, and see content a pharma or medtech company may show only to them. It needs 5 parts: registration, professional verification (in the US, a lookup against the NPI Registry), content gating by audience and market, consent and preferences, and audit logs. This is engineering guidance; RAITHub has not shipped one.

That last point matters, so it comes first. RAITHub has no pharma clients and has shipped no regulated health product. What follows is how RAITHub would design an HCP (healthcare professional) portal, based on role-heavy portals it has built in other industries, with the regulatory questions left to the people who own them.

What is an HCP portal, and who uses one?

A website, usually run by a pharmaceutical or medical-device company, that gives verified doctors, nurses, pharmacists and other professionals access to material the public should not see.

Typical content includes prescribing information, clinical data summaries, dosing tools, medical education, event registration, sample or literature requests and a route to contact a medical information team. The engineering is a normal authenticated web app. What makes it different is that the company is often restricted in who may see promotional material about prescription medicines, and those restrictions change from market to market.

What features does an HCP portal need?

Five core features plus one route to agree with your safety team, each with an engineering detail that is easy to get wrong.

FeatureWhat it doesEngineering detail that matters
RegistrationCollects name, profession, specialty, country and a professional identifierMarket is chosen first, because it decides which identifier and which verification route apply
Professional verificationChecks the person against a professional registerAutomated lookup where a register can be queried, a manual review queue where it cannot, and no silent auto-approval when the lookup fails
Content gatingShows each item only to the audience and markets it was approved forGating is enforced on the server for every request, including file downloads, not only by hiding links
Consent and preferencesRecords what the user agreed to (email, events, research) and lets them change itConsent is stored as versioned, timestamped events, so you can show what the user saw when they agreed
Audit logsRecords verification decisions, consent changes, role changes and access to gated materialAppend-only, with the actor, action, target and time; reviewed by your compliance team, not just stored
Medical information and adverse-event routesLets an HCP ask a question or report a side effectThe portal forwards reports straight to your medical information or safety system; it should not become the record

The last row is the one to agree with your quality and safety teams before design. A form on a website can be ordinary web work; the system that holds safety reports is not.

How do you verify that a user really is a healthcare professional?

Look them up in a public professional register where one can be queried, and send everyone else to a manual review queue. The register you use depends on the market.

United States: the NPI Registry

US healthcare providers are identified by a 10-digit National Provider Identifier (NPI). CMS publishes the NPPES NPI Registry with a free, public API. A request by number, such as https://npiregistry.cms.hhs.gov/api/?version=2.1&number=..., returns JSON with a result_count and a results array. Each result includes an enumeration_type (NPI-1 for individual providers), a basic block with the name, credential and a status (A for active), and a taxonomies list describing the provider's specialty, with one marked primary.

Before calling the API, you can reject typos locally. The tenth digit of an NPI is a check digit calculated with the Luhn formula after prefixing the first nine digits with 80840, as set out in CMS's NPI check-digit document.

United Kingdom: the GMC register and others

Doctors in the UK are on the medical register kept by the General Medical Council (GMC), which the public can search online. For bulk access, the GMC licenses a daily download of the full register, £815 a year plus VAT for the standard licence when we checked, under an agreement that bars republishing without permission (GMC register download service). Confirm the current terms with the GMC before building an integration, and expect a manual check against the online register as the starting point. Nurses, pharmacists and other professions are on other regulators' registers, each with its own access terms.

Everywhere else

Most countries have a register for doctors, but whether it can be queried by machine varies widely. Many portals combine automated lookups for their largest markets with a manual review queue, or use a specialist HCP verification service. Either way, record which route verified each user.

What a register lookup does not prove

An NPI and a name are public. A successful lookup proves the number exists, belongs to an active individual provider and matches the name typed in. It does not prove the person typing is that provider. Add a second signal your compliance team accepts, such as a verified professional email domain or a confirmation step, and treat higher-risk content accordingly.

What does an NPI check with caching and content gating look like in code?

A minimal TypeScript sketch: validate the format and check digit, look the number up, cache the registry record for a day, and gate each content item by audience, market and approval date. It is illustrative, not production code; a real version would use a shared cache, retries and your own logging.

// hcp-verification.ts
type NpiRecord = {
  found: boolean
  active: boolean
  lastName: string
  primaryTaxonomy: string | null
  fetchedAt: number
}

type Verification = 'verified' | 'name_mismatch' | 'inactive' | 'not_found' | 'invalid_format'

const DAY_MS = 24 * 60 * 60 * 1000
const cache = new Map<string, NpiRecord>() // use Redis or a DB table in production

// 10 digits, and the Luhn check passes with the 80840 prefix (CMS).
export function isValidNpiFormat(npi: string): boolean {
  if (npi.length !== 10 || !npi.split('').every((c) => c >= '0' && c <= '9')) return false
  const digits = ('80840' + npi).split('').map(Number).reverse()
  let sum = 0
  digits.forEach((d, i) => {
    if (i % 2 === 1) {
      const doubled = d * 2
      sum += doubled > 9 ? doubled - 9 : doubled
    } else {
      sum += d
    }
  })
  return sum % 10 === 0
}

async function fetchNpiRecord(npi: string): Promise<NpiRecord> {
  const hit = cache.get(npi)
  if (hit && Date.now() - hit.fetchedAt < DAY_MS) return hit

  const url = 'https://npiregistry.cms.hhs.gov/api/?version=2.1&number=' + npi
  const res = await fetch(url, { signal: AbortSignal.timeout(5000) })
  // Do not cache failures: a registry outage must not mark anyone unverified for a day.
  if (!res.ok) throw new Error('NPI Registry unavailable: ' + res.status)

  const body = (await res.json()) as {
    result_count: number
    results?: {
      enumeration_type: string
      basic: { last_name?: string; status?: string }
      taxonomies?: { desc: string; primary: boolean }[]
    }[]
  }
  const r = body.results?.[0]
  const record: NpiRecord = {
    found: Boolean(r) && r!.enumeration_type === 'NPI-1',
    active: r?.basic.status === 'A',
    lastName: (r?.basic.last_name ?? '').trim().toUpperCase(),
    primaryTaxonomy: r?.taxonomies?.find((t) => t.primary)?.desc ?? null,
    fetchedAt: Date.now(),
  }
  cache.set(npi, record)
  return record
}

export async function verifyNpi(npi: string, lastName: string): Promise<Verification> {
  if (!isValidNpiFormat(npi)) return 'invalid_format'
  const rec = await fetchNpiRecord(npi) // on throw: send the user to manual review
  if (!rec.found) return 'not_found'
  if (!rec.active) return 'inactive'
  if (rec.lastName !== lastName.trim().toUpperCase()) return 'name_mismatch'
  return 'verified'
}

// Role-gated content check, enforced on the server for every request.
type Audience = 'public' | 'hcp' | 'prescriber'
type Viewer = { verified: boolean; market: string; roles: string[] }
type ContentItem = {
  id: string
  audience: Audience
  markets: string[] // markets the item was approved for, e.g. ['US'] or ['GB']
  approvalExpiresAt: Date | null
}

export function canView(viewer: Viewer | null, item: ContentItem, now = new Date()): boolean {
  if (item.approvalExpiresAt && item.approvalExpiresAt <= now) return false
  const market = viewer?.market ?? 'unknown'
  if (!item.markets.includes(market)) return false
  if (item.audience === 'public') return true
  if (!viewer || !viewer.verified) return false
  if (item.audience === 'hcp') return viewer.roles.includes('hcp')
  return viewer.roles.includes('prescriber')
}

Three design choices in that sketch are deliberate. The cache holds the registry record, not the verification result, so a name mismatch is always rechecked against fresh input. Failures are never cached, so an outage sends users to manual review instead of rejecting them. And canView denies by default: an item with no market, an expired approval or an unverified viewer is not shown. Write tests for each branch; the RBAC design guide covers how to structure roles and permissions beyond this sketch.

Why do promotional-content rules change the design by market?

Because who may see promotional material about a prescription medicine, and what it must contain, is set by each market's rules and codes, so one global "HCP only" flag is rarely enough.

  • United Kingdom. The ABPI Code of Practice 2024, administered by the PMCPA (a division of the ABPI), sets standards for promoting medicines for prescribing to health professionals and other relevant decision makers in the UK, including digital advertising, and separately covers information provided to the public.
  • United States. FDA's Office of Prescription Drug Promotion (OPDP) works to ensure that prescription drug promotion is "truthful, balanced, and accurately communicated".
  • Other markets. Each has its own law and industry codes. Some allow a single portal with market-specific sections; others need separate sites.

For engineering, that means each content item carries its approved audience, its approved markets, an approval reference from your review process and an expiry date, and the portal decides the viewer's market before it shows anything. The content rules are your regulatory team's call; the portal's job is to enforce whatever they decide, consistently, and to log it.

General information, not legal or regulatory advice. What counts as promotional, who may see it and what verification is enough differ by market and product. Confirm with your adviser, and check the current rules with the PMCPA, FDA OPDP or your local regulator.

As append-only records of events, not as flags you overwrite.

  • Consent as events. Store each grant or withdrawal with the user, the purpose (email, events, market research), the version of the wording shown and the time. The current state is derived from the latest event. That lets you answer "what did this person agree to, and when?" without guessing.
  • Preferences separate from consent. Topics, specialties and frequency are preferences. Keep them apart from the legal basis for contacting someone, which your privacy counsel decides per market.
  • Audit the decisions that matter. Verification outcomes and who approved manual ones, role and market changes, consent events, and access to gated content. Record actor, action, target, time and the source of the decision.
  • Make the log hard to change. Application users get insert-only access to the audit table. The audit log design guide covers schemas, retention and review.

Personal data about HCPs is still personal data. RAITHub signs DPAs and SCCs where needed and follows your security controls; where the data is stored and for how long are decisions for your privacy team.

Should you build an HCP portal or configure an existing platform?

Configure first if your CRM or marketing platform already handles HCP identity, consent and content targeting for your markets. Build when your market rules, verification routes or workflows do not fit it, or when the portal must join several systems that no single platform owns. A common middle path is a custom portal front end that uses your existing CRM as the record for HCP profiles and consent, with the portal handling verification, gating and the user experience.

Why RAITHub for this

For the web engineering of an HCP portal, with your regulatory, medical and privacy teams owning the rules. RAITHub is a founder-led software studio, founded in 2024 in Dhaka, Bangladesh, working with clients worldwide in English. It has not built an HCP portal or worked for a pharma company, so this is the evidence it can offer instead:

  • Fine-grained access control in production. Sundor Skin, a B2B wholesale platform, has 88 permission codes, 12 staff roles and row-level security across 146 PostgreSQL tables, with 530+ automated tests. Audience-and-market gating is the same kind of problem.
  • Several audiences on one platform. TheSkinProof, the founder's own venture rather than a client, runs 5 portals on 217 API endpoints with 750+ tests.
  • Health-adjacent work, stated plainly. RAITHub has built a healthcare scheduling app for a client. It is not a regulated product. The health software guide and the HealthTech page say the same.
  • Portals as a product. The SaaS and web platform development service covers authenticated portals, role models and the tests behind them.
  • Clear terms. A fixed-scope build or a dedicated monthly team, a written quote after a free 15-minute technical audit, an NDA before detail, and you own the IP. See the pricing page. For US teams there is a daily 2-hour evening overlap (Dhaka 19:00–21:00, New York 08:00–10:00 in winter); UK teams get 3 hours in winter and 4 in summer on a 9:00–18:00 day, with async written handoffs for the rest.

When you don't need us

  • Your CRM or marketing platform already does it. If it handles verification, consent and targeting for your markets, configure it instead of commissioning a build.
  • You want a vendor with shipped HCP portals. RAITHub has none to show; a specialist life-sciences web agency will have references.
  • The portal must hold GxP or safety records. That needs a validated vendor with a quality system. RAITHub builds no GxP-validated or 21 CFR Part 11 systems.
  • Your procurement requires a certified vendor. RAITHub holds no SOC 2 or ISO 27001 certification.
  • You want the developer to decide what is promotional. RAITHub implements your regulatory team's rules; it does not interpret them.
  • You want developers placed inside your team. RAITHub offers fixed-scope builds and dedicated teams, not staff augmentation.

How do you start an HCP portal project?

Write down the markets, the professions you want to reach, the verification route you would accept in each market, and who signs off content and consent. Then book the free 15-minute technical audit. Do not send HCP personal data, patient data or unapproved promotional material in the first message.

You will get a written memo covering the verification and gating design, what your existing platforms can already do, and a plain answer on whether RAITHub is the right team to build it.

Frequently asked questions

What is an HCP portal?

A gated website, usually run by a pharmaceutical or medical-device company, where verified healthcare professionals can access content and services not intended for the public, such as prescribing information, medical education, events and medical information requests.

How do you verify a US healthcare professional?

Look up their 10-digit National Provider Identifier in the CMS NPPES NPI Registry, which has a free public API, and check that the record is an active individual provider whose name matches. Because NPIs are public, add a second signal your compliance team accepts.

Can you verify UK doctors automatically?

The GMC's medical register can be searched online by the public. The GMC also licenses a paid daily download of the register; confirm the current terms with the GMC before you design around it. Many portals start with manual checks for UK users.

Is an HCP portal a regulated system?

The content on it is subject to promotional rules such as the ABPI Code in the UK, with FDA's OPDP overseeing prescription drug promotion in the US. The portal itself is usually ordinary web software, unless it holds safety or GxP records. Confirm both points with your regulatory adviser.

Has RAITHub built an HCP portal?

No. RAITHub has no pharma clients and has shipped no regulated health product. This guide is engineering guidance based on role-heavy portals it has built in other industries, such as Sundor Skin's 88 permission codes and 12 staff roles.

How should an HCP portal store consent?

As append-only events recording the user, the purpose, the version of the wording they saw and the time, with the current state derived from the latest event. The lawful basis for contacting HCPs in each market is for your privacy counsel to decide.

HCP portalHCP portal developmentNPI RegistryContent gatingPharma web developmentConsent managementAudit logging

Ready to discuss your project?

Book a free 15-minute technical audit with our engineering team.