Skip to content

Deposits

How it works

A deposit converts KES from the user's M-Pesa into USDC held in their Regini account. The flow:

  1. Quote (recommended): fetch a rate quote for the KES amount. The response shows the exact USDC the user will receive, the fee, and the exchange rate. The quote is locked for 10 minutes.
  2. Initiate: submit the deposit with the rate_id from the quote. Regini sends an M-Pesa STK push to the phone number stored on the account. The API responds immediately; the deposit is now pending.
  3. User confirms: the user approves the payment on their phone.
  4. Webhook: once M-Pesa confirms collection, Regini credits the USDC to the account and fires a deposit.completed webhook.

The M-Pesa prompt goes to the phone stored on the account. You do not supply it per-request. Your backend should listen for the webhook rather than polling for status.


Step 1: Get a rate quote

GET /accounts/{account_id}/deposit-quote?amount_kes=5000

{
  "rate_id": "abc123-...",
  "amount_kes": 5000.0,
  "net_usdc_amount": 38.07,
  "fee_usdc": 0.38,
  "exchange_rate": 131.35
}

exchange_rate is the effective KES/USDC rate with the FX spread already applied, this is the rate shown to the user. The quote is valid for 10 minutes and is single-use.

Step 2: Confirm the deposit

POST /accounts/{account_id}/deposits

{
  "amount_kes": 5000,
  "rate_id": "abc123-...",
  "reference": "optional-your-ref"
}

An Idempotency-Key header is required for safe retries:

Idempotency-Key: <unique-uuid-per-request>

Response:

{
  "status": "success",
  "message": "Deposit initiated",
  "transaction_id": "tx-uuid-..."
}

The deposit is now pending. The user will receive an M-Pesa STK push. Once they confirm, Regini credits their account and fires a deposit.completed webhook.


Option B: Auto-confirm at live rate

Skip the quote step and execute immediately at the live rate.

POST /accounts/{account_id}/deposits

{
  "amount_kes": 5000,
  "auto_confirm_rate": true,
  "reference": "optional-your-ref"
}

Request fields

Field Required Description
amount_kes Yes KES amount to deposit
rate_id Conditional Rate quote from GET .../deposit-quote. Required when auto_confirm_rate is false.
auto_confirm_rate No Default false. When true, executes at the live rate without a prior quote.
reference No Your own reference string (max 255 chars). Returned in the webhook and transaction history.

Limits

Limit Value
Minimum per transaction KES 100
Maximum per transaction KES 250,000
Daily (rolling 24 hours) KES 500,000 per account
Weekly (rolling 7 days) KES 2,000,000 per account

Daily and weekly windows are rolling (not calendar-reset). Failed transactions do not count against the limits. Breaching a limit returns VELOCITY_LIMIT_EXCEEDED.