API Docs

MediLoan SDK

Let a patient finance their care at the point of treatment. Your system starts the application, MyItura underwrites it and runs the loan, and you get told what happened.

How it fits together

  • Your system calls POST /sdk/loans/initiate with the patient and the amount being financed.
  • You get back an applicationUrl. Send the patient there, or open it in a webview.
  • The patient completes the application, KYC and the offer on MyItura's hosted pages.
  • You receive webhooks as the loan moves through its lifecycle.
This is not the Lending API

MediLoan is MyItura lending to your patient. If you are the lender and want to underwrite on your own book, that is the Lending API, which uses the same key pair and a different surface.

Base URL
Productionhttps://api.myitura.com/api/v1
Authenticationx-api-public-key + x-api-secret-key
POST/sdk/loans/initiate

Initiate a loan

The first step: your organisation tells us a patient wants to finance a treatment. The response carries the URL the patient completes the application at.

Body

FieldDescription
clientReferencerequiredstringYour unique identifier for this initiation.
invoiceReferencestringThe invoice being funded. May repeat across initiations.
firstNamerequiredstringFirst name of the patient.
phoneNumberrequiredstringAccepted as 080..., 234... or +234....
treatmentrequiredstringWhat is being financed.
treatmentAmountrequirednumberThe amount, in kobo. 4500000 is NGN 45,000.00.
Amounts are kobo

Sending naira here finances a hundredth of the treatment, and nothing in the response will tell you so. Multiply by 100 before you send.

curl -X POST https://api.myitura.com/api/v1/sdk/loans/initiate \
-H "x-api-public-key: pk_live_abc123def456" \
-H "x-api-secret-key: sk_live_xyz789uvw012" \
-H "Content-Type: application/json" \
-d '{
  "clientReference": "HOSP-001",
  "invoiceReference": "INV-2025-001",
  "firstName": "John",
  "phoneNumber": "08012345678",
  "treatment": "Surgery",
  "treatmentAmount": 500000
}'
{
"status": 201,
"message": "Loan initiation successful",
"data": {
  "sdkReference": "AB12CD34EF",
  "clientReference": "HOSP-001",
  "applicationUrl": "https://loans.myitura.com/apply?sdkref=AB12CD34EF",
  "status": "initiated",
  "expiresAt": "2025-11-02T10:00:00.000Z"
}
}

What happens next

Initiation hands you an applicationUrl and hands the patient to us. Everything between that link and the money reaching you happens on MyItura, and you follow it through webhooks rather than by calling us.

The steps the patient completes

They verify their identity, we run the checks against the bureau, the loan is decisioned and priced, and they accept the offer. None of this is yours to collect or verify. We are the lender on a MediLoan application, so the identity and affordability work is ours.

The direct debit

Before any money moves, the patient authorises a direct debit against their bank account. That authorisation happens on the payment provider's own page, so nobody, us included, ever handles their bank credentials.

Disbursement waits for the mandate

A loan is not disbursed until the direct debit is confirmed live by the provider, which is a separate event from the patient finishing the authorisation form and can lag it. A loan sitting accepted but not yet disbursed is usually waiting on exactly this.

Then you are paid

On disbursement the funds settle to your organisation and you receive loan.disbursed. That is the event to reconcile against, not loan.approved: approval is a decision, disbursement is the money.

The journey, end to end
you    POST /sdk/loans/initiate
       -> applicationUrl, sdkReference

       (you send the patient the link, or we SMS it)

patient  identity and bureau checks      <- we run these
         offer issued and accepted
         authorises the direct debit

         mandate confirmed live          <- gates disbursement

you    <- loan.approved       (decision made)
       <- loan.disbursed      (money settled to you)
POST/sdk/loans/{loanId}/mandate

Set up the direct debit

Repayment is collected by direct debit, and a loan is not disbursed until the mandate is live. A borrower who applied through your system has never signed in here, so there is no session for them to set one up in. This is the route that does it for them.

What comes back is an authorisation URL, not an active mandate. Send your borrower to it and they authorise at their bank. A mandate nobody authorised is not permission to take money, so a link is the honest answer.

Body

Optional. Send it only when the loan has no account to debit, which happens when the profile behind it was completed without bank details. Omit it and we use what the loan already has.

FieldDescription
bankCodestringThe bank to debit. Required if you send accountNumber.
accountNumberstringThe account to debit. Required if you send bankCode.
accountNamestringName on the account.
bankNamestringDisplay name of the bank.

Checking on it

GET /sdk/loans/{loanId}/mandate returns where the borrower has got to, for polling rather than listening. The mandate events reach your webhook either way.

A loan that is not yours answers 404

Tenancy is the organisation that originated the loan. A loan belonging to another partner is a 404 rather than a 403, because a 403 would confirm it exists.

Set up the direct debit
curl -X POST https://api.myitura.com/api/v1/sdk/loans/$LOAN_ID/mandate \
  -H "X-API-Public-Key: $MYITURA_PUBLIC_KEY" \
  -H "X-API-Secret-Key: $MYITURA_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "bankCode": "058",
    "accountNumber": "0123456789",
    "accountName": "Adaeze Okafor",
    "bankName": "Guaranty Trust Bank"
  }'

Events and signatures

We call your endpoint as the loan moves. Every request carries the event name and a signature over the body.

HeaderDescription
X-MyItura-EventThe event name, for example loan.initiated.
X-MyItura-SignatureHMAC-SHA256 of the request body, keyed with your secret key.

Events

loan.initiatedAn application was started from your initiation
loan.application.submittedThe applicant completed KYC
loan.approvedAn admin approved the loan
loan.rejectedThe loan was declined
loan.offer.acceptedThe applicant signed the offer
loan.disbursedFunds were transferred
loan.offer.rejectedThe applicant declined the offer
loan.repayment.dueAn instalment passed its due date unpaid
loan.repayment.completedAn instalment was collected
loan.completedThe last instalment was paid and the loan closed
loan.cancelledThe loan was cancelled
loan.defaultedThe loan passed the default threshold unpaid
Verify before you act

Compute the signature over the raw body and compare in constant time. An endpoint that trusts the payload without checking is an endpoint anyone can drive.

// Signature verification is a server-side process
Payload: loan.initiated
{
"event": "loan.initiated",
"timestamp": "2024-01-08T14:30:00Z",
"data": {
  "sdkReference": "SDK-A1B2C3D4",
  "clientReference": "YOUR_SYSTEM_REF_123",
  "invoiceReference": "INV-001",
  "status": "pending",
  "amount": 5000000,
  "currency": "NGN",
  "applicant": {
    "firstName": "John",
    "lastName": "Doe",
    "gender": "male"
  },
  "applicationUrl": "https://loans.myitura.com/apply?sdkref=SDK-A1B2C3D4"
}
}
GET/sdk/events

Replay a missed event

Deliveries are queued and retried with a backoff, so an endpoint that is briefly unreachable does not lose anything. When yours is down for longer than the retries last, this is how you find what you missed rather than reconciling blind.

It returns your organisation's deliveries, newest first, each with its status and its last error. Pass limit to change how many come back: 1 to 200, and 100 if you do not.

Sending one again

POST /sdk/events/{id}/redeliver queues that delivery again, to the endpoint you have configured now rather than the one you had then.

A redelivery is not a new event

The body and the event name are the ones we first sent, so a replayed event can describe a loan that has moved on since. Key your handler on the loan and make it repeatable, rather than on the order things arrived.

Find and replay
curl "https://api.myitura.com/api/v1/sdk/events?limit=50" \
  -H "X-API-Public-Key: $MYITURA_PUBLIC_KEY" \
  -H "X-API-Secret-Key: $MYITURA_SECRET_KEY"

curl -X POST https://api.myitura.com/api/v1/sdk/events/$DELIVERY_ID/redeliver \
  -H "X-API-Public-Key: $MYITURA_PUBLIC_KEY" \
  -H "X-API-Secret-Key: $MYITURA_SECRET_KEY"