Web Rabbit MediaDocs
Reference

API changelog

Dated entries for every field and behaviour change on the public API.

Dated entries for every field and behaviour change on the public API. This is separate from product release notes — nothing appears here unless it can affect an integration. The matching contract is the OpenAPI document, whose info.version is the date stamp shown against each entry.

iWhat counts as a breaking change
Removing or renaming a field, narrowing an enum, changing a status code, or changing the meaning of an existing field. Those are announced here before they ship. Adding an optional request field, an extra response field, or a new webhook event type is not breaking — ignore what you do not recognise.

Entries

9 November 2026

Changed: disbursement fees are now 1.5% per successful transfer instead of a flat GHS 1, added on top so recipients receive the full amount. Withdrawal (payout) fees are now a flat 1.5% too — the GHS 5 minimum and GHS 100 maximum are removed. Each item's fee and the batch fee_total carry the computed amount; failed transfers are not charged. Your business may have a custom rate. Disbursements are sent through OGateway by default.

5 November 2026

Changed: card payments and POST /v1/bills are switched off (bills return 410; card sessions open with Mobile Money). Added: public status page with incident emails and an RSS feed.

17 October 2026

Fixed: GET /v1/checkout/session?id= returned not_found because the API edge did not route GET requests. It now returns the session and its transaction. GET /v1/checkout/session/{id} also works.

New: reference and metadata (up to 20 flat keys, 2 KB) on /v1/checkout/session and /v1/collect/momo. They are returned, together with checkout_session_id and description, in collection.approved, collection.failed, collection.reversed and GET /v1/transactions/{id}.

New: GET /v1/me returns an enabled object: country, currency, collection and payout methods, Mobile Money networks, phone format and limits.

New — multi-currency collection: Web Rabbit can enable extra collection countries per business. Send country/currency on /v1/checkout/session and /v1/collect/momo; networks and phone numbers are checked per country. Each currency has its own balance, payouts and payout accounts, with no conversion. Webhooks and transaction retrieve carry the real currency. A country that isn't enabled returns 422 currency_not_enabled instead of silently creating a GHS payment. Test mode caps are per currency (about GHS 10 each, e.g. NGN 1,500, KES 100); amount-driven test outcomes are scaled to that cap. GET /v1/me lists enabled.countries.

OGateway is now the default provider for payments and payouts for new and existing merchants, except businesses Web Rabbit has deliberately routed elsewhere. Payments already in progress finish on their original provider. No change to request or response shapes.

Messaging: SMS Marketing campaigns can be sent to your own contacts or the Web Rabbit network, and every campaign can be sent as a test to your own phone first.

9 October 2026

Live payments and payouts are now open to businesses registered in any of the 16 registration countries. Each business collects and is paid out in its own country's currency; outside Ghana this runs on OGateway. (Corrected 17 October: this does not let a business in one country collect in another country's currency.)

Security: API keys stop working when the teammate who created them is removed or loses edit rights; cancelling a messaging campaign through the API needs a write key in the campaign's mode; payment provider notifications are accepted only at our private callback address.

7 October 2026

OGateway is now generally available as a live rail in Ghana, alongside 360Pay. Live payments and payouts remain Ghana-only; other countries stay in test mode.

3 October 2026

OGateway: hosted checkout now offers Mobile Money in Kenya, Uganda, Tanzania, Zambia, Côte d'Ivoire, Cameroon, Gambia, Congo DRC, Benin, Burkina Faso, Mali, Senegal and Togo, and bank transfer in Nigeria (test mode outside Ghana). Failed payments now carry a plain-language reason.

25 September 2026
  • Added Invoices: line items, discounts, taxes, due dates, email sending and reminders, part payments, manual payment records, a hosted pay page with PDF download, and the invoice.paid and invoice.partially_paid webhook events.
  • Added merchant products with permanent shareable links, physical, digital and service types, private product media, delivery fees and customer delivery details.
  • Added limited or unlimited inventory, 15-minute checkout reservations, atomic settlement, low-stock signals, reasoned stock adjustments and full-refund restocking.
  • Added searchable order management, fulfilment states, CSV export, and the order.paid, order.failed, order.fulfilled and inventory.low webhook events.
24 September 2026
  • Added payout limits per business, by tier: a maximum per payout, per day and per month. Over-limit withdrawals are rejected with a clear error; the remaining headroom is shown in the dashboard. Bulk disbursements count toward the same daily and monthly totals.
  • Added a review flag on large payouts, a 24-hour pause on withdrawals after a payout account is added or changed, and a cap of 3 pending payouts at a time.
  • Changed payouts and disbursements are processed on working days only — Monday to Friday, excluding Ghana public holidays. Requests made on a weekend or holiday are scheduled for the next working day; payout records carry scheduled_for with the actual processing date.
  • No contract change. Request and response shapes are unchanged; the OpenAPI version stamp does not move.
19 September 2026openapi 2026.10.17
  • Added Bills & Airtime: POST /v1/bills buys airtime, data bundles and utility bill payments from your settled balance. One action-based endpoint covering catalog, bundles, lookup, purchase, status and list.
  • Added the bill.completed and bill.failed webhook events, and the BillPurchase schema to the OpenAPI document. There is no platform fee on bills, and a failed purchase is refunded to your balance in full.
17 September 2026
  • Added a payout fee of 1.5% on withdrawals, minimum GHS 5.00 and maximum GHS 100.00, deducted from the amount requested. Payout records now carry a non-zero fees, and net_amount is what reaches the destination.
  • Added balance_before and balance_after to payout records. Payouts created before today have neither.
14 September 2026
  • Changed the standard rate for Web Rabbit Processing to a 10% starting rate. Rates may vary depending on business model, transaction volume, risk profile and payment requirements. Businesses created from today start at 10%; existing accounts keep the rate already configured for them, and settled transactions are never recalculated.
  • No contract change. commission_bps already carried the per-business rate — read it from GET /v1/me instead of hard-coding a percentage. Example values in the docs and the OpenAPI document now show 1000.
14 September 2026
  • Corrected live-rail credentials and added environment detection. Live traffic now authenticates against the provider's live environment, and a key whose environment disagrees with its mode is reported as a mismatch on our rails health check instead of failing silently.
  • Confirmed that wr_test_ keys are answered end to end by the built-in simulator. No test-mode call reaches 360Pay or JuniPay, no prompt is sent to a handset and no wallet is debited. Docs that still described a provider sandbox have been corrected on the Authentication, Hosted Checkout and onboarding pages.
  • No contract change. Request and response shapes, status values and the OpenAPI version stamp are unchanged — nothing in an existing integration needs updating.
12 September 2026openapi 2026.09.12
  • Added split payments: sub-accounts (/v1/sub-accounts, ledger and /v1/splits/preview) and an optional split object on /v1/collect/momo and /v1/checkout/session. Legs settle to a recipient ledger on approval and are debited back on reversal.
  • Added the split.settled and split.reversed webhook events, plus split_status and splits on transaction responses.
  • Added exact integer minor units. Every money field now has an *_minor counterpart in pesewas, and amount_minor is accepted on every request that takes an amount. Sending amount and amount_minor with different values returns amount_conflict. See Amounts & currency.
  • Changed next_cursor on /v1/transactions to an opaque cursor over (created_at, id), so rows sharing a timestamp are never skipped or repeated. Legacy ISO-8601 cursors are still accepted; treat the new value as opaque.
  • Clarified that Webrabbit-Event-Id is the canonical, retry-stable event id and equals the body id; Webrabbit-Delivery-Id differs per endpoint and must not be used for idempotency.
  • Documented the reversal windows (7 days Mobile Money, 120 days card) and the full per-provider raw code mapping for 360Pay and JuniPay.
  • Documented that a workspace can hold unlimited approved sender IDs and select one per request.
10 September 2026openapi 2026.09.10
  • Added signed messaging delivery receipts: message.delivered, message.failed and message.rejected, one event per recipient, signed with the same HMAC-SHA256 scheme as payment events. Polling messaging/status is now a fallback, not a requirement.
  • Guaranteed a terminal event for every submitted message. If the upstream never reports, we close the message after 24 hours as undelivered with provider_status: "NO_DLR" and error_reason: "no_delivery_report" — messages no longer stay submitted indefinitely.
  • Added message to data.resource_type and the MessageReceipt payload schema to the OpenAPI document and the TypeScript SDK.
9 September 2026openapi 2026.09.09
  • Raised rate limits. Standard is now 120 req / 10 s with a 240 burst (was 60). New Scale (600 / 10 s, burst 1,200) and Enterprise (2,000 / 10 s) tiers, granted per key without a redeploy. Status and balance reads draw on a separate polling budget.
  • Added x-ratelimit-reset and x-ratelimit-tier alongside the existing limit/remaining headers, on Payments and Messaging alike.
  • Added canonical Messaging routes on the Payments host: POST /v1/messaging/sms, GET /v1/messaging/status/{campaign_id}, POST /v1/messaging/otp, POST /v1/messaging/otp/verify, GET /v1/messaging/balance. Same auth, error envelope and x-request-id as Payments. The legacy functions/v1/messaging-* URLs keep working with no cut-off date.
  • Relaxed Messaging payloads: business_id and mode are now optional on API-key calls and derived from the key. Sending a value that disagrees with the key returns 403 forbidden or 400 mode_mismatch.
  • Added Idempotency-Key support to SMS, OTP and voice, matching Payments.
  • Added OTP purpose (login, payment, pin_reset, custom), plus per-call code_length and template.
  • Enumerated OTP verification failures — invalid_code, otp_expired, too_many_attempts, not_found — each with retryable and, where meaningful, attempts_remaining. Verifying an already-verified code returns 200 with already_verified: true instead of an error.
  • Corrected stale wording that described signed webhooks as planned. HMAC-SHA256 signed webhooks have been live since 5 September 2026.
8 September 2026openapi 2026.09.08
  • Added the machine-readable contract at https://api.webrabbitmedia.com/openapi.json and /openapi.yaml, mirrored on webrabbitmedia.com. OpenAPI 3.1, covering Payments, Messaging and all webhook events.
  • Added the x-openapi-version response header on the spec endpoints, for pinning and CI diffs.
  • Documented nullability for every response field. No runtime behaviour changed: fee_amount is 0 and net_amount equals gross_amount on a pending charge; account_name is always present on a 2xx collection; provider_transaction_id, code and reason are nullable.
  • Published the exhaustive webhook event list — collection.approved, collection.failed, collection.reversed, payout.completed, payout.failed, sms_topup.approved — with an exact payload schema per type.
  • Added an official TypeScript SDK.
3 September 2026
  • Changed test mode to a fully simulated rail. wr_test_ keys no longer reach 360Pay or JuniPay and never move money.
  • Added disclosure fields to GET /v1/me: upstream, test_mode, test_moves_real_money, test_max_amount.
  • Added the x-wr-upstream and x-wr-test-mode response headers.
  • Added a hard GHS 10 per-transaction cap in simulated test mode; larger test amounts are rejected with 400.
  • Added deterministic test outcomes selected by amount (approve, decline, delayed approval, insufficient funds, reversal).
28 August 2026
  • Added optional attribution headers HTTP-Referer and X-Webrabbitmedia-Title so we can see which site an API key is used from.
  • Added the x-wr-attribution-warning response header when they are absent. Existing integrations are unaffected — undeclared traffic is still served and recorded as (undeclared).
  • Added 403 domain_blocked for live traffic from a site blocked after review.
  • Added the app object to GET /v1/me.
20 August 2026
  • Changed the acceptance policy to support ride-hailing, delivery, food and booking platforms under stated conditions, where the platform is merchant of record and pays its own drivers and vendors.
  • Clarified that payout holds and reversals apply to fraud, laundering, serious chargeback exposure or lawful orders — not to routine review.

Staying informed

Poll https://api.webrabbitmedia.com/openapi.json (or just its x-openapi-version header) in CI and fail the build when it moves. This page is also published as Markdown at https://webrabbitmedia.com/docs/changelog.md, so you can diff it directly.