Awadoc

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 TypeWhen to SendImportant Fields
diagnostics.sample.collectedSample successfully collected/picked uporder_id, collected_at, collector_name
diagnostics.sample.receivedSample arrived at laborder_id, received_at
diagnostics.result.readyTest results/report is ready for downloadorder_id, report_url (secure link), ready_at
diagnostics.result.deliveredReport delivered to patient (if physical)order_id, delivered_at
diagnostics.cancelledBooking cancelled by lab or patientorder_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_id
  • collected_at
  • collector_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_id
  • received_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_id
  • delivered_at
  • delivery_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_id
  • cancelled_at
  • reason
  • stage (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! 🧪🔬