Skip to main content
Recurring payments let you pay the same beneficiary or wallet on a fixed schedule from your PeerPesa balance, for example a monthly KES salary to an M-Pesa number or a weekly USDC transfer to a Stellar address. Setup follows three steps: Basic Info (who, what, and how much), Schedule (when and how often), and Review (check upcoming runs and fees, then activate).
1

Basic Info

Create a draft with POST /recurring-payments: name, payment type, source coin and network, amount, and recipient.
2

Schedule

Set frequency, start date, run time, and when it ends with PUT /recurring-payments/{id}/schedule.
3

Review

Call GET /recurring-payments/{id}/review to see the next run dates, estimated fees, and balance check. Then activate with POST /recurring-payments/{id}/activate.
Rates are not locked for recurring payments. Each run creates a fresh quote at execution time and confirms it automatically, so the fee and rate shown in Review are estimates.

Statuses

Step 1: Basic Info

POST /recurring-payments Creates a recurring payment in draft status.
string
required
Label shown in your dashboard, for example "Monthly rent".
string
required
withdraw (pay fiat to a beneficiary, see Withdraw) or send (send crypto to a wallet or PeerPesa user, see Send).
object
required
Balance to pay from.
string
required
Amount per run as a decimal string.
string
required
Currency of amount: the source symbol, or the beneficiary’s fiat code for withdraw (for example KES to pay a fixed fiat amount each run).
object
required
Who gets paid.
string
Note attached to every payment, shown to the recipient where the method supports it.
string
Your own identifier. Each run’s transaction gets reference plus a run number suffix, for example rent-2026-003.
Response

Step 2: Schedule

PUT /recurring-payments/{id}/schedule Sets when and how often the payment runs. You can call it again while the payment is draft or paused.
string
required
Recurring payment ID, for example rp_5t8w2k.
string
required
daily, weekly, biweekly, or monthly.
string
Required for weekly and biweekly: monday to sunday.
integer
Required for monthly: 1 to 31. In shorter months, runs on the last day.
string
required
First possible run date (YYYY-MM-DD). Must be today or later.
string
default:"09:00"
Run time in 24-hour HH:MM format.
string
default:"Africa/Nairobi"
IANA timezone for start_date and time.
object
required
When the schedule stops. Set type to never, on_date (with date), or after_occurrences (with occurrences).
Returns the recurring payment with its schedule filled in. Status stays draft.

Step 3: Review and activate

GET /recurring-payments/{id}/review

Returns a summary to show the user before activation: recipient, upcoming run dates, estimated fees at current rates, and whether the balance covers the next run.
cURL
Response
object
Estimated cost of one run at current rates, including the fee breakdown and the total debited from your balance.
string[]
The next three run times in UTC.
object
Your available balance on the source coin and network, and whether it covers the next run.
string[]
Issues to show the user, for example insufficient_balance_for_next_run or amount_exceeds_monthly_limit.

POST /recurring-payments/{id}/activate

Activates a reviewed draft. Status becomes active and next_run_at is set.
Response

How runs execute

At each run time, PeerPesa creates a quote, confirms it, and debits your balance. The result is a normal order with recurring_payment set to the schedule ID.
  • If the balance is too low, the run fails with insufficient_balance and is not retried.
  • After 3 failed runs in a row, the recurring payment is set to paused.
  • You receive recurring_payment.run_succeeded or recurring_payment.run_failed webhooks for every run, and recurring_payment.run_upcoming 24 hours before.

Pause a recurring payment

POST /recurring-payments/{id}/pause Stops future runs of an active recurring payment without deleting it. A run already in progress finishes normally.
string
required
Recurring payment ID, for example rp_5t8w2k.
string
Optional note stored with the pause, for example "Tenant away in December".
Response

Restart a recurring payment

POST /recurring-payments/{id}/restart Restarts a paused recurring payment. Runs missed while paused are skipped, not paid in arrears, and the next run follows the existing schedule. Skipped runs do not count toward after_occurrences.
string
required
Recurring payment ID.
string
Optional new first run date (YYYY-MM-DD). Defaults to the next date on the existing schedule.
Response
To change the amount or schedule before restarting, call PATCH /recurring-payments/{id} or PUT /recurring-payments/{id}/schedule while the payment is paused.

Delete a recurring payment

DELETE /recurring-payments/{id} Deletes a recurring payment. No further runs execute and it can no longer be restarted. Transactions from past runs are kept and stay available through the transactions endpoint below and GET /orders.
string
required
Recurring payment ID.
Response
Deleting cannot be undone. Pause instead if you may need the schedule again.

List transactions for a schedule

GET /recurring-payments/{id}/transactions Returns every transaction created by one recurring payment, newest first. Failed runs appear too, with status: "failed" and a failure_code.
string
required
Recurring payment ID.
string
Filter by transaction status: pending, processing, completed, failed, or refunded.
Matches transaction ID, reference, and tx_hash. Minimum 2 characters.
string
Only include runs on or after this date (YYYY-MM-DD or ISO 8601).
string
Only include runs on or before this date (YYYY-MM-DD or ISO 8601).
string
default:"desc"
desc for newest run first, asc for oldest first.
integer
default:"1"
Page number to return, starting at 1. See Pagination.
integer
default:"20"
Results per page, up to 100. limit is accepted as an alias.
Response
integer
Position of this run in the schedule, starting at 1.
string
When the run was scheduled to execute (UTC).
string | null
Error code for failed runs, for example insufficient_balance. null otherwise.
object
Totals across all runs of this schedule: completed and failed run counts, total paid, and total fees.
object
Page details: page, size, total, and total_pages. The summary totals always cover all runs, not just the current page.
Each item is a transaction like those in the order object. You can also list the orders a schedule created with GET /orders?recurring_payment=rp_5t8w2k.

Other endpoints

Errors

See Error Codes for the full list.