Getting started
Authentication
Every request must carry your secret API key in the X-API-KEY header. A Bearer
token (Authorization: Bearer <key>) is also accepted.
curl https://api.riwe.io/v1/rupa/me \
-H "X-API-KEY: rk_live_kLREMIRNy0pAJ5QRmbkmQ9OqUaW6xESQ..." \
-H "Accept: application/json"
Your key
- The secret looks like
rk_live_followed by 40 characters. - It is shown once, when Riwe creates the partner or when you rotate the key. Store it in a secrets manager — Riwe cannot show it again.
- If you lose it, ask Riwe to rotate the key. Rotation immediately invalidates the old key and returns a new one.
- Treat it like a password. Never embed it in mobile apps or browser code — call the API only from your backend.
Important —
The
api_…value you may see on the partner dashboard is a public key identifier, not the secret. Authentication only accepts therk_live_…secret.
Live vs sandbox
Your account runs in one mode, returned by GET /me:
| Mode | Meaning |
|---|---|
live |
Production. Lookups bill your real wallet and return real farmer data. |
sandbox |
Test. Use for integration; ask Riwe which behaviour applies to your account. |
IP allow‑listing (optional)
Riwe can restrict your key to specific server IPs. If an allow‑list is set on your
account and you call from an IP that isn't on it, you get 403 "not permitted from
your IP address." An empty allow‑list means all IPs are allowed. Send Riwe the
static egress IP(s) of your backend to enable this.
Your first calls
1 — Confirm the key (free):
curl https://api.riwe.io/v1/rupa/me \
-H "X-API-KEY: rk_live_YOUR_SECRET" -H "Accept: application/json"
{
"success": true,
"data": {
"company_name": "Fin Org2",
"account_type": "bank",
"status": "active",
"mode": "live",
"allowed_sections": ["identity","bvn_nin_data","credit_history","outstanding_loans","transaction_volume"],
"mandatory_sections": ["identity","bvn_nin_data","credit_history","outstanding_loans","transaction_volume"],
"contribution_events": ["loan_disbursed","loan_repayment","loan_defaulted"],
"wallet_balance": 2000,
"compliance": { "lookups": 0, "contributions_expected": 0, "contributions_received": 0, "compliance_rate": 0 }
}
}
2 — Look a farmer up (billed):
curl -X POST https://api.riwe.io/v1/rupa/lookup \
-H "X-API-KEY: rk_live_YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{ "rupa_id": "rp-7lif9u" }'
Account types & entitlements
Your account type determines which data sections you can read and which activity events you must report.
| Account type | Reads (mandatory sections) | Reports (contribution events) |
|---|---|---|
| bank | identity, bvn_nin_data, credit_history, outstanding_loans, transaction_volume | loan_disbursed, loan_repayment, loan_defaulted |
| insurer | identity, bvn_nin_data, farms, underwriting_value | policy_issued, claim_filed, claim_settled |
| agtech | identity, farms | input_purchase, harvest_record |
Riwe can grant optional extra sections (e.g. wallet, socioeconomic_profile) to
your account; the full set you may read is always returned as allowed_sections by
GET /me.
Consent model
Consent is established by possession of a farmer's Rupa ID — the farmer shares it
with you to be served. Your first successful lookup of a Rupa ID records a consent
entry on your roster (see Consents); subsequent lookups
refresh it. You can release a farmer at any time with DELETE /consents/{rupaId}.
Conventions
- All timestamps are ISO‑8601 UTC (e.g.
2026-07-03T12:02:54+00:00). - All money is in NGN unless stated.
- Request bodies are JSON; always send
Content-Type: application/json. - Rupa IDs are case‑insensitive.