Skip to content

Top-ups

Money in: add funds to an AutoPayKe balance from mobile money, card or bank transfer, then follow the top-up until it is credited.

Every endpoint here needs Authorization: Bearer <token> for a signed-in AutoPayKe account. See Authentication.

Get top-up options

GET/api/v1/funding/options
Bearer token

Which top-up methods are switched on right now, their limits, and the card hold periods. Read this before showing a top-up screen and hide the methods that are false.

Request
curl "https://api.autopayke.com/api/v1/funding/options" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN"
Response200 application/json
{
  "ok": true,
  "data": {
    "card": false,
    "mobileMoney": true,
    "mobileMoneyLimitsKes": {
      "min": 10,
      "max": 150000
    },
    "bank": false,
    "bankCountries": [],
    "bankLimitsNgn": null,
    "fromAbroad": false,
    "paymentLinks": true,
    "cardHoldHoursNewUser": 72,
    "cardHoldHoursNewCard": 24,
    "cardDailyLimitUsd": 500,
    "firstCardDailyLimitUsd": 100
  }
}

Top up with mobile money

POST/api/v1/funding/mobile-money
Bearer token 10 top-ups per minute per IP address.

Sends a payment prompt to the phone. The customer approves it with their mobile money PIN and the balance is credited in USDC at the quoted rate.

Availability. Live in Kenya for M-Pesa. The per-top-up limits in force are mobileMoneyLimitsKes from Get top-up options.

Body (JSON)
  • amountstringrequired

    Major units with up to 2 decimals, e.g. "1500".

  • currencystringoptional

    Defaults to the currency of the account's country (KES in Kenya).

  • countrystringoptional

    Defaults to the account's country.

  • phonestringrequired

    The paying phone, international format.

  • operatorstringoptional

    Operator code from /capabilities.

  • idempotencyKeystringoptional

    8–80 characters. You can send it as the Idempotency-Key header instead.

Request
curl -X POST "https://api.autopayke.com/api/v1/funding/mobile-money" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "1500",
    "phone": "+254712345678",
    "operator": "Safaricom",
    "idempotencyKey": "topup-2026-11-03-0001"
  }'
Response201 application/json
{
  "ok": true,
  "data": {
    "id": "3e5b2a90-8c1d-4f6e-b0a2-1c9d7e4f5a33",
    "method": "mobile_money",
    "status": "processing",
    "localAmount": "150000",
    "localCurrency": "KES",
    "chargeAmount": "150000",
    "chargeCurrency": "KES",
    "feeAmount": "0",
    "feeCurrency": "KES",
    "creditAmountUsdc": "11360000",
    "fxRate": "132.04",
    "checkoutUrl": null,
    "stepRequired": "Approve the M-Pesa prompt on your phone",
    "virtualAccount": null,
    "failureReason": null,
    "holdUntil": null,
    "card": null,
    "reference": "APK-TP-8F3K2Q",
    "expiresAt": "2026-11-03T09:15:00.000Z",
    "createdAt": "2026-11-03T09:10:00.000Z",
    "creditedAt": null,
    "progress": {
      "stages": [
        {
          "key": "requested",
          "title": "Payment requested",
          "detail": "We sent a prompt to +254 712 ••• 678",
          "state": "done",
          "at": "2026-11-03T09:10:00.000Z"
        },
        {
          "key": "payer",
          "title": "Waiting for approval",
          "detail": "Approve the prompt with your M-Pesa PIN",
          "state": "active",
          "at": null
        },
        {
          "key": "credited",
          "title": "In your balance",
          "detail": "",
          "state": "pending",
          "at": null
        }
      ],
      "terminal": false,
      "hint": "This usually takes under a minute."
    }
  }
}

Top up with a card

POST/api/v1/funding/card
Bearer token 10 top-ups per minute per IP address.

Creates a hosted checkout and returns its checkoutUrl. Send the customer there; card details never touch your servers or ours.

Availability. Switched off today: /funding/options returns card: false. New cards are held before they can be withdrawn.

Body (JSON)
  • amountstringrequired

    Major units with up to 2 decimals.

  • currencystringoptional

    Defaults to the account's currency.

  • countrystringoptional

    Defaults to the account's country.

  • firstNamestringoptional

    Prefills checkout.

  • lastNamestringoptional

    Prefills checkout.

  • emailstringoptional

    Prefills checkout.

  • idempotencyKeystringoptional

    8–80 characters.

Request
curl -X POST "https://api.autopayke.com/api/v1/funding/card" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "50",
    "currency": "USD",
    "email": "amina@example.com"
  }'
Response201 application/json
{
  "ok": true,
  "data": {
    "id": "c0a4e1d2-5b6f-4c3a-9e8d-7f1a2b3c4d55",
    "method": "card",
    "status": "pending",
    "localAmount": "5000",
    "localCurrency": "USD",
    "chargeAmount": "5000",
    "chargeCurrency": "USD",
    "feeAmount": "0",
    "feeCurrency": "USD",
    "creditAmountUsdc": "50000000",
    "fxRate": null,
    "checkoutUrl": "https://checkout.example.com/s/…",
    "stepRequired": null,
    "virtualAccount": null,
    "failureReason": null,
    "holdUntil": "2026-11-06T09:10:00.000Z",
    "card": null,
    "reference": "APK-TP-2M9W4D",
    "expiresAt": "2026-11-03T09:15:00.000Z",
    "createdAt": "2026-11-03T09:10:00.000Z",
    "creditedAt": null,
    "progress": {
      "stages": [
        {
          "key": "requested",
          "title": "Payment requested",
          "detail": "We sent a prompt to +254 712 ••• 678",
          "state": "done",
          "at": "2026-11-03T09:10:00.000Z"
        },
        {
          "key": "payer",
          "title": "Waiting for approval",
          "detail": "Approve the prompt with your M-Pesa PIN",
          "state": "active",
          "at": null
        },
        {
          "key": "credited",
          "title": "In your balance",
          "detail": "",
          "state": "pending",
          "at": null
        }
      ],
      "terminal": false,
      "hint": "This usually takes under a minute."
    }
  }
}

Top up by bank transfer

POST/api/v1/funding/bank
Bearer token 10 top-ups per minute per IP address.

Returns a bank account to transfer into, the exact amount and when it expires. Bank top-ups are in Nigerian naira today.

Availability. Switched off today: /funding/options returns bank: false.

Body (JSON)
  • amountstringrequired

    Major units.

  • currencystringoptional

    Defaults to NGN.

  • countrystringoptional

    Defaults to NG.

  • refundAccountobjectoptional

    The payer's own account { bankCode, accountNumber (10 digits), accountName }: where money goes back if the top-up can't finish.

  • idempotencyKeystringoptional

    8–80 characters.

Request
curl -X POST "https://api.autopayke.com/api/v1/funding/bank" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "20000",
    "refundAccount": {
      "bankCode": "058",
      "accountNumber": "0123456789"
    }
  }'
Response201 application/json
{
  "ok": true,
  "data": {
    "id": "9d2c7b1a-0e4f-4a5b-8c6d-2e3f4a5b6c77",
    "method": "bank",
    "status": "pending",
    "localAmount": "2000000",
    "localCurrency": "NGN",
    "chargeAmount": "2000000",
    "chargeCurrency": "NGN",
    "feeAmount": "0",
    "feeCurrency": "NGN",
    "creditAmountUsdc": "13020000",
    "fxRate": "1536.10",
    "checkoutUrl": null,
    "stepRequired": null,
    "virtualAccount": {
      "bankName": "Example Bank",
      "accountName": "AutoPayKe Top-up",
      "accountNumber": "9900112233",
      "amount": "2000000",
      "amountText": "₦20,000.00",
      "currency": "NGN",
      "expiresAt": "2026-11-03T10:10:00.000Z",
      "note": "Send the exact amount in one transfer."
    },
    "failureReason": null,
    "holdUntil": null,
    "card": null,
    "reference": "APK-TP-7Q1L8N",
    "expiresAt": "2026-11-03T10:10:00.000Z",
    "createdAt": "2026-11-03T09:10:00.000Z",
    "creditedAt": null,
    "progress": {
      "stages": [
        {
          "key": "requested",
          "title": "Payment requested",
          "detail": "We sent a prompt to +254 712 ••• 678",
          "state": "done",
          "at": "2026-11-03T09:10:00.000Z"
        },
        {
          "key": "payer",
          "title": "Waiting for approval",
          "detail": "Approve the prompt with your M-Pesa PIN",
          "state": "active",
          "at": null
        },
        {
          "key": "credited",
          "title": "In your balance",
          "detail": "",
          "state": "pending",
          "at": null
        }
      ],
      "terminal": false,
      "hint": "This usually takes under a minute."
    }
  }
}

List banks for bank top-ups

GET/api/v1/funding/bank/institutions
Bearer token

The banks a payer can transfer from. Empty while bank top-ups are switched off.

Request
curl "https://api.autopayke.com/api/v1/funding/bank/institutions" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN"
Response200 application/json
{
  "ok": true,
  "data": {
    "banks": []
  }
}

Get a top-up

GET/api/v1/funding/{id}
Bearer token

The top-up now. Poll every 2 seconds while it's on screen, or use the live stream below. Final statuses: credited, failed, expired, cancelled, reversed.

Path parameters
  • idstringrequired

    The top-up id (UUID).

Request
curl "https://api.autopayke.com/api/v1/funding/3e5b2a90-8c1d-4f6e-b0a2-1c9d7e4f5a33" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN"
Response200 application/json
{
  "ok": true,
  "data": {
    "id": "3e5b2a90-8c1d-4f6e-b0a2-1c9d7e4f5a33",
    "method": "mobile_money",
    "status": "credited",
    "localAmount": "150000",
    "localCurrency": "KES",
    "chargeAmount": "150000",
    "chargeCurrency": "KES",
    "feeAmount": "0",
    "feeCurrency": "KES",
    "creditAmountUsdc": "11360000",
    "fxRate": "132.04",
    "checkoutUrl": null,
    "stepRequired": null,
    "virtualAccount": null,
    "failureReason": null,
    "holdUntil": null,
    "card": null,
    "reference": "APK-TP-8F3K2Q",
    "expiresAt": "2026-11-03T09:15:00.000Z",
    "createdAt": "2026-11-03T09:10:00.000Z",
    "creditedAt": "2026-11-03T09:10:41.000Z",
    "progress": {
      "stages": [
        {
          "key": "requested",
          "title": "Payment requested",
          "detail": "We sent a prompt to +254 712 ••• 678",
          "state": "done",
          "at": "2026-11-03T09:10:00.000Z"
        },
        {
          "key": "payer",
          "title": "Approved",
          "detail": "",
          "state": "done",
          "at": "2026-11-03T09:10:31.000Z"
        },
        {
          "key": "credited",
          "title": "In your balance",
          "detail": "",
          "state": "done",
          "at": "2026-11-03T09:10:41.000Z"
        }
      ],
      "terminal": true,
      "hint": null
    }
  }
}

Stream a top-up

GET/api/v1/funding/{id}/live
Bearer token

Server-sent events: one event with the top-up now, then one on every change, until it is credited or fails. Each event's data is the same object Get a top-up returns.

Path parameters
  • idstringrequired

    The top-up id (UUID).

Request
curl -N "https://api.autopayke.com/api/v1/funding/3e5b2a90-8c1d-4f6e-b0a2-1c9d7e4f5a33/live" \
  -H "Authorization: Bearer $AUTOPAYKE_TOKEN"
Response200 text/event-stream
data: {"id":"3e5b2a90-…","status":"processing","progress":{"terminal":false,…}}

data: {"id":"3e5b2a90-…","status":"credited","progress":{"terminal":true,…}}