The attached file contains research about The Doctors Laboratory and how it operates in the context of testing and providing results, as it does with other laboratories - we implemented Option 3 for our app as we are as start-up. I just want to ask about the HL7 method of connecting with TDL - do we need to consult TDL first about this and are they likely to say that we should come back in a year once we have some clients?
Yes, you must consult The Doctor's Laboratory (TDL) directly, as they do not have a public self-service developer portal for generating instant API keys.
Regarding their response to your client volume, they are highly likely to turn you away if you approach them purely as a software developer with zero clients.
Here is exactly how the HL7 onboarding dynamic works and how to play it strategically:
TDL treats integrations as business-to-business (B2B) corporate relationships, not open-source public utilities. Setting up a new HL7 connection requires hours of work from their technical implementation team to configure secure endpoints, firewalls, and route data streams safely.
To get TDL to take your technical request seriously today, you should bypass the developer channel entirely and use a live customer as leverage.
By framing the integration as retaining or winning the physical testing business of a live clinic, TDL will instantly fast-track your team into their non-production staging environment and hand over their proprietary HL7 Message Implementation Guides.
Sticking with Option 3 (PDF Parsing) for your launch is absolutely the right choice, as it completely protects you from this medical industry red tape until you possess the client leverage needed to unlock their servers.
To help you map out your roadmap, would you like to explore how to automate the clinic's email inbox so that TDL's encrypted result emails flow directly into your app without the doctor manually dragging and dropping them?
okay that is we are sticking with option 3 - on that note, when a clinic needs to do a blood test for a patient, they will of course need to access TDL's portal and create a record for that particular test?
Yes, that is exactly how it works. Because your software does not have a live outbound HL7 link (Option 3), it cannot automatically transmit a test request from your app to TDL's servers.
When a clinician needs to order a blood test, they will follow a brief manual workflow across both portals:
Even though you are using Option 3, you can make this manual step feel incredibly smooth for the doctor by building a "Lab Directory Shortcut" in your app:
This setup creates a completely premium user experience for the clinic, giving them an organised clinical audit trail without requiring your startup to write complex API code.
Would you like to see how to design the "Pending Lab" database schema so it seamlessly pairs up with the incoming result PDFs later on?
[1] https://www.tdlpathology.com
[2] https://www.tdlpathology.com
[3] https://www.tdlpathology.com
[4] https://www.tdlpathology.com
[5] https://www.tdlpathology.com
okay I'm intrigued with what you are suggesting about making the app look slick regarding option 3 - I don't fully understand what you mean so please elaborate
To make Option 3 feel like a premium, automated integration—even though it runs on manual file uploads—you want to build a "two-part bridge" inside your app.
Instead of treating the lab order as a surprise file that suddenly appears in an upload box, your app should know the test was ordered before the results arrive.
Here is exactly how to design this user experience step-by-step.
When a doctor decides a patient needs a blood test, they shouldn't just close your app and leave it blank. You provide them with a quick-log dashboard.
+ Log Lab Order.[ → Open TDL Portal & Complete Order ].The moment the doctor clicks that button, your app automatically drops a clean, visual entry into the patient's medical history timeline:
Pending Lab ResultsThe doctor goes to the TDL tab, spends 60 seconds entering the patient details, prints the barcode, and draws the blood. They are done.
Two days later, the TDL lab finishes testing the physical blood sample. They email the encrypted PDF report back to the clinic, or an admin downloads it from eViewPlus.
The admin drags and drops that PDF into your app's universal drop-zone inbox. This is where your code shines:
Your free Python or Node.js background script decrypts the PDF and reads the text layer.
It extracts: Name: John Smith, DOB: 14/03/1982, and the text "Full Blood Count".
Your backend instantly runs a smart database query looking for a Pending lab entry for a John Smith with that exact date of birth.
The UI update: Instead of just filing a random document, your app automatically updates that specific timeline entry:
Pending to Results Authorized (New)If you don't build this, the doctor's patient chart is completely empty and silent during the 48 hours the blood is at the lab. Then, when the PDF is uploaded, it just sits in a generic "Documents" folder like a random desktop shortcut.
By logging the order upfront, you create a digital paper trail. The clinic can look at their main dashboard at any time and see exactly how many tests are currently "Out at the Lab" and which ones are overdue, giving them total control over their clinical workflows for zero software costs.
If you'd like to sketch this out for your team, let me know:
I can provide the exact database schema or UI layout code to help your team build it this week!
Backend is Python, frontend is Bootstrap
Here is the exact blueprint for your development team to build this workflow using Python (Flask or Django) on the backend and a clean, responsive Bootstrap 5 frontend.
You need to store the order record before the PDF arrives. This allows your Python backend to match the incoming file to the correct patient and timeline entry.
# database_models.py (Example using SQLAlchemy)
from datetime import datetime
from database import db
class LabOrder(db.Model):
id = db.Column(db.Integer, primary_key=True)
patient_id = db.Column(db.Integer, db.ForeignKey('patient.id'), nullable=False)
test_names = db.Column(db.String(255), nullable=False) # e.g., "Full Blood Count, Liver Function"
status = db.Column(db.String(50), default="Pending") # Options: Pending, Received, Reviewed
ordered_by = db.Column(db.String(100), nullable=False) # Doctor's name
created_at = db.Column(db.DateTime, default=datetime.utcnow)
pdf_filename = db.Column(db.String(255), nullable=True) # Populated upon match
When a doctor views the patient's record, they will see a visual progress card. You can use Bootstrap's badge utilities to make the status instantly scannable. [1]
<!-- patient_timeline.html -->
<div class="card shadow-sm border-start border-warning border-4 mb-3">
<div class="card-body">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 fw-bold">Pathology Order: TDL Lab</h6>
<p class="text-muted small mb-0">Ordered by Dr. Jenkins on 28/07/2026</p>
<span class="text-secondary small">Tests: Full Blood Count (FBC)</span>
</div>
<!-- Dynamic Status Badge -->
<div class="text-end">
<span class="badge bg-warning text-dark px-3 py-2 rounded-pill fs-7">
<i class="bi bi-hourglass-split me-1"></i> Pending Lab Results
</span>
<div class="mt-2">
<!-- The Shortcut Button to open TDL Portal in new tab -->
<a href="https://tdlpathology.com" target="_blank" class="btn btn-sm btn-outline-primary">
Launch TDL Portal <i class="bi bi-box-arrow-up-right ms-1"></i>
</a>
</div>
</div>
</div>
</div>
</div>
When an administrator drags and drops the TDL results PDF into your Bootstrap upload area, a Python script extracts the patient details using a library like pypdf or pdfplumber and resolves the pending loop.
# pdf_matcher.py
import pdfplumber
import re
from database import db
from models import LabOrder, Patient
def process_incoming_tdl_pdf(pdf_file_path):
extracted_text = ""
# Read the text layer of the TDL PDF
with pdfplumber.open(pdf_file_path) as pdf:
for page in pdf.pages:
extracted_text += page.extract_text() or ""
# Python Regex to scan the PDF text layer for patient identifiers
# Note: Adjust regex strings based on exact TDL PDF layout configurations
name_match = re.search(r"Name:\s*([A-Za-z\s]+)", extracted_text)
dob_match = re.search(r"DOB:\s*(\d{2}/\d{2}/\d{4})", extracted_text)
if name_match and dob_match:
patient_name = name_match.group(1).strip()
patient_dob = dob_match.group(1).strip()
# 1. Locate the patient record in your database
patient = Patient.query.filter_by(name=patient_name, dob=patient_dob).first()
if patient:
# 2. Look for an open "Pending" lab order for this specific patient
pending_order = LabOrder.query.filter_by(
patient_id=patient.id,
status="Pending"
).first()
if pending_order:
# 3. Update the database record automatically
pending_order.status = "Received"
pending_order.pdf_filename = pdf_file_path
db.session.commit()
return f"Success: Matched with open order for {patient_name}."
return "Error: Could not automatically match PDF to a pending order."
Once Python flags that the file matched, the Bootstrap timeline card updates via a conditional statement in your HTML template (like Jinja2) to look like this: [2]
<!-- If status == 'Received' -->
<div class="card shadow-sm border-start border-success border-4 mb-3">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
<h6 class="card-title mb-1 fw-bold text-success">Results Ready: TDL Lab</h6>
<p class="text-muted small mb-0">Arrived via Upload on 30/07/2026</p>
</div>
<div>
<span class="badge bg-success px-3 py-2 rounded-pill me-2">
<i class="bi bi-check-circle-fill me-1"></i> Results Authorized
</span>
<a href="/view-pdf/{{ order.pdf_filename }}" class="btn btn-sm btn-dark">
<i class="bi bi-file-earmark-pdf me-1"></i> View Report
</a>
</div>
</div>
</div>
By presenting this layout to clinics, your app will feel entirely native and bespoke, masking the manual PDF workflow behind an elegant, clinical command centre.
To help your development team move faster, let me know:
I can draft the exact controller view or API endpoint code for handling the file upload!
[2] https://www.simplilearn.com