Tala Pesa Loan data API
Tala: Fast & Safe Pesa Loan is Tala Mobile's Kenya Android client for short-term digital credit (Play package com.inventureaccess.safarirahisi, shipped as the keProd flavor of the Tala / Inventure Access stack). Borrowers enter a Kenyan mobile number, receive an SMS OTP, set or confirm a PIN, then capture national-ID photos before a loan card shows the offered Pesa amount, repayment schedule, CRB status and how-to-repay guides. Cash-out and bill-pay rails include M-Pesa plus in-app payment methods; Zendesk chat handles support. Tala also runs sister apps in other markets, but this listing is the Kenya Pesa product competing with Branch, Okash and Safaricom M-Shwari / Fuliza for the same prepaid-mobile borrowers.
PIN loginSuccess mints sessionId and personId after a phone loginExists check and OTP flags (otpSent, otpValid), with mnoCode and pinStatus on the same payload. National-ID photo uploads return an image URL once idNumber / idName are stored; M-Pesa repayment deep-links arrive as paymentUrl and stopUrl beside each method's displayName and minPayableAmount. Device-signal rows carry androidId, deviceId and personId.
Originations, collections and fraud desks join those session, KYC and repayment records. openData Studio turns them into callable open data.
Screenshots
API surface
The endpoints and request/response examples below are reconstructed from the app's interface — illustrative, not a live capture.
Check phone login exists
POST
/v1/accounts/phone-lookuposintLooks up loginType/loginValue (phone) and returns loginExists so the sign-in screen can branch between OTP registration and PIN login.
Auth: Unauthenticated JSON envelope: a data block plus metadata.country and metadata.device (androidId, deviceId, googleAdId, networkType, version). Later calls reuse the data.sessionId returned by the PIN sign-in call, sent as a session token header (not a Bearer JWT).
- loginType
- loginValue
- loginExists
- status
- statusDescription
- displayMsg
- metadata.country
- device.androidId
- device.deviceId
- device.googleAdId
- device.networkType
- device.version
POST /v1/accounts/phone-lookup HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678" }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "loginExists": true }, "errors": null }Send login OTP
POST
/v1/accounts/verification-codesosintSends an SMS OTP to loginValue and returns otpSent for the Kenya Pesa OTP screen.
Auth: Unauthenticated JSON envelope with metadata.device. OTP verification and PIN sign-in afterwards mint data.sessionId.
- loginType
- loginValue
- otpSent
- displayMsg
- status
POST /v1/accounts/verification-codes HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678" }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "OTP sent", "otpSent": true }, "errors": null }Verify login OTP
POST
/v1/accounts/verification-codes/confirmosintChecks authValue (OTP) for the phone loginValue and returns otpValid before the PIN screen.
Auth: Unauthenticated JSON envelope; data.authValue is the OTP. PIN sign-in afterwards returns data.sessionId.
- loginType
- loginValue
- authValue
- otpValid
- status
POST /v1/accounts/verification-codes/confirm HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678", "authValue": "482913" }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "otpValid": true }, "errors": null }PIN login
POST
/v1/logins/pinosintExchanges the phone PIN (authValue) for loginSuccess, sessionId, personId, mnoCode, pinStatus and numTriesRemaining.
Auth: Unauthenticated JSON envelope; data.authValue is the PIN. Response data.sessionId and data.personId authenticate later KYC, repayment and device-signal calls as a session token header (not Authorization: Bearer).
- loginType
- loginValue
- authValue
- loginSuccess
- mnoCode
- numTriesRemaining
- personId
- pinStatus
- sessionId
- status
POST /v1/logins/pin HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678", "authValue": "135790" }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "loginSuccess": true, "mnoCode": "SAF", "numTriesRemaining": 5, "personId": 1048291, "pinStatus": 1, "sessionId": "sess-7c41d9e2a91f" }, "errors": null }Create auth session
POST
/v1/logins/bootstraposintMints a sessionId on the Kenya sign-in service before or alongside PIN login.
Auth: JSON envelope with metadata.device. Returns data.sessionId used on later authenticated calls (session token header, not a Bearer JWT).
- sessionId
- status
- statusDescription
- displayMsg
POST /v1/logins/bootstrap HTTP/1.1 Content-Type: application/json { "data": {}, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "sessionId": "sess-7c41d9e2a91f" }, "errors": null }PIN reset challenge questions
POST
/v1/credentials/recovery/questionsosintLoads PIN-reset challengeQuestions (id, hint, value) plus challengeStatus and challengeType for the security-question screen.
Auth: JSON envelope with loginType phone and loginValue. May attach the sessionId from the PIN sign-in or session bootstrap call.
- loginType
- loginValue
- challengeStatus
- challengeType
- challengeQuestions
- id
- hint
- value
POST /v1/credentials/recovery/questions HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678" }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "challengeStatus": 1, "challengeType": "SECURITY_QUESTIONS", "challengeQuestions": [ { "id": 12, "hint": "What is your mother's maiden name?", "value": "What is your mother's maiden name?" } ] }, "errors": null }Verify PIN reset answers
POST
/v1/credentials/recovery/answersosintSubmits challengeDataList answers and returns isVerified plus numberOfTries remaining on the PIN-reset flow.
Auth: JSON envelope with loginType phone plus a challengeDataList of id/answer pairs. May attach the sessionId from the sign-in or session call.
- loginType
- loginValue
- challengeDataList
- id
- answer
- isVerified
- numberOfTries
POST /v1/credentials/recovery/answers HTTP/1.1 Content-Type: application/json { "data": { "loginType": "phone", "loginValue": "254712345678", "challengeDataList": [ { "id": 12, "answer": "Wanjiku" } ] }, "metadata": { "country": "KE", "device": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "googleAdId": "38400000-8cf0-11bd-b23e-10b96e40000d", "networkType": "WIFI", "version": "7.30.0" } } }{ "status": "SUCCESS", "statusDescription": "OK", "data": { "displayMsg": "", "isVerified": true, "numberOfTries": 2 }, "errors": null }List repayment methods
GET
/v1/repayments/payment-channelsopenfinanceLists repayment rails for the Kenya Pesa bill screen: each paymentMethods row has displayName (M-Pesa) and minPayableAmount.
Auth: Session token header carrying the sessionId from PIN sign-in (data.sessionId, data.personId, data.mnoCode). Not a Bearer JWT.
- paymentMethods
- displayName
- minPayableAmount
GET /v1/repayments/payment-channels HTTP/1.1 X-Session-Id: <session_id>{ "paymentMethods": [ { "displayName": "M-Pesa", "minPayableAmount": 10.0 }, { "displayName": "Airtel Money", "minPayableAmount": 10.0 } ] }M-Pesa payment parameters
POST
/v1/repayments/checkout-linksopenfinanceBuilds the in-app repayment WebView for an amount: paymentUrl to start M-Pesa STK and stopUrl when the flow ends.
Auth: Session token header carrying the sessionId from PIN sign-in (data.sessionId, data.personId). Not a Bearer JWT.
- amount
- paymentUrl
- stopUrl
POST /v1/repayments/checkout-links HTTP/1.1 Content-Type: application/json X-Session-Id: <session_id> { "amount": 2500.0 }{ "paymentUrl": "https://pay.example.com/mpesa/start?ref=<reference>", "stopUrl": "https://pay.example.com/mpesa/stop" }Store KYC photo
POST
/v1/identity/documents/imagesopendataUploads a national-ID or selfie image (imageData, type) and returns the stored image URL when result is success.
Auth: Session token header carrying the sessionId from PIN sign-in. Body wraps imageData and type inside an appInfoData envelope (androidId, deviceId, networkType, personId, pwd, type=156, version).
- imageData
- type
- image
- result
- androidId
- deviceId
- personId
- pwd
- version
POST /v1/identity/documents/images HTTP/1.1 Content-Type: application/json X-Session-Id: <session_id> { "appInfoData": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "networkType": "WIFI", "personId": 1048291, "pwd": "********", "type": 156, "version": "7.30.0" }, "data": { "imageData": "/9j/4AAQSkZJRgABAQAAAQABAAD...", "type": 1 } }{ "data": { "result": "success", "image": "https://cdn.example.com/kyc/ke/<person_id>/id-front.jpg" } }Change KYC ID number
POST
/v1/identity/documents/numberopendataWrites the borrower's idNumber and idType (national ID) onto the person record after photo KYC.
Auth: Session token header carrying the sessionId from PIN sign-in. Body wraps idNumber and idType plus appInfoData.personId.
- idNumber
- idType
- personId
- displayMsg
POST /v1/identity/documents/number HTTP/1.1 Content-Type: application/json X-Session-Id: <session_id> { "appInfoData": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "networkType": "WIFI", "personId": 1048291, "pwd": "********", "type": 156, "version": "7.30.0" }, "data": { "idNumber": "12345678", "idType": "NATIONAL_ID" } }{ "data": { "displayMsg": "ID number updated" } }Change KYC ID type
POST
/v1/identity/documents/typeopendataSwitches the selected KYC document kind via idName (national ID vs other) on the Kenya person record.
Auth: Session token header carrying the sessionId from PIN sign-in. Body wraps idName plus appInfoData.
- idName
- personId
- result
POST /v1/identity/documents/type HTTP/1.1 Content-Type: application/json X-Session-Id: <session_id> { "appInfoData": { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "networkType": "WIFI", "personId": 1048291, "pwd": "********", "type": 156, "version": "7.30.0" }, "data": { "idName": "NATIONAL_ID" } }{ "data": { "result": "success" } }Device signal upload
POST
/v1/signals/deviceopendataPosts device and person telemetry (androidId, deviceId, networkType, personId, version) used in Kenya underwriting alongside the loan screens.
Auth: The body carries personId and pwd (from PIN sign-in) inside the appInfoData fields; type is fixed at 156 for general device data. The sessionId is not a Bearer JWT.
- androidId
- deviceId
- networkType
- personId
- pwd
- type
- version
POST /v1/signals/device HTTP/1.1 Content-Type: application/json { "androidId": "a1b2c3d4e5f6g7h8", "deviceId": "ke-dev-88421", "networkType": "WIFI", "personId": 1048291, "pwd": "********", "type": 156, "version": "7.30.0" }{ "status": "SUCCESS", "statusDescription": "OK" }
Data categories
- phone identity
- OTP sessions
- PIN login
- KYC photos
- national ID numbers
- M-Pesa repayment
- device telemetry
Where teams use this data
Watch Kenya phone and PIN sessions
An originations desk reads loginExists, otpValid, loginSuccess, personId, mnoCode and pinStatus to tell new OTP registrations from returning PIN logins without scraping the Android UI.
Reconcile M-Pesa repayment deep-links
Collections matches each bill's displayName and minPayableAmount to the paymentUrl / stopUrl pair minted for an amount, instead of waiting for an M-Pesa SMS screenshot.
KYC photo and ID completeness
Underwriting joins the stored image URL with idNumber, idType and idName on the same personId before allowing a Pesa re-loan.
Device telemetry join
A fraud job pairs androidId, deviceId, googleAdId and networkType from the auth envelope with the data-receiver personId and type=156 payload.
Frequently asked questions
How does Tala authenticate API calls?
Phone OTP and PIN login return sessionId, personId, mnoCode and pinStatus. Later KYC, repayment and device-signal calls reuse that sessionId as a session token — it is not a Bearer JWT. Request envelopes also stamp metadata.device fields such as androidId, deviceId, googleAdId, networkType and version.
What identity fields sit behind the KYC screens?
Photo upload stores imageData and type and returns an image URL when result is success. The person record then holds idNumber, idType and idName (national ID). Phone lookup exposes loginExists before OTP.
Can I read M-Pesa repayment rails, not just login?
Yes. The repayment-method list returns displayName and minPayableAmount (M-Pesa and other wallets). Requesting checkout parameters for an amount returns paymentUrl and stopUrl for the in-app repayment WebView.
What device telemetry is attached to Kenya underwriting?
Auth metadata.device carries androidId, deviceId, googleAdId, networkType and version. The device-signal upload posts the same identifiers with personId, pwd and type 156.
Apps similar to Tala: Fast & Safe Pesa Loan
- Branch — Branch is a Kenya, Nigeria and India digital-finance app that offers smartphone instant loans, wallet transfers, bill payments and in-app savings.
- Zenka — Zenka is Zenka Digital Limited's Kenya cash-loan app that sends between KSh 500 and KSh 200,000 to M-Pesa, with customer-chosen tenors of up to 61 days.
- Okash — Okash is Opera's Kenya digital-lending app for short-term cash loans, covered alongside Tala and Branch in reporting on the country's mobile-loan market.
- M-Shwari — M-Shwari is the NCBA Bank and Safaricom product launched in November 2012 that lets M-PESA customers save and borrow on a mobile phone while earning interest on savings.
- KCB M-PESA — KCB M-PESA is the March 2015 savings-and-loan product from Safaricom and KCB Bank that extends mobile credit and savings on the M-PESA menu.
- My OneApp — My OneApp is Safaricom PLC's Kenya super-app for the M-PESA wallet, including Fuliza overdraft when the balance is short, Lipa na M-PESA payments and Ziidi unit trusts.
Topics
- Tala Pesa loan API
- sessionId personId
- Kenya digital credit
- M-Pesa repayment paymentUrl
- KYC image idNumber
- loginExists otpValid
- Tala Mobile data API
Need this app's data API integrated?
We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.
- NDA + SOW on every engagement
- Delivery in 3–7 days
- Payment only after acceptance
- Work scoped to authorized use