Developers
Build on the platform, not around it.
One API reaches mobile money, banks, cards and agents in every market Sente serves. This guide takes you from a new account to your first payment in the sandbox; the developer portal holds your keys, the full API reference and webhook logs.
Step 1
Create a developer account
Sign up at https://developers.sente-platform.com/signup. It is free, and sandbox access needs no approval.
Step 2
Register an app and get a sandbox key
In the portal, create an app and issue a sandbox API key with the payments:write scope.
The full key is shown once. Sente stores only a hash of it, so copy it into your secret manager straight away; afterwards the portal shows its prefix only.
Sandbox and production use the same API address. The key decides the mode: a sandbox key never moves real money.
Step 3
Create your first checkout session
A checkout session asks a customer to pay a merchant a fixed amount. Amounts are whole numbers in minor units (cents, kobo), never decimals, with an ISO 4217 currency code.
Send a fresh UUID in Idempotency-Key for every new payment, and reuse it when you retry, so a payment is never created twice.
Request curl -X POST https://api.sente-platform.com/v1/checkout-sessions -H "X-Api-Key: $SENTE_API_KEY" -H "Idempotency-Key: 6f1c2a1e-6c1a-4f43-9d55-6d3f0e7b2c91" -H "Content-Type: application/json" -d '{ "merchantId": "your-merchant-id", "amountMinorUnits": 150000, "currency": "KES", "reference": "order-1042" }'Step 4
Send the customer to pay
The response carries the session id and its status. In the sandbox the id starts with sandbox_.
Send your customer to https://merchant.sente-platform.com/checkout/<checkoutSessionId>, where they scan a QR code and confirm the payment in the Sente app.
Response · 201 Created { "checkoutSessionId": "sandbox_9b2e4c7a-…", "status": "PENDING" }Step 5
Follow the payment
A session moves from PENDING to SETTLED, or to FAILED. Read it whenever you need to, or stream every change as it happens.
Read or stream the status curl https://api.sente-platform.com/v1/checkout-sessions/$SESSION_ID -H "X-Api-Key: $SENTE_API_KEY" # Server-sent events, one per status change curl -N https://api.sente-platform.com/v1/checkout-sessions/$SESSION_ID/events -H "X-Api-Key: $SENTE_API_KEY"Step 6
Receive webhooks
Register an HTTPS endpoint in the portal to be told about events instead of polling. Each delivery is signed with your endpoint's signing secret.
The X-Sente-Signature header looks like t=1729680000,v1=<hex>. v1 is an HMAC-SHA256 of the timestamp, a dot and the raw request body. Reject a delivery whose signature does not match; we also recommend rejecting one whose timestamp is more than five minutes old.
Failed deliveries are retried twice: after one minute and after five. Answer with any 2xx status once you have stored the event.
Verify a signature (Node.js) import { createHmac, timingSafeEqual } from "node:crypto"; export function verifySenteSignature(rawBody, header, secret) { const parts = Object.fromEntries(header.split(",").map((p) => p.split("="))); const age = Math.abs(Date.now() / 1000 - Number(parts.t)); if (!parts.t || !parts.v1 || age > 300) return false; const expected = Buffer.from( createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex"), ); const given = Buffer.from(parts.v1); return given.length === expected.length && timingSafeEqual(given, expected); }Step 7
Go live
When your integration works in the sandbox, submit your app for review in the portal. Once it is approved, issue a production key and swap it in. Nothing else changes.
Works in your language.
The Sente API is plain HTTPS and JSON, so any language that can make a web request can use it — no special runtime, no lock-in. Here is the same first payment in the languages teams use most.
Also works with
- JavaScript
- PHP
- Ruby
- Swift
- Dart
- Rust
- Elixir
Official SDKs are on the way, open source under github.com/sente-platform.
const response = await fetch("https://api.sente-platform.com/v1/checkout-sessions", {
method: "POST",
headers: {
"X-Api-Key": process.env.SENTE_API_KEY!,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
merchantId: "your-merchant-id",
amountMinorUnits: 150000,
currency: "KES",
reference: "order-1042",
}),
});
const session = await response.json(); // { checkoutSessionId, status: "PENDING" }Conventions every endpoint follows.
Money
Integer minor units plus an ISO 4217 currency. A decimal amount is rejected.
Idempotency
Same key and body replays the first response; same key, different body returns 409 IDEMPOTENCY_CONFLICT. Keys last 24 hours.
Rate limits
60 requests a minute in the sandbox, 600 in production. Every response carries X-RateLimit-* headers; a 429 carries Retry-After.
Errors
JSON bodies with a stable error code. Validation problems return 422 with the fields at fault.
Ready for the full reference?
Every endpoint and schema lives in the developer portal, along with your keys and webhook logs. Stuck? Email us.