Integration Options
Choose the simplest integration that matches your website. Use the API only when you need a custom donation experience or server-side automation.
client_secret or Bearer token in frontend JavaScript, HTML, mobile apps, or public donation forms. Your backend server should call the Akabbo API. Base URL
https://api.akabbo.comAuthentication
The Developer API uses OAuth2 client credentials. The developer backend exchanges its client_id and client_secret for an access token.
Get Access Token
POST/oauth/token/
curl -X POST https://api.akabbo.com/oauth/token/ \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"Token Response
{
"access_token": "ACCESS_TOKEN_HERE",
"expires_in": 36000,
"token_type": "Bearer",
"scope": "read write"
}Use the access token in API requests:
Authorization: Bearer ACCESS_TOKEN_HERERecommended Donation Flow
The donor should submit the donation form to the developer's backend, not directly to Akabbo.
Donor Browser
-> Developer Backend
-> Akabbo APIDo not do this:
Donor Browser
-> Akabbo API with Bearer tokenDonation Endpoints
Profile and campaign donations use the same request body. Choose the endpoint based on where the donation should go.
| Donation target | Endpoint | When to use it |
|---|---|---|
| Profile | POST/v1/profile/donate/ | Use this when a donor is donating directly to the authenticated profile. |
| Campaign | POST/v1/campaign/{campaign_slug}/donate/ | Use this when a donor is donating to a specific campaign owned by the authenticated profile. |
Mobile Money Donation Request
curl -X POST https://api.akabbo.com/v1/campaign/community-water-project/donate/ \
-H "Authorization: Bearer ACCESS_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"amount": "10000",
"currency": "UGX",
"anonymous": false,
"donor": "Jane Doe",
"charge_donor": false,
"fsource": "2567XXXXXXX",
"email": "jane@example.com",
"message": "Supporting this campaign",
"mode": "MM"
}'Card Donation Request
curl -X POST https://api.akabbo.com/v1/campaign/community-water-project/donate/ \
-H "Authorization: Bearer ACCESS_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"amount": "10000",
"currency": "UGX",
"anonymous": false,
"donor": "Jane Doe",
"charge_donor": false,
"email": "jane@example.com",
"message": "Supporting this campaign",
"mode": "CARD",
"country": "UG",
"first_name": "Jane",
"last_name": "Doe",
"street": "Plot 10 Kampala Road",
"city": "Kampala",
"state": "Central",
"zip": "00256"
}'Donation Response
{
"reference": "1b1c1111-2222-3333-4444-777777777777",
"link": null
} For MM payments, link is null. For CARD payments, link contains the gateway checkout URL the user should open to complete payment.
Response Fields
| Field | Description |
|---|---|
reference | Public donation reference. Store this value and use it to check payment status. |
link | Gateway checkout link for CARD payments. This is null for MM payments. |
Check Profile Donation Status
GET/v1/profile/donate/{reference}/status/
curl https://api.akabbo.com/v1/profile/donate/0a0b1111-2222-3333-4444-555555555555/status/ \
-H "Authorization: Bearer ACCESS_TOKEN_HERE"Check Campaign Donation Status
GET/v1/campaign/{campaign_slug}/donation/{reference}/status/
curl https://api.akabbo.com/v1/campaign/community-water-project/donation/1b1c1111-2222-3333-4444-777777777777/status/ \
-H "Authorization: Bearer ACCESS_TOKEN_HERE"Status Response
The status response is the same for profile and campaign donations. Only the status endpoint changes.
{
"ref": "0a0b1111-2222-3333-4444-555555555555",
"status": "PENDING",
"network_response": null
}Request Fields
Fields Used by Both MM and CARD
| Field | Required | Description |
|---|---|---|
amount | Yes | Donation amount. Example: "10000". |
currency | Yes | Currency code. Defaults to UGX. |
email | No | Donor email address. |
message | No | Optional donation message. |
mode | Yes | Payment mode. Must be either MM or CARD; it cannot be null. |
anonymous | Yes | Set to true to hide the donor name publicly. Defaults to false. |
Mobile Money Fields
| Field | Required | Description |
|---|---|---|
fsource | Yes | Funding source, usually the donor phone number. |
Card Fields
| Field | Required | Description |
|---|---|---|
country | Yes | Country code. Defaults to UG. |
first_name | Yes | Card payer first name. |
last_name | Yes | Card payer last name. |
street | Yes | Card billing street address. |
city | Yes | Card billing city. |
state | Yes | Card billing state or region. |
zip | Yes | Card billing postal code. Defaults to 256. |
Donation Identity Fields
| Field | Description |
|---|---|
donor | Optional name of the person donating. |
charge_donor | Set to true if the donor should pay payment charges. |
Status Values
Common payment statuses include:
| Status | Meaning |
|---|---|
PENDING | The payment has been initiated and is waiting for confirmation. |
SUCCESSFUL | The payment completed successfully. |
COMPLETED | The payment completed successfully. |
FAILED | The payment failed. |
Error Responses
Invalid or Missing Token
{
"detail": "Authentication credentials were not provided."
}Donation Not Found
{
"detail": "Donation not found"
}Validation Error
{
"amount": [
"A valid number is required."
]
}Payment Limit or Permission Error
{
"error": "This profile has reached the maximum amount allowed for unverified profiles."
}Backend Integration Example
The developer backend should store the access token securely and call the donation endpoint after a donor submits a form.
// Example Node.js/Express-style flow
app.post("/api/donate", async (req, res) => {
const token = await getAkabboAccessToken();
const payload = {
amount: req.body.amount,
currency: req.body.currency || "UGX",
anonymous: Boolean(req.body.anonymous),
donor: req.body.donor || null,
charge_donor: Boolean(req.body.charge_donor),
fsource: req.body.fsource,
email: req.body.email || null,
message: req.body.message || "",
mode: "MM"
};
const response = await fetch(
"https://api.akabbo.com/v1/campaigns/community-water-project/donate/",
{
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
}
);
const data = await response.json();
res.status(response.status).json(data);
});Security Checklist
- Keep
client_secreton the backend only. - Keep Bearer tokens on the backend only.
- Do not call Akabbo directly from browser JavaScript with a Bearer token.
- Validate donor input and send only approved payload fields to Akabbo.
- Store the returned
referencefor status checks. - Always verify status from the backend before showing final payment success to the donor.
Last updated: May 15, 2026
