Awadoc

Loan Provider Guide

For Businesses Integrating as Loan Partners on AwaDoc

This guide reflects the exact live platform behaviour as of December 2025.


Your Role as a Loan Provider

You receive loan requests and underwriting triggers from AwaDoc, must acknowledge quickly, run eligibility/underwriting, return a deterministic decision (approved, declined, or needs_info), and — when approved — initiate funding or provide a clear funding timeline. All callbacks are shown live to users and their family; accuracy and timeliness protect user trust.

This is a high-priority integration: decision and funding SLAs are monitored.


Prerequisites (same for all partners)

  • Business Record status: ACTIVE
  • One or more APPROVED offerings in category loan
  • testCallbackUrl & productionCallbackUrl configured by AwaDoc team
  • Test and/or Production API keys issued
  • Bank account verified (required for production disbursals)
  • Required regulatory documents submitted (KYC, license) — partner responsibility

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.
  • Clock skew tolerance: ±5 minutes.
  • All timestamps must be ISO8601 UTC.

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");
}

Core Concepts & Statuses

  • request_id — platform-generated loan request ID (e.g. loan-4421)
  • Deterministic status values (platform validates):
    • acknowledged (we received the request)
    • underwriting (partner is assessing)
    • needs_info (partner requires more data; must include fields_required)
    • approved (decision made; include approved_amount, tenor, interest_rate, repayment_schedule)
    • declined (include reason)
    • funding_initiated (disbursal started)
    • funded (disbursal complete)
    • cancelled (request cancelled)

Primary Flow & SLAs

Step Event Type When Sent SLA (monitored) Required Response
1 loan.requested (platform → partner) User submits loan application ≤ 5 minutes — initial ack required reply acknowledged or unavailable (see below)
2 loan.acknowledged Partner acknowledges receipt immediate (within SLA above) status: acknowledged, request_id, acknowledged_at
3 loan.underwriting Partner starts check / automated underwriting within 30 minutes recommended status: underwriting, request_id, started_at
4 loan.decision Final decision (approved/declined/needs_info) ≤ 30 minutes for automated flows; ≤ 4 hours for manual underwriting (monitored) see required fields per decision (below)
5 loan.funding_initiated Disbursal started ASAP after approval (partner must kick off funding) request_id, provider_txn_id, initiated_at, expected_funded_at
6 loan.funded Funds arrived to user's account Within partner's disbursal timelines request_id, funded_at, amount, disbursal_method
7 loan.cancelled User or partner cancels immediate request_id, reason, cancelled_at

What You Receive: loan.requested (only event you receive)

Example payload (platform → you):

{
  "event_id": "evt-9001",
  "event_type": "loan.requested",
  "timestamp": "2025-12-09T14:22:17Z",
  "user": {
    "id": "usr-8921",
    "name": "Aisha Ibrahim",
    "phone": "+2348123456789",
    "national_id": "NID-441233"
  },
  "context": {
    "request_id": "loan-4421",
    "product_code": "PAYDAY-1",
    "requested_amount": 50000,
    "currency": "NGN",
    "tenor_days": 30,
    "purpose": "medical",
    "location": {
      "address": "Plot 5, Banana Island, Ikoyi, Lagos",
      "coordinates": { "lat": 6.4592, "lng": 3.4268 }
    },
    "metadata": {
      "customer_score": 640,
      "existing_debt": 0
    }
  },
  "meta": { "trace_id": "trace-789012" }
}

Immediate Response (≤ 5 minutes — critical)

  • Success — acknowledged
{
  "status": "acknowledged",
  "request_id": "loan-4421",
  "acknowledged_at": "2025-12-09T14:24:05Z",
  "provider_name": "QuickFund Microfinance",
  "contact": "+2349012345678",
  "next_expected_action": "underwriting_started"
}
  • Failure — cannot serve
{
  "status": "unavailable",
  "request_id": "loan-4421",
  "reason": "product_not_enabled",
  "retry_after": "2025-12-09T15:00:00Z"
}

Note: Never ignore a loan.requested. If you cannot process it, reply unavailable with a clear reason.


Events You Must Send Back (Callbacks)

POST https://partners-{env}.awadoc.com/api/partners/:partnerId/callback
All callbacks must be delivered in real time — users see them live.

Event list (must send when state changes)

  • loan.acknowledged — when you received the request (see above)
  • loan.underwriting — when underwriting starts
    • Critical fields: request_id, started_at, underwriter_reference (optional)
  • loan.needs_info — when additional user info is required
    • Critical fields: request_id, fields_required (array), notes, expires_at
  • loan.approved — decision to approve
    • Critical fields: request_id, approved_amount, tenor_days, interest_rate, repayment_schedule (array), approved_at, offer_id
  • loan.declined — decision to decline
    • Critical fields: request_id, reason, declined_at, appeal_instructions (optional)
  • loan.funding_initiated — transfer to user's account initiated
    • Critical fields: request_id, provider_txn_id, initiated_at, expected_funded_at, disbursal_method
  • loan.funded — funds delivered
    • Critical fields: request_id, funded_at, amount, destination_account_id, disbursal_receipt
  • loan.cancelled — request cancelled
    • Critical fields: request_id, reason, cancelled_at

Example loan.approved callback:

{
  "event_id": "evt-9011",
  "event_type": "loan.approved",
  "timestamp": "2025-12-09T15:00:22Z",
  "context": {
    "request_id": "loan-4421",
    "approved_amount": 45000,
    "tenor_days": 30,
    "interest_rate": 0.05,
    "repayment_schedule": [
      { "due_date": "2026-01-08T00:00:00Z", "amount": 47250 }
    ],
    "approved_at": "2025-12-09T15:00:20Z",
    "offer_id": "offer-77"
  }
}

Timestamps & Formats

  • All timestamps must be ISO8601 with Z (UTC). Example: 2025-12-09T15:00:20Z.
  • Use precise monetary amounts (integer of minor units, or decimal with documented currency). Example: 45000 NGN.

Error Handling & Edge Cases

  • If callback URL is not set: you will not receive requests — AwaDoc will show provider as unreachable.
  • Underwriting timeouts: If your systems do not send a decision in the SLA window, AwaDoc may mark the request timed_out and re-route to alternative providers.
  • Partial approvals: If you can only partially satisfy a requested amount, send loan.approved with approved_amount < requested_amount and include notes.
  • Retry headers & idempotency: All callbacks include event_id and trace_id. Ensure idempotency by storing event_id.

Monitoring & Penalties

  • Initial acknowledgment SLA (≤ 5 minutes) is enforced. Repeated failures may cause de-listing or suspension.
  • Decision SLA (≤ 30 minutes automated / ≤ 4 hours manual) is monitored. Repeated slow decisions impact ranking.
  • AwaDoc provides logs and replay tools for debugging.

Best Practices

  • Provide tracking_url where possible (shows funding progress to users).
  • Share exact coordinates when available in requests to help fraud checks.
  • Always include provider_txn_id for funding events to reconcile payments.
  • For needs_info, include an expiration (expires_at) so users see time-limited requests.

Quick Reference — Required Fields by Event

  • loan.acknowledged: request_id, acknowledged_at
  • loan.underwriting: request_id, started_at
  • loan.needs_info: request_id, fields_required, expires_at
  • loan.approved: request_id, approved_amount, tenor_days, interest_rate, repayment_schedule, approved_at, offer_id
  • loan.declined: request_id, reason, declined_at
  • loan.funding_initiated: request_id, provider_txn_id, initiated_at, expected_funded_at
  • loan.funded: request_id, funded_at, amount, destination_account_id, disbursal_receipt

Sample Error Response (when you cannot accept new requests)

{
  "status": "unavailable",
  "request_id": "loan-4421",
  "reason": "daily_limit_reached",
  "retry_after": "2025-12-10T00:00:00Z"
}

Contact & Support

  • For integration help contact: integration@awadoc.com (include partner_id and trace_id in subject)
  • For production disbursal issues: settlements@awadoc.com

You are now equipped to offer loans through the AwaDoc network. Fast, clear decisions save users time and money — ensure your callbacks are real-time and idempotent.

Respond fast. Users rely on you. 💸✅