Skip to content

7.3 APIs and contracts

The following is a representative API surface. Adapt to each partner’s preferences; some partners require SFTP-only or have their own house specs.

  • Base: https://api.platform.in/partner/v1
  • Auth: mTLS + bearer token
  • Idempotency: Idempotency-Key header on every mutating call
  • Versioning: in URL (/v1, /v2)
  • Webhooks: signed by HMAC; partner provides URL

POST /partners

Onboard a new partner.

Request:
{
"name": "ACME Bank",
"master_agreement_ref": "MCLA-ACME-2026-001",
"escrow_account": {
"bank": "Sponsor Bank",
"ifsc": "SPON0000001",
"account_number": "...",
"type": "co_lending_escrow"
},
"default_ratio": {"partner": 80, "originator": 20},
"settlement_frequency_days": 1,
"mis_format": "csv_v1"
}
Response:
{
"partner_id": "pln_abc123",
"created_at": "2026-01-10T05:00:00Z"
}

GET /partners/{partner_id}/eligible-applications?since=...

Returns applications that have passed originator’s underwriting and are eligible for the partner’s co-lending policy.

Response:
{
"applications": [
{
"application_id": "app_001",
"borrower_summary": {...PII tokenised...},
"loan_summary": {
"amount_requested": 2500000,
"tenure_days": 90,
"purpose": "working_capital"
},
"risk_grade": "A2",
"originator_decision": "APPROVE"
},
...
],
"next_cursor": "..."
}

POST /partners/{partner_id}/loans/submit

Request (Idempotency-Key: required):
{
"application_id": "app_001",
"loan_proposal": {
"amount": 2500000,
"tenure_days": 90,
"rate": 0.205,
"product_code": "WC_LINE_V1"
},
"underwriting_evidence_uri": "https://...evidence-package",
"share_split": {
"partner": 80,
"originator": 20
}
}
Response:
{
"submission_id": "sub_001",
"status": "submitted",
"expected_decision_by": "2026-01-10T06:00:00Z"
}

4. Partner returns approval (webhook to originator)

Section titled “4. Partner returns approval (webhook to originator)”

POST {originator_webhook_url}/co-lending/decision

{
"submission_id": "sub_001",
"partner_id": "pln_abc123",
"decision": "APPROVE",
"decision_at": "2026-01-10T05:45:00Z",
"approved_share_amount": 2000000,
"conditions": ["specific_bank_account_required"]
}

Errors / declines use the same webhook with "decision": "DECLINE" and a "decline_reasons": [...].

5. Confirm allocation (notify partner of acceptance + sanction)

Section titled “5. Confirm allocation (notify partner of acceptance + sanction)”

POST /partners/{partner_id}/loans/{submission_id}/sanction

Request (Idempotency-Key):
{
"sanction_amount": 2500000,
"partner_share_amount": 2000000,
"originator_share_amount": 500000,
"rate": 0.205,
"tenure_days": 90,
"kfs_uri": "https://.../kfs.pdf",
"agreement_uri": "https://.../agreement.pdf",
"mandate_npci_ref": "NM00000000XXXX"
}
Response:
{
"sanction_id": "snc_001",
"partner_loan_account_id": "PLA-ACME-12345"
}

6. Disbursement event (originator notifies partner)

Section titled “6. Disbursement event (originator notifies partner)”

POST /partners/{partner_id}/loans/{partner_loan_account_id}/disbursed

Request (Idempotency-Key):
{
"disbursed_at": "2026-01-10T08:30:00Z",
"disbursed_amount_total": 2500000,
"partner_share_disbursed": 2000000,
"originator_share_disbursed": 500000,
"utr": "SBIN0XXXXXXX",
"escrow_movement_ref": "ESC-001"
}

Either as API pull (GET /partners/{partner_id}/mis?date=2026-01-10) or as SFTP CSV. Columns:

  • partner_loan_account_id
  • originator_application_id
  • borrower_pan_token
  • outstanding_principal (partner share)
  • outstanding_interest_accrued (partner share)
  • dpd_days
  • classification (standard / sma_0 / 1 / 2 / npa / sub / doubt / loss)
  • repayments_today (partner share)
  • charges_today (partner share)
  • last_payment_date

Daily settlement file generated by NBFC. For each partner:

  • Total partner-share repayments collected today.
  • Net of any servicing fee / DLG draw.
  • Bank instruction: NEFT / RTGS from escrow → partner main account.

POST /partners/{partner_id}/loans/{partner_loan_account_id}/npa

{
"npa_classification_date": "2026-04-15",
"dpd_days": 92,
"outstanding_principal": 1500000,
"outstanding_interest": 50000
}

Both lenders update simultaneously (lockstep classification).

POST /partners/{partner_id}/loans/{partner_loan_account_id}/closed

{
"closed_at": "2026-05-10T...",
"closure_reason": "fully_paid",
"final_settlement_amount": 0,
"noc_uri": "https://.../noc.pdf"
}

11. Webhook events from originator → partner (push)

Section titled “11. Webhook events from originator → partner (push)”
  • application.eligible_for_partner
  • loan.allocated
  • loan.disbursed
  • loan.repayment_received (with share breakdown)
  • loan.npa_classified
  • loan.upgraded
  • loan.closed
  • settlement.completed
  • reconciliation.exception (if material)
X-Signature: HMAC-SHA256({timestamp}|{body}, partner_secret)
X-Timestamp: {epoch ms}

Partner verifies signature; rejects on tampering.

  • Every mutating call requires Idempotency-Key.
  • Server stores key + response for 7 days.
  • Duplicate call returns the same response.
{
"error": {
"code": "INVALID_RATIO",
"message": "Share ratio does not match agreement",
"details": {
"provided": {"partner": 75, "originator": 25},
"expected": {"partner": 80, "originator": 20}
}
}
}

Common error codes: UNAUTHORIZED, IDEMPOTENCY_MISMATCH, VALIDATION_ERROR, PARTNER_CAP_EXCEEDED, BORROWER_INELIGIBLE, INTERNAL_ERROR.

Each bank partner will negotiate variations. Document each partner’s deviation as a per-partner integration spec, kept in the platform’s documentation alongside the agreement.