Escrow Safe Trade is live: protect your next high-value deal Learn more
ProductsPayment links & checkoutM-Pesa, cards, invoices, split payoutsEscrow Safe TradeMilestone and release-based escrowWallets & P2PPersonal and business walletsChama, Lengo & DeniGroup savings, goals and IOUsBusiness toolkitAccounting, payroll, POS, ticketingBulk payments & payrollPay many people in one uploadSubscriptions & billingRecurring plans and renewalsRent, loans & donationsCollections and campaignsAll products
SolutionsMerchantsBuyersChama groupsBusiness solutionsIndustries
Pricing
DevelopersDeveloper overviewQuickstart, auth and sandboxREST APIsCheckout, invoices and requestsWebhooksSigned, real-time eventsWallet-as-a-ServiceVirtual sub-accountsDocumentationGuides and API reference
Security
CompanyAbout usCareersPartnersBlogHelp centreContact us
Log in Get started Talk to sales
Savings & credit

Deni (Debt / IOU)

Record who owes what, for users and for guests with only a phone or email. Includes hosted pay and acknowledgement pages, reminders and disputes.

Base URLhttps://api.paysasa.com/api/v1Authx-api-keyFormatJSON

Deni records IOUs for registered users and guests (phone/email). Each record gets a public_token for hosted pay and acknowledgment pages. Wallet settlement uses p2p_transfer fees; M-PESA uses checkout metadata deni_public_checkout. Reminder channels (SMS/email) debit the creditor wallet per send; quote fees with GET /deni/reminder-fees.

POST/deni#
JavaScript
const res = await fetch("https://api.paysasa.com/api/v1/deni", {
  method: "POST",
  headers: { "Content-Type": "application/json", Authorization: "Bearer YOUR_API_KEY" },
  body: JSON.stringify({
    creditor_wallet_id: "wallet_creditor_id",
    debtor_phone: "2547XXXXXXXX",
    debtor_email: "[email protected]",
    debtor_name: "Jane Doe",
    principal_amount: 50000,
    currency: "KES",
    description: "Goods on credit",
    due_at: new Date(Date.now() + 7 * 86400000).toISOString(),
    reminder_channels: ["sms", "email"],
    allow_partial_payment: true,
  }),
});
const { deni } = await res.json();
// deni.public_token → share /pay/deni/{token}
GET/deni?role=creditor|debtor|all#
PATCH/deni/:id#

Creditor adjusts remaining balance; debtor is notified.

POST/deni/:id/remind#

Body: { "channels": ["sms","email"] }

POST/deni/:id/pay#

Authenticated debtor wallet + PIN (P2P fees).

Public (no API key)#

GET /deni/token/:token/public

POST /deni/token/:token/checkout — M-PESA checkout

POST /deni/token/:token/pay — wallet (session)

POST /deni/token/:token/acknowledge — acknowledge or decline

POST /deni/token/:token/dispute — guest dispute