Labs Provider Guide
For Businesses Integrating as Lab/Diagnostics Partners on AwaDoc
This guide reflects the exact live platform behaviour as of December 2025.
Your Role as a Labs Provider
You handle diagnostic tests (e.g., blood work, imaging, pathology), manage sample collection (home pickup, walk-in, or lab-based), confirm availability & pricing, and update the platform on sample status, results readiness, and report delivery.
Prerequisites (same for all partners)
- Business Record status: ACTIVE
- One or more APPROVED offerings in category diagnostics / lab
- testCallbackUrl & productionCallbackUrl configured by AwaDoc team
- Test and/or Production API keys issued
- Bank account verified (required for production keys)
Base URLs
Sandbox: https://partners-staging.awadoc.com/api-doc Production: https://partners-prod-001.awadoc.com/api-doc
Security
HMAC SHA256 signatures on every inbound and outbound payload (identical to Consultation guide). Clock skew tolerance: ±5 minutes.
Security: HMAC SHA256 Signatures
All communication is secured with HMAC SHA256 using your environment-specific secret.
From Platform → You (Inbound)
| Header | Value |
|---|---|
X-Event-Id |
Unique event UUID |
X-Timestamp |
Unix seconds |
X-Signature |
HMAC_SHA256( sha256(body) + "\n" + timestamp, secret ) → hex |
Content-Type |
application/json |
From You → Platform (Outbound)
Endpoint:
POST /api/partners/:partnerId/callback
| Header | Value |
|---|---|
x-timestamp |
Unix seconds |
x-signature |
HMAC_SHA256( sha256(body) + "\n" + timestamp, secret ) → hex |
Content-Type |
application/json |
Clock skew allowed: ±5 minutes
Signature Generation (Node.js Example)
import crypto from "crypto";
function signPayload(body: any, secret: string, timestamp: number): string {
const bodyHash = crypto
.createHash("sha256")
.update(JSON.stringify(body))
.digest("hex");
const canonical = `${bodyHash}\n${timestamp}`;
return crypto.createHmac("sha256", secret).update(canonical).digest("hex");
}
Complete Labs Flow & Events You Will Receive
| Step | Event Type | When It Is Sent | Response Time Expected | Required Response Fields (exact JSON) |
|---|---|---|---|---|
| 1 | diagnostics.availability.query | User searches for tests or collection slots (e.g., "blood test near me") | ≤ 10 seconds | See below |
| 2 | diagnostics.requested | User selects your lab/test and proceeds to book | ≤ 30 seconds | Confirm with pricing & collection details |
| 3 | diagnostics.confirmed | Payment succeeds on AwaDoc side | ≤ 10 seconds | Simple acknowledgement |
1. diagnostics.availability.query
Payload example (platform → you)
JSON
{
"event_id": "evt-2001",
"event_type": "diagnostics.availability.query",
"timestamp": "2025-12-09T12:45:00Z",
"context": {
"query_id": "labq-4456",
"tests": [
{ "test_code": "FBC", "test_name": "Full Blood Count" },
{ "test_code": "LFT", "test_name": "Liver Function Test" }
],
"collection_mode": "home_collection",
"service_area": "Lagos Mainland",
"schedule": {
"preferred_time": "2025-12-10T09:00:00Z",
"preferred_lang": "en"
}
}
}
Your response (you → platform)
JSON
{
"status": "available", // or "unavailable"
"query_id": "labq-4456",
"queried_at": "2025-12-09T12:45:05Z",
"tests": [
{
"test_code": "FBC",
"available": true,
"collection_modes": ["home_collection", "walkin"],
"pricing": { "amount": 8500.00, "currency": "NGN" },
"turnaround_time": "24 hours",
"collection_times": [
{
"timezone": "Africa/Lagos",
"days": ["MON", "TUE", "WED", "THU", "FRI"],
"hours": { "start": "08:00", "end": "17:00" }
}
]
},
{
"test_code": "LFT",
"available": false,
"reason": "equipment_maintenance"
}
],
"total_pricing": { "amount": 8500.00, "currency": "NGN" },
"estimated_collection_time": "2025-12-10T09:30:00Z"
}
2. diagnostics.requested
Sent when the user chooses your lab and confirms the booking.
{
"event_id": "evt-lab-9021",
"event_type": "diagnostics.requested",
"timestamp": "2025-12-09T13:00:00Z",
"user": {
"id": "usr-7788",
"name": "Chinwe Okafor",
"phone": "+2348012345678"
},
"context": {
"request_id": "labreq-4456",
"tests": [
{
"test_code": "FBC",
"collection_mode": "home_collection"
},
{
"test_code": "LFT",
"collection_mode": "walkin"
}
],
"collection_details": {
"preferred_time": "2025-12-10T09:30:00Z",
"address": {
"line1": "12 Admiralty Way",
"city": "Lagos",
"state": "Lagos",
"country": "NG"
}
},
"notes": "Patient has been fasting for 10 hours"
},
"meta": {
"trace_id": "trace-99221"
}
}
Your response (MUST include final pricing and collection details)
JSON
{
"status": "confirmed", // or "rejected"
"order_id": "lab-7789",
"confirmed_at": "2025-12-09T12:50:00Z",
"order": {
"order_id": "lab-7789",
"tests": [
{
"test_code": "FBC",
"pricing": { "amount": 8500.0, "currency": "NGN" }
}
],
"fees": {
"collection_fee": { "amount": 1000.0, "currency": "NGN" }
},
"total_pricing": { "amount": 9500.0, "currency": "NGN" }
},
"collection": {
"mode": "home_collection",
"address": {
"line1": "23 Adeola Odeku",
"city": "Victoria Island",
"state": "Lagos",
"country": "NG"
},
"scheduled_time": "2025-12-10T09:30:00Z"
},
"notes": "Fasting required for 8 hours"
}
If rejected:
JSON
{
"status": "rejected",
"reason": "no_slots_available",
"retry_after": "2025-12-11T08:00:00Z"
}
3. diagnostics.confirmed
Sent after successful payment.
Your response (simple ack)
JSON
{
"status": "acknowledged",
"acknowledged_at": "2025-12-09T12:52:00Z"
}
Events You Must Send Back (Callbacks)
POST to https://partners-{env}.awadoc.com/api/partners/:partnerId/callback
| Event Type | When to Send | Important Fields |
|---|---|---|
| diagnostics.sample.collected | Sample successfully collected/picked up | order_id, collected_at, collector_name |
| diagnostics.sample.received | Sample arrived at lab | order_id, received_at |
| diagnostics.result.ready | Test results/report is ready for download | order_id, report_url (secure link), ready_at |
| diagnostics.result.delivered | Report delivered to patient (if physical) | order_id, delivered_at |
| diagnostics.cancelled | Booking cancelled by lab or patient | order_id, reason |
diagnostics.result.ready
Example result ready callback
JSON
{
"event_id": "evt-2010",
"event_type": "diagnostics.result.ready",
"timestamp": "2025-12-11T10:15:00Z",
"context": {
"order_id": "lab-7789",
"status": "ready",
"ready_at": "2025-12-11T10:00:00Z",
"report_url": "https://storage.awadoc.com/reports/lab-7789.pdf",
"notes": "Normal results; consult doctor if symptoms persist"
}
}
diagnostics.sample.collected
📌 When to Send
Send this event immediately after the sample has been successfully collected from the patient (home collection) or handed over at a walk-in center.
📦 Important Fields
order_idcollected_atcollector_name
Example Request
{
"event_id": "evt-2001",
"event_type": "diagnostics.sample.collected",
"timestamp": "2025-12-10T09:35:00Z",
"context": {
"order_id": "lab-7789",
"collected_at": "2025-12-10T09:30:00Z",
"collector_name": "John Adewale"
}
}
diagnostics.sample.received
📌 When to Send
Send this event when the laboratory confirms that the sample has arrived at the lab facility and is ready for processing.
📦 Important Fields
order_idreceived_at
Example Request
{
"event_id": "evt-2002",
"event_type": "diagnostics.sample.received",
"timestamp": "2025-12-10T11:10:00Z",
"context": {
"order_id": "lab-7789",
"received_at": "2025-12-10T11:05:00Z"
}
}
diagnostics.result.delivered
📌 When to Send
Send this event after the patient has successfully accessed/downloaded the report (or it has been officially delivered via your system).
🎯 Purpose
Confirms final completion of the diagnostics lifecycle.
Example Request
{
"event_id": "evt-2011",
"event_type": "diagnostics.result.delivered",
"timestamp": "2025-12-11T10:45:00Z",
"context": {
"order_id": "lab-7789",
"delivered_at": "2025-12-11T10:44:00Z",
"delivery_channel": "email",
"recipient": "patient",
"status": "delivered"
}
}
📦 Important Fields
order_iddelivered_atdelivery_channel(email, sms, portal, api)status
diagnostics.cancelled
📌 When to Send
Send this event if the diagnostics order is cancelled at any stage (before collection, after collection but before result, etc.).
🎯 Purpose
Stops further processing and ensures platform state consistency.
Example Request
{
"event_id": "evt-2012",
"event_type": "diagnostics.cancelled",
"timestamp": "2025-12-09T14:20:00Z",
"context": {
"order_id": "lab-7789",
"cancelled_at": "2025-12-09T14:18:00Z",
"reason": "patient_request",
"stage": "before_collection"
}
}
📦 Important Fields
order_idcancelled_atreasonstage(before_collection, after_collection, processing)
Key Notes & Gotchas
- Field name is exactly "currency" (not "curency")
- Always return total_pricing in requested response — platform requires it for order creation
- Use ISO8601 UTC for all timestamps
- Respond <10s to availability queries, <30s to booking requests
- Support modes: home_collection, walkin, lab_dropoff
- For urgent tests (e.g., PCR), include "urgency": "stat" in availability
- No callback URL set → you are completely skipped in searches and bookings
You’re now fully equipped to receive and fulfil lab/diagnostics orders on AwaDoc! 🧪🔬