Developers
Build on stable primitives for collections, payouts, settlement reporting and account visibility. Create scoped credentials in the portal, then call the endpoints below.
The Payme API moves insurance money: premium collections in, claim and commission payouts out, with every record carrying your own policy or claim reference so reconciliation stays clean. It is a JSON over HTTPS API — no SDK required.
Base URL: https://paymeafrica.lovable.app/api/public/v1. Every response is either { data: ... } or { error: { code, message } }. Cross-origin requests are allowed and OPTIONS preflight is handled on every endpoint.
Send your key on every request: Authorization: Bearer <your Payme API key>. Create and revoke keys in the portal under Developers. Keys are stored hashed — the full value is shown once at creation, so save it in your secret manager immediately.
A key is bound to one account. Requests only ever see that account's records, and a key stops working the moment it is revoked or the account is suspended.
A payme_test_… key returns simulated, immediately completed results so you can build without moving money. A payme_live_… key settles real funds. Both accept identical requests, and sandbox records appear in the portal marked as sandbox.
Each key is limited to 120 requests per rolling minute. Over the limit you receive 429 with a Retry-After header in seconds.
Send an Idempotency-Key header on every POST. Reuse the same key when you retry a timed-out or failed request so a premium is never debited twice and a claim is never paid twice. A natural key works well — for example the policy number plus the instalment number.
/api/public/v1Discovery document listing every endpoint. No key required.
{
"name": "Payme by Insurerity — Developer API",
"version": "1.0.0",
"authentication": "Authorization: Bearer <your Payme API key>",
"endpoints": [ { "method": "GET", "path": "/api/public/v1/balance", "description": "..." } ],
"idempotency": "Send an Idempotency-Key header on POST requests to safely retry."
}/api/public/v1/balanceCurrent float and settlement balances held for your account.
{ "data": { "available": "128400.00", "currency": "GHS" } }/api/public/v1/providersMobile-money providers and bank codes you can pass to collections and payouts.
{
"data": {
"mobile_providers": [ { "code": "MTN", "name": "MTN Mobile Money" } ],
"banks": [ { "code": "GCB", "name": "GCB Bank" } ]
}
}/api/public/v1/collectionsList premium collections and checkout sessions, newest first.
Query parameters
| limit | integer | optional | 1–100, defaults to 50. |
{
"data": [
{
"merchant_reference": "COL-8F2K1",
"kind": "collection",
"amount": 120,
"currency": "GHS",
"status": "completed",
"checkout_url": null,
"customer_mobile": "0244000000",
"provider": "MTN",
"description": "Policy MOT/2026/00412 premium",
"created_at": "2026-09-09T10:22:04.113Z"
}
]
}/api/public/v1/collectionsDebit a mobile wallet directly, or create a hosted checkout link for the policyholder.
Body parameters
| amount | number | required | Positive, up to 10,000,000. |
| currency | string(3) | optional | ISO code. Defaults to GHS. |
| method | "mobile_money" | "checkout" | optional | Defaults to mobile_money. |
| mobile | string | optional | 10–15 digits. Required for mobile_money. |
| provider | string | optional | Provider code from /providers. Required for mobile_money. |
| description | string(140) | optional | Use the policy or invoice number so reconciliation matches. |
| callback_url | url | optional | Checkout only — where the payer returns after paying. |
201 Created
{
"data": {
"reference": "COL-8F2K1",
"status": "pending",
"checkout_url": null,
"amount": 120,
"currency": "GHS"
}
}/api/public/v1/payoutsList claim disbursements and commission payouts, newest first.
Query parameters
| limit | integer | optional | 1–100, defaults to 50. |
{
"data": [
{
"merchant_reference": "PAY-3J9QZ",
"payout_type": "bank",
"amount": 5000,
"currency": "GHS",
"status": "processing",
"account_number": "0123456789",
"bank_code": "GCB",
"narration": "Claim CLM/2026/00087",
"created_at": "2026-09-09T11:04:51.902Z"
}
]
}/api/public/v1/payoutsPay a claimant, broker or agent to a mobile wallet or bank account.
Body parameters
| type | "mobile_money" | "bank" | required | Selects which fields apply below. |
| amount | number | required | Positive, up to 10,000,000. |
| currency | string(3) | optional | ISO code. Defaults to GHS. |
| mobile | string | optional | mobile_money only — 10–15 digits. |
| provider | string | optional | mobile_money only — code from /providers. |
| account_number | string | optional | bank only. |
| bank_code | string | optional | bank only — code from /providers. |
| narration | string(140) | optional | Claim or commission reference shown on the statement. |
201 Created
{
"data": {
"reference": "PAY-3J9QZ",
"status": "processing",
"amount": 5000,
"currency": "GHS"
}
}/api/public/v1/transactions/{reference}Look up any collection or payout by its reference and refresh its status from the provider.
{
"data": {
"reference": "COL-8F2K1",
"status": "completed",
"kind": "collection",
"amount": 120,
"currency": "GHS",
"created_at": "2026-09-09T10:22:04.113Z"
}
}Collect a premium from a mobile wallet:
curl -X POST https://paymeafrica.lovable.app/api/public/v1/collections \
-H "Authorization: Bearer payme_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c8a20-premium-00412" \
-d '{
"method": "mobile_money",
"amount": 120,
"currency": "GHS",
"mobile": "0244000000",
"provider": "MTN",
"description": "Policy MOT/2026/00412 premium"
}'Pay a claim to a bank account:
curl -X POST https://paymeafrica.lovable.app/api/public/v1/payouts \
-H "Authorization: Bearer payme_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 91ab77c4-claim-00087" \
-d '{
"type": "bank",
"amount": 5000,
"currency": "GHS",
"account_number": "0123456789",
"bank_code": "GCB",
"narration": "Claim CLM/2026/00087"
}'The same collection call from Node or any modern JavaScript runtime:
const res = await fetch("https://paymeafrica.lovable.app/api/public/v1/collections", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PAYME_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": policyNumber + "-" + instalment,
},
body: JSON.stringify({
method: "mobile_money",
amount: 120,
currency: "GHS",
mobile: "0244000000",
provider: "MTN",
description: `Policy ${policyNumber} premium`,
}),
});
const { data, error } = await res.json();
if (error) throw new Error(error.message);
console.log(data.reference, data.status);Money movement settles asynchronously. Poll the transaction endpoint, or read the record in the portal.
| pending | Created and awaiting the payer or the partner. |
| processing | Accepted by the partner and being settled. |
| completed | Funds have moved and settled. |
| failed | The partner rejected it. Read the record for the reason and retry with a new reference. |
| cancelled | Stopped before execution — for example a payout batch declined by an approver. |
| 400 | invalid_json / invalid_request / invalid_reference | The body was not JSON, or a field failed validation. The message names the field. |
| 401 | missing_credentials / invalid_credentials | No Authorization header, or the key is unknown, revoked or belongs to a suspended account. |
| 403 | account_inactive | The account has not been approved yet, or was suspended by Payme. |
| 404 | not_found | No record with that reference exists on your account. |
| 429 | rate_limited | More than 120 requests in a rolling minute for this key. Retry after the seconds in Retry-After. |
| 500 | storage_error | Payme could not read or write the record. Safe to retry with the same Idempotency-Key. |
| 502 | provider_error | The banking or mobile-money partner rejected or failed the request. |
| 503 | provider_unconfigured | Live money movement is not enabled on this account yet. |
Payme receives settlement callbacks from the payment partner and updates your collections and payouts automatically, then raises an in-app notification. You do not need to host an endpoint to stay in sync — polling the transaction endpoint is enough for most integrations.
If you want events pushed to your own systems, ask us to enable outbound webhooks for your account. Deliveries are signed with an HMAC-SHA256 signature over {timestamp}.{raw_body} and are at-least-once, so de-duplicate on the event id.
{
"id": "evt_01J8...",
"type": "payout.completed",
"data": {
"object": {
"merchant_reference": "PAY-3J9QZ",
"status": "completed",
"amount": "5000.00",
"fee_amount": "8.00"
}
}
}Put your policy, claim or commission reference in description (collections) or narration (payouts). Payme returns its own reference for every record — store it against the policy in your core system so both sides can be matched line by line at settlement.
Bulk payouts submitted in the portal follow submit → approve → execute: nothing leaves the account until a second authorised person releases the batch. API payouts execute directly, so restrict live keys to systems that already apply your own approval controls.
Start in the sandbox, then request live keys once your flows pass. If a call fails with provider_unconfigured your account is not yet enabled for live money movement — contact us and we will switch it on.