Credit Scoring
/v1/credit/scoresPOST/v1/credit/scores/batchesGet a credit score for a DRC citizen, computed from verified alternative and financial data — mobile money, telecom, banking and utility payment histories — linked to their RDCPASS identity. Each score comes with a risk band, a 12-month probability of default and the factors that drove it, so you can make fast, explainable lending decisions for customers with or without a banking history.
Every score requires the citizen’s explicit consent
RDCPASS never scores a citizen without their approval. Each request must carry a validconsent obtained from that citizen — through a consent request they approve in the RDCPASS app, or through Login with RDCPASS with the rdcpass:credit.score scope. A missing, expired, revoked or mismatched consent returns 403 consent_required, and nothing is computed or billed.At a glance
| Single | POST /v1/credit/scores |
| Batch | POST /v1/credit/scores/batches — up to 50 items synchronously, 10,000 asynchronously |
| Consent | Mandatory, per citizen — consent.method rdcpass_app |
| Score | 300 – 850, bands A to E, with probability_of_default |
| Identity data | account and kyc.basic only — additional KYC scopes never apply |
| Purpose | credit_assessment |
| Webhook | credit_score.completed (asynchronous calls) |
| Production | Enhanced due diligence — see Going to production |
Obtaining consent
Consent is given by the citizen, on their own device, after seeing exactly who is asking and why. There are two ways to obtain it; both produce a consent identifier prefixed cns_ that you pass in consent.consent_id.
| Method | How it works |
|---|---|
| RDCPASS app consent request | Your application sends a consent request to the citizen. They receive it in the RDCPASS app, which shows your organization’s name, the product and the amount, and approve it with face confirmation. The approved request gives you the consent_id. |
| Login with RDCPASS | Include rdcpass:credit.score in the scope of your authorization request. The citizen approves it on the RDCPASS consent screen together with the other scopes, and the rdcpass:credit.consent claim returns method, consent_id and expires_at. See Login with RDCPASS. |
In both cases the citizen approves inside the RDCPASS app, so consent.method is always rdcpass_app.
Consent rules
- A consent is bound to one citizen and one application. It cannot be reused for another identifier or shared between applications.
- It is valid for 30 days from approval (
expires_at) and can be used for new scores during that period — for example to re-score before disbursement. - The citizen can revoke it at any time from the RDCPASS app. Revocation takes effect immediately; subsequent requests return
consent_required. - Scores already delivered remain valid until their own
valid_until, but you may only use them for the credit decision the citizen consented to.
HTTP/1.1 403 Forbidden
{
"error": "consent_required",
"message": "Consent cns_5e8a2d71c4 has expired. Ask the citizen to approve a new consent request."
}Request
The plaintext body below is encrypted and signed before it is sent, as described in Authentication. Every POST also accepts the optional Idempotency-Key header (24-hour window) and Prefer: respond-async.
| Field | Type | Required | Description |
|---|---|---|---|
| identifier | object | Yes | The citizen to score. |
| identifier.type | string enum | Yes | rdcpass_id (recommended), passport, ceni, driving_licence or national_id. |
| identifier.value | string | Yes | The identifier value, e.g. COD-2103-0214-4937. |
| consent | object | Yes | The citizen’s consent for this score. |
| consent.method | string enum | Yes | rdcpass_app. |
| consent.consent_id | string | Yes | The consent identifier, prefixed cns_. |
| purpose | string enum | Yes | Must be credit_assessment, approved for your application. |
| product | string enum | Yes | The credit product being assessed — see Product types below. |
| amount_requested | object | No | Optional { "value", "currency" } — the amount applied for, in CDF or USD. Improves the relevance of the probability of default. |
| reference | string | No | Your own identifier for this application, echoed back in the response and webhooks. |
{
"identifier": {
"type": "rdcpass_id",
"value": "COD-2103-0214-4937"
},
"consent": {
"method": "rdcpass_app",
"consent_id": "cns_5e8a2d71c4"
},
"purpose": "credit_assessment",
"product": "microcredit",
"amount_requested": { "value": 1500000, "currency": "CDF" },
"reference": "loan-2026-0917"
}Response
A successful call returns 200 OK with a credit_score object.
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier, prefixed crs_. |
| object | string | Always credit_score. |
| livemode | boolean | true in production, false in the sandbox. |
| reference | string | null | The reference you sent, or null. |
| status | string enum | Always completed for a synchronous call. Asynchronous and batch items can be failed. |
| identifier | object | The identifier you submitted. |
| consent | object | The consent used: method, consent_id, granted_at, expires_at. |
| product | string | The product you declared. |
| amount_requested | object | null | The amount you declared, or null. |
| score | integer | Credit score from 300 (highest risk) to 850 (lowest risk). |
| band | string enum | A to E — see Score bands below. |
| probability_of_default | number | Estimated probability, from 0 to 1, that the citizen defaults on a credit obligation within the next 12 months. |
| factors | object[] | The factors that most influenced the score, ordered by weight: code, impact (positive | negative), weight (0 – 1) and a human-readable description. |
| data_sources | string[] | The data sources that contributed to this score. |
| valid_until | string (RFC 3339) | Until when the score may be relied on for a credit decision — 30 days after computation. Request a new score after this date. |
| account | object | The citizen’s RDCPASS account: rdcpass_id, status, certified, created_at, level_of_assurance. |
| kyc.basic | object | Basic KYC: full_name, first_name, last_name, date_of_birth, age, gender, nationality. |
| purpose | string | The purpose you declared. |
| created_at | string (RFC 3339) | When the score was computed. |
Credit Scoring returns basic KYC only. Additional KYC scopes never apply to this service — use KYC Validation if your onboarding needs addresses, documents or other scoped data.
Score bands
Bands group scores into risk levels. Probability-of-default ranges are indicative, based on observed 12-month default rates across the RDCPASS scored population; always rely on the probability_of_default returned for the individual citizen.
| Band | Score range | Risk level | Indicative 12-month default rate |
|---|---|---|---|
| A | 750 – 850 | Very low | < 2 % |
| B | 670 – 749 | Low | 2 – 5 % |
| C | 580 – 669 | Moderate | 5 – 12 % |
| D | 500 – 579 | High | 12 – 25 % |
| E | 300 – 499 | Very high | > 25 % |
Factors
Each factor explains part of the score. Use them to give applicants the principal reasons for a decision and to guide them on how to improve their score.
| code | What it measures |
|---|---|
| payment_history | Timeliness of repayments on loans, mobile credit and instalment plans. |
| mobile_money_activity | Regularity and volume of mobile money inflows and outflows. |
| credit_utilization | Share of available credit currently in use. |
| income_stability | Stability of recurring income over time. |
| account_age | Age of the citizen’s financial and mobile money accounts. |
| telecom_tenure | Length of use of the citizen’s primary phone number. |
| utility_payments | Punctuality of electricity, water and other utility payments. |
| recent_inquiries | Number of recent credit applications. |
Data sources
| data_sources | Origin |
|---|---|
| mobile_money | Mobile money operators — wallet activity, transfers and repayments. |
| telecom | Mobile network operators — tenure, top-up and airtime-credit behaviour. |
| banking | Banks and microfinance institutions — accounts, loans and repayments. |
| utilities | Utility providers — electricity and water billing and payment history. |
data_sources lists only the sources that contributed data for this citizen. A score built on fewer sources is still valid; its factors show what it is based on.
Product types
| product | Description |
|---|---|
| personal_loan | Unsecured personal loan. |
| microcredit | Microcredit, including group and micro-enterprise loans. |
| mobile_credit | Short-term credit or overdraft on a mobile money wallet or airtime. |
| mortgage | Home loan secured on real estate. |
| bnpl | Buy now, pay later — instalment purchase at a merchant. |
| other | Any other credit product. |
Full response
{
"id": "crs_5a9e2c7b14",
"object": "credit_score",
"livemode": true,
"reference": "loan-2026-0917",
"status": "completed",
"identifier": { "type": "rdcpass_id", "value": "COD-2103-0214-4937" },
"consent": {
"method": "rdcpass_app",
"consent_id": "cns_5e8a2d71c4",
"granted_at": "2026-09-26T10:12:40Z",
"expires_at": "2026-10-26T10:12:40Z"
},
"product": "microcredit",
"amount_requested": { "value": 1500000, "currency": "CDF" },
"score": 712,
"band": "B",
"probability_of_default": 0.034,
"factors": [
{
"code": "payment_history",
"impact": "positive",
"weight": 0.35,
"description": "Mobile credit and loan instalments repaid on time over the last 24 months."
},
{
"code": "mobile_money_activity",
"impact": "positive",
"weight": 0.25,
"description": "Regular monthly inflows on the primary mobile money wallet."
},
{
"code": "credit_utilization",
"impact": "negative",
"weight": 0.15,
"description": "Outstanding balances use 68 % of available credit lines."
},
{
"code": "telecom_tenure",
"impact": "positive",
"weight": 0.1,
"description": "Same primary phone number for more than 6 years."
},
{
"code": "utility_payments",
"impact": "positive",
"weight": 0.08,
"description": "Electricity and water bills settled without arrears."
},
{
"code": "recent_inquiries",
"impact": "negative",
"weight": 0.07,
"description": "3 credit applications in the last 90 days."
}
],
"data_sources": ["mobile_money", "telecom", "banking", "utilities"],
"valid_until": "2026-10-26T10:15:02Z",
"account": {
"rdcpass_id": "COD-2103-0214-4937",
"status": "active",
"certified": true,
"created_at": "2025-03-14T09:22:41Z",
"level_of_assurance": "LOA3"
},
"kyc": {
"basic": {
"full_name": "Kabeya Mwamba Tshisekedi",
"first_name": "Kabeya",
"last_name": "Tshisekedi",
"date_of_birth": "1988-04-12",
"age": 38,
"gender": "male",
"nationality": "COD"
}
},
"purpose": "credit_assessment",
"created_at": "2026-09-26T10:15:02Z"
}Example request
The header values are illustrative placeholders — see Authentication for how to compute a real X-RDCPASS-Signature and encrypt the body. Each sample handles consent_required.
# Plaintext body shown — it is AES-256-GCM encrypted (IV in X-RDCPASS-IV) and signed per /docs/authentication before sending.
curl https://api.rdcpass.cd/v1/credit/scores \
-X POST \
-H "X-RDCPASS-Key-Id: key_live_8f2a1c0e9b" \
-H "X-RDCPASS-Timestamp: 1735689600" \
-H "X-RDCPASS-Nonce: 2d7b4e91-6c3a-4f08-b5e2-8a1f0c9d3e67" \
-H "X-RDCPASS-Signature: 8c1d4f...b62e" \
-H "X-RDCPASS-IV: mX4p9Qz2Lr8sT1vB" \
-H "Idempotency-Key: e4a9c2f7-1b3d-4e6a-9f05-7c2b8d1e0a53" \
-H "Content-Type: application/json" \
-d '{
"identifier": { "type": "rdcpass_id", "value": "COD-2103-0214-4937" },
"consent": { "method": "rdcpass_app", "consent_id": "cns_5e8a2d71c4" },
"purpose": "credit_assessment",
"product": "microcredit",
"amount_requested": { "value": 1500000, "currency": "CDF" },
"reference": "loan-2026-0917"
}'Responsible lending
A score informs a credit decision; it does not make it. Combine it with your own affordability assessment, tell applicants the principal reasons for an adverse decision (thefactors are designed for this), never use a score for anything other than the credit decision the citizen consented to, and do not store scores beyond your documented retention period. Your lending practices must comply with the regulations of the Banque Centrale du Congo applicable to your institution.Request modes
Credit Scoring supports all four request modes. See Single, batch & async for polling, pagination and cancellation.
| Synchronous (default) | Asynchronous (Prefer: respond-async) | |
|---|---|---|
| Single | 200 with the credit_score object | 202 with a job; result via credit_score.completed or GET /v1/jobs/{job_id} |
| Batch | 200 with every result — up to 50 items | 202 with a batch — up to 10,000 items; results via webhook or GET /v1/batches/{batch_id}/results |
Batch: pre-approval campaigns
Score a list of customers at once — for example to pre-approve mobile credit limits for wallet holders who opted in. Each item must carry its own valid consent: a batch never bypasses consent, and items without one fail individually with consent_required while the rest succeed. purpose and product set at batch level apply to every item unless the item overrides them.
curl https://api.rdcpass.cd/v1/credit/scores/batches \
-X POST \
-H "X-RDCPASS-Key-Id: key_live_8f2a1c0e9b" \
-H "X-RDCPASS-Timestamp: 1735689600" \
-H "X-RDCPASS-Nonce: 2d7b4e91-6c3a-4f08-b5e2-8a1f0c9d3e67" \
-H "X-RDCPASS-Signature: 8c1d4f...b62e" \
-H "X-RDCPASS-IV: mX4p9Qz2Lr8sT1vB" \
-H "Idempotency-Key: e4a9c2f7-1b3d-4e6a-9f05-7c2b8d1e0a53" \
-H "Prefer: respond-async" \
-H "Content-Type: application/json" \
-d @preapproval-campaign.json # plaintext shown; encrypt per /docs/authentication before sending{
"purpose": "credit_assessment",
"product": "mobile_credit",
"items": [
{
"reference": "camp-0917-00001",
"identifier": { "type": "rdcpass_id", "value": "COD-2103-0214-4937" },
"consent": { "method": "rdcpass_app", "consent_id": "cns_5e8a2d71c4" },
"amount_requested": { "value": 100, "currency": "USD" }
},
{
"reference": "camp-0917-00002",
"identifier": { "type": "rdcpass_id", "value": "COD-1907-5530-1186" },
"consent": { "method": "rdcpass_app", "consent_id": "cns_91c3b7e0a2" },
"amount_requested": { "value": 250, "currency": "USD" }
},
{
"reference": "camp-0917-00003",
"identifier": { "type": "rdcpass_id", "value": "COD-1512-8841-0273" },
"consent": { "method": "rdcpass_app", "consent_id": "cns_0d4f6a8b17" }
}
]
}HTTP/1.1 202 Accepted
{
"id": "bat_7c2e91f04a",
"object": "batch",
"service": "credit_scoring",
"status": "pending",
"total_items": 3,
"processed_items": 0,
"succeeded_items": 0,
"failed_items": 0,
"created_at": "2026-09-26T10:15:00Z",
"completed_at": null,
"results_url": "/v1/batches/bat_7c2e91f04a/results"
}{
"object": "list",
"data": [
{
"reference": "camp-0917-00001",
"status": "succeeded",
"result": {
"id": "crs_5a9e2c7b14",
"object": "credit_score",
"score": 712,
"band": "B",
"probability_of_default": 0.034,
"valid_until": "2026-10-26T10:15:02Z",
"...": "..."
}
},
{
"reference": "camp-0917-00002",
"status": "succeeded",
"result": {
"id": "crs_b82f1d6e03",
"object": "credit_score",
"score": 598,
"band": "C",
"probability_of_default": 0.091,
"valid_until": "2026-10-26T10:15:03Z",
"...": "..."
}
},
{
"reference": "camp-0917-00003",
"status": "failed",
"error": {
"code": "consent_required",
"message": "Consent cns_0d4f6a8b17 was revoked by the citizen."
}
}
],
"next_cursor": null
}Synchronous batches over 50 items return 413 batch_too_large. Asynchronous batches accept up to 10,000 items; you receive batch.completed or batch.completed_with_errors when processing ends. Each succeeded item is billed individually; items rejected for consent_required are not billed.
Asynchronous scoring
Send Prefer: respond-async with a single request to get a job back immediately. When the score is ready, RDCPASS delivers a credit_score.completed event to your webhook URL; its data is the completed job, with the same object a synchronous call returns embedded in result. You can also poll GET /v1/jobs/{job_id}.
HTTP/1.1 202 Accepted
{
"id": "job_9e3c5a1f7d",
"object": "job",
"service": "credit_scoring",
"status": "pending",
"created_at": "2026-09-26T10:15:00Z",
"result_url": "/v1/jobs/job_9e3c5a1f7d"
}{
"id": "evt_5d1a8f3c7e2b9a40",
"object": "event",
"type": "credit_score.completed",
"livemode": true,
"created_at": "2026-09-26T10:15:03Z",
"data": {
"object": {
"id": "job_9e3c5a1f7d",
"object": "job",
"service": "credit_scoring",
"status": "completed",
"created_at": "2026-09-26T10:15:00Z",
"result_url": "/v1/jobs/job_9e3c5a1f7d",
"result": {
"id": "crs_5a9e2c7b14",
"reference": "loan-2026-0917",
"object": "credit_score",
"status": "completed",
"score": 712,
"band": "B",
"probability_of_default": 0.034,
"...": "..."
}
}
}
}Verify the webhook signature before trusting the payload — see Webhooks.
Errors
Errors use the standard format described in Errors. Codes specific to this service:
| Code | HTTP | When |
|---|---|---|
| invalid_identifier | 400 | identifier.value does not match the format of identifier.type, or no certified RDCPASS account exists for it. |
| unsupported_identifier_type | 400 | The identifier type is not accepted by this service (for example a business identifier). |
| insufficient_balance | 402 | Prepaid wallet balance is exhausted. |
| credit_limit_reached | 402 | Postpaid usage has reached your credit limit. |
| consent_required | 403 | Consent missing, expired, revoked, or issued for another citizen or application. |
| purpose_not_approved | 403 | purpose is not credit_assessment, or it is not approved for this application. |
| service_not_enabled | 403 | Credit Scoring is not enabled on this application. |
| production_access_required | 403 | A production key was used before the application passed enhanced due diligence. |
| job_not_found | 404 | The job ID does not exist for this application. |
| batch_not_found | 404 | The batch ID does not exist for this application. |
| batch_too_large | 413 | More than 50 items in a synchronous batch. |
| quota_exceeded | 429 | Your plan’s quota for the period is exhausted. |
| rate_limited | 429 | Too many requests — retry after the indicated delay. |
Next steps
- Login with RDCPASS — collect credit consent at sign-in with
rdcpass:credit.score. - Single, batch & async — batches, jobs and pagination in detail.
- Going to production — enhanced due diligence required for Credit Scoring in production.
- Billing — how scores and batch items are metered.