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&productionCallbackUrlconfigured 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 includefields_required)approved(decision made; includeapproved_amount,tenor,interest_rate,repayment_schedule)declined(includereason)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, replyunavailablewith a clearreason.
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)
- Critical fields:
loan.needs_info— when additional user info is required- Critical fields:
request_id,fields_required(array),notes,expires_at
- Critical fields:
loan.approved— decision to approve- Critical fields:
request_id,approved_amount,tenor_days,interest_rate,repayment_schedule(array),approved_at,offer_id
- Critical fields:
loan.declined— decision to decline- Critical fields:
request_id,reason,declined_at,appeal_instructions(optional)
- Critical fields:
loan.funding_initiated— transfer to user's account initiated- Critical fields:
request_id,provider_txn_id,initiated_at,expected_funded_at,disbursal_method
- Critical fields:
loan.funded— funds delivered- Critical fields:
request_id,funded_at,amount,destination_account_id,disbursal_receipt
- Critical fields:
loan.cancelled— request cancelled- Critical fields:
request_id,reason,cancelled_at
- Critical fields:
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:
45000NGN.
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_outand re-route to alternative providers. - Partial approvals: If you can only partially satisfy a requested amount, send
loan.approvedwithapproved_amount<requested_amountand includenotes. - Retry headers & idempotency: All callbacks include
event_idandtrace_id. Ensure idempotency by storingevent_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_urlwhere possible (shows funding progress to users). - Share exact coordinates when available in requests to help fraud checks.
- Always include
provider_txn_idfor 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_atloan.underwriting:request_id,started_atloan.needs_info:request_id,fields_required,expires_atloan.approved:request_id,approved_amount,tenor_days,interest_rate,repayment_schedule,approved_at,offer_idloan.declined:request_id,reason,declined_atloan.funding_initiated:request_id,provider_txn_id,initiated_at,expected_funded_atloan.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(includepartner_idandtrace_idin 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. 💸✅