Developers

Infrastructure your technical team can trust.

Build on stable primitives for collections, payouts, settlement reporting and account visibility. Create scoped credentials in the portal, then call the endpoints below.

Overview

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.

Authentication

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.

Environments and rate limits

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.

Idempotency

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.

Endpoints

GET/api/public/v1

Discovery 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."
}
GET/api/public/v1/balance

Current float and settlement balances held for your account.

{ "data": { "available": "128400.00", "currency": "GHS" } }
GET/api/public/v1/providers

Mobile-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" } ]
  }
}
GET/api/public/v1/collections

List premium collections and checkout sessions, newest first.

Query parameters

limitintegeroptional1–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"
    }
  ]
}
POST/api/public/v1/collections

Debit a mobile wallet directly, or create a hosted checkout link for the policyholder.

Body parameters

amountnumberrequiredPositive, up to 10,000,000.
currencystring(3)optionalISO code. Defaults to GHS.
method"mobile_money" | "checkout"optionalDefaults to mobile_money.
mobilestringoptional10–15 digits. Required for mobile_money.
providerstringoptionalProvider code from /providers. Required for mobile_money.
descriptionstring(140)optionalUse the policy or invoice number so reconciliation matches.
callback_urlurloptionalCheckout only — where the payer returns after paying.
201 Created
{
  "data": {
    "reference": "COL-8F2K1",
    "status": "pending",
    "checkout_url": null,
    "amount": 120,
    "currency": "GHS"
  }
}
GET/api/public/v1/payouts

List claim disbursements and commission payouts, newest first.

Query parameters

limitintegeroptional1–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"
    }
  ]
}
POST/api/public/v1/payouts

Pay a claimant, broker or agent to a mobile wallet or bank account.

Body parameters

type"mobile_money" | "bank"requiredSelects which fields apply below.
amountnumberrequiredPositive, up to 10,000,000.
currencystring(3)optionalISO code. Defaults to GHS.
mobilestringoptionalmobile_money only — 10–15 digits.
providerstringoptionalmobile_money only — code from /providers.
account_numberstringoptionalbank only.
bank_codestringoptionalbank only — code from /providers.
narrationstring(140)optionalClaim or commission reference shown on the statement.
201 Created
{
  "data": {
    "reference": "PAY-3J9QZ",
    "status": "processing",
    "amount": 5000,
    "currency": "GHS"
  }
}
GET/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"
  }
}

Examples

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);

Transaction statuses

Money movement settles asynchronously. Poll the transaction endpoint, or read the record in the portal.

pendingCreated and awaiting the payer or the partner.
processingAccepted by the partner and being settled.
completedFunds have moved and settled.
failedThe partner rejected it. Read the record for the reason and retry with a new reference.
cancelledStopped before execution — for example a payout batch declined by an approver.

Errors

400invalid_json / invalid_request / invalid_referenceThe body was not JSON, or a field failed validation. The message names the field.
401missing_credentials / invalid_credentialsNo Authorization header, or the key is unknown, revoked or belongs to a suspended account.
403account_inactiveThe account has not been approved yet, or was suspended by Payme.
404not_foundNo record with that reference exists on your account.
429rate_limitedMore than 120 requests in a rolling minute for this key. Retry after the seconds in Retry-After.
500storage_errorPayme could not read or write the record. Safe to retry with the same Idempotency-Key.
502provider_errorThe banking or mobile-money partner rejected or failed the request.
503provider_unconfiguredLive money movement is not enabled on this account yet.

Webhooks

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"
    }
  }
}

Reconciliation practice

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.

Getting help

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.