Developer documentation

Build a backend-to-backend donation flow with the Developer API. Add Akabbo donations to WordPress, embed campaign forms on your website.

Updated May 15, 2026

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.

extensionWordPress plugin Install the Akabbo Donations plugin from WordPress.org to add donation forms to a WordPress site. open_in_new
code_blocksCampaign embed Open a campaign in Akabbo, use the embed option on the campaign view, copy the iframe code, then paste it into an HTML page, CMS custom HTML block, or website builder embed block.
apiDeveloper API Build a custom backend donation flow using OAuth2 client credentials and scoped Bearer tokens.
Important: Never expose your 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.com

Authentication

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_HERE
The Bearer token identifies the developer app and the profile connected to that app. The API automatically scopes requests to that profile.

Recommended Donation Flow

The donor should submit the donation form to the developer's backend, not directly to Akabbo.

Donor Browser
  -> Developer Backend
  -> Akabbo API

Do not do this:

Donor Browser
  -> Akabbo API with Bearer token

Donation Endpoints

Profile and campaign donations use the same request body. Choose the endpoint based on where the donation should go.

Donation targetEndpointWhen to use it
ProfilePOST/v1/profile/donate/Use this when a donor is donating directly to the authenticated profile.
CampaignPOST/v1/campaign/{campaign_slug}/donate/Use this when a donor is donating to a specific campaign owned by the authenticated profile.
The payload is the same for profile and campaign donations. Only the endpoint changes.

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

FieldDescription
referencePublic 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

FieldRequiredDescription
amountYesDonation amount. Example: "10000".
currencyYesCurrency code. Defaults to UGX.
emailNoDonor email address.
messageNoOptional donation message.
modeYesPayment mode. Must be either MM or CARD; it cannot be null.
anonymousYesSet to true to hide the donor name publicly. Defaults to false.

Mobile Money Fields

FieldRequiredDescription
fsourceYesFunding source, usually the donor phone number.

Card Fields

FieldRequiredDescription
countryYesCountry code. Defaults to UG.
first_nameYesCard payer first name.
last_nameYesCard payer last name.
streetYesCard billing street address.
cityYesCard billing city.
stateYesCard billing state or region.
zipYesCard billing postal code. Defaults to 256.

Donation Identity Fields

FieldDescription
donorOptional name of the person donating.
charge_donorSet to true if the donor should pay payment charges.

Status Values

Common payment statuses include:

StatusMeaning
PENDINGThe payment has been initiated and is waiting for confirmation.
SUCCESSFULThe payment completed successfully.
COMPLETEDThe payment completed successfully.
FAILEDThe 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."
}
Upload KYC documents to verify the profile via the dashboard & unlock higher collection limits. This affects profile donations and campaigns under that profile.

Backend Integration Example

The developer backend should store the access token securely and call the donation endpoint after a donor submits a form.

Validate donor input on your backend and build an allowlisted payload before calling Akabbo. Do not forward the raw browser request body directly.
// 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_secret on 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 reference for status checks.
  • Always verify status from the backend before showing final payment success to the donor.

Last updated: May 15, 2026