# Changelog
Source: https://docs.monime.io/apis/changelog
Track our API evolution
Track our API evolution — from the first public launch to the latest versions.
[OpenAPI file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/caph/2025-08-23/openapi.yaml)
### 🚀 Added
* **Receipts management**:
Two resource operations were introduced for payment receipt management:
* `GET /v1/receipts/{orderNumber}` → Retrieve full receipt details.
* `POST /v1/receipts/{orderNumber}/redeem` → Redeem entitlements (full or partial).
* **USD support for Checkout Sessions**:
Checkout Sessions now accept collections in **USD**, expanding beyond local currency support.
### 💡 Common Use Cases
* **Verify a purchase** – Retrieve a receipt by order number to confirm items, status, and timestamp.
* **Redeem event tickets or vouchers** – Mark entitlements as redeemed at point of entry.
* **Partial redemption** – Consume part of a multi-item receipt (e.g., ride credits, vouchers).
* **Full redemption** – Mark a receipt as fully consumed to prevent reuse.
* **Checkout in USD** – Allow merchants to receive funds in U.S. dollars.
### ❌ Breaking Changes
* ✅ None. Fully backward-compatible with `caph.2025-06-20`.
***
### Upgrade Guide — caph.2025-06-20 → caph.2025-08-23
* No migration required.
* All existing integrations remain valid.
***
This release extends the **caph** line into post-payment fulfillment (Receipts) and broadens
checkout session supports with USD collections.
### 🔄 Major Expansion — First `caph` Version
This version officially launched the **`caph` release line**, introducing versioned endpoints (`/v1/...`) and
establishing the foundation for stable, long-term growth.
[OpenAPI
file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/caph/2025-06-20/openapi.yaml)
### 🚀 Added
* `POST /v1/payments` → Unified payment initiation.
* `GET /v1/financial-accounts`, `/v1/financial-transactions` → Accounts and ledger-style transaction history.
* `POST /v1/checkout-sessions` → Hosted checkout for e-commerce & embedded flows.
* `POST /v1/internal-transfers` → Secure transfers between accounts.
* `POST /v1/ussd-otps` → OTP generation & validation.
* `GET /v1/provider-kyc/{providerId}` → Standardized provider KYC.
### 🏗️ New Resources
* `Payment`, `CheckoutSession`, `FinancialAccount`, `FinancialTransaction`,
`InternalTransfer`, `UssdOtp`, `ProviderKYC`.
### ❌ Breaking Changes (from 2024-08-01)
* All endpoints moved under `/v1/...` namespace.
* Enumerated values for fields changed from camelCase to snake\_case.
* Schema migration: The schema of all previous resources has been updated, fields renamed, dropped, or added.
* Legacy unversioned endpoints (`/banks`, `/momos`, `/countries`, `/payment-codes`, `/payouts`, `/webhooks`) are no
longer supported.
***
### Upgrade Guide — 2024-08-01 → caph.2025-06-20
If you’re upgrading from the **2024-08-01** version, follow these steps:
1. Switch to `/v1/...` endpoints.
2. Replace the schema of all old resources with the new ones.
3. Re-register webhooks under `/v1/webhooks`.
4. Validate new flows (payments, checkout, accounts).
✅ After this migration, you are on the **caph release track**, ensuring compatibility with all future updates.
### 🎉 Public API Launch
This release marked the **public debut of our API**, giving developers their first programmable entry point
into the platform.
[OpenAPI file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/2024-08-01-openapi.yaml)
### Operations
* `/banks`, `/momos`, `/countries` → Provider and country lookups.
* `/payment-codes` → Generate short-lived collection codes.
* `/payouts` → Disburse funds externally.
* `/kyc-verifications/{providerCode}` → Provider-level KYC checks.
* `/webhooks` → Subscribe to basic events.
### 🏗️ Base Schemas
* `Bank`, `Country`, `Momo`, `PaymentCode`, `Payout`, `Webhook`, `KYCVerification`.
***
# Introduction
Source: https://docs.monime.io/apis/index
Welcome to Monime’s API Reference — your gateway to integrating payments, payouts, embedded finance, and more through
simple, scalable, and intuitive APIs.
***
## Base URLs
The Live and Test APIs operate in two fully separate environments:
* **Live:** `https://api.monime.io` with (Live token)
* **Test:** `https://api.monime.io` with (Test token)
Read [Personal Access Tokens](/dashboard-guide/personal-access-tokens) on how to create Live and Test tokens.
***
## Standards & Conventions
### RESTful Design
The API follows standard HTTP methods:
* `GET` — fetch a single object or list of objects
* `POST` — create a new object or trigger an action
* `PATCH` — make partial updates to an object (send only what you want to change)
* `DELETE` — remove an object
### JSON by Default
Unless stated otherwise, requests and responses use **JSON**.
* Fields are returned with stable, predictable keys
* Moneys are given in **minor currency units** (e.g., cents for SLE and USD)
* Timestamps are in **UTC** using **RFC 3339** format, e.g. `2025-08-24T06:00:00Z`
### Usable Status Codes
The API uses standard HTTP status codes:
* `200` — success, i.e., server handled the request.
* `4xx` — client errors such as invalid input, or authentication issues.
* `5xx` — internal server errors, safe to retry with backoff
# Get Checkout Session
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/checkout-session/get-checkout-session
get /v1/checkout-sessions/{id}
Retrieves the full details of a checkout session by ID.
# List Checkout Sessions
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/checkout-session/list-checkout-sessions
get /v1/checkout-sessions
Retrieves list of checkout sessions.
# Checkout Session
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/checkout-session/object
A **Checkout Session** represents a Monime-hosted payment flow where customers complete purchases for a defined set of items.\
It is designed for **e-commerce** and **embedded payment scenarios** where merchants want a simple, secure way to accept payments across multiple channels without building the payment UI themselves.
Unlike direct API-based payments, a Checkout Session aggregates **multiple payment methods** — such as **Mobile Money**, **Card**, and **Bank Transfers** — and presents them in a unified checkout experience.
***
### Use Cases
* **E-Commerce Cart Checkout**\
A customer selects items in a cart. The merchant creates a Hosted Checkout Session, and Monime presents Mobile Money, Card, and Bank options in one unified flow.
* **Embedded SaaS Billing**\
A SaaS platform embeds a Hosted Checkout Session to bill users. Customers pick their preferred channel (Card, MoMo, Bank), and once payment is confirmed, the SaaS receives `checkout_session.completed`.
* **QR or Link-Based Payment**\
Merchants generate a checkout session link or QR code. Customers open the hosted page and choose any available payment method.
* **Fallback Across Methods**\
If a user’s card payment fails, they can seamlessly retry with Mobile Money — all within the same checkout session.
```json JSON Model theme={null}
{
"id": null,
"status": "pending",
"name": null,
"orderNumber": null,
"reference": null,
"description": null,
"redirectUrl": null,
"cancelUrl": null,
"successUrl": null,
"lineItems": {
"data": []
},
"financialAccountId": null,
"brandingOptions": {
"primaryColor": null
},
"expireTime": null,
"createTime": null,
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"metadata": null
}
```
Unique identifier of the checkout session.
**Status** of the checkout session. Possible values:
* pending: Awaiting initiation.
* completed: Checkout completed successfully.
* cancelled: User cancelled the session.
* expired: Session expired due to inactivity.
Available options: pending cancelled expired completed
Title or label for the checkout session. Used for display in customer-facing UIs.
Internally generated order number that uniquely identifies the payment associated to this checkout session.
Optional external reference identifier (e.g., order ID) used to link this session with the developer’s backend system.
Optional long-form description explaining the purpose or context of the checkout session.
The URL where the customer should be redirected to begin the checkout session. This is typically a hosted checkout page managed by Monime.
The URL to redirect the customer to if they cancel the checkout process before completing payment. This typically returns the user to your site or app with context about the cancellation.
The URL to redirect the customer to after successfully completing the checkout. Typically used to confirm the order or show a success message on your site or app.
Container for the list of items included in the checkout session. Each item represents a product or service being purchased, along with its quantity and pricing.
Array of individual line items representing products or services included in the checkout session. Each item specifies details like name, quantity, and unit price.
Financial account where the collected funds were settled. Defaults to the main account if omitted.
Visual customization options for the checkout UI, such as color schemes or logos.
Primary brand color in hex format (e.g., '#00FF00') used to customize the appearance of the checkout interface.
MaxLength: 255
The timestamp at which the checkout session will automatically expire.
Timestamp indicating when the checkout session was created.
**Ownership graph** that traces the origin of this checkout session, enabling deep auditability and understanding of its creation context.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Structured key-value metadata for tagging the session with contextual or custom information.
# Create Financial Account
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-account/create-financial-account
post /v1/financial-accounts
Creates a new financial account for holding or managing funds within a Space.
# Get Financial Account
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-account/get-financial-account
get /v1/financial-accounts/{id}
Retrieves details of a financial account by its ID.
# List Financial Accounts
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-account/list-financial-accounts
get /v1/financial-accounts
Retrieves list of financial accounts.
# Financial Account
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-account/object
A **Financial Account** is a logical wallet or ledger unit that holds and tracks money for a user or entity.\
It represents a balance in a specific currency and serves as the foundation for all money movement within Monime.
Each account is uniquely identifiable, has a human-friendly display name (e.g., **“Main Wallet”**), and is always tied to a single currency such as **SLE** or **USD**.
In APIs, Financial Accounts act as the **source** or **destination** of funds for transfers, payouts, or collections.
***
### Use Cases
* **Embedded Finance**\
With **Embedded Finance on Monime**, fintechs can create **dynamic wallet accounts** hosted directly on Monime’s infrastructure.\
Incoming collections from **cards, Mobile Money, or banks** are deposited into these accounts, which can then be used for **spend, cash-out, or peer-to-peer (P2P) transfers** by moving funds between accounts.
*Example* : Payments received through **Checkout Sessions** are credited to a user’s wallet account and can later be transferred to another user’s wallet, enabling seamless P2P experiences.
* **Settlement Account**\
Businesses separate collected funds from the account used to settle merchants or subsidiaries.\
*Example*: A PSP routes daily Mobile Money collections into a **Settlement Account** before initiating payouts.
* **Disbursement Float**\
A pre-funded account maintained to ensure outgoing transfers and payouts can always be covered.\
*Example*: Your platform maintains a **Disbursement Float** account; when it runs low, you top it up via an Internal Transfer.
* **Dedicated Currency Account**\
Multi-currency platforms maintain one account per supported currency.\
*Example*: A customer has both a **USD Account** and an **SLE Account**, ensuring currency isolation and easier reconciliation.
***
```json JSON Model theme={null}
{
"id": null,
"uvan": null,
"name": null,
"currency": null,
"reference": null,
"description": null,
"balance": {
"available": {
"currency": null,
"value": null
}
},
"createTime": null,
"updateTime": null,
"metadata": null
}
```
Unique identifier of the financial account.
**UVAN** (Universal Virtual Account Number) — a unique, checksum alias used for secure, error-resistant inbound transfers across Monime and external providers.
Human-readable label for the financial account, such as 'Main Wallet' or 'Operations Reserve'.
ISO 4217 currency code (e.g., 'SLE', 'USD') indicating the account's currency.
Optional external reference ID for this account (e.g., the account's identifier in your internal system). Must be unique across accounts. Useful for reconciliation, tracking, or cross-system mapping.
Optional description of the account's purpose or usage context.
Current available balance of the financial account.
The amount of funds currently available for use or withdrawal.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Timestamp when the financial account was created.
Timestamp when the financial account was last modified.
Updated metadata for storing additional context about the account.
# Update Financial Account
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-account/update-financial-account
patch /v1/financial-accounts/{id}
Partially updates a financial account. Fields not included in the request body remain unchanged.
# Get Financial Transaction
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-transaction/get-financial-transaction
get /v1/financial-transactions/{id}
Retrieves the details of a financial transaction, including its type, amount, source account, and ownership trace.
# List Financial Transactions
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-transaction/list-financial-transactions
get /v1/financial-transactions
Retrieves a list of financial transactions.
# Financial Transaction
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/financial-transaction/object
A **Financial Transaction** represents a movement of funds that affects a Financial Account, either as a **credit** (inflow) or a **debit** (outflow).\
Every transaction adjusts the balance of an account and provides a full audit trail of how money moves within Monime.
***
### Use Cases
* **Customer Payment Recording**\
A user pays SLE 500 into your platform via Mobile Money.\
*Result*: A **credit transaction** is posted to a financial account of the space; this transaction is linked to a **Payment** created from the originating **Payment Code**.
* **Fee Deduction**\
A SLE 50 fee is charged for a payout of SLE 1,000.\
*Result*:
* A **debit transaction** of SLE 1,000 from the payout account.
* A **debit transaction** of SLE 50 from the payout account.
* **Internal Transfer**\
Moving SLE 10,000 from a Settlement Account to a Disbursement Float.\
*Result*:
* A **debit transaction** on the Settlement Account.
* A **credit transaction** on the Disbursement Float Account.
* **Refund or Reversal**\
If a payment is refunded, a corresponding **debit transaction** reduces the merchant’s balance.\
*Result*: The audit trail shows both the original credit and the refund debit, linked together.
***
```json JSON Model theme={null}
{
"id": null,
"type": "credit",
"amount": {
"currency": null,
"value": null
},
"timestamp": null,
"reference": null,
"financialAccount": {
"id": null,
"balance": {
"after": {
"currency": null,
"value": null
}
}
},
"originatingReversal": {
"originTxnId": null,
"originTxnRef": null
},
"originatingFee": {
"code": null
},
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"metadata": null
}
```
Unique identifier for this financial transaction.
Indicates whether the transaction is a 'credit' or 'debit'.
Available options: credit debit
The monetary value involved in this transaction.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
The exact time when this transaction was recorded.
Internal identifier associated with this transaction for reconciliation purposes.
The account that was debited or credited as part of this transaction, including post-transaction balance snapshot.
**Account ID**: Unique identifier of the financial account affected by this transaction.
**Account balance**: Balance snapshot of the account immediately after the transaction, if available.
**Post-transaction balance**: The available balance of the account immediately after this transaction completed.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Indicates that this transaction was created as the result of a reversal action. The transaction itself represents the reversal of fund.
The ID of the transaction that was reversed by this transaction
The reference of the transaction that was reversed by this transaction
Indicates that this transaction was created as the result of an internal platform fee. The transaction itself represents the fee.
The type of charge applied.
Traceability structure showing which resource or object owns or initiated this transaction.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Custom structured key-value pairs associated with this transaction for additional context.
# Create Internal Transfer
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/create-internal-transfer
post /v1/internal-transfers
Initiates a transfer of funds between two financial accounts within the same ecosystem.
# Delete Internal Transfer
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/delete-internal-transfer
delete /v1/internal-transfers/{id}
Deletes a specific transfer object by its ID. Only applicable for transfers in a deletable state (e.g., pending).
# Get Internal Transfer
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/get-internal-transfer
get /v1/internal-transfers/{id}
Retrieves detailed information about a specific transfer by its ID.
# List Internal Transfers
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/list-internal-transfers
get /v1/internal-transfers
Retrieves a list of internal fund transfers between financial accounts within the Monime ecosystem.
# Internal Transfer
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/object
An **Internal Transfer** is the movement of funds between financial accounts that exist within the same Space.\
Unlike payouts or customer payments that cross external networks (banks, card schemes, or mobile money), an Internal Transfer happens entirely within Monime’s ledger.
It is the mechanism for shifting balances between accounts you own or manage, and it never leaves your organization’s financial boundary.
***
### Use Cases
* **Wallet Top-ups**\
A customer wallet account can be funded by moving money from your master operational account.\
*Example*: A user adds **SLE 1,000** to their app wallet. Your backend issues an Internal Transfer from your **Operational Float** to the user’s **Wallet Account**.
* **Inter-Account Routing**\
Businesses often separate funds for accounting clarity (e.g., “Card Collections,” “Mobile Money Collections,” “Bank Transfers”).\
*Example*: At the end of each day, you route all **Mobile Money collections** into a central **Settlement Account**.
* **Internal Settlements**\
Useful when multiple departments or sub-entities operate under one Space.\
*Example*: Subsidiary A owes Subsidiary B **SLE 50,000**. Instead of moving money through the banking system, you perform an Internal Transfer inside your Monime ledger.
* **Float Management**\
Fintechs maintain float across accounts to support disbursements.\
*Example*: If your **Disbursement Account** is running low, you move funds from your **Collection Account** to top it up before processing payouts.
***
```json JSON Model theme={null}
{
"id": null,
"status": "pending",
"amount": {
"currency": null,
"value": null
},
"sourceFinancialAccount": {
"id": null
},
"destinationFinancialAccount": {
"id": null
},
"financialTransactionReference": null,
"description": null,
"failureDetail": {
"code": "unknown",
"message": null
},
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"createTime": null,
"updateTime": null,
"metadata": null
}
```
Unique identifier for this transfer object.
Current status of the transfer:
* 'pending': Created but not yet processed.
* 'processing': Currently being processed.
* 'failed': Transfer failed.
* 'completed': Transfer successfully completed.
Available options: pending processing failed completed
Amount to be transferred from the source to the destination account.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Source financial account from which the funds will be debited.
Unique identifier for the financial account
Destination financial account to which the funds will be credited.
Unique identifier for the financial account
Reference to the resulting financial transaction(s), if the transfer was completed.
Human-readable description of the transfer. Useful for developer context, admin UIs, or logs.
Failure details, populated only when the transfer status is 'failed'.
**Error code** representing the reason this transfer failed. Possible values include:
* **unknown**: Generic or unclassified failure.
* **fund\_insufficient**: Not enough funds in the source account.
Available options: unknown fund\_insufficient
**Optional explanation** providing more context about the failure. Useful for developer logs or end-user display.
Ownership chain that shows which object or action triggered the transfer — enabling audit traceability.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Timestamp indicating when the transfer was created.
Timestamp of the most recent update to the transfer.
Custom metadata for tagging this transfer with additional context or identifiers.
# Update Internal Transfer
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/internal-transfer/update-internal-transfer
patch /v1/internal-transfers/{id}
Updates mutable fields (like description or metadata) of an existing transfer object.
# Create Payment Code
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/create-payment-code
post /v1/payment-codes
Creates a new payment code with the specified parameters for value collection and provider restrictions.
# Delete Payment Code
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/delete-payment-code
delete /v1/payment-codes/{id}
Deletes a payment code by ID. This operation is only allowed if the code hasn't been used.
# Get Payment Code
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/get-payment-code
get /v1/payment-codes/{id}
Retrieve a payment code object by its ID.
# List Payment Codes
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/list-payment-codes
get /v1/payment-codes
Retrieves a list of payment codes with support for filtering by mode, USSD code, and status.
# Payment Code
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/object
A **Payment Code** is a programmable, short-lived token that allows users to collect payments from others.\
It is especially useful in **USSD-like** or **QR-based** flows, where the payer enters or scans a code to complete a transaction.
Payment Codes provide flexibility for both **one-time** and **recurrent** collections, with configurable restrictions and targets.
***
### Use Cases
* **USSD Payment Collection**\
A merchant generates a Payment Code and displays it in USSD. Customers enter the code to make payments.\
*Example*: A vendor creates a one-time code for **SLE 50** which a customer redeems via their mobile money wallet.
* **QR Code at Point of Sale**\
The Payment Code is encoded as a QR displayed at checkout. Customers scan the QR to pay.\
*Example*: A shop generates a QR-based Payment Code for **SLE 200**, which is redeemed on the spot.
* **Recurring Subscription Collection**\
A fitness center issues a recurrent Payment Code for monthly fees.\
*Example*: The code accepts up to **12 payments** of **SLE 500** each, after which it auto-completes.
* **Targeted Collection**\
Restrict a Payment Code to a specific MSISDN or provider.\
*Example*: Only customers on **Orange Money** with a registered number can redeem the code.
***
```json JSON Model theme={null}
{
"id": null,
"mode": "one_time",
"status": "pending",
"name": "Home EDSA Meter Top-up",
"amount": {
"currency": null,
"value": null
},
"enable": null,
"expireTime": null,
"customer": {
"name": "Musa Kamara"
},
"ussdCode": null,
"reference": null,
"authorizedProviders": [
[
"m17",
"m18"
]
],
"authorizedPhoneNumber": null,
"recurrentPaymentTarget": {
"expectedPaymentCount": null,
"expectedPaymentTotal": {
"currency": null,
"value": null
}
},
"financialAccountId": null,
"processedPaymentData": {
"amount": {
"currency": null,
"value": null
},
"orderId": null,
"paymentId": null,
"orderNumber": null,
"channelData": {
"providerId": null,
"accountId": null,
"reference": null
},
"financialTransactionReference": null,
"metadata": null
},
"createTime": null,
"updateTime": null,
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"metadata": null
}
```
Unique identifier of the payment code object.
Usage mode of the payment code:
* 'one\_time': Can be used only once
* 'recurrent': Can be used multiple times until a target is met or it expires.
Available options: one\_time recurrent
Lifecycle status of the payment code: 'pending' (created but not in use), 'processing' (currently in use), 'expired' (duration elapsed), 'completed' (usage or target fulfilled), or 'cancelled' (manually invalidated).
Available options: pending cancelled processing expired completed
Optional human-readable name for the payment code, useful for labeling or tracking.
Example: Home EDSA Meter Top-up
Amount charged per use of the payment code. For 'recurrent' mode, this applies to each payment instance.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Indicates whether the payment code is currently enabled for use.
The time at which the payment code expires, provided the code is still pending.
Optional customer information linked to this payment code. Often used for USSD or receipt context.
Optional name of the customer associated with the payment code. Displayed in the USSD prompt for contextual reference.
MaxLength: 100
Example: Musa Kamara
The USSD dial string customer(s) can use to initiate a payment for this code.
Reference string associated with the payment code. Useful for transaction tagging or reconciliation.
List of mobile money providers permitted to process payments using this code.
Example: \[m17 m18]
MSISDN of the mobile money account exclusively allowed to use this code. Other users will be rejected.
Target payment count or amount that determines when a recurrent payment code is considered complete.
Minimum expected number of payments after which the recurrent payment code may be considered complete. Optional.
Minimum total amount to be collected before the recurrent payment code is considered complete. Optional.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
ID of the financial account where collected funds will be settled. Defaults to the main account if not provided.
The data of the payment that was processed for this payment code. This field is available only during the 'payment\_code.processed' webhook event.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Metadata is a flexible map of string key-value pairs for tagging or attaching additional information. A maximum of 64 pairs is allowed per object.
Timestamp indicating when the payment code was created.
Timestamp indicating when the payment code was last updated.
Full ownership graph tracing the origin of this payment code objects across multiple objects.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Custom metadata attached to the payment code for storing business-specific context or tags.
# Update Payment Code
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment-code/update-payment-code
patch /v1/payment-codes/{id}
Partially updates an existing payment code with new values, rules, or account bindings.
# Get Payment
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment/get-payment
get /v1/payments/{id}
Retrieve the full details of a specific payment using its ID.
# List Payments
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment/list-payments
get /v1/payments
Lists payments with optional filters like status or creation date.
# Payment
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment/object
A **Payment** represents a customer payment made through Monime’s platform.\
It captures high-level information about the user-initiated payment, including the **amount**, **status**, **channel** (e.g., **Mobile Money**, **Card**, **Bank**), associated **order**, **fees applied**, and links to **downstream financial transactions**.
The **Payment** is a business object — the single record developers and merchants interact with when tracking or reconciling user payments.\
It should not be confused with **Financial Transactions**, which are lower-level, fine-grained ledger entries.\
In fact, **one Payment usually generates multiple Financial Transactions** — for example:
* A **credit** of the received funds into the merchant’s account.
* One or more **debits** representing platform charges or processing fees.
```json JSON Model theme={null}
{
"id": null,
"status": "pending",
"amount": {
"currency": null,
"value": null
},
"channel": {
"type": "bank"
},
"name": null,
"reference": null,
"orderNumber": null,
"financialAccountId": null,
"financialTransactionReference": null,
"fees": [],
"createTime": null,
"updateTime": null,
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"metadata": null
}
```
Unique identifier for the payment object.
Current status of the payment. Can be one of:
* pending: Created but not yet processed.
* processing: Payment is currently being processed.
* completed: Payment was successfully completed.
Available options: pending processing completed
Total payment amount requested from the payer.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
Payment channel details (e.g., Mobile Money, Bank, Card) used to complete this payment.
**Type** of payment channel used to process the payment. Supported values:
* bank: Bank account payments
* card: Debit or credit card payments
* momo: Mobile money payments
* wallet: Digital wallet payments.
Available options: bank card momo wallet
Optional label for identifying or grouping the payment. Useful in dashboards or reporting tools.
External reference to associate this payment with a system outside Monime (e.g., an order ID or invoice number).
Monime Order Number — internal order identifier associated with this payment. Used to track payments initiated from an embedded commerce or checkout session.
ID of the destination financial account where the funds will be credited after a successful payment.
Reference to the resulting financial transaction(s), if the payment was successful.
List of applied fees associated with this payment, such as platform or processing fees.
Timestamp indicating when the payment was created.
Timestamp indicating when the payment was last updated.
Ownership chain showing how this payment was initiated — enabling full audit traceability.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Custom metadata attached to the payment
# Patch Payment
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payment/patch-payment
patch /v1/payments/{id}
Updates mutable fields of a payment object like name, description, or metadata.
# Create Webhook
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/create-webhook
post /v1/webhooks
Create a new webhook with configuration for target URL, events, headers, and security.
# Delete Webhook
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/delete-webhook
delete /v1/webhooks/{id}
Delete a webhook by its ID. This action is irreversible.
# Get Webhook
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/get-webhook
get /v1/webhooks/{id}
Retrieve details of a specific webhook by its ID.
# List Webhooks
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/list-webhooks
get /v1/webhooks
Retrieves list of webhooks.
# Webhook
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/object
A **Webhook** is a user-defined HTTP endpoint that Monime invokes with a **POST request** whenever specific events occur, such as **`payment.completed`** or **`payout.failed`**.\
Webhooks allow you to receive real-time notifications and integrate Monime’s event stream directly into your own systems.
### Use Cases
* **Realtime Payment Updates**\
Receive an immediate notification when a payment succeeds and update your user’s dashboard without polling the API.
* **Automated Payout Reconciliation**\
Trigger accounting workflows or ERP system updates when a payout is marked as `completed` or `failed`.
* **Fraud & Risk Monitoring**\
Stream payment events into your fraud detection system as they happen.
***
```json JSON Model theme={null}
{
"id": null,
"name": "My Ecommerce Webhook",
"url": null,
"enabled": null,
"events": [],
"apiRelease": "caph",
"verificationMethod": {
"type": "ES256"
},
"headers": null,
"alertEmails": [],
"createTime": null,
"updateTime": null,
"metadata": null
}
```
Unique identifier of the webhook object.
Human-readable name for the webhook configuration. Useful for identifying its purpose in dashboards or logs.
Example: My Ecommerce Webhook
Publicly accessible URL that will receive event POST requests from this webhook.
Indicates whether the webhook is currently enabled. If false, events will not be sent.
List of event types (e.g., 'payment.created') that will trigger this webhook.
The release identifier of the API expected by this webhook. Ensures the webhook receives the latest object schema for a given release cycle.
Available options: caph siriusb
Method used to verify the integrity of incoming webhook requests.
The type of verification method in use. Either 'HS256' for HMAC or 'ES256' for ECDSA.
Available options: ES256 HS256
Optional HTTP headers to include in webhook requests. Useful for passing authentication or context info.
Email addresses to notify when delivery to this webhook repeatedly fails.
Timestamp when the webhook was created.
Timestamp when the webhook was last updated.
Custom metadata for storing additional context or labels for this webhook.
# Update Webhook
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/webhook/update-webhook
patch /v1/webhooks/{id}
Partially update an existing webhook's configuration and behavior.
# Creating a Monime Space
Source: https://docs.monime.io/dashboard-guide/create-a-business-account
Step-by-step guide to setting up your business account (Monime Space)
A **Monime Space** is your dedicated business account on the Monime platform. It allows you to accept payments, manage transactions, and oversee your business's financial operations.
**Prerequisite**: You must have a verified [Monimeer
account](/dashboard-guide/create-an-account) before creating a Space.
## Creating Your Space
### Method 1: From Your Dashboard
Log in to your Monimeer Dashboard at [my.monime.io](https://my.monime.io)
Locate the "Create a space" section and click the **New Space** button
### Method 2: Direct Navigation
You can also navigate directly to the Space creation interface by visiting: [my.monime.io/space-board](https://my.monime.io/space-board)
## Space Configuration
Fill out the "Create Space" dialog with your business information:
**Purpose**: The full, formal name of your business or venture
**Requirements**:
* Maximum 32 characters
* Will be used for official identification within Monime
* Can be changed later if needed
**Example**: "Kamara Enterprise", "Potter's Food Joint"
**Purpose**: A unique, short identifier for your payment URL **Requirements**:
* Maximum 15 characters - Must be unique across the platform - Forms your
payment link: `https://[your-alias].monime.space` **Example**: If you enter
'kamara', your payment link becomes `https://kamara.monime.space/payments`
Choose carefully! While you can change this later, it will affect your
existing payment links.
**Purpose**: Helps Monime categorize your business for relevant features and
support Select from the dropdown menu: - Retail - Food & Beverage - Services -
Technology - Healthcare - Education - And more...
**Purpose**: Indicates whether your business is formally registered
**Check this box if**:
* Your business is registered with Corporate Affairs Commission
* You have official business registration documents
* You operate as a formal entity
**Leave unchecked if**:
* Informal venture or sole proprietorship
* Not formally registered with authorities
Ensure all information is accurate as it will be used for your business
identification and compliance purposes.
Click the **Create** button when all fields are completed.
## Space Creation Process
After clicking **Create**, you'll see a loading screen indicating that Monime is setting up your Space.
Please remain on the page while your Space is being created. This process
typically takes only a few moments.
## Setting Your Space PIN
Once your Space is created, you'll be prompted to create a **4-digit PIN** for security.
Enter a new 4-digit PIN that you'll remember. This PIN will be used to authorize
sensitive actions within your Space.
Re-enter the same 4-digit PIN to confirm it and ensure there are no typos.
Choose a PIN that is strong but easy for you to recall, and keep it
confidential. You'll need this PIN for sensitive operations in your Space.
## Accessing Your Space Dashboard
After setting your PIN, you'll be automatically redirected to your new Monime Space dashboard. The URL will incorporate your chosen alias:
`https://[your-alias].monime.space`
**Example**: If you chose 'kamara' as your alias, your Space dashboard URL would be `https://kamara.monime.space`
## Space Dashboard Features
From your Space dashboard, you can:
Set up payment methods and start accepting payments
View and manage all your business transactions
Configure your Space settings and preferences
## Next Steps
Your Monime Space is now ready! You can start accepting payments immediately or
integrate with your applications using our APIs.
Create access tokens for API integration
Explore our comprehensive API reference
Tools, documentation, and references to support your development work.
Learn about your Space dashboard features
# Setting Up Your Monimeer Account
Source: https://docs.monime.io/dashboard-guide/create-an-account
Complete guide to creating your personal Monime account (Monimeer)
Welcome to Monime! This comprehensive guide will walk you through creating your personal Monime account, called a **Monimeer account**. As a Monimeer, you'll gain access to your personal dashboard and the ability to create and manage **Monime Spaces** for your business operations.
**What You'll Need**: An active Sierra Leonean phone number or valid email
address **Estimated Time**: 3-5 minutes
## Account Creation Process
### Step 1: Choose Your Registration Method
Navigate to [auth.monime.io](https://auth.monime.io) to begin the registration process.
You'll be presented with two registration options:
**For Sierra Leone Residents**
Type your active Sierra Leonean mobile phone number in the format:
`+232XXXXXXXX`
This method is highly recommended for users within Sierra Leone as it integrates seamlessly with local mobile services service providers.
**For International Users**
Enter your complete and valid email address (e.g., `yourname@example.com`)
This method is highly recommended for International users
### Step 2: Verify Your Account with OTP
Once you've entered your contact information, Monime will send a verification code.
A 6-digit OTP will be sent via SMS to your Sierra Leonean mobile number.
A 6-digit OTP will be sent to your email inbox.
Check your spam/junk folder if you don't receive the email OTP within 60
seconds.
**Enter the OTP** in the verification field. If you don't receive the code within 60 seconds, click the "Resend OTP" button.
### Step 3: Complete Your Profile
After successful verification, you'll need to provide some basic personal information.
Enter your complete legal first and last names as they appear on your official
identification documents.
This should match your National ID, Passport, or Driver's License for future
KYC processes.
Choose from the available options: Male, Female, or Prefer not to say.
Input your date of birth in DD/MM/YYYY format (e.g., `01/01/1990` for January 1st,
1990\).
## Your Monimeer Dashboard
Congratulations! After completing the registration, you'll be automatically redirected to your personal Monimeer Dashboard at [my.monime.io](https://my.monime.io).
### Dashboard Features
Your dashboard serves as the central hub where you can:
Manage your personal profile details and account settings
View and manage all your business Spaces
Manage logged-in devices and security settings
Access API tokens and developer resources
### OTP Delivery Settings
You can configure how you receive OTP codes for future logins and sensitive operations through your dashboard settings.
# Overview
Source: https://docs.monime.io/dashboard-guide/index
Overview of the Monime Dashboard guide
Welcome to the Monimeer Dashboard guides. These guides help you set up your personal Monimeer account, create a business Space, and manage developer access so you can accept payments, make payouts, and run your operations with confidence.
## Who these guides are for
* Developers integrating Monime with their apps
* Business owners and operators managing payments and payouts
* Team members who need access to Spaces and developer tools
## Quick start
Sign up and verify your personal account to access the dashboard
Set up your business Space to start accepting payments
Create secure API tokens for integrations
## What you'll learn
* Create and verify a Monimeer account
* Create and configure a Monime Space for your business
* Navigate the dashboard and key features (Profile, Spaces, Developer)
* Generate and manage personal Access Tokens for API usage
* Follow security best practices for production and test environments
## Recommended path
Start here to set up and verify your personal account. See
Create an account.
Set up your Space (business account) to enable payment features. See
Create a Monime Space.
Create API tokens to integrate your systems and automate operations. See
Personal Access Tokens.
## Key areas of the dashboard
Manage your personal details, login methods, and security preferences
Create and manage business Spaces, team access, and operational settings
Generate Access Tokens, view Space IDs, and access integration resources
Review active sessions and devices; update security controls
Configure alerts and communication preferences (where available)
Find help resources and contact support when you need it
## Prerequisites
You'll need:
* A valid email address or Sierra Leonean phone number for verification
* Internet access and a modern browser
* Basic business details (business name and alias) when creating a Space
## Test vs Live environments
Use Test mode for development and Live mode for real transactions. You can learn more about environments and headers in
API Basics → Environments and
Standard Headers.
## FAQ
A Monimeer is your personal account that owns and manages one or more business
Spaces. A Space is a business account where payments, payouts, and analytics live.
You can create tokens from your personal dashboard. For production, we recommend
scoping tokens to specific Spaces using whitelist options where applicable.
Yes. When creating tokens you can toggle Test Mode. In Test Mode, transactions are
simulated and some options are restricted. In Live Mode, full configuration is available.
# Personal Access Tokens
Source: https://docs.monime.io/dashboard-guide/personal-access-tokens
Generate and manage secure access tokens for Monime API integration
## Overview
To programmatically interact with your Monime Spaces, you need **Access Tokens** (API Keys). These tokens authenticate your applications and grant permission to perform actions across all Monime Spaces associated with your Monimeer account.
**Security Critical**: Treat your Access Tokens like passwords. Never share
them publicly, commit them to code repositories, or expose them on the
client-side of applications.
## Accessing the Developer Portal
Navigate to [my.monime.io](https://my.monime.io) and log in with your Monimeer
credentials
From the left sidebar navigation, click on **Developer** You'll see a list of
all your Monime Spaces with their unique **Space IDs** (e.g., `spc_xxxxxxxxx`)
In the Developer Portal sidebar, click on **Access Tokens** This page shows
all your existing tokens, their status (ACTIVE, EXPIRED), and creation dates
## Creating a New Access Token
Click the **Create token** button at the top right of the Access Tokens page A
full-screen configuration dialog will appear
Fill out the token configuration form with the following details:
### Token Configuration Options
**Purpose**: A descriptive label to identify this token's purpose
**Examples**:
* "Main Website Integration"
* "Mobile App v2"
* "Inventory Sync Script"
Use meaningful names to easily identify tokens later
**Purpose**: Defines how long the token remains active (security best practice)
**Options**: - **2 Months**: Short-term projects or testing - **1 Year**:
Production applications - **Custom**: Set a specific future expiration date -
**No Expiry**: Indefinite access (use with caution)
Tokens without expiry dates pose higher security risks if compromised
**Purpose**: Specifies which API version this token targets Select your
preferred API version from the dropdown (e.g., "v1.0.0", "v2.1.0")
For more information on API versions, visit our [API Versioning
documentation](/developer-resources/api-versioning)
**Purpose**: Toggle between test and production environments **When Test Mode
is ON**: - Expiry date defaults to 2 months (non-editable) - Whitelist options
are disabled - Token prefix: `mon_test_` - Only processes simulated
transactions **When Test Mode is OFF**: - Full configuration options available
* Token prefix: `mon_` - Processes real money transactions
**Purpose**: Restricts token access to a specific Monime Space Use the combobox
to search and select a specific Space by name or ID
This adds an extra security layer by preventing accidental cross-Space
operations
**Purpose**: Limits token usage to specific IP addresses **Examples**: - Single
IP: `203.0.113.45` - CIDR range: `203.0.113.0/24`
Ensure your production servers' IP addresses are included to avoid access
issues
**Purpose**: Filter API services to manage permissions more easily Choose from
available services: - Payments - Payouts - Customers - Analytics - And more...
This selection affects the available roles in the next section
**Purpose**: Define specific actions the token can perform
**Implementation of Least Privilege**:
* Only grant permissions your application actually needs
* Selected roles appear as removable "pills" or "tags"
* Different services have different available roles
**Common Role Examples**:
* `payments:read` - View payment information
* `payments:write` - Create new payments
* `customers:read` - Access customer data
* `payouts:write` - Initiate payouts
### Finalize Token Creation
After configuring all settings, click the **Create** button to generate your token.
## Securing Your New Token
**One-Time Display**: Your token will be shown only once. If you close the
dialog without copying it, you'll need to generate a new token.
When the token dialog appears, immediately click the **Copy** button The token
will look like: - Test: `mon_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` - Live:
`mon_YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY`
Save your token in a secure location: - Environment variables - Secrets
manager (AWS Secrets Manager, Azure Key Vault, etc.) - Encrypted configuration
files - Password vault
* Environment variables - Secrets management services - Encrypted
configuration - Server-side only
* Hardcoded in source code - Public repositories - Client-side code - Plain
text files
## Token Types & Environments
### Test Tokens
**Prefix**: `mon_test_` **Purpose**: Development and testing with simulated
transactions **Limitations**: 2-month expiry, no whitelist options
### Live Tokens
**Prefix**: `mon_` **Purpose**: Production environment with real money
transactions **Full Features**: All configuration options available
## Managing Existing Tokens
From the Access Tokens page, you can:
See name, creation date, expiry, and status of all tokens
Immediately invalidate compromised or unused tokens
Track API calls and usage patterns
Replace tokens regularly for security
## Security Best Practices
* Regularly rotate tokens (every 3-6 months)
* Replace tokens immediately if compromised
* Use expiry dates appropriate for your use case
* Grant minimum necessary permissions - Use Space whitelisting when possible -
Implement IP address restrictions - Monitor token usage patterns
* Never commit tokens to version control - Use environment variables or secrets
managers - Encrypt tokens at rest - Audit access to token storage
* Keep tokens server-side only
* Use HTTPS for all API calls
* Implement proper error handling
* Log security events
## Next Steps
Once you have your Access Token, you're ready to start integrating with
Monime's APIs!
Tools, documentation, and references to support your development work.
Explore our comprehensive API documentation
Use our official SDKs for faster development
Test your integration in our sandbox
# MCP Server
Source: https://docs.monime.io/developer-resources/ai-development-tools/mcp-server
Learn how to use the Monime Docs MCP server and integrate it with AI clients like VS Code (Copilot), Cursor, Claude, and more
## Overview
The Monime Documentation MCP (Model Context Protocol) server is automatically generated and hosted, providing AI assistants with direct access to Monime's comprehensive documentation. This integration enables your AI tools to search through documentation and interact with APIs directly from within your favorite AI clients
## MCP Server Access
Your Monime MCP server is automatically generated and hosted at:
**`https://docs.monime.io/mcp`**
This server is automatically updated to ensure it is always up-to-date with
the latest documentation changes.
## Features
The Monime Docs MCP server provides:
Built-in search tool to query information across all Monime documentation
Direct access to Monime API endpoints (when configured with OpenAPI specs)
Automatically stays current with the latest documentation changes
Works with any MCP-compatible AI client using the same connection method
## Supported AI Clients
Claude Desktop has native MCP support and can connect to our MCP server.
**Compatible with**: Claude 3.5 Sonnet, Claude 3.5 Haiku, and newer models
Cursor has built-in MCP support for connecting to external documentation servers.
**Compatible with**: Latest Cursor versions with MCP protocol support
Any MCP-compatible AI client can connect to the Monime documentation server.
**Examples**: Goose, Continue, and other tools supporting MCP protocol
## Quick Setup
### Prerequisites
Use an AI client that supports the Model Context Protocol (Claude Desktop, Cursor, etc.)
Ensure your client can access `https://docs.monime.io/mcp`
The Monime MCP server is publicly accessible - no API keys needed for documentation access
### Server URL
Simply use this URL in your MCP client configuration:
```
https://docs.monime.io/mcp
```
Since this is a cloud hosted, there's no need to install or run
any local servers. Just connect directly to the URL.
## Detailed Integration Guides
### Claude Desktop Integration
In Claude Desktop, navigate to **Settings** → **Connectors**
Click **"Add custom connector"** and enter: - **Name**: `Monime Documentation`
* **URL**: `https://docs.monime.io/mcp`
Click **"Add"** to save the configuration. Test by starting a new chat and
selecting the Monime Documentation connector from the attachments menu (plus
icon).
### Cursor Integration
Use **Cmd/Ctrl + Shift + P** to open the command palette, then search for **"Open MCP settings"**
Select **"Add custom MCP"** to open the `mcp.json` file, then add:
```json theme={null}
{
"mcpServers": {
"monime-docs": {
"url": "https://docs.monime.io/mcp"
}
}
}
```
In Cursor's chat, ask: **"What tools do you have available?"**
You should see the Monime documentation search tool listed.
## Usage Examples
Once configured, you can ask your AI assistant questions about Monime:
* "How do I create a Monimeer account?" - "What information is needed for
Space creation?" - "How do I verify my phone number with Monime?"
* "Show me how to generate API tokens" - "What are the rate limits for Monime
API?" - "How do I authenticate API requests?"
* "How do I create a payment link?" - "What payment methods does Monime
support?" - "How do I handle payment webhooks?"
* "Why am I getting a 401 error?" - "How do I resolve OTP delivery issues?" -
"What should I do if my Space creation fails?"
## Available Tools
The Monime MCP server provides the following tools to AI assistants:
Search across all Monime documentation pages for relevant information
Access to configured Monime API endpoints (when OpenAPI specs are available)
## Troubleshooting
**Issue**: AI client cannot access the Monime MCP server
**Solutions**:
* Verify the URL is correct: `https://docs.monime.io/mcp`
* Check your internet connection
* Ensure your AI client supports MCP protocol
* Try restarting your AI client
**Issue**: AI assistant doesn't show Monime documentation tools
**Solutions**:
* Confirm the MCP server is properly configured in your client
* Check that the connection is active in your AI client's interface
* Try asking "What tools do you have available?" to verify connection
* Restart your AI client and reconnect to the server
**Issue**: Documentation search returns no results
**Solutions**:
* Try rephrasing your search query
* Use more specific or more general search terms
* Verify the MCP connection is active
* Check if docs.monime.io is accessible from your network
**Issue**: Problems with specific AI clients
**Solutions**:
* For Claude: Ensure you're using Claude 3.5 Sonnet or newer
* For Cursor: Verify MCP support is enabled in settings
* Check the official documentation for your specific AI client
* Contact the AI client's support team for client-specific issues
## Security and Privacy
The Monime MCP server provides read-only access to publicly available
documentation. No authentication is required for documentation access.
**Security Features:**
* All communication uses HTTPS encryption
* No user credentials required or stored
* Read-only access to public documentation
* No sensitive information transmitted or cached
## Support and Resources
Learn more about the Model Context Protocol specification
Refer to your AI client's documentation for MCP setup assistance
## Next Steps
With the Monime Docs MCP server configured, your AI assistant now has
comprehensive knowledge about Monime's platform, APIs, and best practices.
Begin your Monime integration journey with our quickstart guide
Explore the complete API documentation
Browse practical implementation examples
Join our developer community for support and discussions
# Authentication
Source: https://docs.monime.io/developer-resources/api-basics/authentication
How clients prove identity and gain the right access
# Overview
We use Bearer token authentication to secure all API requests. \
Every request to the API must include a valid bearer token in the `Authorization` header,
along with a `Monime-Space-Id` header that identifies which Space you're operating in. This dual-header approach creates a powerful security model where tokens provide identity and authentication, while Space IDs provide context and isolation.
```shell theme={null}
curl -X GET https://api.monime.io/v1/financial-accounts \
--header "Authorization: Bearer " \
--header "Monime-Space-Id: "
```
Tokens are owned by a **Monimeer** (user) and are **space-agnostic** by design; effective access comes from the intersection of the token’s scopes and the Monimeer’s role in the Space you target.
## Quick Token Test
You can sanity-check a token by hitting the root endpoint. The response echoes whether you’re authenticated, which environment you’re in, and what Monime sees as your origin.
```text theme={null}
GET https://api.monime.io
```
### 1) Not Authenticated
```shell theme={null}
curl -X GET https://api.monime.io \
-H "Accept: application/json"
```
**Response:**
```json theme={null}
{
"platform": "Monime - Ⓜ️",
"tagline": "APIs Beyond Payments ⚡️⚙️💰️",
"status": {
"environment": null,
"isAuthenticated": false
},
"apiVersion": null,
"requestOrigin": {
"country": "SL",
"ipAddress": "2c0f:2a80:4ea:1f08:2c1b:e667:f921:ddcf"
}
}
```
What this tells you:
* ❌ **`isAuthenticated: false`** - Token is missing, invalid, or expired
* ❌ **`environment: null`** - Cannot determine environment without valid token
* ❌ **`apiVersion: null`** -Cannot determine API version.
### 2) Authenticated with Test Token
```shell theme={null}
curl -s https://api.monime.io \
-H "Accept: application/json" \
-H "Authorization: Bearer mon_test_XXXXXXXXXXXXXXXX"
```
**Response:**
```json theme={null}
{
"platform": "Monime - Ⓜ️",
"tagline": "APIs Beyond Payments ⚡️⚙️💰️",
"status": {
"environment": "test",
"isAuthenticated": true
},
"apiVersion": {
"id": "caph.2025-08-23",
"release": {
"name": "caph",
"date": "2025-06-20"
},
"deprecated": false,
"apiSchemas": {
"openApi": "https://github.com/monimesl/monime-developer-apis/blob/main/api-versions/-/specifications/openapi.yaml"
}
},
"requestOrigin": {
"country": "SL",
"ipAddress": "2c0f:2a80:4ea:1f08:2c1b:e667:f921:ddcf"
}
}
```
What this tells you:
* ✅ **`isAuthenticated: true`** - Valid test token
* ✅ **`environment: "test"`** - Connected to test environment
* ✅ **`apiVersion`** - Current API version you're accessing
* ⚠️ **Safe for testing** - No real money moves in test environment
### 3) Authenticated with Live Token
```shell theme={null}
curl -s https://api.monime.io \
-H "Accept: application/json" \
-H "Authorization: Bearer mon_XXXXXXXXXXXXXXXX"
```
**Response:**
```json theme={null}
{
"platform": "Monime - Ⓜ️",
"tagline": "APIs Beyond Payments ⚡️⚙️💰️",
"status": {
"environment": "live",
"isAuthenticated": true
},
"apiVersion": {
"id": "caph.2025-08-23",
"release": {
"name": "caph",
"date": "2025-06-20"
},
"deprecated": false,
"apiSchemas": {
"openApi": "https://github.com/monimesl/monime-developer-apis/blob/main/api-versions/-/specifications/openapi.yaml"
}
},
"requestOrigin": {
"country": "SL",
"ipAddress": "2c0f:2a80:4ea:1f08:2c1b:e667:f921:ddcf"
}
}
```
What this tells you:
* ✅ **`isAuthenticated: true`** - Valid test token
* ✅ **`environment: "live"`** - Connected to production environment
* ✅ **`apiVersion`** - Current API version you're accessing
* 🚀 **Production mode** - Real financial transactions will occur
## Security best practices
* **Server-Side Only:** Never expose tokens in browsers or mobile apps.
* **Least-Privilege Scopes:** Grant a token only the roles the job needs.
* **One Token per Integration:** Use separate tokens per service/use-case (single responsibility).
* **Rotate & Revoke Fast:** Rotate on a schedule; revoke immediately if leaked or unused.
* **Secure Storage:** Keep tokens in a secrets manager (Vault/AWS/GCP/K8s secret); never hardcode or store in plain `.env` file in production.
* **No Logging:** Mask/redact tokens in logs, metrics, traces, and error messages.
* **Ownership:** Name tokens clearly (owner, purpose, scope) and review them regularly.
* **Limited Lifetime:** Prefer shorter expirations or scheduled rotation windows.
* **Usage Boundaries:** Restrict where tokens can be used (e.g., IP whitelisting, Space whitelisting).
## Common errors & fixes
* **401 Unauthorized**
* **Cause:** Missing/invalid/expired access token.
* **Fix:** send a valid and active access token.
* **403 Forbidden**
* **Cause:** Token valid, but with insufficient permission or owner has no access to the space.
* **Fix:** Grant the needed persmission or adjust the monimeer’s Space role.
# Environment
Source: https://docs.monime.io/developer-resources/api-basics/environment
Flip from Test to Live with a token swap or dashboard toggle.
# Overview
Our API and Dashboard can both operate in two fully separated environments: **Live** and **Test**. Each is completely isolated, so activity in one environment never impacts the other. This separation allows you to build, test, and launch with complete confidence.
**API Endpoint**:
```shell theme={null}
https://api.monime.io/
```
The endpoint is the same for both Live and Test environments. Which environment you interact with depends on your **access token** — not the URL.
***
## Test Environment
The test environment offers a full simulation of our API, allowing you to build and validate your integration without touching real money or networks.
* **Tokens**: During token creation, if test mode is enabled, the token will be prefixed with `mon_test_`
* **Data & Networks**: Sandbox accounts and simulated payment rails
* **Use case**: Development, integration testing, and QA
## Live Environment
The live environment connects directly to real payment networks, processing actual funds and transactions. Use it only when your integration is fully tested and production-ready.
* **Tokens**: All live tokens are generated with the prefix `mon_` **NOT** `mon_test_`
* **Data & Networks**: Real accounts, banks, mobile money providers, card networks, and wallets
* **Use case**: Production operations and live customer payments
***
## How Environments Are Chosen
* **API environment** → Determined by the access token:
* **`mon_...`** → Live environment
* **`mon_test_...`** → Test environment
* **Dashboard environment** → Controlled by the Live/Test toggle in the Space dashboard.
This all means:
* The Base API URL and the Space dashboard URL never change.
* Switching between environments is as simple as swapping tokens or toggling your dashboard mode.
***
## Webhooks
Webhooks are also environment-specific:
* A webhook in **Live** only receives live events.
* A webhook in **Test** only receives test events.
This keeps your sandbox activity and production event flow completely separate.
# Errors
Source: https://docs.monime.io/developer-resources/api-basics/errors
Retry with confidence for resilience
# Idempotency
Source: https://docs.monime.io/developer-resources/api-basics/idempotency
Retry with confidence for resilience
## What is Idempotency?
[Idempotency](https://en.wikipedia.org/wiki/Idempotence) is the property of an API operation where executing the same
request multiple times results in the same outcome as executing it once. If a request succeeds but the client never
receives the response — because of a timeout, network drop, crash, or restarts — you can safely retry it without duplicating side-effect operations.
Imagine your system is creating a payout to a mobile money user. You send the request, but the network drops before you get the response.
Without idempotency, retrying could result in two payouts — sending the same funds twice to the user.
With idempotency, you attach a unique Idempotency-Key to the request:
* If the first attempt succeeded, we will return the original result when you retry.
* If the first attempt never reached us, the request is processed normally.
## How it Works in Monime
When you send a request to Monime with an idempotency key, something fascinating happens that sets it apart from most payment APIs.
Your key doesn't just exist in some global namespace where it could collide with keys from other spaces.
Instead, we evaluate your key within the context of the specific Space your request is targeting, creating what we call **space-scoped** idempotency.
This means that if you're managing payments for multiple businesses through different Spaces,
you can use the exact same key pattern across all of them without any risk of collision or confusion.
Think about what this means in practice. Suppose you're building a payroll platform that serves several companies,
and suppose your model requires that each company have an associating Space on Monime so you delegate financial services to Monime.
Now, when **Company A** creates a payout with **Idempotency-Key: payout-12345** for their employee **Aminata**,
and **Company B** simultaneously creates a payout with the same **Idempotency-Key: payout-12345** for their employee **Musa**,
these operations remain completely independent. They're not just different transactions; they exist in entirely separate idempotency universes.
This Space-scoped design means you can use consistent, meaningful idempotency key patterns across your entire platform without
maintaining complex namespacing schemes or worrying about key collisions between different clients.
Protection happens in two layers.
* **High-speed cache (24 hours)**: Monime stores the key and its result in a fast-access cache for one day, instantly returning the original response for any matching retry during that window.
* **Last-mile enforcement**: Unlike most financial APIs, protection doesn’t disappear when the cache expires. Even after 24 hours, retries hitting the internal service undergo transaction-level deduplication—so whether a retry comes after five seconds or five days, duplicates are still prevented.
Unlike many other systems, Monime does not cache API errors — failed requests bypass the idempotency
mechanism. This lets you retry after transient issues, like service unavailability, or bad request without having
the need to generate a new key.
We also have some conflict detection mechanism that protects you from a particular class of bugs.
When you send a request with an idempotency key that's already been used, Monime doesn't just blindly return the previous result.
Instead, it first checks whether you're sending the exact same request. If you accidentally reuse an idempotency key but with different parameters—say,
you meant to create a **SLE 100** payout but accidentally sent **SLE 10** with a recycled key — Monime will immediately return a `409 Conflict` error with the reason `idempotency_key_in_use`.
This validation happens at both the URL level and the request body level, ensuring that an idempotency key truly represents one and only one specific intention.
Without this protection, a simple key generation bug in your code could lead to wildly incorrect financial operations being silently accepted.
Mismatch detection (same key, different request) is limited to the 24-hour retention period; beyond that, a retry
won’t trigger a 409.
By combining Space-scoping, dual-layer protection, and strict validation, we turn the uncertainty of
distributed systems into predictable, safe payment operations—no accidental duplicates, no guesswork.
## How to Use It in Monime
Using idempotency in Monime is straightforward. Include an `Idempotency-Key` header with every POST request that creates resources or performs side-effect operations.
The key should be unique to each logical operation you want to perform:
```shell theme={null}
curl --request POST \
--url https://api.monime.io/v1/payouts \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: ' \
--header 'Monime-Space-Id: ' \
--data '{
"amount": {
"currency": "SLE",
"value": 100
},
"destination": {
"type": "momo",
"providerId": "m17",
"phoneNumber": "078000111"
}
}'
```
### Generating Idempotency Keys
Choose a key generation strategy that fits your use case:
* **UUID Approach** (Recommended for most cases):
```javascript theme={null}
import { v4 as uuidv4 } from 'uuid';
const idempotencyKey = uuidv4(); // "550e8400-e29b-41d4-a716-446655440000"
```
### Implementing Retry Logic
With idempotency, you can safely retry failed requests without fear of duplicates:
```javascript theme={null}
async function createPayoutWithRetry(data, idempotencyKey, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch('https://api.monime.io/v1/payouts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${ACCESS_TOKEN}`,
'Monime-Space-Id': SPACE_ID,
'Idempotency-Key': idempotencyKey, // Same key for all retries
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (response.ok) {
return await response.json();
}
// Handle 409 Conflict specifically
if (response.status === 409) {
const error = await response.json();
if (error.reason === 'idempotency_key_in_use') {
throw new Error('Idempotency key already used with different request');
}
}
// Retry on network errors or 5xx responses
if (response.status >= 500) {
console.log(`Attempt ${attempt} failed, retrying...`);
await sleep(Math.pow(2, attempt) * 1000); // Exponential backoff
continue;
}
throw new Error(`Request failed: ${response.status}`);
} catch (error) {
if (attempt === maxRetries) throw error;
await sleep(Math.pow(2, attempt) * 1000);
}
}
}
```
### Conflict Error Response
If you reuse an idempotency key with a different endpoint or payload, Monime will reject the request with the following error:
```json theme={null}
{
"success": false,
"messages": [],
"error": {
"code": 409,
"reason": "idempotency_key_in_use",
"message": "Conflict: Idempotency key reused with a non-identical request.",
"details": []
}
}
```
## Best Practices for Idempotency
* **Generation and Use**
1. Use a unique key per logical operation. UUIDv4 works well, or use a deterministic key (UUIDv5) from a stable business ref (e.g., payout:) when you want automatic retries across services.
2. Keep keys above 25 and below 64 characters. When a stable identifier exceeds this, convert it to a UUIDv5 so it remains compatible and deterministic.
3. Send the exact same request on retry. Method, URL, headers, and JSON body must match byte-for-byte (including field order if your client doesn’t canonicalize).
* **Store & Retry**
1. **Persist keys client-side** alongside your business operation ID. This lets you retry confidently after crashes or timeouts.
2. **Leverage the retention window**. Cache retention is 24 hours; beyond that Monime still enforces last-mile idempotency, but plan to reconcile using your business refs if you expect very late retries.
3. **GET resource on uncertainty**. If you don’t know the outcome, prefer fetching the resource before issuing a new creation; `404` means it was never created.
* **Handle Outcomes**
1. **On success**: reuse the same key if you must confirm; you’ll receive the original response.
2. **On 409 Conflict**: your key was used for a different request; generate a new key and fix the caller logic.
3. **On errors (5xx/timeout)**: retry with the same key. Errors aren’t cached, so you’re not forced to issue a new key.
* **Security**
1. Avoid putting sensitive information in the key. Treat it as an identifier that is safe to log and helful for tracing.
# API Overview
Source: https://docs.monime.io/developer-resources/api-basics/index
Learn how to build with the APIs
Monime’s API is your gateway to building modern, flexible, and truly borderless payment experiences. Whether you’re creating a hosted checkout, managing financial accounts, or orchestrating payouts across banks, mobile money, cards, and wallets, the API gives you a single, consistent interface to do it all.
It’s built on REST principles, with predictable resource-oriented URLs, JSON request and response bodies, standard HTTP verbs and status codes, and secure bearer token authentication. Every request is designed for reliability and safety—idempotency keys prevent duplicate operations, cursor-based pagination makes data fetching predictable, and rich metadata helps you tailor resources to your business logic.
## Live and Test Modes
You can work in two completely separate environments:
* **Live mode** — processes real payments and moves actual funds.
* **Test mode** — a sandbox for building and experimenting without touching real accounts or networks.
The **access token** you use determines the mode: live tokens start with `mon_` and test tokens start with `mon_test_`.
***
## Multi-Tenancy by Design
With Monime’s API, every call lives inside a Space—your own secure, self-contained payment world. Each Space has its own accounts, policies, and event streams, completely isolated from others.
Monimeers can work across multiple Spaces, but tokens only unlock what’s allowed by both their scopes and Space permissions. The result is bulletproof isolation, precision access control, and the freedom to power many organisations with a single integration.
***
## Built for Evolving Needs
Monime’s API is designed to evolve at your pace. Each version combines a release name and a date, giving you a clear, predictable view of how the API behaves.
Within a release, every change is safe and backward-compatible. Breaking changes only arrive in a new release - so you control when to upgrade and how to prepare.
Webhooks are sent using the latest version of the release you’ve selected—giving you dependable stability with the advantage of continuous enhancements.
# Object Metadata
Source: https://docs.monime.io/developer-resources/api-basics/metadata
Tag your objects with your own contexts
## Overview
Metadata is a developer-controlled extension field available on most API objects. It allows you to attach custom key-value pairs that Monime will store and return with the object, without interpreting them.
This feature is designed to help you bridge the gap between Monime’s standard fields (like id, status, or amount) and the real-world business context your systems require for reconciliation, reporting, or debugging.
When you create a payment code, payout, or checkout session in Monime, the API provides all the financial attributes needed for processing. But businesses, depending on their domain, may often ask questions such as:
* Which order at the shop or restaurant does this payment code belong to?
* Which branch, kiosk, or agent in Waterloo or Kenema initiated this payout?
* Which campaign or promotion should this checkout session be tied to?
* Which customer from my database should I link this Monime object back to?
Without metadata, you’d have to manage a separate mapping table in your system to tie Monime’s ID to your own references. With metadata, you can embed those references directly in the Monime object itself.
This makes every API object self-describing in your domain context.
## How it Works
### Flat Structure Only
* Metadata is always flat keys map directly to values.
* Nested JSON `{"billingAddress": {"Chiefdom": "Nongowa"}} ` and arrays are not supported.
* If you need hierarchy, encode it into the key itself (e.g., billing\_address\_chiefdom).
This rule makes metadata predictable and fast to validate.
### Partial Update Support
Metadata updates in Monime are incremental. You don’t need to resend the full set every time. Instead:
* Omit a key → its value will remain unchanged.
* Send a key with a value → it will be created or updated.
* Send a key with null or "" (empty string) → the key will be removed if present.
This allows you to make targeted changes without worrying about overwriting unrelated keys.
## Limitations
Metadata is powerful, but it has deliberate limitations to ensure Monime stays consistent, performant, and secure.
| Limitation | Rule |
| ---------------------- | ---------------------------------------------------------------- |
| Max pairs | 64 key-value entries per object |
| Max key length | 64 characters |
| Max value length | 100 characters |
| Allowed key characters | `[a-zA-Z0-9_-]` |
| Reserved prefix | Keys cannot begin with `_`, `-` or `"monime"` (case-insensitive) |
| Value length | Must be a string ≤ 100 chars; `null` or `""` deletes the key |
| Nesting | Not supported; metadata is always flat |
If your request includes invalid metadata (e.g., key too long, invalid characters, or too many pairs),
the request will be rejected with the appropriate message
***
## Use Cases
* **Reconciliation:**
Add your `order_id` or `invoice_no` to payments and payouts, so your finance system can line up with Monime.
* **Operational tags:**
Tag payments by branch, e.g. `"branch": "Kenema-Kiosk-1234"`, or campaigns like `"fund_raising_ref": "save-life-1234"`.
* **Flexible extensions:**
Quickly add flags like `"priority": "high"` or `"batch": "salary-August"` without waiting for schema changes.
Metadata is **opaque to Monime**. It has no semantic meaning to us. The only
enforcement done on them is on the limitations (key length, value length, allowed characters).
***
## Best Practice
* **Use Predictable Keys:**
Define a clear convention (`order_id`, `customer_ref`, `kiosk`, `osusu_id`). This makes reconciliation easier across systems.
* **Keep Values Concise:**
Values are capped at 100 characters. Use them for IDs, short tags, or labels, not descriptions or logs.
* **Avoid Sensitive Data:**
Metadata is returned in API responses. Never store credentials, personal private data, or secrets here.
* **Treat Metadata as Context, Not State:**
Use metadata for annotations and reconciliation. Do not rely on it as your system of record.
* **Clean Up Over Time:**
Remove keys with `null` or `""` when they’re no longer needed to keep your objects lean.
* **Flat-Only Design:**
If you need to represent hierarchy, encode it into the key name (contact\_phone\_number, contact\_email\_address).
* **Leverage Metadata for Reconciliation:**
Always attach your own IDs (`order_id`, `invoice_no`) so Monime objects can be directly matched to your internal records without external tables.
# Ownership Graph
Source: https://docs.monime.io/developer-resources/api-basics/ownership-graph
Retry with confidence for resilience
# API Pagination
Source: https://docs.monime.io/developer-resources/api-basics/pagination
How to page through Monime resources efficiently using cursors.
# Overview
Monime uses **cursor-based pagination** for list endpoints. Every `listing` Responses include a `pagination` object with a cursor you pass back to fetch the next page.
This design is stable, efficient, and avoids the pitfalls of offset-based paging under changing datasets.
***
## Request Shape
Pagination on Monime APIs is controlled with **query parameters**:
* **`limit`** → how many objects to return in one page.
* **`after`** → an opaque cursor (usually the `id` of the last object from the previous page).
This allows you to step through results page by page in a consistent order.
Example request:
```bash theme={null}
curl "https://api.monime.io/v1/payouts?limit=10&after=pyt-k6GMRZsCr61zfwCQtVemY2RrvQH" \
-H "Authorization: Bearer mon_***"
```
***
## Response Shape
Every paginated response includes a `pagination` object:
```json theme={null}
{
"success": true,
"messages": [],
"result": [
{}, // Item 1
{}, // Item 2
....
],
"pagination": {
"count": ,
"next": ""
}
}
```
### When to Stop Paging
* If `pagination.next` is present → there are more results. Pass this value as `after` in your next request.
* If `pagination.next` is `null` or absent → you’ve reached the end of the collection. Stop paging.
A smaller `count` than your requested `limit` often indicates you’re on the final page, but the definitive signal
is when `next` is `null` or missing.
## Best Practices for Paging
### Choose sane page sizes
* Start with `limit=30–50` for bulk jobs; use smaller limits for interactive UIs.
* Larger pages → fewer round trips; balance with payload size and client memory.
### Always drive from the cursor
* Read `pagination.next` and pass it back as `after` in the next call.
* Don’t fabricate or modify cursors; they are opaque and query-specific.
* Stop when `pagination.next` is `null`/ absent.
### Keep filters stable while paging
* Apply all filterss before paging.
* Changing filters mid-stream invalidates the cursor and can skip/duplicate items.
### Checkpoint for resumability
* Persist `{endpoint, filters}` after each page.
* On restart, resume with the last `after`. For strict windows, bound by timestamp.
### Be nice to rate limits
* Pace requests: small delay (50–200ms) between pages for steady flows.
* On `429`, honor `Retry-After`; then continue from the **same** cursor.
* Remember endpoint caps (live: **20 req/s**, test: **5 req/s**) and token/space quotas.
### Avoid N+1 request patterns
* Prefer list responses that already include fields you need.
* If you must hydrate per-item, batch those lookups and rate-gate them.
### Control parallelism
* Cap concurrency per token and per endpoint; add jitter to avoid synchronized bursts.
# Rate Limits
Source: https://docs.monime.io/developer-resources/api-basics/rate-limiting
API limits keep Monime stable; learn how to use it to your advantage.
## Overview
API Rate limiting in Monime is a fundamental control mechanism designed to maintain platform reliability, equitable usage, and predictable performance. Every request passing through is subject to limit evaluation to prevent system abuse, contain noisy workloads, and ensure that resources are shared fairly across all tenants.
Unlike single-threshold throttling, we apply limits at multiple contextual layers - capturing the identity of the caller, the scope of the tenant, and the type of request being made. This provides a balanced enforcement model that protects both the infrastructure and individual tenants, while giving clients precise feedback for adaptive behavior.
## Enforcement Model
Rate limiting operates in a chainable fashion. Each incoming request is intercepted before it reaches the core service(s). At this stage, Monime evaluates the request against several limits, each responsible for a different dimension of usage control.
If any limit rejects the request:
* The request will not be forwarded to the target service.
* No billing or side effect action will occur downstream.
* A structured response is returned with rate limit headers (the limit and retry info).
This ensures that rejected requests are cheap for the platform and safe for the client.
### Error Response
When a request is throttled, Monime always returns a structured error so your client knows exactly what happened and how to recover.
#### Status Code
**`429 Too Many Requests`**
Standard HTTP code indicating the client has hit a rate limit.
#### Headers
1. **`Monime-Rate-Limit`** → shows which limit was triggered:
* `token-limit` — the per-token quota was exceeded.
* `space-limit` — the per-space quota was exceeded.
* `endpoint-limit` — the per-endpoint quota for the token was exceeded.
2. **`Retry-After`** → the number of seconds to wait before retrying. Always at least `1`.
#### Body
The response body is JSON and mirrors the structure used across Monime errors:
```json theme={null}
{
"success": false,
"messages": [],
"error": {
"code": 429,
"reason": "too_many_requests",
"message": "Too many requests sent in a short period. Request blocked due to rate limiting",
"details": []
}
}
```
## Limits by Dimension
Our API rate limiting is built on a multidimensional enforcement model, rather than a single global cap.
This means every request is evaluated through multiple layers of control, each representing a different perspective of usage.
At its core, the model ensures that traffic is constrained at the edges where pressure naturally builds:
* **At the caller level**, so no individual token can monopolize capacity.
* **At the tenant level**, so traffic bursts from one Space don’t affect others.
* **At the route level**, so individual endpoints remain reliable under heavy access.
The key principle behind this design is **balance**. By layering limits across dimensions, Monime can:
* Protect **platform stability** by ensuring no single dimension overwhelms the system.
* Preserve **fairness** so tenants (Spaces) share resources equitably.
* Provide **granularity**, allowing clients to understand exactly where throttling occurred (token, space, or endpoint).
Instead of treating all traffic equally, Monime evaluates requests in context.
For example, a Space may still have capacity overall, but if a specific endpoint is being hammered, the endpoint limit can apply targeted pressure.
Conversely, a token might be consuming more than its share even though the endpoint is underutilized — the token limit steps in at that layer.
This **context-aware layering** makes the protection mechanism adaptive: it scales with diverse workloads, isolates noisy patterns, and gives developers actionable feedback when limits are exceeded.
Think of it as a series of guardrails: if traffic skews too far in one direction — whether by token, by space, or
by endpoint — the limit at that dimension catches it before it destabilizes the rest of the system.
### Space-Based Limit
**`Limit name: space-limit`**
A Space in Monime represents an organizational boundary — typically a tenant or business account. To protect stability and ensure fair use, Monime applies rate limits at the Space level.
#### Per-second Quotas
* **Test mode:** up to *100 requests per second* across all space interactions.
* **Live mode:** up to *500 requests per second* across all space interactions.
This aggregate limit ensures that even if multiple tokens are used, the combined throughput of the Space does not exceed the allowed budget.
#### Why Space Limit Exists
* **Tenant fairness:** Prevents a single tenant from monopolizing platform resources.
* **Poison Containment:** Controls noisy workloads where multiple apps or services operating under a Space generate bursts simultaneously.
#### Developer Implications
* Monitor Space-wide usage, since limits apply across all tokens and endpoints.
* When multiple apps share a Space, spread out their workloads and add jitter to avoid synchronized spikes.
* Keep test traffic in test mode to stay within the lower quota and avoid affecting production.
* One app exceeding its share can cause throttling for the entire Space, so coordinate usage across teams.
Even if tokens are individually within their own quotas, exceeding the Space quota (500 req/s for live, 100 req/s for test) will result in throttling across the entire Space.
### Token-Based Limit
**`Limit name: token-limit`**
Each access token has its own request-per-second budget. Live and test tokens are evaluated separately, ensuring development workloads don’t interfere with production traffic.
#### Per-second Quotas
* **Test tokens:** up to *20 requests per second*
* **Live tokens:** up to *80 requests per second*
This separation ensures that production workloads can operate at higher throughput, while test and staging environments remain safely throttled.
#### Why Token Limit Exists
* **Fairness:** Prevents any single application from monopolizing shared infrastructure.
* **Isolation:** Ensures that runaway traffic from one integration won’t spill over into others, even inside the same Space.
* **Environment separation:** Keeps test workloads clearly isolated from production, avoiding cross-impact.
#### Developer Implications
* Use separate tokens for independent applications or services. This guarantees each gets its own request budget.
* Always use test tokens in staging, CI, and development environments.
* Instrument your clients to log throttling events at the token level, so you can quickly identify integrations exceeding their fair share.
Even if your Space still has available capacity, exceeding the per-token quota (80 req/s live, 20 req/s test) will
cause requests to be throttled at the token layer.
### Endpoint-Based Limit
**`Limit name: endpoint-limit`**
In addition to token and Space limits, Monime also enforces limits at the **endpoint level**, applied per token.
This ensures that no single token can overload a specific API route, regardless of which Space it operates in.
#### Per-second Quotas
* **Test tokens:** up to *5 requests per second per token per endpoint*
* **Live tokens:** up to *20 requests per second per token per endpoint*
Each token has its own independent budget for every endpoint. If a token exceeds the limit on one route, only that endpoint is throttled for that token — other endpoints (or other tokens) remain unaffected.
#### Why Endpoint Limits Exist
* **Protect sensitive APIs:** Prevents abuse of routes that are commonly polled or accessed at high frequency.
* **Fair distribution:** Ensures all clients using the same endpoint can share capacity fairly.
* **Localized throttling:** Restricts overload at the narrowest scope (token and endpoint), without penalizing unrelated traffic.
#### Developer Implications
* Avoid rapid polling of a single endpoint — use webhooks, or conditional requests where possible.
* If polling is required, spread requests with jitter to avoid breaching the 20|5 req/s cap.
* Monitor endpoint-level throttling per token to identify “hot routes” that need optimization.
Even if token-level and Space-level quotas are not reached, exceeding the **endpoint quota (20 req/s live, 5 req/s test)** will result in throttling on that specific route for the token.
## Why Rate Limiting Happens & How to Avoid It
Rate-limiting errors (`429 Too Many Requests`) occur when traffic goes beyond Monime’s defined quotas at the **space**, **token**, or **endpoint** level.
### Common Causes
* Polling status endpoints (e.g., `GET /v1/payouts/{payout-id}`) too frequently instead of using webhooks.
* Many small API calls in loops or tiny pagination.
* Multiple apps sharing the same token.
* Staging traffic using live tokens/Spaces.
* High concurrency from workers/consumers.
### Best Practices
* **Use webhooks** as your primary signal; poll sparingly.
* **Batch & paginate smartly** — fewer, larger requests.
* **Issue separate tokens** per app/service; keep test traffic in test mode.
* **Cap concurrency** and add jitter to spread requests.
* **Respect** `Retry-After` and log the `Monime-Rate-Limit` header to know what triggered the block.
In Monime, 429s are not failures — they’re **flow-control signals**. Handle them with backoff + jitter to keep your integrations resilient and reliable.
# API Headers
Source: https://docs.monime.io/developer-resources/api-basics/standard-headers
Learn how to use and deal with Monime's API
## API Request
### `Authorization` *(required)*
Authenticates the caller and selects the API environment.
We must know who is calling and which environment to use. Live tokens execute in production; test tokens run in sandbox.
```shell theme={null}
curl --request GET \
--url https://api.monime.io/v1/payments \
--header 'Authorization: Bearer '
```
### `Content-Type` *(required)*
This must be set to `application/json` for endpoint that requires payload unless otherwise stated.
```shell theme={null}
curl --request POST \
--url https://api.monime.io/v1/payment-codes \
--header 'Content-Type: application/json'
```
### `Monime-Space-Id` — *(required)*
This is the tenancy parameter that tells Monime on whose behalf the request should be processed. Set to the Space ID.
```shell theme={null}
curl --request GET \
--url https://api.monime.io/v1/payments \
--header 'Monime-Space-Id: spc-1234567890'
```
### `Monime-Version`
Pins behavior to a release name + '.' + version date (e.g., caph.2025-06-20).
This locks your integration to a predictable schema and behavior. Updates within a release are backward-compatible;
breaking changes only arrive in a new release—so you decide when to upgrade.
```shell theme={null}
curl --request GET \
--url https://api.monime.io/v1/payments \
--header 'Monime-Version: caph.2025-06-20'
```
### `Idempotency-Key`
A unique key per resource creation that makes it safe to retry. Prevents duplicates when networks flake or clients time out.
```shell theme={null}
curl --request POST \
--url https://api.monime.io/v1/payment-codes \
--header 'Idempotency-Key': 461d61c9-e7d0-4fc4-904a-565aefa1f4a6'
```
***
## API Response
Monime returns a small set of diagnostic headers so you can trace requests, see performance, and understand caching and throttling behavior.
### `Monime-Request-Id`
A unique ID for this request attempt. Capture it in logs and include it in support tickets for end-to-end tracing.
### `Monime-Request-Checksum`
A deterministic checksum of the request signature (method + path + body) primarily used for idempotency conflict detection.
### `Monime-Request-Timestamp`
The UTC (ISO-8601) time your request hit Monime, useful for log correlation and clock-skew checks.
### `Monime-Request-Duration`
Approximate server-side processing time, excluding network latency—handy for SLO tracking and regression spotting.
### `Monime-Cache`
The cache that served the response. The value is the cache name; for example, `irc` means idempotent request cache (a replayed result from a prior successful call).
This helps explain when a response was satisfied from cache versus computed.
### `Monime-Rate-Limit`
Identifies the rate limit that was triggered. Appears only on HTTP 429 responses and is typically paired with
`Retry-After: ` indicating when to retry.
***
## Webhook Request
### `Monime-Signature`
Cryptographic signature with timestamp. Lets you verify that the request really came from Monime,
that the body wasn’t tampered with, and that it’s fresh (replay-safe).
# Best Practices
Source: https://docs.monime.io/developer-resources/authentication/best-practices
Secure your integration
Security in authentication systems isn't achieved through a single mechanism or practice.
Instead, it emerges from multiple layers of protection working together, each compensating for potential weaknesses in others.
This defense-in-depth approach means that even if one security measure fails, others remain to protect your Space and data.
This guide presents security practices organized by lifecycle phase, helping you build and maintain secure integrations with Monime.
## Principle of Least Privilege
Only grant tokens the permissions needed for their task. Broad permissions create unnecessary risk if the token is compromised.
Even though Monime’s permission intersection prevents tokens from exceeding their creator’s authority, always scope them to the minimum required.
## Secure Token Practices
Tokens are shown once on creation—store them securely and immediately afterwards using password manager, secret vault, or encrypted config.
Never paste into chat, email, or documents. Document purpose, permissions, creation date, and rotation schedule to prevent forgotten, risky tokens.
## Shorter Token Lifetime
Shorter lifetimes reduce exposure from leaks but require more rotation. Use short-lived tokens for sensitive operations
or automated services that handle rotation easily. Longer lifetimes may be acceptable for lower-risk use, but still rotate regularly.
## Storage & Handling
Never commit tokens to version control—even private repos. Use .gitignore, pre-commit hooks, and secret scanning tools.
Separate environments—store production tokens in secure secret managers with audit logs and rotation; use test tokens for development.
Use secret management solutions—AWS Secrets Manager, Azure Key Vault, Google Secret Manager, or HashiCorp Vault to store, rotate, and audit token use.
## Runtime Usage Practices
Always transmit tokens over HTTPS/TLS; never send them via email or unencrypted channels.
Keep tokens in memory only as long as needed; avoid logging them.
Sanitize logs, error messages, and monitoring data to prevent leaks.
***
Security is always ongoing. Start with least privilege, secure storage, and monitoring, then layer on advanced protections as your needs grow.
By combining multiple controls and keeping security top of mind, you protect your Spaces, and data while staying ready for evolving threats.
# Concepts
Source: https://docs.monime.io/developer-resources/authentication/concepts
Learn what holds it together.
Before you can effectively implement Monime's authentication system, you need to understand three fundamental concepts that form its foundation: Spaces, Monimeers, and Personal Access Tokens. These aren't just terminologies; they represent the architectural decisions that make Monime's authentication both powerful and secure.
## Spaces: Your Isolation Boundary
A Space in Monime is a completely isolated environment that belongs to a single business or organization.
Think of it as your own private section of the Monime platform where your data, settings, and operations are completely separated from everyone else's.
### The Multi-Tenant Architecture
Monime operates on a multi-tenant architecture, which means many Spaces coexist on the same platform infrastructure. This is similar to how multiple companies might have offices in the same building.
This architecture provides several critical benefits. First, it enables economies of scale, as the platform infrastructure is shared efficiently across all Spaces. Second, it ensures complete isolation, so problems in one Space never affect another. Third, it allows for Space-specific customization while maintaining platform-wide consistency where needed.
### Space Boundaries and Security
The boundaries between Spaces are absolute and enforced at every level of the system.
When a request attempts to access resources in a Space, the system verifies not only the authentication credentials
but also whether those credentials have the appropriate permissions within that specific Space.
Personal Access Tokens in Monime have a powerful relationship with Spaces.
While tokens are created by Monimeers and can potentially work across multiple Spaces (inheriting the Monimeer's permissions in each),
they can also be optionally bounded to a single Space at creation time. When a token is Space-bounded,
it becomes tied to that specific Space and cannot be used elsewhere—like having a key that only works for a room even though you have access to multiple rooms.
This flexibility allows for both broad integration scenarios and tightly scoped security requirements.
### Working with Multiple Spaces
Many organizations use multiple Spaces for different purposes, such as separating production from development,
isolating different departments or projects, or creating temporary Spaces for specific initiatives.
Monimeers can belong to multiple Spaces simultaneously, potentially with different roles in each, and this flexibility
allows us to model complex organizational structures accurately.
## Monimeers: The Actors in Your Space
A Monimeer is any entity that can authenticate and perform actions within Monime's platform. The term intentionally
encompasses both human users and automated systems because, from the authentication system's perspective,
they're treated similarly—both need to prove their identity and have their permissions verified.
Human Monimeers are individuals who interact with the platform through web interfaces, mobile apps, or API tools.
They typically authenticate initially through aliases(phone or email) and OTP, then create Personal Access Tokens for API access.
Automated Monimeers are scripts, applications, or integrations that interact with the platform programmatically.
They authenticate exclusively through Personal Access Tokens and often run without human intervention.
### Monimeer Identity and Roles
When a Monimeer joins a Space, they're assigned a role that defines their permissions within that Space.
A Monimeer's identity across the platform consists of several components. Their unique identifier remains constant and provides a permanent reference for audit trails and permission management. In each Space they belong to, they have an assigned role that determines their base permissions within that specific Space. Any role modifications include temporary permission grants or restrictions for specific scenarios. Their activity history includes all authentication events and actions performed across all Spaces they have access to.
It's crucial to understand that a Monimeer's role is Space-specific. The same individual might be an `Owner` in one Space, but a `Developer` only in another Space. This separation allows organizations to implement the principle of least privilege effectively, giving people exactly the access they need in each context, no more and no less.
## Personal Access Tokens: The Keys to the Kingdom
A Personal Access Token (PAT) is a cryptographically secure string that authenticates API requests on behalf of a Monimeer. Unlike passwords, which are typically short and memorable, PATs are long, random strings that are impossible to guess and difficult to forge.
Each token is fundamentally tied to the Monimeer who created it and encodes several pieces of critical information. The Monimeer identifier links the token to its creator for audit and permission purposes. Declared permissions specify what operations the token is intended to perform. Creation timestamp and expiration time define the token's validity period. An optional Space identifier can bound the token to a specific Space if desired.
### Token Creation and Configuration
When a Monimeer creates a Personal Access Token, they're essentially delegating a subset of their permissions to that token. This delegation follows strict rules to ensure security is maintained.
During creation, the Monimeer makes several important decisions. First, they specify what permissions the token should have (its declared permissions). Second, they decide whether the token should work across all Spaces they have access to or be bounded to a single Space. Third, they set how long the token should remain valid. Fourth, they can specify in which evnrionment (Live or Test) the token should operate. Fifth, whether they want IP whitelisting of the calling instance. Finally, they can add a description to help identify the token's purpose later.
The choice between a cross-Space token and a Space-bounded token depends on the use case. Cross-Space tokens are ideal for integrations that need to synchronize data across multiple environments or for administrative tools that manage multiple Spaces. Space-bounded tokens are perfect for production systems that should never accidentally access other environments or for third-party integrations that should have limited scope.
### The Sophisticated Nature of Token Permissions
Personal Access Tokens have a permission model that adapts based on context. A token always carries its declared permissions—what it claims it should be able to do. However, the effective permissions of a token in any given Space are calculated through an intersection model.
When a cross-Space token is used to access a particular Space, the system calculates effective permissions by intersecting two sets: the token's declared permissions and the Monimeer's current permissions in that Space. This means a single token can have different effective permissions in different Spaces, automatically adapting to the Monimeer's role in each context.
### Token Security and Management
The actual token string is shown only once during creation. After that, it is no longer visible for management purposes. This prevents tokens from being casually exposed through administrative interfaces.
Tokens can be revoked individually by the Monimeer who created them. When a token is revoked, it immediately stops working. For cross-Space tokens, revocation affects all Spaces. For Space-bounded tokens, the revocation is inherently limited to that Space's context.
## How These Concepts Work Together
The true power of Monime's authentication system emerges from how Spaces, Monimeers, and Personal Access Tokens work together in a powerful dance of permissions and contexts.
When an API request arrives with a Personal Access Token, the system follows a comprehensive validation process. First, it verifies the token's validity and checks if it's expired or revoked. Then, it identifies which Monimeer created the token.
If the token is Space-bounded, the system ensures the request is targeting that specific Space. If it's a cross-Space token, the system identifies which Space the request is targeting based on the `Monime-Space-Id` header.
Next, the system retrieves the Monimeer's current role and permissions in the target Space. If the Monimeer doesn't have access to the target Space, the request is immediately denied. The system then calculates the effective permissions by intersecting the token's declared permissions with the Monimeer's permissions in that Space. Finally, it evaluates whether the requested operation falls within these effective permissions.
This layered approach means that security can be managed at multiple levels. Space administrators can set broad policies that apply to everyone, role definitions can establish standard permission sets for common job functions, individual Monimeers can have their roles adjusted as needed, and tokens can be scoped to specific tasks without compromising overall security.
## Practical Implications
Understanding these core concepts has practical implications for how you design and implement your integrations.
When planning your token strategy, consider whether your integration needs to work across multiple Spaces or can be limited to one. Cross-Space tokens offer flexibility but require careful permission management to ensure they don't inadvertently grant too much access in any particular Space. Space-bounded tokens provide an extra layer of security for sensitive operations.
When assigning roles to Monimeers, remember that their permissions in each Space directly affect what their tokens can do in that Space.
When creating Personal Access Tokens, always declare the minimum permissions necessary for the specific task. Even if you have broad permissions across multiple Spaces, constraining tokens limits damage if they're compromised. Consider token lifetime carefully—shorter is more secure but requires more management overhead.
For automated systems that need to operate across multiple Spaces, you might create a dedicated Monimeer account with carefully calibrated roles in each Space. This Monimeer can then create cross-Space tokens that automatically inherit appropriate permissions in each context.
# Authentication
Source: https://docs.monime.io/developer-resources/authentication/index
Learn how your requests get permitted.
Whether you’re a developer building your first integration, a security professional evaluating our authentication model,
or an administrator managing access for your Space, this documentation will provide the knowledge you need.
Authentication forms the foundation of every interaction with the Monime platform. Before diving into
implementation details, it's essential to understand the philosophy and architecture behind our authentication system.
This overview will introduce you to the key concepts and prepare you for the more detailed guides that follow.
## Personal Access Tokens
Monime uses Personal Access Tokens (PATs) as the primary authentication mechanism for all API interactions.
To understand why we made this architectural choice, let's consider the alternatives and their limitations.
Traditional username and password authentication creates several challenges in modern distributed systems.
When you use the same credentials everywhere, a compromise in one location endangers all your systems.
Additionally, passwords don't naturally support the fine-grained permissions that complex systems require.
You either have full access with your password, or you don't have access at all.
Another common approach is API keys—simple strings passed with each API request.
While straightforward to implement, their simplicity often hides serious limitations.
Their biggest weakness is that they don’t convey the identity of the caller, only that a valid key was presented.
This makes it difficult to attribute actions to specific users and weakens audit trails.
On top of that, API keys often grant broad, unrestricted access without scope or role-based controls,
so a single leaked key can expose everything it touches.
Personal Access Tokens (PATs) solve these problems by combining identity with granular control.
Each PAT is tied directly to a specific user account—what Monime calls a Monimeer—so every action taken with a token
is traceable back to the individual behind it.
You can issue different tokens for different applications or integrations,
each with precisely the permissions it needs and nothing more. If one token is compromised,
it can be revoked instantly without disrupting other tokens or integrations, and optional expiry dates ensure
that unused or forgotten tokens don’t linger as security risks.
## The Three Pillars of Monime Authentication
Our authentication system rests on three fundamental pillars that work together to provide security, flexibility, and scalability:
### 1. Multi-Tenant Architecture with Spaces
Every organization using Monime operates within its own Space—a completely isolated environment that ensures your data never mingles with others'.
This isolation goes beyond simple data separation; each Space maintains its own security policies, user roles, operational rules and even test environment.
The authentication system enforces these boundaries absolutely, ensuring that a token scoped for one Space can never access another Space's resources.
### 2. Role-Based Access Through Monimeers
Within each Space, individuals are assigned specific roles that define their capabilities.
These roles aren't just labels; they're comprehensive permission sets that determine exactly what operations each Monimeer can perform.
The beauty of this system lies in its flexibility—a Monimeer might be an `Owner` role in one Space while having `Developer` role in another, perfectly modeling real-world organizational structures.
### 3. The Permission Intersection Model
This is where Monime’s authentication model becomes truly sophisticated. When a Monimeer creates a
Personal Access Token (PAT), the system evaluates two separate permission sets to determine what that token can actually do:
1. **The token’s declared permission set** – the specific scopes and actions the creator explicitly grants to that
token at creation time. This allows the Monimeer to design tokens for narrow, purpose-built use cases—such as
viewing payout details without modifying them, accessing transaction history for analytics,
or checking account balances without the ability to initiate transfers—all without exposing unrelated or higher-risk capabilities.
2. **The Monimeer’s own permission set** – this is the full range of actions the Monimeer is allowed to perform in a specific Space,
based on their assigned role(s) granted within that Space. It acts as the upper bound for what anyPersonal Access Token created by that Monimeer can do.
In other words, the access token’s effective permissions are the intersection of these two sets.
This mathematical approach ensures that access tokens are both identity-bound and context-aware. It prevents privilege escalation, enforces least privilege by design, and guarantees that no token—no matter how it is configured—can ever operate beyond the limits of its creator’s legitimate authority.
## Understanding Token Types
Monime issues two distinct types of Personal Access Tokens (PATs), each designed for a specific stage of the development and operational lifecycle:
1. **Live Tokens (prefix: mon\_)** – These operate in the production environment, where real transactions and business operations occur. Every API call made with a live token directly interacts with production data—moving funds, updating balances, creating payouts, or triggering events with genuine business impact. Because of their direct link to real-world consequences, live tokens require strict access control, secure storage, and disciplined operational handling. They should only be issued to trusted integrations and must be treated as high-value credentials.
2. **Test Tokens (prefix: mon\_test\_)** – These are used exclusively in the sandbox environment, a fully functional replica of production that is completely isolated from live data. Test tokens allow developers to simulate transactions, explore API endpoints, and experiment with edge cases without risking operational systems. This sandbox environment mirrors production behavior, enabling teams to validate their logic, test error handling, and perfect their workflows before moving to live operations.
By separating token types and environments, Monime ensures that experimentation and learning remain safe and consequence-free, while production remains secure and controlled. This clear boundary is fundamental to reducing risk and maintaining both development agility and operational integrity.
## How Authentication Flows
When you make an API request to Monime, a multi-layered security process ensures that the request is both authentic and authorized before it touches any resource. This process begins the moment your request arrives with a Personal Access Token (PAT) in the Authorization header.
1. **Token structure validation** – The system first checks that the token matches Monime’s required format (including its prefix, such as mon\_ or mon\_test\_) and confirms that it exists in our database.
2. **Token status verification** – The system determines whether the token is still valid, ensuring it has not expired, been revoked, or been rendered inactive by policy changes.
3. **Identity resolution** – The system identifies the Monimeer who created the token, establishing the direct link between the request and the specific user account.
4. **Role and context retrieval** – It then determines the Monimeer’s current role and permissions in the relevant Space, ensuring the evaluation is based on the latest organizational context.
5. **Effective permissions calculation** – The system calculates the intersection between:
The token’s declared permission set (the scopes the token was created with).
The Monimeer’s permission set (the maximum authority the user has in that Space).
This ensures no token can exceed the authority of its creator, even if it was issued with broader scopes.
6. **Operation authorization** – Finally, the system verifies that the requested API operation falls within these effective permissions.
All of this happens in milliseconds, but the effect is significant: every API request is authenticated and authorized against the current permissions of the Monimeer, not just the permissions that existed at the time the token was created.
This guarantees real-time enforcement of access controls, even if roles or policies change.
## Security as a Continuous Process
Authentication security isn't achieved through a single mechanism but through multiple layers of protection working together.
Tokens are transmitted only over encrypted connections, rate limiting prevents abuse, and comprehensive audit logs track every authentication event.
Moreover, the permission intersection model means that security can be dynamically adjusted.
If a Monimeer's role changes, their tokens' effective permissions immediately reflect that change.
If a security issue is discovered, tokens can be revoked instantly, with the revocation taking effect immediately across all systems.
# Troubleshooting
Source: https://docs.monime.io/developer-resources/authentication/troubleshoot
Fix your problem
When authentication fails, the path from problem to solution isn't always obvious. A token that worked perfectly yesterday might fail today for reasons that aren't immediately apparent. This guide provides a systematic approach to diagnosing and resolving authentication issues, helping you move from confusion to clarity when things go wrong.
## Common Errors
### 401 Unauthorized – Token Not Validated
Occurs when we can’t recognize your token. This can happened due to one of the reasons:
1. **Expired token** – check the token's lifetime.
2. **Malformed token** – ensure the full string is sent with no extra spaces.
3. **Revoked token** – Check if token may have been disabled, deleted, or the associating Monimeer itself offboarded.
4. **Environment mismatch** – *mon\_* for production, *mon\_test\_* for sandbox.
### 403 Forbidden – Permission Intersection Failed
1. Token is valid but lacks permissions for the operation.
2. Check declared token permissions set at creation.
3. Check Monimeer’s role in the Space—role changes can reduce access.
Remember: `effective permissions = token permissions ∩ Monimeer’s role permissions`
4. Check if token was bounded to a different space than the one in context.
5. Check if IP whitelisting was configured for the token during creation.
### Network & Environment Issues
1. Verify connectivity to Monime endpoints.
2. Check TLS certificates, system clock, and DNS resolution.
3. Watch for proxy/firewall stripping `Authorization` or `Monime-Space-Id` headers.
4. In containerized environments, ensure secrets are mounted and networking is correct.
## When to Escalate
Contact Monime support or your Space admin if:
1. Standard troubleshooting fails.
2. The issue seems platform-side.
Most authentication problems are simple — expired tokens, wrong permissions, or misconfiguration. Check the basics first before diving deeper.
# Configuration
Source: https://docs.monime.io/developer-resources/integrations/wordpress/custom_plugin/configuration
Configure a custom adapter for Monime checkout and webhooks.
Your custom plugin should implement the Monime payment adapter interface, and optionally the webhook adapter interface if you need to update your own records.
The configuration you need depends on how much responsibility your plugin owns:
* If your plugin only creates payments, the payment adapter is enough.
* If your plugin also needs to update orders, donations, invoices, or membership records after payment, implement the webhook adapter too.
Monime's bootstrap file loads the shared contracts and services first, then boots the platform integrations, shared adapter service, and webhook handler. Because of that, your custom integration should register its adapter from the main plugin file so Monime can discover it during plugin boot.
## Payment Adapter
The payment adapter should provide:
* an adapter ID,
* a method for building the Monime payment payload,
* and optional payment options and metadata.
The adapter ID should be unique across your site so Monime can identify which integration created the payment.
### Payload Fields
The `CreateMonimePayload` object used by Monime includes the following fields:
| Field | Purpose |
| :------------------- | :-------------------------------------------------------------------- |
| `items` | The line items being paid for. |
| `idempotency_key` | A unique value that prevents duplicate payment creation. |
| `reference` | Your internal payment, order, or donation reference. |
| `name` | Checkout display name. |
| `description` | Text shown to the payer in checkout. |
| `cancelurl` | URL Monime should use when the payer cancels. |
| `success_url` | URL Monime should use after successful checkout. |
| `financialAccountId` | Optional settlement target inside Monime. |
| `currency` | The payment currency for the session. |
| `paymentOptions` | The channels and provider restrictions you want to send to Monime. |
| `metadata` | Extra application data you want to preserve through the payment flow. |
| `callbackState` | Optional state preserved for callback handling. |
### What These Fields Usually Represent
* **items:** what the customer is paying for.
* **idempotency key:** a unique value that prevents duplicate checkout session creation.
* **reference:** your internal payment or order reference.
* **name / description:** text shown to the donor or customer in checkout.
* **cancel URL / success URL:** where Monime should return the user after cancel or success.
* **financial account ID:** optional settlement target inside Monime.
* **currency:** the payment currency used for the checkout session.
* **payment options:** the channels and provider restrictions you want to send to Monime.
* **metadata:** any additional application data you want to carry through the payment flow.
* **callback state:** extra state you want returned or preserved for post-payment handling.
## Webhook Adapter
If your plugin needs to process Monime webhook events, implement the webhook handler as well.
This is where you convert a Monime payment event into your application's internal state update. For example, you might mark an invoice as paid, activate a membership, or mark a donation as complete.
## Registration
Register the adapter from your main plugin file before you create any checkout sessions. That is the safest place to load your adapter class and register it with Monime.
Example pattern:
```php theme={null}
Settings** for the shared credentials, then go to **GiveWP > Settings > Gateways > Monime** to configure the GiveWP-specific gateway options.
## Main Monime Settings
These credentials authenticate your site with the Monime API.
| Setting | Description | Where to find it |
| :------------ | :-------------------------------------- | :----------------------------------------------------------------------------------- |
| **API Token** | Your secret API Bearer token. | Monime Dashboard > **Developers** > **Access Tokens**. Create a new token if needed. |
| **Space ID** | The identifier for your business space. | Monime Dashboard > **Developers** > **Spaces**. It starts with the prefix `spc`. |
Keep your API Token secret. Never share it or expose it in frontend code.
## Webhooks Setup
Webhooks are **required** for this plugin to work correctly. They ensure your site receives payment confirmations even if the donor closes their browser immediately after paying.
1. **Copy the Webhook URL:**
In the plugin settings, locate the **Webhook URL** field and copy it. It will look like `https://your-site.com/wp-json/monime/v1/webhook`.
2. **Configure in Monime:**
* Log in to the [Monime Dashboard](https://my.monime.io).
* Open the desired Space you want webhook events for.
* Navigate to **Developer > Webhooks**.
* Click **Create Webhook**.
* Paste your URL into the **Endpoint URL** field.
* Select the following **Events**:
* `checkout_session.completed`
* `checkout_session.expired`
* `checkout_session.cancelled`
* Create the webhook.
3. **Set the Webhook Secret (Recommended):**
* When creating the webhook, copy the **Generated HMAC Secret** or, if you are using **ECDSA P-256**, copy the **Public Key** after the webhook is created by clicking the Actions dropdown and then View Public Key.
* Paste the secret into the **Webhook Secret** field in the Monime GiveWP plugin settings.
* This ensures that incoming webhooks actually come from Monime.
## GiveWP Gateway Settings
The plugin maps these settings directly to the `paymentOptions` object sent to the [Checkout Session API](/apis/versions/caph-2025-08-23/checkout-session/create-checkout-session).
### Gateway Details
| Setting | Description |
| :----------------------- | :--------------------------------------------------------------------------------------------- |
| **Gateway Title** | The label donors see at checkout, such as `Monime` or `Pay with Monime`. |
| **Gateway Description** | Short text that explains the payment method to donors. |
| **Financial Account ID** | Optional. Use this when you want donations to settle into a specific Monime financial account. |
### Channel Control
You can completely disable specific payment channels.
| Setting | Effect |
| :-------------------------- | :------------------------------------------------------------------- |
| **Disable Card Payments** | Hides the card option. |
| **Disable Mobile Money** | Hides all mobile money providers such as Orange Money and AfriMoney. |
| **Disable Bank Transfers** | Hides the bank transfer option. |
| **Disable Digital Wallets** | Hides digital wallet options. |
### Provider Control
For finer control, you can enable or disable specific providers within a channel.
You configure this by entering **Provider IDs** as comma-separated values.
**Logic:** If an allow list is set, only those providers are shown. If the allow list is empty, all providers are shown except those listed in the disable list.
#### Mobile Money Providers
| Setting | Description |
| :--------------------- | :---------------------------------------------------- |
| **Allowed Providers** | List IDs to explicitly allow, for example `m17, m18`. |
| **Disabled Providers** | List IDs to explicitly block. |
#### Bank Providers
| Setting | Description |
| :--------------------- | :---------------------------------------------------------- |
| **Allowed Providers** | List IDs to explicitly allow, for example `slb001, slb003`. |
| **Disabled Providers** | List IDs to explicitly block. |
#### Wallet Providers
| Setting | Description |
| :--------------------- | :---------------------------- |
| **Allowed Providers** | List IDs to explicitly allow. |
| **Disabled Providers** | List IDs to explicitly block. |
### Common Provider IDs
| Provider | ID | Type |
| :------------------------------- | :------- | :----------- |
| **Orange Money** | `m17` | Mobile Money |
| **AfriMoney** | `m18` | Mobile Money |
| **QMoney** | `m13` | Mobile Money |
| **Sierra Leone Commercial Bank** | `slb001` | Bank |
| **Rokel Commercial Bank** | `slb002` | Bank |
| **Ecobank** | `slb003` | Bank |
| **Guaranty Trust Bank** | `slb004` | Bank |
| **UBA** | `slb005` | Bank |
*Note: This list may change. Check the Monime Dashboard or API documentation for the most up-to-date provider IDs.*
## Configuration Checklist
Before you start accepting live donations, confirm the following:
1. Main Monime settings are saved.
2. GiveWP gateway settings are saved.
3. The webhook endpoint is configured in Monime.
4. The webhook secret matches on both sides.
5. At least one payment channel is enabled.
# Installation
Source: https://docs.monime.io/developer-resources/integrations/wordpress/givewp/installation
Install the Monime GiveWP integration and prepare GiveWP.
## Installation Steps
You can install the Monime WordPress plugin by uploading the zip file directly to your WordPress admin dashboard.
### 1. Download the Plugin
Download the latest version of the plugin from the [main WordPress overview](../overview).
### 2. Upload to WordPress
1. Log in to your WordPress Admin Dashboard (for example, `your-site.com/wp-admin`).
2. Navigate to **Plugins > Add New**.
3. Click the **Upload Plugin** button at the top of the screen.
4. Click **Choose File** and select the ZIP file you downloaded from the main overview.
5. Click **Install Now**.
### 3. Activate the Plugin
1. Once the installation is complete, click **Activate Plugin**.
2. You should now see **Monime Gateway** listed on your plugins page.
### 4. Install GiveWP
1. Install and activate **GiveWP** if it is not already available on your site.
2. Confirm that the GiveWP admin menus and donation form settings are visible.
### 5. Verify Installation
1. Go to the Monime settings page in WordPress admin.
2. Confirm that the main Monime credentials are saved.
3. Open the GiveWP payment gateway settings.
4. Confirm that **Monime** appears as an available gateway.
5. Open a test donation form and verify that Monime is selectable at checkout.
If Monime does not appear, usually one of three things is missing:
* the Monime Gateway plugin is inactive,
* GiveWP is inactive,
* or the shared Monime credentials have not been saved yet.
## Updates
To update the plugin in the future:
1. Download the new version from the [main WordPress overview](../overview).
2. Go to **Plugins > Add New > Upload Plugin**.
3. Upload the new zip file.
4. WordPress will ask if you want to replace the existing version. Click **Replace current with uploaded**.
# Overview
Source: https://docs.monime.io/developer-resources/integrations/wordpress/givewp/overview
Introduction to the Monime GiveWP integration.
The **Monime WordPress** plugin includes a GiveWP adapter for donation flows. It lets donors complete payments through Monime's hosted checkout while keeping donation records and form management inside GiveWP.
In practice, GiveWP remains the system where you manage donation forms, donor records, and donation statuses. Monime handles the payment step itself by creating a hosted checkout session, redirecting the donor to Monime, then returning the donor to your WordPress site after payment.
The GiveWP integration uses Monime's [Checkout Session API](/apis/versions/caph-2025-08-23/checkout-session/object) to create and track each payment session. That gives you a hosted checkout flow instead of handling card or mobile money entry directly on your WordPress site.
## Key Features
* **Hosted Checkout:** Redirects donors to a secure Monime payment page, reducing the amount of payment data handled by your WordPress site.
* **Donation-First Flow:** GiveWP stays responsible for donation forms, donor records, and donation status management.
* **Channel Support:** Accept cards, mobile money, bank transfers, and digital wallets.
* **Provider Controls:** Allow or block specific payment providers for finer routing control.
* **Webhook Status Updates:** Donation completion is confirmed through Monime webhooks, not just the browser redirect.
* **Optional Financial Routing:** Route donation settlement to a specific Monime financial account if needed.
* **One-Time Donations:** Built for standard GiveWP donation flows.
* **Shared Credentials:** Uses the main Monime settings page for API credentials and webhook configuration.
## Requirements
* **WordPress:** 6.2 or higher
* **GiveWP:** Installed and active
* **PHP:** 7.4 or higher
* **Monime Account:** A business account with an active Space, API token, and webhook secret
* **Monime Gateway:** Installed and active so the GiveWP adapter can register itself
You also need to be able to configure inbound webhooks from Monime to your site. If your WordPress installation is behind a firewall, security plugin, or local-only environment, webhook delivery may fail until the endpoint is publicly reachable.
## How It Works
1. A donor opens a GiveWP donation form and selects **Monime** as the payment method.
2. GiveWP passes the donation details to the Monime adapter.
3. The adapter creates a Monime checkout session.
4. The donor is redirected to Monime's hosted checkout page.
5. The donor completes payment using the providers you enabled.
6. Monime returns the donor to your site after checkout.
7. Monime sends a webhook to confirm the donation and update the GiveWP record.
This split is important: the redirect gives the donor a smooth checkout experience, but the webhook is what makes payment confirmation reliable.
## When To Use It
Use the GiveWP integration when you need to:
* collect one-time donations,
* keep donation management inside GiveWP,
* accept payments through multiple Monime channels,
* or settle donations into a specific Monime financial account.
If you are building a custom donation or fundraising flow outside GiveWP, use the custom plugin integration instead.
# Troubleshooting
Source: https://docs.monime.io/developer-resources/integrations/wordpress/givewp/troubleshooting
Common GiveWP and Monime issues and fixes.
If you encounter issues with the Monime GiveWP integration, check the following common problems and solutions.
## Common Issues
### "Payment gateway not configured"
**Symptom:** Donors see an error message when trying to pay.
**Cause:** The shared Monime credentials are missing or incorrect in the main Monime settings.
**Solution:**
1. Go to **Monime > Settings**.
2. Verify that both the **API Token** and **Space ID** are filled in.
3. Save the settings again and reload the GiveWP payment page.
### Monime does not appear in GiveWP
**Symptom:** Monime is missing from the list of available donation gateways.
**Cause:** The Monime Gateway plugin, GiveWP, or both are inactive, or the shared settings have not been saved.
**Solution:**
1. Confirm that **Monime Gateway** is active.
2. Confirm that **GiveWP** is installed and active.
3. Verify that the main Monime credentials are saved.
4. Refresh the GiveWP settings page after saving.
If the gateway still does not appear, confirm that no plugin conflict is preventing GiveWP from loading its payment gateway extensions.
### Donations remain pending
**Symptom:** A donor paid, but the donation still shows as pending.
**Cause:** Your site is not receiving or processing webhooks correctly.
**Solution:**
1. Check that the webhook URL is configured in Monime exactly as shown in the plugin settings.
2. Ensure your website is publicly reachable. Webhooks cannot reach `localhost` or password-protected sites.
3. Check whether a firewall or security plugin is blocking the `/wp-json/monime/v1/webhook` route.
### "Invalid Signature" in logs
**Symptom:** The donation does not update and the webhook is rejected.
**Cause:** The Webhook Secret in WordPress does not match the webhook secret configured in Monime.
**Solution:**
1. Copy the signing secret again from the Monime Dashboard.
2. Update the **Webhook Secret** field in Monime settings.
3. Save the settings and test the webhook again.
### Donor is redirected to a 404 page or back to the cart
**Symptom:** After clicking pay, the donor lands on a 404 page or is sent back to the cart.
**Cause:** Permalink settings or a redirect conflict is interfering with the offsite return flow.
**Solution:**
1. Go to **Settings > Permalinks** in WordPress and click **Save Changes** to flush rewrite rules.
2. Confirm that the donation form and success/failed pages exist.
3. Check for redirects introduced by caching, security, or page builder plugins.
## Debugging Tips
If a donation does not complete cleanly, check the following in order:
1. WordPress debug logs or PHP error logs.
2. Monime webhook delivery status.
3. The donation record inside GiveWP.
4. The browser return URL the donor received after payment.
## Support
If you cannot resolve the issue, contact Monime support.
* **Email:** [support@monime.io](mailto:support@monime.io)
* **Developer Docs:** [https://docs.monime.io](https://docs.monime.io)
When contacting support, include:
1. Your **Space ID**.
2. The donation reference or session ID.
3. The exact time the payment was attempted.
4. A copy of any relevant logs or webhook payloads.
# Usage
Source: https://docs.monime.io/developer-resources/integrations/wordpress/givewp/usage
How donors complete a Monime-backed GiveWP donation.
## Donation Flow
1. A donor fills out a GiveWP donation form.
2. The donor selects **Monime** as the payment method.
3. GiveWP creates a Monime checkout session using the donation details.
4. The donor is redirected to Monime checkout.
5. The donor completes the payment using the payment channels you enabled.
6. After payment, the donor returns to the site.
7. Monime sends a webhook to confirm the donation.
The redirect handles the user experience, while the webhook confirms the actual payment result. You should rely on the webhook, not only on the browser return, when deciding whether a donation is complete.
## Donation Statuses
| Status | Meaning |
| :------------ | :----------------------------------------------------------------------------- |
| **Pending** | The checkout session was created, but payment is not yet confirmed. |
| **Complete** | The payment was successful and the webhook confirmed it. |
| **Failed** | The donor cancelled the payment or the checkout did not complete successfully. |
| **Abandoned** | The checkout session expired before payment was completed. |
| **Cancelled** | The donor explicitly cancelled the payment on Monime. |
Depending on your GiveWP configuration, some donations may move from Complete to a final processed state inside GiveWP after Monime confirms the payment.
## Admin Management
### Viewing Donation Details
When viewing a donation inside GiveWP, check the donation notes and payment metadata for Monime references.
Useful details include:
* the Monime session or reference ID,
* the donation amount,
* the final status returned from the webhook,
* and any Monime payload stored for debugging.
### Refunds
Refunds are not yet supported directly within GiveWP.
To refund a payment:
1. Log in to your [Monime Dashboard](https://my.monime.io).
2. Locate the transaction using the Monime reference found in the donation details.
3. Process the refund from the Monime Dashboard.
4. Update the donation record manually in GiveWP if you need your records to show the refund.
### Logging and Debugging
The GiveWP integration stores useful payment metadata and webhook payloads on the donation record. Use those details, along with your WordPress and PHP logs, when troubleshooting.
If a donor says they paid but the donation still shows as pending, check the webhook delivery first. In most cases, the browser return already happened, but the payment confirmation was never received by WordPress.
# Monime for WordPress
Source: https://docs.monime.io/developer-resources/integrations/wordpress/overview
Official WordPress integrations for accepting payments with Monime.
# Monime WordPress Plugin
Monime provides official WordPress integrations that allow businesses, nonprofits, and developers to securely accept payments using Monime’s payment infrastructure.
By default, the plugin ships with official support for:
* WooCommerce
* GiveWP
Download the latest version of the Monime WordPress package from [here](https://github.com/monimesl/Wp-Monime/archive/refs/heads/main.zip).
### Custom Integrations
In addition to the officially supported integrations, developers can extend Monime to work with custom WordPress plugins, themes, and applications.
Monime’s flexible architecture makes it possible to integrate payment functionality into virtually any WordPress-based workflow or platform.
Common integration scenarios include:
* Membership and subscription platforms
* Learning management systems (LMS)
* Event registration and ticketing systems
* Donation and fundraising platforms
* Marketplace and multi-vendor solutions
* Custom eCommerce experiences
* Internal business tools and portals
Developers can integrate Monime payment flows directly into their applications while using webhooks for secure payment confirmation and automated status updates.
### Requirements
* WordPress 6.2 or higher
* PHP 7.4 or higher
* Monime Token
* Monime Space Id
# Configuration
Source: https://docs.monime.io/developer-resources/integrations/wordpress/woocommerce/configuration
Configure API credentials, webhooks, and payment options.
After activating the plugin, you must configure it to connect with your Monime account. Go to **WooCommerce > Settings > Payments > Monime WooCommerce** to access these settings.
## API Credentials
These credentials authenticate your store with the Monime API.
| Setting | Description | Where to find it |
| :------------ | :-------------------------------------- | :---------------------------------------------------------------------------------------------------- |
| **API Token** | Your secret API Bearer token. | Monime Dashboard > \*\*Developers \*\*>**Access Tokens** . Create a new token if you haven't already. |
| **Space ID** | The identifier for your business space. | Monime Dashboard > **Developers** > **Spaces**. It is starts with the prefix `spc` |
Keep your API Token secret. Never share it or expose it in frontend code.
## Webhooks Setup
Webhooks are **required** for this plugin to work correctly. They ensure your store receives payment confirmations even if the customer closes their browser immediately after paying.
1. **Copy the Webhook URL:**
In the plugin settings, locate the **Webhook URL** field (e.g., `https://your-site.com/wp-json/monime/v1/webhook`) and copy it.
2. **Configure in Monime:**
* Log in to the [Monime Dashboard](https://my.monime.io).
* Open the desired Space you wish to get webhook events for.
* Navigate to **Developer > Webhooks**.
* Click **Create Webhook**.
* Paste your URL into the **Endpoint URL** field.
* Select the following **Events**:
* `checkout_session.completed`
* `checkout_session.expired`
* `checkout_session.cancelled`
* Create the webhook.
3. **Set the Webhook Secret (Recommended):**
* When creating the webhook, copy the **Generated HMAC Secret** or if you are using **ECDSA P-256**, copy the **Public Key** after the webhook is created by clicking the Actions dropdown and then View Public Key.
* Paste the secret(HMAC or ECDSA Public Key) into the **Webhook Secret** field in the Monime WooCommerce plugin settings.
* This ensures that incoming webhooks actually come from Monime.
## Payment Options Configuration
You can control which payment methods are available to your customers. The plugin maps these settings directly to the `paymentOptions` object sent to the [Checkout Session API](/apis/versions/caph-2025-08-23/checkout-session/create-checkout-session).
### Channel Control
You can completely disable specific payment channels.
| Setting | Effect |
| :-------------------------- | :---------------------------------------------------------- |
| **Disable Card Payments** | Hides the Credit/Debit Card option. |
| **Disable Mobile Money** | Hides all Mobile Money providers (Orange, AfriMoney, etc.). |
| **Disable Bank Transfers** | Hides the Bank Transfer option. |
| **Disable Digital Wallets** | Hides digital wallet options. |
### Provider Control
For finer control, you can enable or disable specific providers within a channel (e.g., accept Orange Money but not AfriMoney).
You configure this by entering **Provider IDs** (comma-separated).
**Logic:** If "Enable Providers" is set, **only** those providers will be shown. If it is empty, all providers are shown **except** those listed in "Disable Providers".
#### Mobile Money Providers
| Setting | Description |
| :-------------------- | :----------------------------------------------- |
| **Enable Providers** | List IDs to explicitly allow (e.g., `m17, m18`). |
| **Disable Providers** | List IDs to explicitly block. |
#### Bank Providers
| Setting | Description |
| :-------------------- | :----------------------------------------------------- |
| **Enable Providers** | List IDs to explicitly allow (e.g., `slb001, slb003`). |
| **Disable Providers** | List IDs to explicitly block. |
#### Wallet Providers
| Setting | Description |
| :-------------------- | :---------------------------- |
| **Enable Providers** | List IDs to explicitly allow. |
| **Disable Providers** | List IDs to explicitly block. |
### Common Provider IDs
| Provider | ID | Type |
| :------------------------------- | :------- | :----------- |
| **Orange Money** | `m17` | Mobile Money |
| **AfriMoney** | `m18` | Mobile Money |
| **QMoney** | `m13` | Mobile Money |
| **Sierra Leone Commercial Bank** | `slb001` | Bank |
| **Rokel Commercial Bank** | `slb002` | Bank |
| **Ecobank** | `slb003` | Bank |
| **Guaranty Trust Bank** | `slb004` | Bank |
| **UBA** | `slb005` | Bank |
*Note: This list may change. Check the Monime Dashboard or API documentation for the most up-to-date provider IDs.*
# Installation
Source: https://docs.monime.io/developer-resources/integrations/wordpress/woocommerce/installation
Install the Monime Woocommerce integration and prepare Woocommerce
## Installation Steps
You can install the Monime Wordpress plugin by uploading the zip file directly to your WordPress admin dashboard.
### 1. Download the Plugin
Download the latest version of the plugin from the [main WordPress overview](../overview).
### 2. Upload to WordPress
1. Log in to your WordPress Admin Dashboard (e.g., `your-site.com/wp-admin`).
2. Navigate to **Plugins > Add New**.
3. Click the **Upload Plugin** button at the top of the screen.
4. Click **Choose File** and select the ZIP file you downloaded from the main overview.
5. Click **Install Now**.
### 3. Activate the Plugin
1. Once the installation is complete, click **Activate Plugin**.
2. You should now see **MonimeGateway** listed in your plugins page.
### 4. Verify Installation
1. Go to **WooCommerce > Settings > Payments**.
2. You should see **Monime** listed as a payment method.
3. Click the toggle to **Enable** the gateway (you will need to configure it first).
## Updates
To update the plugin in the future:
1. Download the new version from the [main WordPress overview](../overview).
2. Go to **Plugins > Add New > Upload Plugin**.
3. Upload the new zip file.
4. WordPress will ask if you want to replace the existing version. Click **Replace current with uploaded**.
# Overview
Source: https://docs.monime.io/developer-resources/integrations/wordpress/woocommerce/overview
Introduction to the Monime WooCommerce plugin.
The **Monime Wordpress** plugin allows store owners in Sierra Leone (and other supported regions) to accept payments directly through their WooCommerce store using Monime's payment infrastructure.
It leverages Monime's [Checkout Session API](/apis/versions/caph-2025-08-23/checkout-session/object) to provide a secure, hosted payment experience.
## Key Features
* **Hosted Checkout:** Redirects customers to a secure Monime payment page, reducing PCI compliance scope.
* **Broad Payment Support:** Accept payments via:
* **Mobile Money:** Orange Money, AfriMoney, etc.
* **Cards:** Visa, Mastercard.
* **Bank Transfers:** Direct bank integrations (e.g., SLCB).
* **Digital Wallets:** Supported wallet providers.
* **HPOS Compatible:** Fully supports WooCommerce High-Performance Order Storage (HPOS).
* **Block Theme Support:** Integrated with WooCommerce Cart & Checkout Blocks.
* **Granular Control:** Configure exactly which payment providers are available to your customers.
* **Automated Statuses:** Uses webhooks to automatically update order statuses (Pending -> Processing/Failed).
## How It Works
1. **Checkout:** When a customer chooses "Monime" at your store, an order is created with `Pending Payment` status.
2. **Redirect:** The plugin creates a Monime Checkout Session and redirects the customer to the secure payment page.
3. **Payment:** The customer completes the payment using their preferred method.
4. **Confirmation:** Monime redirects the customer back to your "Order Received" page.
5. **Webhook:** Simultaneously, Monime sends a secure webhook to your server to confirm the payment and update the order status.
## Requirements
* **WordPress:** 6.2 or higher
* **WooCommerce:** 8.2 or higher
* **PHP:** 7.4 or higher
* **Monime Account:** A business account with an active Space.
# Troubleshooting
Source: https://docs.monime.io/developer-resources/integrations/wordpress/woocommerce/troubleshooting
Common issues and solutions for the Monime WooCommerce plugin.
If you encounter issues with the Monime WooCommerce plugin, check the following common problems and solutions.
## Common Issues
### "Payment gateway not configured"
**Symptom:** Customers see an error message when trying to pay.
**Cause:** The **API Token** or **Space ID** is missing or incorrect in the plugin settings.
**Solution:**
1. Go to **WooCommerce > Settings > Payments > Monime WooCommerce**.
2. Verify that both fields are filled.
3. Ensure you copied the correct **Space ID** from your Monime Dashboard.
### Orders remain "Pending Payment"
**Symptom:** Customers have paid, and money has left their account, but the WooCommerce order status stays "Pending Payment".
**Cause:** Your website is not receiving or processing **Webhooks** correctly.
**Solution:**
1. Check that you configured the **Webhook URL** in the Monime Dashboard exactly as shown in the plugin settings.
2. Ensure your website is publicly accessible (webhooks cannot reach `localhost` or password-protected sites).
3. Check if you have a security plugin (like Wordfence) blocking incoming REST API requests. Whitelist the `/wp-json/monime/v1/webhook` route.
### "Invalid Signature" in Logs
**Symptom:** You see "Invalid webhook signature" in the logs, and orders don't update.
**Cause:** The **Webhook Secret** in your plugin settings does not match the **Signing Secret** of the webhook in the Monime Dashboard.
**Solution:**
1. Copy the Signing Secret again from the Monime Dashboard.
2. Update the **Webhook Secret** field in WooCommerce.
3. Alternatively, clear the field in WooCommerce to disable signature verification (not recommended for production).
### Checkout Page 404 or Redirect Loop
**Symptom:** When clicking "Place Order", the user is redirected to a 404 page or back to the cart.
**Cause:** Permalink settings issues or API communication failure.
**Solution:**
1. Go to **Settings > Permalinks** in WordPress and click **Save Changes** to flush rewrite rules.
2. Check the **WooCommerce Logs** (`WooCommerce > Status > Logs > monime-woocommerce-...`) for API error messages.
## Support
If you cannot resolve the issue, please contact Monime support.
* **Email:** [support@monime.io](mailto:support@monime.io)
* **Developer Docs:** [https://docs.monime.io](https://docs.monime.io)
When contacting support, please provide:
1. Your **Space ID**.
2. The **Session ID** of a failed transaction (if available in the order notes).
3. A copy of the relevant logs from **WooCommerce > Status > Logs**.
# Usage & Order Management
Source: https://docs.monime.io/developer-resources/integrations/wordpress/woocommerce/usage
Understanding the payment flow and managing orders in WooCommerce with Monime Payment Gateway.
## The Customer Experience
1. **Checkout:** The customer proceeds to checkout and selects **Monime Checkout**.
2. **Redirection:** Upon clicking "Place Order", they are redirected to `https://checkout.monime.io/...`.
3. **Payment:** They choose their preferred payment method (Mobile Money, Card, etc.) and complete the transaction.
4. **Return:** After success, they are redirected back to your store's "Order Received" (Thank You) page.
## Order Statuses
The plugin automatically manages order statuses based on the payment lifecycle.
| Status | Meaning |
| :------------------ | :-------------------------------------------------------------------------------------------------------- |
| **Pending Payment** | The order has been created, and the user has been redirected to Monime. The payment is not yet confirmed. |
| **Processing** | Payment was **successful**. The webhook was received and verified. You can now fulfill the order. |
| **Failed** | The payment failed, or the checkout session expired (usually after 30 minutes of inactivity). |
| **Cancelled** | The user explicitly clicked "Cancel" on the Monime checkout page. |
If your products are strictly **Virtual** and **Downloadable**, WooCommerce may automatically move the order from "Processing" to **Completed** depending on your store settings.
## Admin Management
### Viewing Payment Details
When viewing a single order in **WooCommerce > Orders**, you will see a **Monime Payment Details** box in the sidebar (or below the order details).
It provides:
* **Session ID:** The unique ID for the checkout session (useful for support).
* **Monime Order #:** The transaction reference number from the Monime system.
### Refunds
**Refunds are not yet supported directly within WooCommerce.**
To refund a payment:
1. Log in to your [Monime Dashboard](https://my.monime.io).
2. Locate the transaction using the **Monime Order #** found in the WooCommerce order details.
3. Process the refund from the Monime Dashboard.
4. Manually mark the order as "Refunded" in WooCommerce to keep your records in sync.
### Logging
The plugin logs important events and errors to the WooCommerce logging system. This is useful for debugging.
1. Go to **WooCommerce > Status > Logs**.
2. Select `monime-woocommerce-...` from the dropdown.
3. Click **View**.
# Concepts
Source: https://docs.monime.io/get-started/concepts
Learn Monime's core conceptual model
## Space — The Organizational Boudary
A **Space** is the foundational unit of isolation in the Monime ecosystem. It represents an organizational entity — a business, a company, a merchant, a platform, government institution or NGO — and everything associated with its payment operations and financial identity.
#### Key Characteristics:
* **Isolation by Design:** Every resource (payment, transfer, customer, financial account) is scoped to a single Space. No data leaks or overlaps across Spaces.
* **Namespace and Environment Boundaries:** Each Space can have environments (like test and live) for safe development and deployment workflows.
* **Operational Identity:** All configurations, policies, and memberships are defined within the scope of a Space.
* **Segregated Ledgers:** Fund tracking, settlement, and balances are kept separate across Spaces. This is crucial for legal, financial, and operational clarity.
Think of a Space as the “tenant” in Monime’s multi-tenant architecture.
## Monimeer — The Personal Identity
A **Monimeer** is a user account — a developer, operator, or finance personnel. Unlike Spaces, Monimeers are personal and global across Monime.
#### Key Characteristics:
* **Cross-Space Access:** A Monimeer can be a member of multiple Spaces with different roles.
* **Personal Tokens:** Monimeer access via APIs is authenticated with Personal Access Tokens (PATs), which carry permissions.
* **Role-Scoped Authorization:** Monime implements a dual-layer permission system that controls what actions a Monimeer can perform within a Space:
1. **Dashboard Access:** What a Monimeer can do via the dashboard is determined solely by the roles (permission sets) assigned to the Monimeer in that Space
2. **API Access:** What a Monimeer can do via the API is determined by the intersection of:
* The Monimeer's roles (permission sets) in the Space, (dashboard access)
* and, the specific roles (permission sets) assigned to the access token they create.
This means API access tokens can never exceed the permissions of their creator but can be scoped down for security.
For example, if a Monimeer has full `transfer` management rights in the dashboard, they can create an API token with read-only `transfer` access, but cannot create a token with `webhook` management if they lack that dashboard role.
This model separates who the user is (Monimeer) from what organization they are operating in (Space) — enabling powerful collaboration scenarios.
## Financial Account — The Value Container
A Financial Account in Monime is an internal ledger abstraction representing where money is held, routed, or reconciled.
It is the heart of Monime's Money Management for a Space. Every financial operation in a Space, be it payment, disbursement,
internal transfer e.t.c, is scoped to a financial account.
#### Key Characteristics:
* **Currency Bounded:** Holds money in a specific currency
* **Space Scoped:** Operates within a Space's secure boundaries
* **Real-time:** Provides real-time point-in-time and historical view of its balance.
* **Unit Financial Transparency:** Tracks every fund movement with complete transparency
* **Deeply Programmatic:** Supports programmatic control though APIs.
Financial accounts abstract away the complexities of real bank accounts while remaining tightly modeled to
real-world money flow.
## Ownership Graph — Resource Genealogy
This provides a complete genealogy for every created financial resource, creating an immutable chain of relationships that traces back to the originating object.
An Ownership Graph is a hierarchical data structure that captures the complete lineage of any object in Monime. It answers critical questions like:
* **What triggered this transaction?**
* **Who initiated the original action?**
* **What was the business context?**
* **How did we get here?**
**Basic Structure**
```json theme={null}
{
"ownershipGraph": {
"owner": {
"id": "pmt-k6Em1Aap25VZ8oWg7ajhxHX3JqF",
"type": "payment",
"metadata": {
"channel": "momo",
"provider": "m17"
},
"owner": {
"id": "sps-k6Em1aAap254VXg6fhxk9HX3JqF",
"type": "checkout_session",
"metadata": {
"orderId": "ord-3n4o5p6q7r8s"
},
"owner": {
"id": "arq-k6Em12r5VZ8oW9r9Xh7xsH3J4qF",
"type": "api_request",
"metadata": {
"endpoint": "/v1/checkout-sessions",
"subjectId": "acc-k6Em15VsZ8go5W9lX2h7dxsJ4qF",
"ipAddress": "192.168.1.100"
}
}
}
}
}
}
```
```
Payment Code
└── Payment (when someone pays)
└── Financial Transaction (when payment is process)
└── Fee Transaction (when you takes your service fee)
```
## Next steps
Step-by-step instructions to help you navigate and use your dashboard effectively.
Tools, documentation, and references to support your development work.
# Welcome
Source: https://docs.monime.io/get-started/index
Monime is a business-first payment orchestration platform that unifies Sierra Leone’s diverse payment
channels — Mobile Money, Cards, Banks, and Digital Wallets — into a single, standardized programmable interface.
Get setup and start running with Monime in no-time. ⚡️
Read Monime concepts and examples so you will get speed up 📚.
Explore the full suite of API resources available at your disposal. 👨💻
## Join our Community
Source codes for all our open-source libraries, SDKs and platform plugins.
Discover the technical stories and insights from the team building Monime's infrastructure.
Connect with our developer community, find more possibilities, and see how people are using us.
# Learn More
Source: https://docs.monime.io/get-started/overview
Monime - How It Works, and How to Get Started?
## How Monime Works?
Monime is a single gateway to accept payments from anywhere—connecting your business to both local payment systems and international payment methods through unified, simple integration.
## How may it work for you?
1. **You integrate once** — Connect your business to Monime's API (no need to integrate with dozens of payment providers separately)
2. **Customer pays their way** — Whether your customer is:
* Local: Using Mobile Money, Digital Wallets, and Banks
* International: Paying with Visa, Mastercard, Apple Pay, Google Pay
3. **Monime handles everything** — The platform automatically:
* Routes payout to the optimal provider (between SAPS and direct provider)
* Handles failures with automatic retries
* Standardizes all responses into one consistent format
4. **You get unified operations** — One dashboard for:
* Real-time payment notifications (whether from Mobile Money or Visa card)
* Combined reconciliation across all channels
* Single settlement process
* Unified reporting for accounting
[//]: # "## Spaces — Multi-Tenancy Reimagined"
[//]: # "At the heart of Monime’s architecture is a uniquely expressive and secure multi-tenant model built around the concept of __Spaces__."
[//]: # "To us, it is the digital boundary that encapsulates the entire operational identity of an organization:"
[//]: # "its payment infrastructure, financial operations, access policies, team roles,"
[//]: # "and real-time event streams all into one secure, programmable environment."
[//]: #
[//]: # "But what makes this model truly powerful is how we deliberately decouple the individual — called a __monimeer__ — from the business entity they operate within."
[//]: # "A monimeer is a personal user account that exists independently of any specific organization or Space."
[//]: # "This abstraction allows the same developer, finance operator, or admin to participate in multiple Spaces, each with its own isolated set of roles, permissions, and access scopes."
[//]: #
[//]: # "This design unlocks flexible and secure collaboration, enabling scenarios such as:"
[//]: #
[//]: # "* Developers working across multiple products or clients,"
[//]: #
[//]: # "* Agencies managing several businesses under one login,"
[//]: #
[//]: # "* Finance teams overseeing subsidiaries or business units."
[//]: #
[//]: # "By cleanly separating personal identity from organizational context, we prevent cross-organization data entanglement, simplify access control, and ensure that every action is executed strictly within the scope of a Space and in the context of the acting Monimeer."
[//]: #
[//]: # "Within each Space:"
[//]: #
[//]: # "* Access is role-based, scoped specifically to that Space."
[//]: #
[//]: # "* Personal Access Tokens (PATs) issued by Monimeers inherit only the permissions granted to them in that space."
[//]: #
[//]: # "* All resources — accounts, transactions, and permissions — are strictly sandboxed within their Space, ensuring zero leakage across tenants."
[//]: #
[//]: #
[//]: # "This separation of individual from organization gives businesses:"
[//]: #
[//]: # "* Clear ownership boundaries across teams and external collaborators."
[//]: #
[//]: # "* Scalable developer onboarding without risk to internal operations."
[//]: #
[//]: # "* Fine-grained permissioning that reflects real-world business structure."
[//]: #
[//]: # "This inversion of control is what makes Monime not just multi-tenant, but multi-organization, multi-team, and multi-use-case by design."
# Create checkout session
Source: https://docs.monime.io/guide/checkout-session/create-checkout-session
# Overview
Source: https://docs.monime.io/guide/checkout-session/index
Overview of Monime Checkout Sessions and how to use them
A Checkout Session is a short-lived object that creates a hosted checkout page for collecting payments on your behalf. Use it to accept payments quickly without building your own payment UI. You control what the customer is paying for, the amount, allowed payment methods, and where to return the customer after payment.
## When to use Checkout Session
* You want a fast, secure way to accept payments with minimal UI work
* You need a hosted page that supports multiple payment methods out-of-the-box
* You want Monime to handle payment state, redirection, and receipt UI
## How it works
Your server calls the API to create a session with amount, currency, and options.
Redirect the customer to the hosted checkout URL returned in the session.
The customer completes payment on Monime's secure page.
Receive payment status via webhook and/or redirect back to your site.
## Quick start
Create a new checkout session from your backend
Look up a session to check its latest status
Browse sessions for reporting or debugging
## Key session fields
Total amount to be collected. Define in the smallest currency unit when applicable.
The currency for the payment (e.g., SLE). Must be supported by selected methods.
Allowed payment methods for the checkout (e.g., mobile money, bank, card).
Where customers are redirected after a successful payment or when they cancel.
Optional key/value pairs you can use to store order identifiers or context.
## Webhooks
We recommend handling payment lifecycle events using webhooks to ensure your system is updated even if the customer closes the browser before redirecting.
Learn how webhooks work on Monime
Verify webhook signatures securely
## Environments: Test vs Live
Use Test mode for development and Live for production. Tokens, behavior, and prefixes differ between environments.
See API Basics → Environments and
Standard Headers for details.
## Next steps
End-to-end example using Next.js API routes
Explore the Checkout Session object and full API
# Create Checkout Session (Next.js App Router)
Source: https://docs.monime.io/guide/checkout-session/nextjs-app-router
Step-by-step guide to implement a Checkout Session endpoint using the Next.js App Router API routes
## Overview
This guide shows how to build a Next.js App Router API route that creates a Checkout Session and returns a `redirectUrl` to send your customer to Monime's hosted checkout.
Base URL: `https://api.monime.io` · Auth: Bearer token · Required headers: `Monime-Space-Id`, `Idempotency-Key`
## Prerequisites
* Access Token (server-side) and Space ID
* Create tokens:
Personal Access Tokens
* Find your Space ID:
Create a Monime Space
(see Developer section → Space list)
* Next.js 13+ with the App Router
### Environment variables
Create `.env.local`:
```bash theme={null}
MONIME_ACCESS_TOKEN=mon_test_xxxxxxxxxxxxxxxxxxxxxxxxx
MONIME_SPACE_ID=spc-xxxxxxxxxxxxxxxx
```
Never expose tokens in the browser.
## Implement the API route
Create `app/api/checkout/route.ts`:
```ts theme={null}
import { randomUUID } from 'crypto'
type LineItem = {
type: 'custom'
name: string
price: { currency: 'SLE'; value: number }
quantity: number
description?: string
reference?: string
}
export async function POST(req: Request) {
const token = process.env.MONIME_ACCESS_TOKEN!
const spaceId = process.env.MONIME_SPACE_ID!
const { name, orderId, lineItems, metadata, callbackState } = (await req.json()) as {
name: string
orderId: string
lineItems: LineItem[]
metadata?: Record
callbackState?: string
}
if (!Array.isArray(lineItems) || lineItems.length === 0) {
return new Response(JSON.stringify({ error: 'lineItems is required' }), { status: 400 })
}
// Build redirect URLs on the server to prevent tampering
const appUrl = process.env.APP_URL || 'https://example.com'
const successUrl = `${appUrl}/api/checkout/success?orderId=${encodeURIComponent(orderId)}`
const cancelUrl = `${appUrl}/checkout/cancelled?orderId=${encodeURIComponent(orderId)}`
const res = await fetch('https://api.monime.io/v1/checkout-sessions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Monime-Space-Id': spaceId,
'Idempotency-Key': randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, successUrl, cancelUrl, lineItems, metadata, callbackState }),
})
if (!res.ok) {
const error = await res.text()
return new Response(JSON.stringify({ error }), { status: 500 })
}
const data = await res.json()
// TODO: Persist mapping of orderId -> checkoutSessionId for later verification
// await db.orders.update(orderId, { checkoutSessionId: data?.result?.id })
return Response.json({ redirectUrl: data?.result?.redirectUrl, sessionId: data?.result?.id })
}
```
Notes:
* Amount is derived from `lineItems` (`price.value × quantity`, where `value` is in SLE minor units).
* `callbackState` is optional and is echoed back via callbacks for correlation.
* Always send a new `Idempotency-Key` (e.g., UUID) per logical attempt.
## Call the endpoint from your UI
Example client-side handler using fetch:
```ts theme={null}
function toMinorUnits(amountSLE: number) {
return Math.round(amountSLE * 100)
}
async function startCheckout() {
const payload = {
name: 'Order #1001',
orderId: 'ord_1001',
lineItems: [
{ type: 'custom', name: 'Starter bundle', price: { currency: 'SLE', value: toMinorUnits(25) }, quantity: 1 },
],
metadata: { cartId: 'cart_123' },
callbackState: 'state_cart_123',
}
const res = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!res.ok) {
console.error('Checkout failed', await res.text())
return
}
const { redirectUrl } = await res.json()
if (redirectUrl) window.location.href = redirectUrl
}
```
## Handle successUrl with a server redirect
Point the `successUrl` to a Next.js API route that will:
1. Verify the session and update your server-side state
2. Redirect the user to your success UI page
Create `app/api/checkout/success/route.ts`:
```ts theme={null}
import { NextResponse } from 'next/server'
export async function POST(req: Request) {
const token = process.env.MONIME_ACCESS_TOKEN!
const spaceId = process.env.MONIME_SPACE_ID!
const url = new URL(req.url)
const orderId = url.searchParams.get('orderId')
if (!orderId) return new Response('Missing orderId', { status: 400 })
// 1) Load order and get stored checkoutSessionId
// const order = await db.orders.findOne(orderId)
// if (!order?.checkoutSessionId) return new Response('Order not found', { status: 404 })
// 2) Optionally verify status with the API
// const res = await fetch(`https://api.monime.io/v1/checkout-sessions/${order.checkoutSessionId}`, {
// headers: {
// Authorization: `Bearer ${token}`,
// 'Monime-Space-Id': spaceId,
// },
// })
// const data = await res.json()
// const status = data?.result?.status // e.g., 'completed'
// await db.orders.update(orderId, { status })
// 3) Redirect to your success UI
const uiUrl = new URL(`/checkout/success?orderId=${encodeURIComponent(orderId)}`, process.env.APP_URL || 'https://example.com')
return NextResponse.redirect(uiUrl)
}
```
Notes:
* You can embed extra context in the `successUrl` query (e.g., `orderId`).
* Persist the session ID when creating it, so you can look it up here and confirm status.
* Prefer webhooks for authoritative status; the success redirect is for UX continuity.
## Webhooks (recommended)
Use webhooks to reliably update your system about payment outcomes, even if the customer closes the browser before redirection.
How webhooks work on Monime
Verify webhook signatures securely
## Troubleshooting
* 400 Validation: ensure `lineItems` is non-empty and URLs are absolute
* 401/403 Auth: use a valid server-side token and correct `Monime-Space-Id`
* 409 Conflict: reuse `Idempotency-Key` only to retry the same logical request
## Next steps
Request schema and responses
Deep dive, options, and multi-stack examples
# Best Practices
Source: https://docs.monime.io/guide/webhook/best-practices
⏳...
# HMAC Verification
Source: https://docs.monime.io/guide/webhook/hmac-verification
⏳...
# Introduction
Source: https://docs.monime.io/guide/webhook/introduction
⏳...
# Structure and Events
Source: https://docs.monime.io/guide/webhook/structure
⏳...
## General Structure
Every webhook event for a resource is wrapped in the following structure:
```json theme={null}
{
"apiVersion": "2024-08-01", // The API version of the webhook event payload.
"event": {
"id": "", // The unique ID for the event; remains the same during reties.
"name": "., eg. payment_code.expired.
"timestamp": "1725018144" // The timestamp in Unix seconds when the event was fired.
},
"object": {
"id": "", // The id of the resource for which the event was triggered
"type": "" // The unique string representing the resource
},
"data": {} // Resource definition. (The payment code object)
}
```
⏳...
## Payment Code
⏳...
#### Supported Events
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-e8daf2bdea9f5e8587388a3a30b1efc6",
"name": "payment_code.created",
"timestamp": "1725018090"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423582Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "pending",
"ussdCode": "*715*1*7344331308#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-63e45a9f1e9652ed8419cc33abf13542",
"name": "payment_code.expired",
"timestamp": "1725022085"
},
"object": {
"id": "pmc-YhTQVSnJTHiiUqzzKXBBg2wJz",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T12:45:04.967509Z",
"customerTarget": null,
"expireTime": "2024-08-30T12:48:04.967536489Z",
"financialTarget": null,
"id": "pmc-YhTQVSnJTHiiUqzzKXBBg2wJz",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "expired",
"ussdCode": "*715*1*3836223839#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object) with
the addition of the `paymentData` object holding the information of the processed payment.
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-37b29f69ad8b560994aba0cb0a5a6d1c",
"name": "payment_code.processed",
"timestamp": "1725018144"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"paymentData": {
"amount": {
"currency": "SLE",
"value": 100
},
"channelData": {
"accountId": "232783****7",
"providerId": "m17",
"transactionReference": "MP240830.1142.B79174"
},
"metadata": {
"providerKey": "71e2b193-de88-5b83-99ae-662abfdb05e4"
},
"orderId": "ord-YhNdfzSsTYdAzPswmDHU4Siwe",
"orderNumber": "808956084535",
"paymentId": "spm-YhNdgPdTrrSi2PJD45Dg5Vp3X",
"transactionReference": "20240830-114224065-VNAEFR"
},
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "processing",
"ussdCode": "*715*1*7344331308#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-afd41c1aa68d555b8c7be85bb4a15e7f",
"name": "payment_code.completed",
"timestamp": "1725018144"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": true,
"totalPaymentCount": 1,
"totalPaymentSum": {
"currency": "SLE",
"value": 100
}
},
"status": "completed",
"ussdCode": "*715*1*7344331308#"
}
}
```
## Payout
⏳...
#### Supported Events
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/payout/the-payout-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-1890fe24fa7457698c8ea20944403e4b",
"name": "payout.failed",
"timestamp": "1725022815"
},
"object": {
"id": "pyt-YhUZVFtffj6JSbxpv9puNzYkE",
"type": "payout"
},
"data": {
"amount": {
"currency": "SLE",
"value": 10000
},
"charges": [],
"createTime": "2024-08-30T13:00:15.220463Z",
"destination": {
"accountId": "+23278341807",
"providerCode": "m17",
"transactionReference": null
},
"failureDetail": {
"code": "fundInsufficient",
"explanation": "Financial account has insufficient funds."
},
"id": "pyt-YhUZVFtffj6JSbxpv9puNzYkE",
"metadata": null,
"source": {
"financialAccountId": "fac-EBNBbzJXihwSFPcubG2v61YJH",
"transactionReference": null
},
"status": "failed"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/payout/the-payout-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-8f2287f0f68b53adbd57f1f0662757c2",
"name": "payout.completed",
"timestamp": "1725023198"
},
"object": {
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"type": "payout"
},
"data": {
"amount": {
"currency": "SLE",
"value": 100
},
"charges": [
{
"name": "Base",
"amount": {
"currency": "SLE",
"value": 1
},
"metadata": null
}
],
"createTime": "2024-08-30T13:06:37.3016Z",
"destination": {
"accountId": "+23278341807",
"providerCode": "m17",
"transactionReference": "CI240830.1306.B90450"
},
"failureDetail": null,
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"metadata": null,
"source": {
"financialAccountId": "fac-EBNBbzJXihwSFPcubG2v61YJH",
"transactionReference": "20240830-130637332-MRTMCV"
},
"status": "completed"
}
}
```
# Checkout Session
⏳...
#### Supported Events
Coming soon... ⏳
Coming soon... ⏳
Coming soon... ⏳
## =======
title: Structure and Events
sidebarTitle: Structure and Events
icon: "brackets-curly"
iconType: "solid"
-----------------
⏳...
## General Structure
Every webhook event for a resource is wrapped in the following structure:
```json theme={null}
{
"apiVersion": "2024-08-01", // The API version of the webhook event payload.
"event": {
"id": "", // The unique ID for the event; remains the same during reties.
"name": "., eg. payment_code.expired.
"timestamp": "1725018144" // The timestamp in Unix seconds when the event was fired.
},
"object": {
"id": "", // The id of the resource for which the event was triggered
"type": "" // The unique string representing the resource
},
"data": {} // Resource definition. (The payment code object)
}
```
⏳...
## Payment Code
⏳...
#### Supported Events
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-e8daf2bdea9f5e8587388a3a30b1efc6",
"name": "payment_code.created",
"timestamp": "1725018090"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423582Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "pending",
"ussdCode": "*715*1*7344331308#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-63e45a9f1e9652ed8419cc33abf13542",
"name": "payment_code.expired",
"timestamp": "1725022085"
},
"object": {
"id": "pmc-YhTQVSnJTHiiUqzzKXBBg2wJz",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T12:45:04.967509Z",
"customerTarget": null,
"expireTime": "2024-08-30T12:48:04.967536489Z",
"financialTarget": null,
"id": "pmc-YhTQVSnJTHiiUqzzKXBBg2wJz",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "expired",
"ussdCode": "*715*1*3836223839#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object) with
the addition of the `paymentData` object holding the information of the processed payment.
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-37b29f69ad8b560994aba0cb0a5a6d1c",
"name": "payment_code.processed",
"timestamp": "1725018144"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"paymentData": {
"amount": {
"currency": "SLE",
"value": 100
},
"channelData": {
"accountId": "232783****7",
"providerId": "m17",
"transactionReference": "MP240830.1142.B79174"
},
"metadata": {
"providerKey": "71e2b193-de88-5b83-99ae-662abfdb05e4"
},
"orderId": "ord-YhNdfzSsTYdAzPswmDHU4Siwe",
"orderNumber": "808956084535",
"paymentId": "spm-YhNdgPdTrrSi2PJD45Dg5Vp3X",
"transactionReference": "20240830-114224065-VNAEFR"
},
"progress": {
"isCompleted": false,
"totalPaymentCount": 0,
"totalPaymentSum": null
},
"status": "processing",
"ussdCode": "*715*1*7344331308#"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/paymentcode/the-payment-code-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-afd41c1aa68d555b8c7be85bb4a15e7f",
"name": "payment_code.completed",
"timestamp": "1725018144"
},
"object": {
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"type": "payment_code"
},
"data": {
"allowedProviders": [],
"amount": {
"currency": "SLE",
"value": 100
},
"createTime": "2024-08-30T11:41:30.513423Z",
"customerTarget": null,
"expireTime": "2024-08-30T11:46:30.513451171Z",
"financialTarget": null,
"id": "pmc-YhNZjnLJR4fY7T3GXAXJrQmLY",
"isActive": true,
"metadata": null,
"mode": "oneTime",
"name": "Topup",
"progress": {
"isCompleted": true,
"totalPaymentCount": 1,
"totalPaymentSum": {
"currency": "SLE",
"value": 100
}
},
"status": "completed",
"ussdCode": "*715*1*7344331308#"
}
}
```
## Payout
⏳...
#### Supported Events
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/payout/the-payout-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-1890fe24fa7457698c8ea20944403e4b",
"name": "payout.failed",
"timestamp": "1725022815"
},
"object": {
"id": "pyt-YhUZVFtffj6JSbxpv9puNzYkE",
"type": "payout"
},
"data": {
"amount": {
"currency": "SLE",
"value": 10000
},
"charges": [],
"createTime": "2024-08-30T13:00:15.220463Z",
"destination": {
"accountId": "+23278341807",
"providerCode": "m17",
"transactionReference": null
},
"failureDetail": {
"code": "fundInsufficient",
"explanation": "Financial account has insufficient funds."
},
"id": "pyt-YhUZVFtffj6JSbxpv9puNzYkE",
"metadata": null,
"source": {
"financialAccountId": "fac-EBNBbzJXihwSFPcubG2v61YJH",
"transactionReference": null
},
"status": "failed"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/payout/the-payout-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-8f2287f0f68b53adbd57f1f0662757c2",
"name": "payout.completed",
"timestamp": "1725023198"
},
"object": {
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"type": "payout"
},
"data": {
"amount": {
"currency": "SLE",
"value": 100
},
"charges": [
{
"name": "Base",
"amount": {
"currency": "SLE",
"value": 1
},
"metadata": null
}
],
"createTime": "2024-08-30T13:06:37.3016Z",
"destination": {
"accountId": "+23278341807",
"providerCode": "m17",
"transactionReference": "CI240830.1306.B90450"
},
"failureDetail": null,
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"metadata": null,
"source": {
"financialAccountId": "fac-EBNBbzJXihwSFPcubG2v61YJH",
"transactionReference": "20240830-130637332-MRTMCV"
},
"status": "completed"
}
}
```
The structure of the data field is the same as the object structure in the [Rest
API](https://docs.monime.io/apis2/2024-08-01/resources/payout/the-payout-object)
Below is a sample:
```json theme={null}
{
"apiVersion": "2024-08-01",
"event": {
"id": "wke-8f2287f0f68b53adbd57f1f0662757c2",
"name": "payout.delayed",
"timestamp": "1725023198"
},
"object": {
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"type": "payout"
},
"data": {
"amount": {
"currency": "SLE",
"value": 100
},
"charges": [],
"createTime": "2024-08-30T13:06:37.3016Z",
"destination": {
"accountId": "+23278341807",
"providerCode": "m17"
},
"failureDetail": null,
"failureDetail": null,
"id": "pyt-YhV3cLZ3bLsiEi3t14A6bFa42",
"metadata": null,
"source": {
"financialAccountId": "fac-EBNBbzJXihwSFPcubG2v61YJH",
"transactionReference": "20240830-130637332-MRTMCV"
},
"status": "delayed",
"delayedReason": "Provider state is ambiguous",
}
}
```
# Checkout Session
⏳...
#### Supported Events
Coming soon... ⏳
Coming soon... ⏳
Coming soon... ⏳
> > > > > > > 8c11980ce072affe07883ed5e3140c5dd3b920e3
# Troubleshoot
Source: https://docs.monime.io/guide/webhook/troubleshoot
Troubleshoot ⏳...
# Changelog
Source: https://docs.monime.io/apis/changelog
Track our API evolution
Track our API evolution — from the first public launch to the latest versions.
[OpenAPI file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/caph/2025-08-23/openapi.yaml)
### 🚀 Added
* **Receipts management**:
Two resource operations were introduced for payment receipt management:
* `GET /v1/receipts/{orderNumber}` → Retrieve full receipt details.
* `POST /v1/receipts/{orderNumber}/redeem` → Redeem entitlements (full or partial).
* **USD support for Checkout Sessions**:
Checkout Sessions now accept collections in **USD**, expanding beyond local currency support.
### 💡 Common Use Cases
* **Verify a purchase** – Retrieve a receipt by order number to confirm items, status, and timestamp.
* **Redeem event tickets or vouchers** – Mark entitlements as redeemed at point of entry.
* **Partial redemption** – Consume part of a multi-item receipt (e.g., ride credits, vouchers).
* **Full redemption** – Mark a receipt as fully consumed to prevent reuse.
* **Checkout in USD** – Allow merchants to receive funds in U.S. dollars.
### ❌ Breaking Changes
* ✅ None. Fully backward-compatible with `caph.2025-06-20`.
***
### Upgrade Guide — caph.2025-06-20 → caph.2025-08-23
* No migration required.
* All existing integrations remain valid.
***
This release extends the **caph** line into post-payment fulfillment (Receipts) and broadens
checkout session supports with USD collections.
### 🔄 Major Expansion — First `caph` Version
This version officially launched the **`caph` release line**, introducing versioned endpoints (`/v1/...`) and
establishing the foundation for stable, long-term growth.
[OpenAPI
file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/caph/2025-06-20/openapi.yaml)
### 🚀 Added
* `POST /v1/payments` → Unified payment initiation.
* `GET /v1/financial-accounts`, `/v1/financial-transactions` → Accounts and ledger-style transaction history.
* `POST /v1/checkout-sessions` → Hosted checkout for e-commerce & embedded flows.
* `POST /v1/internal-transfers` → Secure transfers between accounts.
* `POST /v1/ussd-otps` → OTP generation & validation.
* `GET /v1/provider-kyc/{providerId}` → Standardized provider KYC.
### 🏗️ New Resources
* `Payment`, `CheckoutSession`, `FinancialAccount`, `FinancialTransaction`,
`InternalTransfer`, `UssdOtp`, `ProviderKYC`.
### ❌ Breaking Changes (from 2024-08-01)
* All endpoints moved under `/v1/...` namespace.
* Enumerated values for fields changed from camelCase to snake\_case.
* Schema migration: The schema of all previous resources has been updated, fields renamed, dropped, or added.
* Legacy unversioned endpoints (`/banks`, `/momos`, `/countries`, `/payment-codes`, `/payouts`, `/webhooks`) are no
longer supported.
***
### Upgrade Guide — 2024-08-01 → caph.2025-06-20
If you’re upgrading from the **2024-08-01** version, follow these steps:
1. Switch to `/v1/...` endpoints.
2. Replace the schema of all old resources with the new ones.
3. Re-register webhooks under `/v1/webhooks`.
4. Validate new flows (payments, checkout, accounts).
✅ After this migration, you are on the **caph release track**, ensuring compatibility with all future updates.
### 🎉 Public API Launch
This release marked the **public debut of our API**, giving developers their first programmable entry point
into the platform.
[OpenAPI file](https://raw.githubusercontent.com/monimesl/monime-developer-apis/refs/heads/main/versions/2024-08-01-openapi.yaml)
### Operations
* `/banks`, `/momos`, `/countries` → Provider and country lookups.
* `/payment-codes` → Generate short-lived collection codes.
* `/payouts` → Disburse funds externally.
* `/kyc-verifications/{providerCode}` → Provider-level KYC checks.
* `/webhooks` → Subscribe to basic events.
### 🏗️ Base Schemas
* `Bank`, `Country`, `Momo`, `PaymentCode`, `Payout`, `Webhook`, `KYCVerification`.
***
# Introduction
Source: https://docs.monime.io/apis/index
Welcome to Monime’s API Reference — your gateway to integrating payments, payouts, embedded finance, and more through
simple, scalable, and intuitive APIs.
***
## Base URLs
The Live and Test APIs operate in two fully separate environments:
* **Live:** `https://api.monime.io` with (Live token)
* **Test:** `https://api.monime.io` with (Test token)
Read [Personal Access Tokens](/dashboard-guide/personal-access-tokens) on how to create Live and Test tokens.
***
## Standards & Conventions
### RESTful Design
The API follows standard HTTP methods:
* `GET` — fetch a single object or list of objects
* `POST` — create a new object or trigger an action
* `PATCH` — make partial updates to an object (send only what you want to change)
* `DELETE` — remove an object
### JSON by Default
Unless stated otherwise, requests and responses use **JSON**.
* Fields are returned with stable, predictable keys
* Moneys are given in **minor currency units** (e.g., cents for SLE and USD)
* Timestamps are in **UTC** using **RFC 3339** format, e.g. `2025-08-24T06:00:00Z`
### Usable Status Codes
The API uses standard HTTP status codes:
* `200` — success, i.e., server handled the request.
* `4xx` — client errors such as invalid input, or authentication issues.
* `5xx` — internal server errors, safe to retry with backoff
# Get Bank
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/bank/get-bank
get /v1/banks/{providerId}
Retrieves detailed information about a specific bank provider using its Monime-assigned provider ID.
# List Banks
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/bank/list-banks
get /v1/banks
Retrieves a list of supported banks available in the specified country. Useful for rendering provider selection options during user payment setup or onboarding.
# Bank
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/bank/object
```json JSON Model theme={null}
{
"providerId": "slb004",
"name": "Guarantee Trust Bank",
"country": "SL",
"status": {
"active": null
},
"featureSet": {
"payout": {
"canPayTo": null,
"schemes": [],
"metadata": null
},
"payment": {
"canPayFrom": null,
"schemes": [],
"metadata": null
},
"kycVerification": {
"canVerifyAccount": null,
"metadata": null
}
},
"createTime": null,
"updateTime": null
}
```
The provider ID for the momo as assigned by Monime.
Example: slb004
The name of the bank.
Example: Guarantee Trust Bank
The country of the bank.
Example: SL
The status of the bank's operations within monime'.
Whether or not this bank is active within Monime.
The set of Monime features that the bank supports.'
The bank's payout feature information.
Whether or not Monime can pay out to an account in the bank.
The supported payout schemes of the bank.
Further metadata describing this bank's payout feature.
The bank's payment feature information.
Whether or not Monime can accept payment from an account in the bank.
The supported payment schemes of the bank.
Further metadata describing this bank's payment feature.
The bank's KYC verification feature information.
Whether or not Monime can verify an account's KYC' in the bank.
Further metadata describing this bank's KYC verification feature.
The time the bank's support was added.
The last time the bank's support was updated.
# Create Checkout Session
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/checkout-session/create-checkout-session
post /v1/checkout-sessions
Creates a new checkout session to initiate a user payment experience.
# Delete Checkout Session
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/checkout-session/delete-checkout-session
delete /v1/checkout-sessions/{id}
Deletes a checkout session. This operation is only allowed if the session has not yet been initiated by the user.
# Get Momo
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/momo/get-momo
get /v1/momos/{providerId}
Retrieves detailed information about a specific momo provider using its Monime-assigned provider ID.
# List Momos
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/momo/list-momos
get /v1/momos
Retrieves a list of supported momos available in the specified country. Useful for rendering provider selection options during user payment setup or onboarding.
# Momo
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/momo/object
```json JSON Model theme={null}
{
"providerId": "m17",
"name": "Orange Money",
"country": "SL",
"status": {
"active": null
},
"featureSet": {
"payout": {
"canPayTo": null,
"schemes": [],
"metadata": null
},
"payment": {
"canPayFrom": null,
"schemes": [],
"metadata": null
},
"kycVerification": {
"canVerifyAccount": null,
"metadata": null
}
},
"createTime": null,
"updateTime": null
}
```
The provider ID for the momo as assigned by Monime.
Example: m17
The name of the momo.
Example: Orange Money
The country of the momo.
Example: SL
The status of the momo's operations within monime'.
Whether or not this momo is active within Monime.
The set of Monime features that the momo supports.'
The momo's payout feature information.
Whether or not Monime can pay out to an account in the momo.
The supported payout schemes of the momo.
Further metadata describing this momo's payout feature.
The momo's payment feature information.
Whether or not Monime can accept payment from an account in the momo.
The supported payment schemes of the momo.
Further metadata describing this momo's payment feature.
The momo's KYC verification feature information.
Whether or not Monime can verify an account's KYC' in the momo.
Further metadata describing this momo's KYC verification feature.
The time the momo's support was added.
The last time the momo's support was updated.
# Create Payout
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/create-payout
post /v1/payouts
Creates a new payout with a specified amount, destination, and optional source account.
# Delete Payout
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/delete-payout
delete /v1/payouts/{id}
Deletes a payout object by ID. This is only allowed if the payout is still in a pre-processing state (e.g., pending or scheduled).
# Get Payout
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/get-payout
get /v1/payouts/{id}
Retrieves a payout object by its unique identifier.
# List Payouts
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/list-payouts
get /v1/payouts
Retrieves list of payouts.
# Payout
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/object
A **Payout** is a disbursement of funds from a **Financial Account** to a designated destination such as a **Bank Account** or **Mobile Money Wallet**.\
It represents outbound money flows and is commonly used for **salary disbursements**, **vendor payments**, and **refunds** in automated workflows.
Each payout records the **amount**, the **source account**, the **destination details**, and optional **metadata**.\
It also tracks **status changes** throughout its lifecycle and may include **provider-specific references** for reconciliation.
```json JSON Model theme={null}
{
"id": null,
"status": "pending",
"amount": {
"currency": null,
"value": null
},
"source": {
"financialAccountId": null,
"transactionReference": null
},
"destination": {
"type": "bank"
},
"fees": [],
"failureDetail": {
"code": "unknown",
"message": null
},
"createTime": null,
"updateTime": null,
"ownershipGraph": {
"owner": {
"id": null,
"type": null,
"metadata": null,
"": null
}
},
"metadata": null
}
```
Unique identifier for the payout object.
Current status of the payout:
* 'pending': Created but not yet scheduled.- 'processing': Currently being processed.
* 'completed': Successfully completed.
* 'failed': Processing failed or rejected.
Available options: pending processing completed failed
Amount to be paid to the destination provider account.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
SourceAccount of funds, including debit account and transaction details. Can be null if the default account is used.
ID of the financial account where the funds is disbursed from.
Internal Monime reference for the debit transaction from the source account. This is null until the payout is processed.
Destination account details that will receive the payout.
Specifies the type of destination account. Must be either 'bank', 'momo', or 'wallet'.
Available options: bank momo wallet
List of fees applied during payout processing. Empty if not yet processed.
Detailed information about the failure, if the payout status is 'failed'.
**Error code** indicating why the payout failed. Possible values include:
* unknown: General or unclassified failure.
* fund\_insufficient: Source account lacks sufficient funds.
* authorization\_failed: Authorization failed or was denied.
* provider\_unknown: Unexpected error from the external provider.
* provider\_account\_blocked: The destination provider account is blocked.
* provider\_account\_missing: The destination provider account does not exist.
* provider\_account\_quota\_exhausted: Daily or per-transaction quota has been exceeded.
Available options: unknown fund\_insufficient authorization\_failed provider\_unknown provider\_account\_blocked provider\_account\_missing provider\_account\_quota\_exhausted
**Human-readable message** providing more context about the failure. Useful for logs, dashboards, or client-facing error messages.
Timestamp indicating when the payout object was created.
Timestamp indicating when the payout object was last updated.
Full ownership graph tracing the origin of this payout objects across multiple objects.
**Immediate object** that owns this entity. This is the direct originator or source object.
**Unique ID** of the object instance that owns this entity.
**Type of the object** that owns this entity. Examples include: 'internal\_transfer', 'checkout\_session', 'payment\_code'.
**Arbitrary metadata** describing the owning object.
Optional metadata attached to the payout for additional context.
# Update Payout
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/payout/update-payout
patch /v1/payouts/{id}
Updates an existing payout object by ID. Fields can only be modified if the payout has not yet been processed.
# Get Provider KYC
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/provider-kyc/get-provider-kyc
get /v1/provider-kyc/{providerId}
Retrieves the KYC profile of an account from a specified provider.
# Provider KYC
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/provider-kyc/object
A **Provider KYC** object represents the **know-your-customer (KYC) information** retrieved from a financial provider (e.g., Mobile Money operator, Bank).
***
```json JSON Model theme={null}
{
"account": {
"id": null,
"name": null,
"holderName": null,
"metadata": null
},
"provider": {
"id": "m17",
"type": "momo",
"name": "Orange Money"
}
}
```
The information of the account in the provider's ecosystem.
Unique identifier of the account in the provider's system.
Display name associated with the account, if different from the holder's name.
Full name of the account holder as registered with the provider.
Additional metadata of the account.
The information of the financial provider hosting the account.
The id of the provider as assigned by Monime.
Example: m17
The type of the provider.
Example: momo
Available options: momo bank wallet
The name of the provider
Example: Orange Money
# Get Receipt
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/receipt/get-receipt
get /v1/receipts/{orderNumber}
Retrieves a receipt using its order number.
# Receipt
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/receipt/object
A **Receipt** is a record of entitlements generated by Monime whenever a payment completes successfully.\
It serves as proof of what the customer is entitled to claim — such as tickets, vouchers, credits, or digital rights.\
Receipt links a **payment** via an order to **entitlement claims**, enabling both verification and controlled redemption via APIs.
### Use Cases
* **Purchase Verification**\
Confirm that a customer’s payment went through and display transaction details in your app without manual reconciliation.
* **Ticket & Voucher Redemption**\
Use receipts as redeemable proof of access — for example, scanning a receipt at an event gate or validating a voucher at checkout.
* **Partial Consumption**\
Support use cases where receipts hold multiple entitlements, such as ride credits or digital assets, and allow them to be redeemed incrementally.
```json JSON Model theme={null}
{
"status": "not_redeemed",
"orderName": null,
"orderNumber": null,
"orderAmount": {
"currency": null,
"value": null
},
"createTime": null,
"updateTime": null,
"entitlements": [],
"metadata": null
}
```
Lifecycle status of the receipt.
Available options: not\_redeemed partially\_redeemed fully\_redeemed
Human friendly name of the order.
Human-friendly order number.
Total order amount in minor units and currency.
The [3-letter](https://en.wikipedia.org/wiki/ISO_4217) ISO currency code. Currently supported: 'SLE', 'USD'
The value representation in the currency's minor unit. E.g. For 1 Leone (SLE 1), the value should be 100, denoting cents, the minor unit.
The timestamp when the receipt was created.
The last timestamp when the receipt was updated.
Entitlements granted by this receipt; each can be redeemed until exhausted.
Optional metadata for attaching context or tracking info.
# Redeem Receipt
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/receipt/redeem-receipt
post /v1/receipts/{orderNumber}/redeem
Redeem one or more entitlements from a receipt. When processing a bulk redemption, if any entitlement is already exhausted, the entire operation is rejected.
# Create USSD OTP
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/ussd-otp/create-ussd-otp
post /v1/ussd-otps
Creates a new USSD OTP session for secure phone-bound verification.
# Delete USSD OTP
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/ussd-otp/delete-ussd-otp
delete /v1/ussd-otps/{id}
Deletes a USSD OTP session by its ID.
# Get USSD OTP
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/ussd-otp/get-ussd-otp
get /v1/ussd-otps/{id}
Retrieve a single USSD OTP session by its ID.
# List USSD OTPs
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/ussd-otp/list-ussd-otps
get /v1/ussd-otps
Retrieves a list of USSD OTP sessions with optional filtering and pagination.
# Ussd Otp
Source: https://docs.monime.io/apis/versions/caph-2025-08-23/ussd-otp/object
A **USSD OTP** represents a **one-time passcode session** used to authenticate users through a USSD dial flow.\
It enables secure, **phone-bound verification**, ensuring that the person interacting via USSD is the legitimate account holder.
In addition to generating and validating the OTP, the flow may include **user-facing feedback messages** that confirm the process.
***
```json JSON Model theme={null}
{
"id": null,
"status": "pending",
"dialCode": null,
"authorizedPhoneNumber": null,
"verificationMessage": null,
"createTime": null,
"expireTime": null,
"metadata": null
}
```
**Unique identifier** for this USSD OTP session.
**Status** of the OTP session. One of:
* pending: Awaiting verification.
* verified: OTP was successfully confirmed.
* expired: OTP expired before verification.
Available options: pending verified expired
**USSD dial code** that the user should dial (e.g., \*715\*12345#) to initiate the OTP verification.
**Authorized phone number** (MSISDN) associated with this OTP. May be masked for privacy.
**Message** shown to the user after successful verification, typically rendered on the USSD interface.
MaxLength: 255
Timestamp when this OTP session was created.
**Expiration time** after which the OTP becomes invalid.
**Optional metadata** for attaching additional context or tracking info to this OTP session.